Math 2250

Homework Due Wednesday September 20

Numerical solutions to differential equations

#5, sections 2.4-2.6: I have saved myself time by copying and pasting pieces of code from the Sept 13 class/internet handout, which you can access via the internet. Of course the code needed minor changes to reflect the fact that we are doing a different initial value problem.

> restart:

> with(DEtools):

> dsolve({diff(y(x),x)=y(x)-x-1,y(0)=1},y(x));
#find the solution to our initial value problem

y(x) = x+2-exp(x)

> sol:= x->x+2-exp(x); #our solution

sol := proc (x) options operator, arrow; x+2-exp(x)...

> x0:=0.0; xn:=0.5; y0:=1.0; n:=5; h:=(xn-x0)/n;
#initial values, 5 steps of step size 0.1.

x0 := 0

xn := .5

y0 := 1.0

n := 5

h := .1000000000

>

> f:=(x,y)->y-x-1; #this is the slope function f(x,y)
#in dy/dx = f(x,y), for #5.

f := proc (x, y) options operator, arrow; y-x-1 end...

Here are the results for step-size = 0.1:

> x:=x0;y:=y0;
for i from 1 to n do

> k:= f(x,y): #current slope, use : to suppress output

> y:= y + h*k: #new y value via Euler

> x:= x + h: #updated x-value:

> print(x,y,sol(x)); #display current values,

> #and compare to exact solution.

> od: #``od'' ends a do loop

x := 0

y := 1.0

.1000000000, 1.0, .994829082

.2000000000, .9900000000, .978597242

.3000000000, .9690000000, .950141192

.4000000000, .9359000000, .908175302

.5000000000, .8894900000, .851278729

So Euler approximation at x=.5 is about 0.89 vs. actual solution of about 0.85.

Now repeat with h=0.05:

> x:=x0;y:=y0;n:=10;h:=0.05;

x := 0

y := 1.0

n := 10

h := .5e-1

> x:=x0;y:=y0;
for i from 1 to n do

> k:= f(x,y): #current slope, use : to suppress output

> y:= y + h*k: #new y value via Euler

> x:= x + h: #updated x-value:
if frac(i/2)=0

> then print(x,y,sol(x)); #display current values
fi; #other time

> #and compare to exact solution.

> od: #``od'' ends a do loop

x := 0

y := 1.0

.10, .9975, .994829082

.20, .98449375, .978597242

.30, .9599043594, .950141192

.40, .9225445563, .908175302

.50, .8711053733, .851278729

Now for improved Euler, #5 in section 2.5:

> x:=x0;y:=y0;n:=5;h:=.1;

> for i from 1 to n do

> k1:=f(x,y): #left-hand slope

> k2:=f(x+h,y+h*k1): #approximation to right-hand slope

> k:= (k1+k2)/2: #approximation to average slope

> y:= y+h*k: #improved Euler update

> x:= x+h: #update x

> print(x,y,sol(x));

> od:

x := 0

y := 1.0

n := 5

h := .1

.1, .9950000000, .994829082

.2, .9789750000, .978597242

.3, .9507673750, .950141192

.4, .9090979494, .908175302

.5, .8525532341, .851278729

So improved Euler did better than unimproved Euler: its value at x=0.5 is 0.853 vs. the actual value of 0.851, and unimproved Euler's calculation of 0.89. Notice we also did much better than unimproved Euler with h=0.05.

Finally, use Runge-Kutta: (This is #5 from 2.6) Notice we only have to do two steps, with h=0.25,

> x:=x0;y:=y0;n:=2;h:=.25;

> for i from 1 to n do

> k1:=f(x,y): #left-hand slope

> k2:=f(x+h/2,y+h*k1/2): #1st guess at midpoint slope

> k3:=f(x+h/2,y+h*k2/2): #second guess at midpoint slope

> k4:=f(x+h,y+h*k3): #guess at right-hand slope

> k:=(k1+2*k2+2*k3+k4)/6: #Simpson's approximation for the integral

> x:=x+h: #x update

> y:=y+h*k: #y update

> print(x,y,sol(x)); #display current values

> od:

x := 0

y := 1.0

n := 2

h := .25

.25, .9659830729, .965974583

.50, .8513005309, .851278729

Pretty Good: Runge Kutta rounded to five decimal places 0.85130 whereas the exact solution rounds to 0.85128, and error of 0.00002.

#25 section 2.5:

> restart:

> with(DEtools):

> sol:=t->294.0*exp(-t/25.0) - 245;
#from the book; could also have used dsolve.

sol := proc (t) options operator, arrow; 294.0*exp(...

> f:=(t,v)->-0.04*v -9.8;
t0:=0;v0:=49;
t:=t0;v:=v0;n:=50;h:=10.0/n; #50 subdivisions

> for i from 1 to n do

> k1:=f(t,v): #left-hand slope

> k2:=f(t+h,v+h*k1): #approximation to right-hand slope

> k:= (k1+k2)/2: #approximation to average slope

> v:= v+h*k: #improved Euler update for v

> t:= t+h: #update t
if frac(i/5)=0

> then print(t,v,sol(t),sol(t)-v);
#also print the difference between exact solution
#and approximate solution.
fi;

> od:

f := proc (t, v) options operator, arrow; -.4e-1*v-...

t0 := 0

v0 := 49

t := 0

v := 49

n := 50

h := .2000000000

1.000000000, 37.47221636, 37.4720951, -.12126e-3

2.000000000, 26.39643881, 26.3962058, -.23301e-3

3.000000000, 15.75494416, 15.7546084, -.33576e-3

4.000000000, 5.530704084, 5.5302740, -.430084e-3

5.000000000, -4.292642013, -4.2931586, -.516587e-3

6.000000000, -13.73081325, -13.7314088, -.59555e-3

7.000000000, -22.79891241, -22.7995800, -.66759e-3

8.000000000, -31.51145004, -31.5121831, -.73306e-3

9.000000000, -39.88236779, -39.8831601, -.79231e-3

10.00000000, -47.92506060, -47.9259065, -.84590e-3

> t:=t0;v:=v0;n:=100;h:=10.0/n; #100 subdivisions

> for i from 1 to n do

> k1:=f(t,v): #left-hand slope

> k2:=f(t+h,v+h*k1): #approximation to right-hand slope

> k:= (k1+k2)/2: #approximation to average slope

> v:= v+h*k: #improved Euler update for v

> t:= t+h: #update t
if frac(i/10)=0

> then print(t,v,sol(t),sol(t)-v);
fi;

> od:

t := 0

v := 49

n := 100

h := .1000000000

1.000000000, 37.47212533, 37.4720951, -.3023e-4

2.000000000, 26.39626391, 26.3962058, -.5811e-4

3.000000000, 15.75469208, 15.7546084, -.8368e-4

4.000000000, 5.530381164, 5.5302740, -.107164e-3

5.000000000, -4.293029838, -4.2931586, -.128762e-3

6.000000000, -13.73126040, -13.7314088, -.14840e-3

7.000000000, -22.79941363, -22.7995800, -.16637e-3

8.000000000, -31.51200039, -31.5121831, -.18271e-3

9.000000000, -39.88296265, -39.8831601, -.19745e-3

10.00000000, -47.92569564, -47.9259065, -.21086e-3

>

So both the n=50 and n=100 improved Euler agree to 2 decimal places, over the entire interval.

One way to get better data about when the bolt reaches maximum height (v=0), and its contact velocity at time t=9.41 seconds would be to rerun improved Euler, with n=100, but only over the time intervals t=4..5 and t=0..10. One can use initial values from the table:

> t:=4.0;v:=5.530381164;n:=100;h:=1.0/n; #100 subdivisions,
#from t=4 to t=5.

> for i from 1 to n do

> k1:=f(t,v): #left-hand slope

> k2:=f(t+h,v+h*k1): #approximation to right-hand slope

> k:= (k1+k2)/2: #approximation to average slope

> v:= v+h*k: #improved Euler update for v

> t:= t+h: #update t
if t>4.5 and t<4.6 #I don't want all 100 entries

> then print(t,v,sol(t),sol(t)-v);
#also print the difference between exact solution
#and approximate solution.
fi;

> od:

t := 4.0

v := 5.530381164

n := 100

h := .1000000000e-1

4.510000000, .4713391963, .4712340, -.1051963e-3

4.520000000, .3731702983, .3730652, -.1050983e-3

4.530000000, .2750406600, .2749356, -.1050600e-3

4.540000000, .1769502657, .1768452, -.1050657e-3

4.550000000, .7889909974e-1, .787941e-1, -.10499974...

4.560000000, -.1911285359e-1, -.192178e-1, -.104946...

4.570000000, -.1170856100, -.1171906, -.1049900e-3

4.580000000, -.2150191851, -.2151241, -.1049149e-3

4.590000000, -.3129135946, -.3130185, -.1049054e-3

This table makes it likely that the time of zero velocity it t=4.56 seconds, since the speed is smallest at that time.

Now for the velocity at time of impact:

>

> t:=9.0;v:=-39.88296265;n:=100;h:=1.0/n; #100 subdivisions,
#from t=9 to t=10.

> for i from 1 to n do

> k1:=f(t,v): #left-hand slope

> k2:=f(t+h,v+h*k1): #approximation to right-hand slope

> k:= (k1+k2)/2: #approximation to average slope

> v:= v+h*k: #improved Euler update for v

> t:= t+h: #update t
if t>9.35 and t<9.45 #I don't want all 100 entries

> then print(t,v,sol(t),sol(t)-v);
#also print the difference between exact solution
#and approximate solution.
fi;

> od:

t := 9.0

v := -39.88296265

n := 100

h := .1000000000e-1

9.360000000, -42.81548309, -42.8156778, -.19471e-3

9.370000000, -42.89634072, -42.8965354, -.19468e-3

9.380000000, -42.97716602, -42.9773606, -.19458e-3

9.390000000, -43.05795899, -43.0581535, -.19451e-3

9.400000000, -43.13871965, -43.1389141, -.19445e-3

9.410000000, -43.21944801, -43.2196424, -.19439e-3

9.420000000, -43.30014409, -43.3003384, -.19431e-3

9.430000000, -43.38080790, -43.3810021, -.19420e-3

9.440000000, -43.46143945, -43.4616336, -.19415e-3

So the velocity at time t=9.41 seconds is about -43.22 ft/sec. Of course, to find the time of impact without using the actual solution, we would have to numerically integrate v(t) to get y(t), and then find out when y(t) equaled zero.