Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Solving electronics problems with Perl

by tsee (Curate)
on Sep 07, 2003 at 13:48 UTC ( [id://289568]=perlcraft: print w/replies, xml ) Need Help??

   1: #!/usr/bin/perl
   2: use strict;
   3: use warnings;
   4: 
   5: # Perl solving a physics / electrodynamics problem involving
   6: # symbolic mathematics, derivatives and complex numbers:
   7: 
   8: use Math::Symbolic qw/:all/;
   9: use Math::Complex;
  10: 
  11: # Given the following simple circuit:
  12: #
  13: #  ----|||||-----/\/\/\----       (R = resistor,
  14: # |      R          L      |       L = solenoid,
  15: # |                        |       U = alternating voltage)
  16: #  ---------O ~ O----------
  17: #            U(t)
  18: #
  19: # Question: What's the current in this circuit?
  20: #
  21: # We'll need some physics before letting the computer do the
  22: # math:
  23: # Applying Kirchhoff's rules, one quickly ends up with the
  24: # following differential equation for the current:
  25: #     (L * dI/dt) + (R * I)  =  U
  26: 
  27: my $left  = parse_from_string('L * total_derivative(I(t), t) + R * I(t)');
  28: my $right = parse_from_string('U(t)');
  29: 
  30: 
  31: # If we understand current and voltage to be complex functions,
  32: # we'll be able to derive. ("'" denoting complex here)
  33: #    I'(t) = I'_max * e^(i*omega*t)
  34: #    U'(t) = U_max  * e^(i*omega*t)
  35: # (Please note that omega is the frequency of the alternating voltage.
  36: # For example, the voltage from German outlets has a frequency of 50Hz.)
  37: 
  38: my $argument = parse_from_string('e^(i*omega*t)');
  39: my $current  = parse_from_string('I_max') * $argument;
  40: my $voltage  = parse_from_string('U_max') * $argument;
  41: 
  42: # Putting it into the equation:
  43: $left->implement( I  => $current );
  44: $right->implement( U => $voltage );
  45: 
  46: $left = $left->apply_derivatives()->simplify();
  47: 
  48: # Now, we can solve the equation to get a complex function for
  49: # the current:
  50: 
  51: $left  /= $argument;
  52: $right /= $argument;
  53: my $quotient = parse_from_string('R + i*omega*L');
  54: $left  /= $quotient;
  55: $right /= $quotient;
  56: 
  57: # Now we have:
  58: #    $left    = $right
  59: #    I_max(t) = U_max / (R + i*omega*L)
  60: # But I_max(t) is still complex and so is the right-hand-side of the
  61: # equation!
  62: 
  63: # Making the symbolic i a "literal" Math::Complex i
  64: $right->implement(
  65:     e => Math::Symbolic::Constant->euler(),
  66:     i => Math::Symbolic::Constant->new(i),    # Math::Complex magic
  67: );
  68: 
  69: print <<'HERE';
  70: Sample of complex maximum current with the following values:
  71:   U_max => 100
  72:   R     => 10
  73:   L     => 10
  74:   omega => 1
  75: HERE
  76: 
  77: print "Computed to: "
  78:   . $right->value(
  79:     U_max => 100,
  80:     R     => 10,
  81:     L     => 10,
  82:     omega => 1,
  83:   ),
  84:   "\n\n";
  85: 
  86: # Now, we're dealing with alternating current and voltage.
  87: # So let's make a generator that generates nice current
  88: # functions of time!
  89: #   I(t) = Re(I_max(t)) * cos(omega*t - phase);
  90: 
  91: # Usage: generate_current(U_Max, R, L, omega, phase)
  92: sub generate_current {
  93:     my $current = $right->new();    # cloning
  94: 
  95:     $current *= parse_from_string('cos(omega*t - phase)');
  96: 
  97:     $current->implement(
  98:         U_max => $_[0],
  99:         R     => $_[1],
 100:         L     => $_[2],
 101:         omega => $_[3],
 102:         phase => $_[4],
 103:     );
 104:     $current = $current->simplify();
 105:     return sub { Re( $current->value( t => $_[0] ) ) };
 106: }
 107: 
 108: print "Sample current function with: 230V, 2Ohms, 0.1H, 50Hz, PI/4\n";
 109: my $current_of_time = generate_current( 230, 2, 0.1, 50, PI / 4 );
 110: 
 111: print "The current at 0 seconds:   " . $current_of_time->(0) . "\n";
 112: print "The current at 0.1 seconds: " . $current_of_time->(0.1) . "\n";
 113: print "The current at 1 second:    " . $current_of_time->(1) . "\n";
 114: 
 115: </readmore>

Replies are listed 'Best First'.
Re: Solving electronics problems with Perl
by blue_cowdawg (Monsignor) on Feb 01, 2013 at 16:02 UTC

    and the question?


    Peter L. Berghold -- Unix Professional
    Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
Re: Solving electronics problems with Perl
by Anonymous Monk on Feb 01, 2013 at 15:38 UTC
    0: #!/usr/bin/perl 1: use strict; 2: use warnings; 3: 4: # Perl solving a physics / electrodynamics problem involving 5: # symbolic mathematics, derivatives and complex numbers: 6: 7: use Math::Symbolic qw/:all/; 8: use Math::Complex; 9: 10: # Given the following simple circuit: 11: # 12: # ----|||||-----/\/\/\---- (R = resistor, 13: # | R L | L = solenoid, 14: # | | U = alternating voltage) 15: # ---------O ~ O---------- 16: # U(t) 17: # 18: # Question: What's the current in this circuit? 19: # 20: # We'll need some physics before letting the computer do the 21: # math: 22: # Applying Kirchhoff's rules, one quickly ends up with the 23: # following differential equation for the current: 24: # (L * dI/dt) + (R * I) = U 25: 26: my $left = parse_from_string('L * total_derivative(I(t), t) + R * + I(t)'); 27: my $right = parse_from_string('U(t)'); 28: 29: <readmore> 30: # If we understand current and voltage to be complex functions, 31: # we'll be able to derive. ("'" denoting complex here) 32: # I'(t) = I'_max * e^(i*omega*t) 33: # U'(t) = U_max * e^(i*omega*t) 34: # (Please note that omega is the frequency of the alternating volt +age. 35: # For example, the voltage from German outlets has a frequency of +50Hz.) 36: 37: my $argument = parse_from_string('e^(i*omega*t)'); 38: my $current = parse_from_string('I_max') * $argument; 39: my $voltage = parse_from_string('U_max') * $argument; 40: 41: # Putting it into the equation: 42: $left->implement( I => $current ); 43: $right->implement( U => $voltage ); 44: 45: $left = $left->apply_derivatives()->simplify(); 46: 47: # Now, we can solve the equation to get a complex function for 48: # the current: 49: 50: $left /= $argument; 51: $right /= $argument; 52: my $quotient = parse_from_string('R + i*omega*L'); 53: $left /= $quotient; 54: $right /= $quotient; 55: 56: # Now we have: 57: # $left = $right 58: # I_max(t) = U_max / (R + i*omega*L) 59: # But I_max(t) is still complex and so is the right-hand-side of t +he 60: # equation! 61: 62: # Making the symbolic i a "literal" Math::Complex i 63: $right->implement( 64: e => Math::Symbolic::Constant->euler(), 65: i => Math::Symbolic::Constant->new(i), # Math::Complex magi +c 66: ); 67: 68: print <<'HERE'; 69: Sample of complex maximum current with the following values: 70: U_max => 100 71: R => 10 72: L => 10 73: omega => 1 74: HERE 75: 76: print "Computed to: " 77: . $right->value( 78: U_max => 100, 79: R => 10, 80: L => 10, 81: omega => 1, 82: ), 83: "\n\n"; 84: 85: # Now, we're dealing with alternating current and voltage. 86: # So let's make a generator that generates nice current 87: # functions of time! 88: # I(t) = Re(I_max(t)) * cos(omega*t - phase); 89: 90: # Usage: generate_current(U_Max, R, L, omega, phase) 91: sub generate_current { 92: my $current = $right->new(); # cloning 93: 94: $current *= parse_from_string('cos(omega*t - phase)'); 95: 96: $current->implement( 97: U_max => $_[0], 98: R => $_[1], 99: L => $_[2], 100: omega => $_[3], 101: phase => $_[4], 102: ); 103: $current = $current->simplify(); 104: return sub { Re( $current->value( t => $_[0] ) ) }; 105: } 106: 107: print "Sample current function with: 230V, 2Ohms, 0.1H, 50Hz, PI/ +4\n"; 108: my $current_of_time = generate_current( 230, 2, 0.1, 50, PI / 4 ) +; 109: 110: print "The current at 0 seconds: " . $current_of_time->(0) . "\ +n"; 111: print "The current at 0.1 seconds: " . $current_of_time->(0.1) . +"\n"; 112: print "The current at 1 second: " . $current_of_time->(1) . "\ +n"; 113: 114: </readmore>

      Dear Unknown Monk,
      Please use code tags. Is there a question in there somewhere? I can't tell...


      Peter L. Berghold -- Unix Professional
      Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
Re: Solving electronics problems with Perl
by wolfger (Deacon) on Sep 08, 2003 at 15:53 UTC
    Really should have been a "read more" in there...

    Believe nothing, no matter where you read it, or who said it - even if I have said it - unless it agrees with your own reason and your own common sense. -- Buddha
      I didn't dare to include a readmore tag because I don't trust the craft section's formatter. For example, it even screws up the greater-than characters on the front page that display correctly in the node itself.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (5)
As of 2024-03-29 12:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found