> restart; > # Mehrschrittverfahren > > RungeKutta:=proc(y0,t0,f,T,N) > # Schrittweite ist (T-t0)/N > local y,t,k1,k2,k3,k4,j,h; > y:=y0; t:=t0; h:=(T-t0)/N; > print(`Runge-Kutta-Verfahren:`); > for j from 0 to N-1 do > k1:=f(t,y); k2:=f(t+h/2,y+k1*h/2); k3:=f(t+h/2,y+k2*h/2); > t:=t+h; k4:=f(t,y+k3*h); y:=y+h*(k1+2*k2+2*k3+k4)/6; print(t,y) > od > end: > > AdamsBashforth:=proc(t0,y0,y1,y2,y3,f,h,N) > #(t0,y0) Anfangswert > #(t0+h,y1),(t0+2*h,y2),(t0+3*h,y3) mit Einschrittverfahren vorberechnet > local j,t, w0,w1,w2,w3,w; > t:=t0+3*h; w0:=y0; w1:=y1; w2:=y2; w3:=y3; > for j from 1 to N do > w:=w3+h*(55*f(t,w3)-59*f(t-h,w2)+37*f(t-2*h,w1)-9*f(t-3*h,w0))/24; > t:=t+h; w0:=w1; w1:=w2; w2:=w3; w3:=w; > print(t,w) > od > end: > > AdamsBashforthMoulton:=proc(t0,y0,y1,y2,f,h,N) > #(t0,y0) Anfangswert > #(t0+h,y1),(t0+2*h,y2) mit Einschrittverfahren vorberechnet > local j,t, w0,w1,w2,w,y; > t:=t0+2*h; > w0:=y0; w1:=y1; w2:=y2; > for j from 1 to N do > y:=w2+h*(23*f(t,w2)-16*f(t-h,w1)+5*f(t-2*h,w0))/12; > w:=w2+h*(9*f(t+h,y)+19*f(t,w2)-5*f(t-h,w1)+f(t-2*h,w0))/24; > t:=t+h; w0:=w1; w1:=w2; w2:=w; > print(t,w) > od > end: > > #Beispiel 1 > f:=proc(t,y) local g; g:=-2*t*y^2; RETURN(g) end: > RungeKutta(1.0,0.0,f,0.3,3); > Runge-Kutta-Verfahren: .1000000000, .9900989250 .2000000000, .9615381437 .3000000000, .9174305976 > h:=0.1: > N:=7: > print(Adams-Bashforth-Verfahren); > AdamsBashforth(0.0,1.0,0.9900990099,0.9615384615,0.9174311927,f,h,N); > print(Adams-Bashforth-Moulton-Verfahren); > N:=8: > AdamsBashforthMoulton(0.0,1.0,0.9900990099,0.9615384615,f,h,N); Adams - Bashforth - Verfahren .4, .8623890930 .5, .8005270722 .6, .7359439656 .7, .6717539204 .8, .6102675268 .9, .5528506480 1.0, .5002374012 Adams - Bashforth - Moulton - Verfahren .3, .9174337864 .4, .8620615099 .5, .7999732319 .6, .7352455870 .7, .6710746358 .8, .6096794497 .9, .5524068883 1.0, .4999240670 > # Vergleich mit Runge-Kutta-Verfahren > RungeKutta(1.0,0.0,f,1.0,10); Runge-Kutta-Verfahren: .1000000000, .9900989250 .2000000000, .9615381437 .3000000000, .9174305976 .4000000000, .8620681836 .5000000000, .7999992091 .6000000000, .7352935003 .7000000000, .6711406195 .8000000000, .6097561192 .9000000000, .5524865299 1.000000000, .5000006022 > # Vergleich mit genauer Lösung > print(`genaue Lösung:`); for j from 1 to 10 do evalf(1/(1+(j*0.1)^2)) od; genaue Lösung: .9900990099 .9615384615 .9174311927 .8620689655 .8000000000 .7352941176 .6711409396 .6097560976 .5524861878 .5000000000 > > >