Runge-Kutta method: Difference between revisions

→‎{{header|Perl 6}}: added translation to perl5
(→‎{{header|Perl 6}}: added translation to perl5)
Line 451:
t = 9.000000, y = 451.562459, err = 4.07232e-05
t = 10.000000, y = 675.999949, err = 5.09833e-05</pre>
 
=={{header|Perl}}==
{{trans|Perl 6}}
Notice how we have to deal with floating points rounding with sprintf. See perlfaq4.
<lang perl>sub runge_kutta {
my ($yp, $t, $y, $dt) = @_;
my $first;
sub {
return $y unless $first++;
my @dy;
push @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 $y += (@dy[0] + 2*$dy[1] + 2*$dy[2] + $dy[3]) / 6;
}
}
 
my $t = 0;
my $RK = runge_kutta sub { $_[0] * sqrt $_[1] }, 0, 1, .1;
 
while (sprintf("%.0f", $t) <= 10) {
my $y = $RK->();
printf "y(%2.0f) = %12f ± %e\n", $t, $y, abs($y - ($t**2 + 4)**2 / 16)
if sprintf("%.4f", $t) =~ /0000$/;
$t += .1;
}</lang>
 
Output should match Perl 6's.
 
=={{header|Perl 6}}==
1,934

edits