# # Program that, with Runge-Kutta method, solves mxm system of IVP of ODE # x[i]' = f[i](t,x[1],x[2],...,x[m]), t in [a,b] # x[i](0) = x0[i], # i=1,2,...,m # # input: m --- size of the system # f --- an array of operators # for example: # > f:=array(1..2); # > f[1]:=(t,x,y)->x-0.1*x*y; f[2]:=(t,x,y)->-.5*y+.02*x*y; # a, b --- end points of the t interval # x0 --- array(1..m) of initial conditions # n --- number of subintervals dividing [a,b] # # output: t --- the array of nodes dividing [a,b] # x --- the array(1..m), each entry x[i] is an array(0..n) # x[i][j] is the approximate value of x[i](t[j]) # RKmxm := proc( m::integer, f::array, a::numeric, b::numeric, x0::array, n::integer ) local i, j, k, l, delta, delta2, t, x; delta:=evalf( (b-a)/n ); delta2:=0.5*delta; t:=array(0..n, [ seq( evalf( a+i*delta ), i=0..n )]); x:=array(1..m, [ seq( array(0..n), i=1..m) ] ); k:=array(1..4, [ seq( array(1..m), i=1..4) ] ); for i to m do x[i][0]:=evalf(x0[i]) od; for i from 0 to n-1 do for j to m do k[1][j]:= evalf( delta*f[j](t[i], seq( x[l][i], l=1..m ) ) ) od; for j to m do k[2][j]:= evalf( delta*f[j](t[i]+delta2, seq( x[l][i]+0.5*k[1][l], l=1..m ) ) ) od; for j to m do k[3][j]:= evalf( delta*f[j](t[i]+delta2, seq( x[l][i]+0.5*k[2][l], l=1..m ) ) ) od; for j to m do k[4][j]:= evalf( delta*f[j](t[i]+delta, seq( x[l][i]+k[3][l], l=1..m ) ) ) od; for j to m do x[j][i+1]:= evalf( x[j][i] + (k[1][j]+2.0*(k[2][j]+k[3][j])+k[4][j])/6.0 ) od; od; print(` End of Runge-Kutta method for mxm IVP-ODE `); return t, x; end;