Runge-Kutta method: Difference between revisions

Added Algol W
(Added 11l)
(Added Algol W)
Line 176:
9.0000000 451.5625000 451.5624593 -9.0183e-08
10.0000000 676.0000000 675.9999490 -7.5419e-08
</pre>
 
=={{header|ALGOL W}}==
{{Trans|Algol 68}}
As originally defined, the signature of a procedure parameter could not be specified in Algol W (as here), modern compilers may require parameter specifications for the "f" parameter of rk4.
<lang algolw>begin
real procedure rk4 ( real procedure f ; real value y, x, dx ) ;
begin % Fourth-order Runge-Kutta method %
real dy1, dy2, dy3, dy4;
dy1 := dx * f(x, y);
dy2 := dx * f(x + dx / 2.0, y + dy1 / 2.0);
dy3 := dx * f(x + dx / 2.0, y + dy2 / 2.0);
dy4 := dx * f(x + dx, y + dy3);
y + (dy1 + 2.0 * dy2 + 2.0 * dy3 + dy4) / 6.0
end rk4;
real x0, x1, y0, dx;
integer numPoints;
x0 := 0; x1 := 10; y0 := 1.0; % Boundary conditions. %
dx := 0.1; % Step size. %
numPoints := entier ((x1 - x0) / dx + 0.5); % Add 0.5 for rounding errors. %
begin
real procedure dyByDx ( real value x, y ) ; x * sqrt(y); % Differential equation. %
real array y ( 0 :: numPoints); y(0) := y0; % Grid and starting point. %
for i := 1 until numPoints do y(i) := rk4 (dyByDx, y(i-1), x0 + dx * (i - 1), dx);
write( " x true y calc y relative error" );
for i := 0 step 10 until numPoints do begin
real x, trueY;
x := x0 + dx * i;
trueY := (x * x + 4.0) ** 2 / 16.0;
write( r_format := "A", r_w := 12, r_d := 7, s_w := 3, x, trueY, y( i )
, r_format := "S", r_w := 12, y( i ) / trueY - 1
)
end for_i
end
end.</lang>
{{out}}
<pre>
x true y calc y relative error
0.0000000 1.0000000 1.0000000 0.0000e+000
1.0000000 1.5625000 1.5624998 -9.3262e-008
2.0000000 4.0000000 3.9999990 -2.2986e-007
3.0000000 10.5625000 10.5624971 -2.7546e-007
4.0000000 25.0000000 24.9999937 -2.4939e-007
5.0000000 52.5625000 52.5624891 -2.0584e-007
6.0000000 100.0000000 99.9999834 -1.6594e-007
7.0000000 175.5625000 175.5624764 -1.3395e-007
8.0000000 289.0000000 288.9999684 -1.0922e-007
9.0000000 451.5625000 451.5624592 -9.0182e-008
10.0000000 676.0000000 675.9999490 -7.5419e-008
</pre>
 
3,068

edits