Runge-Kutta method: Difference between revisions

m
→‎{{header|REXX}}: changed/added comments and whitespace, optimized the sqrt and RK4 functions, changed the fmt function for better output alignment.
(Add Nim code for RK task)
m (→‎{{header|REXX}}: changed/added comments and whitespace, optimized the sqrt and RK4 functions, changed the fmt function for better output alignment.)
Line 2,158:
</pre>
<lang rexx>/*REXX program uses the Runge─Kutta method to solve the equation: y'(t)=t² √[y(t)] */
numeric digits 40; f=digits() % 4 /*use 40 digitsdecimal digs, but only show 1/4 that10*/
x0=0; x1=10; wdx=digits()%2; .1 dx= .1 /*setdefine X0variables: & X1;X0 calculateX1 W DX & DX */
n=1 + (x1-x0) / dx
y.=1; do m=1 for n-1; p=m-1; mm=y.m-1=RK4(dx, x0 + dx*p, y.p)
end /*m*/ y.m=RK4(dx, x0+dx*mm, y.mm) /* [↑] use 4th order Runge─Kutta. */
w=digits() % 2 end /*mW: width used for displaying numbers.*/
say center('X', f, "═") center('Y', w+2, "═") center("relative error", w+8, '═') /*hdr*/
 
do i=0 to n-1 by 10; x=(x0 + dx*i) / 1; $=y.i/(x*x/4+1)**2 -1
say center('X', f, "═") center('Y', w+2, "═") center("relative error", w+8, '═')
say center(x, f) fmt(y.i) left('', 2 + ($>=0) ) fmt($)
 
do i=0 to n-1 by 10; end /*i*/ x=(x0+dx*i)/1; $=y.i / (x*x/4+1)**2└┴┴┴───◄─────── -aligns 1positive #'s. */
say center(x,f) fmt(y.i) left('', 2 + ($>=0)) fmt($)
end /*i*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
fmt: z=right( format( arg(1), w, f), w); hasE=pos('E', z)\==0; /*right adjust number has.*/=pos(., z)\==0
if pos(.,z)\jus==0has. & \hasE; if jus then z=left( strip( strip(z, 'T', 0), "T", .), w)
return translate(right(z, (z>=0) + w + 5*hasE + 2*(jus & (z<0) ) ), 'e', "E") /*Positive | E, adjust*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
rateRK4: return arg(1)procedure; * sqrt(parse arg(2) )dx,x,y; dxH=dx/2; k1= dx * (x ) * sqrt(y /*compute the rate. */)
k4k2= dx * rate ( x +dx dxH) ,* sqrt(y +k3 k1/2)
/*──────────────────────────────────────────────────────────────────────────────────────*/
RK4: procedure; parse arg dx,x,y; k1= dx * rate( x , y k3= dx * (x + dxH) * sqrt(y + k2/2)
k2k4= dx * rate( (x + dx/2 ,) * sqrt(y +k1/2 k3 )
return y + (k1 + k2*2 + k3= dx * rate( x2 +dx/2 ,k4) y +k2/2 )6
k4= dx * rate( x +dx , y +k3 )
return y + (k1 + k2+k2 + k3+k3 + k4) / 6
/*──────────────────────────────────────────────────────────────────────────────────────*/
sqrt: procedure; parse arg x; if x=0 then return 0; d=digits(); m.=9; numeric form; h=d+6
numeric digits; parse value format(x,2,1,,0) 'E0' with g 'E' _ .; g=g * .5'e'_ % 2
do j=0 while h>9; m.j=h; h=h%2+1; end /*j*/
do k=j+5 to 0 by -1; numeric digits m.k; g=(g+x/g)*.5; end /*k*/; return g</lang>
Programming note: &nbsp; the &nbsp; '''fmt''' &nbsp; function is used to
numeric digits d; return g/1</lang>
align the output with attention paid to the different ways some
'''output''' &nbsp; when using Regina REXX:
<br>REXXes format numbers that are in floating point representation.
 
 
'''{{out|output''' |text=&nbsp; when using Regina REXX:}}
<pre>
════X═════ ══════════Y═══════════ ═══════relative error═══════
Line 2,204 ⟶ 2,205:
10 675.9999490167 -7.5419068846e-8
</pre>
'''{{out|output''' |text=&nbsp; when using PC/REXX, Personal REXX, ROO, or R4 REXX:
<pre>
════X═════ ══════════Y═══════════ ═══════relative error═══════
0 1 0
1 1.5624998543 -0.0000000933
2 3.9999990805 -0.0000002299
3 10.5624970904 -0.0000002755
4 24.9999937651 -0.0000002494
5 52.5624891803 -0.0000002058
6 99.9999834054 -0.0000001659
7 175.5624764823 -0.000000134
8 288.9999684348 -0.0000001092
9 451.5624592768 -0.0000000902
10 675.9999490167 -0.0000000754
</pre>