Program RKdemo
!
! shows use of Runge-Kutta integrator
!
declare def func
print "The program demonstrates the solution"
print "of a differential equation using the"
print "Runge-Kutta method."
print
print "Consider the differential equation"
print
print " y' = f(x,y)"
print
print "where f(x,y) is some reasonably smooth"
print "function, which gives the slope of y(x)"
print "at any point (x,y) in the plane."
print
print "We consider f(x,y) = -2xy^2. ('^' denotes"
print "'to the power' so that the last factor"
print "in f is y-squared.)"
print
print "The solution in this case is"
print " ____1____ "
print " (x^2 + a^2)"
print "where a is a constant determined by the"
print "initial value y(x0). For simplicity"
print "take x0 = 0 and y(x0) = 1. Then a = 1."
print
print "Press any key to continue"
do
loop until key input
clear
! These statements select the highest resolution
! (for DOS only)
SET MODE "VGA"
ASK MODE m$
IF NewMode$ = "MEDRES" THEN SET MODE "HIRES"
ASK MODE m$
!
ask color printcolor$
open #1: screen 0, 1, 0, 1
set window -.2,5,-.2,1.2
plot 0,0;
plot 5,0
plot 0,-.2;
plot 0,1.2
for i = 1 to 5
plot i,0;
plot i,.015
next i
plot text, at .98,-.05: "1"
plot text, at 1.98,-.05: "2"
plot text, at 2.98,-.05: "3"
plot text, at 3.98,-.05: "4"
for i = 1 to 5
plot 0,i/5;
plot .02,i/5
next i
plot text, at -0.05,.98: "1"
plot text, at -0.05,-.02: "0"
plot text, at -.1,1.1: "y"
plot text, at 4.6,-.1: "x"
plot text, at 2,1.4: "Exact solution"
SET COLOR "red"
for i = 1 to 101
let x = (i-1)/20
let y = 1/(x^2 + 1)
plot x,y;
next i
plot
SET COLOR printcolor$
pause 1
open #2: screen .5,1,.5,1
print
print
print
print "Here is the exact solution of dy/dx = -2xy^2."
print "Now consider the Euler method solution."
print
print "First we'll zoom in on the function a bit."
pause 4
window #1
clear
set window -.2,2.1,.1,1.1
plot .9385,1.1;
plot .9385,.595;
plot 2.1,.595
call exact
window #2
print "Here is the exact solution of dy/dx = -2xy^2."
print "Now consider the Euler method solution."
print
print "First we'll zoom in on the function a bit."
print "Using delta x = .125. We'll integrate to"
print " x=1/2, i.e. 4 steps"
pause 3
window #1
let deltax = 0.125
let x = 0
let y = 1
for i = 1 to 4
pause 2
let slope = func(x,y)
call slprint(slope,x,y,i)
let ynew = y + slope*deltax
let xnew = x + deltax
pause 2
plot text, at (x+xnew)/2,(y+ynew)/2: "Take the step"
plot x,y;
plot xnew,ynew
plot xnew,ynew - .01;
plot xnew,ynew + .01
let x = xnew
let y = ynew
next i
window #2
let yeuler = ynew
let yexact = .8
print "At x=1/2 the exact value is :";yexact
print " the Euler value is :";yeuler
pause 2
print
print "Press any key to continue"
window #1
get key k
do
loop until key input
get key k
clear
Print "The Runge-Kutta approach improves the slope"
print "estimate for each step by feeling ahead of"
print "itself as illustrated following. Before it"
print "takes a step the 4th-order RK algorithm"
print "actually evaluates the slope 4 times in"
print "4 different places. Therefore, to make this"
print "a fair comparison, we will use an overall"
print "delta x = 0.5, 4 times as large as that used"
print "by the Euler algorithm."
print
print "Before demonstrating the RK algorithm, we'll"
print "put back on the screen the exact function and"
print "the Euler solution, the latter being marked with"
print "small plus signs."
print
print "Press any key to continue."
do
loop until key input
get key k
clear
call exact
let x = 0
let y = 1
for i = 1 to 4
let slope = func(x,y)
let ynew = y + slope*deltax
let xnew = x + deltax
plot xnew,ynew - .01;
plot xnew,ynew + .01
plot xnew - .015, ynew;
plot xnew + .015, ynew
let x = xnew
let y = ynew
next i
let yeuler = ynew
plot .9385,1.1;
plot .9385,.595;
plot 2.1,.595
window #2
print "0. Here is the exact function again"
print " and the Euler values"
pause 2
print "1. Begin by evaluating slope as before."
pause 2
let deltax = .5
let x = 0
let y = 1
let m1 = func(x,y)
let x1 = x + .1
let y1 = y + .1*m1
window #1
plot x,y;
plot x1,y1
pause 2
window #2
print "2. Take a temporary half step using"
print " the slope, m1."
pause 2
let x1 = x + deltax/2
let y1 = y + m1*deltax/2
window #1
plot x1-.015,y1+.01;
plot x1+.015,y1-.01
plot x1+.015,y1+.01;
plot x1-.015,y1-.01
pause 2
window #2
print "3. And evaluate the slope, m2, there."
pause 2
let m2 = func(x1,y1)
window #1
plot x1-.1,y1-.1*m2;
plot x1+.1,y1+.1*m2
window #2
pause 2
print "4. Go back to start and use that"
print " slope, m2, to do a half step again."
pause 2
let x2 = x + deltax/2
let y2 = y + m2*deltax/2
window #1
plot x2-.015,y2+.01;
plot x2+.015,y2-.01
plot x2+.0115,y2+.01;
plot x2-.015,y2-.01
pause 2
window #2
print "5. And evaluate the slope there, m3."
pause 2
let m3 = func(x2,y2)
window #1
plot x2-.1,y2-.1*m3;
plot x2+.1,y2+.1*m3
pause 2
window #2
print "6. Go back to start and use the"
print " slope m3 to take a full step"
pause 2
let x3 = x + deltax
let y3 = y + deltax*m3
window #1
plot x3-.015,y3+.01;
plot x3+.015,y3-.01
plot x3+.015,y3+.01;
plot x3-.015,y3-.01
pause 2
window #2
print "7. And evaluate the slope there, m4."
pause 2
let m4 = func(x3,y3)
window #1
plot x3-.1,y3-.1*m4;
plot x3+.1,y3+.1*m4
pause 2
window #2
print "8. Determine weighted av. slope"
print " m = (m1 + 2*m2 + 2*m3 +m4)/6"
let slope = (m1 + 2*m2 +2*m3 + m4)/6
pause 2
print "9. And take the actual step"
pause 2
let xnew = x + deltax
let ynew = y + deltax*slope
window #1
plot x,y;
plot xnew,ynew
box area xnew-.01,xnew+.01,ynew-.005,ynew+.005
pause 2
window #2
print "Results at x = 1/2"
let yexact = .8
let erreul = yexact - yeuler
let errrk4 = yexact - ynew
print " Exact value: y = ";yexact
print " Euler value: y = ";yeuler;" Æy = ";erreul
print " RK-4 value: y = ";ynew;" Æy = ";errrk4
let ratio = abs(erreul/errrk4)
print "The RK-4 is better by a factor of ";
print using "###.": ratio
pause 3
print "10. Now take the next 3 R-K steps"
print " (w/o commentary)."
let x = xnew
let y = ynew
let m1 = func(x,y)
let x1 = x + .1
let y1 = y + .1*m1
window #1
plot x,y;
plot x1,y1
pause 2
let x1 = x + deltax/2
let y1 = y + m1*deltax/2
plot x1-.015,y1+.01;
plot x1+.015,y1-.01
plot x1+.015,y1+.01;
plot x1-.015,y1-.01
pause 2
let m2 = func(x1,y1)
plot x1-.1,y1-.1*m2;
plot x1+.1,y1+.1*m2
pause 2
let x2 = x + deltax/2
let y2 = y + m2*deltax/2
plot x2-.015,y2+.01;
plot x2+.015,y2-.01
plot x2+.0115,y2+.01;
plot x2-.015,y2-.01
pause 2
let m3 = func(x2,y2)
plot x2-.1,y2-.1*m3;
plot x2+.1,y2+.1*m3
pause 2
let x3 = x + deltax
let y3 = y + deltax*m3
plot x3-.015,y3+.01;
plot x3+.015,y3-.01
plot x3+.015,y3+.01;
plot x3-.015,y3-.01
pause 2
let m4 = func(x3,y3)
plot x3-.1,y3-.1*m4;
plot x3+.1,y3+.1*m4
pause 2
let slope = (m1 + 2*m2 +2*m3 + m4)/6
let xnew = x + deltax
let ynew = y + deltax*slope
plot x,y;
plot xnew,ynew
box area xnew-.01,xnew+.01,ynew-.005,ynew+.005
pause 2
window #2
print "Results at x = 1"
let yexact = .5
let errrk4 = yexact - ynew
print " Exact value: y = ";yexact
print " RK-4 value: y = ";ynew;" Æy = ";errrk4
print "Not bad!"
let x = xnew
let y = ynew
let m1 = func(x,y)
let x1 = x + .1
let y1 = y + .1*m1
window #1
plot x,y;
plot x1,y1
pause 2
let x1 = x + deltax/2
let y1 = y + m1*deltax/2
plot x1-.015,y1+.01;
plot x1+.015,y1-.01
plot x1+.015,y1+.01;
plot x1-.015,y1-.01
pause 2
let m2 = func(x1,y1)
plot x1-.1,y1-.1*m2;
plot x1+.1,y1+.1*m2
pause 2
let x2 = x + deltax/2
let y2 = y + m2*deltax/2
plot x2-.015,y2+.01;
plot x2+.015,y2-.01
plot x2+.0115,y2+.01;
plot x2-.015,y2-.01
pause 2
let m3 = func(x2,y2)
plot x2-.1,y2-.1*m3;
plot x2+.1,y2+.1*m3
pause 2
let x3 = x + deltax
let y3 = y + deltax*m3
plot x3-.015,y3+.01;
plot x3+.015,y3-.01
plot x3+.015,y3+.01;
plot x3-.015,y3-.01
pause 2
let m4 = func(x3,y3)
plot x3-.1,y3-.1*m4;
plot x3+.1,y3+.1*m4
pause 2
let slope = (m1 + 2*m2 +2*m3 + m4)/6
let xnew = x + deltax
let ynew = y + deltax*slope
plot x,y;
plot xnew,ynew
box area xnew-.01,xnew+.01,ynew-.005,ynew+.005
pause 2
window #2
print "Results at x = 1.5"
let yexact = .307692307
let errrk4 = yexact - ynew
print " Exact value: y = ";yexact
print " RK-4 value: y = ";ynew;" Æy = ";errrk4
print "Not bad!"
let x = xnew
let y = ynew
let m1 = func(x,y)
let x1 = x + .1
let y1 = y + .1*m1
window #1
plot x,y;
plot x1,y1
pause 2
let x1 = x + deltax/2
let y1 = y + m1*deltax/2
plot x1-.015,y1+.01;
plot x1+.015,y1-.01
plot x1+.015,y1+.01;
plot x1-.015,y1-.01
pause 2
let m2 = func(x1,y1)
plot x1-.1,y1-.1*m2;
plot x1+.1,y1+.1*m2
pause 2
let x2 = x + deltax/2
let y2 = y + m2*deltax/2
plot x2-.015,y2+.01;
plot x2+.015,y2-.01
plot x2+.0115,y2+.01;
plot x2-.015,y2-.01
pause 2
let m3 = func(x2,y2)
plot x2-.1,y2-.1*m3;
plot x2+.1,y2+.1*m3
pause 2
let x3 = x + deltax
let y3 = y + deltax*m3
plot x3-.015,y3+.01;
plot x3+.015,y3-.01
plot x3+.015,y3+.01;
plot x3-.015,y3-.01
pause 2
let m4 = func(x3,y3)
plot x3-.1,y3-.1*m4;
plot x3+.1,y3+.1*m4
pause 2
let slope = (m1 + 2*m2 +2*m3 + m4)/6
let xnew = x + deltax
let ynew = y + deltax*slope
plot x,y;
plot xnew,ynew
box area xnew-.01,xnew+.01,ynew-.005,ynew+.005
pause 2
window #2
print "Results at x = 2"
let yexact = .2
let errrk4 = yexact - ynew
print " Exact value: y = ";yexact
print " RK-4 value: y = ";ynew;" Æy = ";errrk4
print "Not bad!"
pause 2
print "That's all folks."
end
!
def func(x,y)
let func = -2*x*y^2
end def
!
sub slprint(slope,x,y,i)
plot x,y;
let xend = x + .08
let yend = y + .08*slope
plot xend,yend
if i = 1 then
plot text, at 0,1.03: "Evaluate slope"
end if
if i <> 1 then
plot text, at x-.3,y-.05: "Evaluate slope"
end if
end sub
!
sub exact
call axes
plot text, at 2,1.4: "Exact solution"
ask color printcolor$
set color "red"
for i = 1 to 101
let x = (i-1)/20
let y = 1/(x^2 + 1)
plot x,y;
next i
plot
set color printcolor$
end sub
!
sub axes
plot 0,.15;
plot 5,.15
plot 0,-.2;
plot 0,1.2
for i = 1 to 5
plot i/2,.15;
plot i/2,.16
next i
plot text, at .98,.12: "1"
plot text, at 1.98,.12: "2"
plot text, at .46,.12: "1/2"
plot text, at 1.46,.12: "3/2"
for i = 1 to 5
plot 0,i/5;
plot .02,i/5
next i
plot text, at -0.05,.99: "1"
plot text, at -0.08,.79: "0.8"
plot text, at -0.08,.59: "0.6"
plot text, at -0.08,.39: "0.4"
plot text, at -0.08,.19: "0.2"
plot text, at -.08,1.05: "y"
plot text, at 2.04,.11: "x"
end sub