Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Solving electronics problems with Perl

by tsee (Curate)
on Sep 07, 2003 at 13:48 UTC ( #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>

Comment on Solving electronics problems with Perl
Download Code
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.
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 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

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlcraft [id://289568]
Approved by gmax
Front-paged by grinder
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (8)
As of 2014-11-28 16:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My preferred Perl binaries come from:














    Results (199 votes), past polls