Jump to content

Runge-Kutta method: Difference between revisions

→‎{{header|Perl}}: changing style and strategy
m (→‎{{header|Perl}}: wrong sigil)
(→‎{{header|Perl}}: changing style and strategy)
Line 453:
 
=={{header|Perl}}==
 
{{trans|Perl 6}}
There are many ways of doing this. Here we define the runge_kutta function
as a function of <math>y'</math> and <math>\delta t</math>, returning a closure
which itself takes <math>(t, y)</math> as argument and returns the next <math>(t, y)</math>.
 
Notice how we have use sprintf to deal with floating point rounding. See perlfaq4.
<lang perl>sub runge_kutta {
my ($yp, $t, $y, $dt) = @_;
sub {
my ($t, $y) = 0@_;
my @dy = $dt * $yp->( $t , $y );
push @dy, $dt * $yp->( $t + $dt/2, $y + $dy[0]/2 );
push @dy, $dt * $yp->( $t + $dt/2, $y + $dy[1]/2 );
push @dy, $dt * $yp->( $t += $dt , $y + $dy[2] );
return $t + $dt, $y += ($dy[0] + 2*$dy[1] + 2*$dy[2] + $dy[3]) / 6;
}
}
 
my $RK = runge_kutta sub { $_[0] * sqrt $_[1] }, 0, 1, .1;
my $t = 0;
my $RK = runge_kutta sub { $_[0] * sqrt $_[1] }, 0, 1, .1;
for(
 
while my (sprintf("%.0f"$t, $ty) <= 10)(0, {1);
my $y =sprintf("%.0f", $t) =<= 0 ? 1 : $RK->()10;
($t, $y) = $RK->($t, $y)
) {
printf "y(%2.0f) = %12f ± %e\n", $t, $y, abs($y - ($t**2 + 4)**2 / 16)
if sprintf("%.4f", $t) =~ /0000$/;
$t += .1;
}</lang>
 
1,934

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.