You are on page 1of 10

# Math 128A Spring 2002

Sergey Fomel

Handout # 27
May 7, 2002

Answers to Homework 11: Numerical Solution of ODE:
Multistep Methods )
1. Derive a variable-step Adams-Bashforth method of the form
yk+1 = yk + h k Ak f (xk , yk ) + h k Bk f (xk−1 , yk−1 ) ,

(1)

where xk+1 = xk +h k , h k = αk h k−1 , and yk approximates y(xk ) – the solution of the initial-value
problem 
0
y (x) = f (x, y)
(2)
y(x0 ) = y0
Considering αk and h 0 as given, derive appropriate expressions for the coefficients Ak and Bk
and determine the order of the method.
To derive this method, we can use linear interpolation to approximate the derivative of the
function y(x):
y 0 (x) ≈ P(x) =

f (xk , yk ) (x − xk−1 ) − f (xk−1 , yk−1 ) (x − xk )
.
h k−1

The predicted value of y(xk+1 ) is then approximated as follows:
xk+1
xk+1
Z
Z
0
y(xk+1 ) = y(xk ) +
y (x) d x ≈ yk +
P(x) d x
xk

xk

f (xk , yk )
= yk +
h k−1

xk+1
Z

xk+1
Z
(x − xk ) d x .

xk

xk

f (xk−1 , yk−1 )
(x − xk−1 ) d x −
h k−1

We find that
1
Ak =
h k h k−1

xk+1
Z
(x − xk−1 ) d x =
xk

and
1
Bk = −
h k h k−1

1
h k h k−1

h kZ
+h k−1

t dt =

(h k + h k−1 )2 − h 2k−1
αk
= 1+
,
2 h k h k−1
2

h k−1
xk+1
Z
(x − xk ) d x = −
xk

1
h k h k−1

Z

h 2k
αk
h k t dt = −
=− .
2 h k h k−1
2

0

To determine the local error of this method, we can integrate the error of the polynomial interpolation:
xk+1
Z
y 000 (ξx )
(x − xk−1 ) (x − xk ) d x ,
E=
2
xk

1

B = −2. with the Taylor method. Answer: We can find the coefficients. we arrive at a system of linear equations for the coefficients of the approximation h y 0 (xk+1 ) ≈ A y(xk+1 ) + B y(xk ) + C y(xk−1 ) . we can apply the weighted mean-value theorem for integrals to deduce that E = = xk+1 Z Zh k y 000 (ξ ) (t + h k−1 ) t dt (x − xk−1 ) (x − xk ) d x = 2 xk 0 ! 3 2 000 y (ξ ) h k−1 αk (2 αk + 3) y 000 (ξ ) h 3k h 2k h k−1 + = . xk+1 ] and ξ2 is a point in [xk−1 . xk+1 ]. and C = 1/2. Using the Taylor series expansions h3 h2 y(xk ) = y(xk+1 ) − h y 0 (xk+1 ) + y 00 (xk+1 ) − y 000 (ξ1 ) 2 6 and (2 h)3 000 y (ξ2 ) . y) . 2. (4) i=0 Derive a BDF method of the form A yk+1 + B yk + C yk−1 = h f (xk+1 . for example.where y 000 (x) is assumed to exist and ξx is some point between xk−1 and xk+1 (which depends on x). The method order is 2. (3) we can arrive at the backward differentiation formula (BDF) n X Ai yk+1−i ≈ h f (xk+1 . 2 . xk+1 ]. yk+1 ) . 2 3 2 12 y 000 (ξ ) 2 where ξ is some point in [xk−1 . Applying numerical differentiation to approximate the derivative y 0 (xk+1 ) in the ordinary differential equation y 0 (x) = f (x. We see that the local error has the order O(h 30 ). The equations are A+ B +C = 0 −B − 2 C = 1 1 B +2C = 0 2 and the solution is easily found to be A = 3/2. (5) find its error and compare it with the error of the Adams-Moulton method of the same order. y(xk−1 ) = y(xk+1 ) − 2 h y 0 (xk+1 ) + 2 h 2 y 00 (xk+1 ) − 6 where ξ1 is a point in [xk . Since the factor (x − xk−1 ) (x − xk ) does not change sign on the interval of integration. yk+1 ) .

 1 −h −h 1  3 yk+1 pk+1   = yk pk  . The bound on the magnitude of E AM is approximately eight times smaller than the bound on |E B D F |. 9 3 The local error of the second-order Adams-Moulton method is E AM = −y 000 (ξ ) h3 . The system takes the form  0 y (x) = p(x) p 0 (x) = y(x) with the initial conditions  y(0) = y0 p(0) = −y0 In the matrix form. xk−1 ]. (7) i=0 Answer: The first step is to rewrite the second-order equation as a system of two first-order equations. In Homework 10. not necessarily equal to ξ1 . the backward Euler method applied to this system is       yk pk+1 yk+1 +h = yk+1 pk+1 pk or. |y 000 (ξ2 )| .The error of the approximation is EBDF = −   2 h3 B h 3 000 C (2 h)3 000 y (ξ1 ) − y (ξ2 ) = y 000 (ξ1 ) − 2 y 000 (ξ2 ) A 6 A 6 9 Its magnitude is bounded by |E B D F | ≤ |y 000 (ξ1 )| + 2 |y 000 (ξ2 )|  2 h3  2 h3 ≤ max |y 000 (ξ1 )|. 12 where ξ is a point in [xk . Adams-Moulton methods have the general form n X yk+1 = yk + h Ai f (xk+1−i . yk+1−i ) . we found that Euler’s method can be unstable when applied to the initial-value problem  00  y (x) = y(x) y(0) = y0 (6)  0 y (0) = −y0 Prove that both the backward Euler method (Adams-Moulton of order 1) and the trapezoidal method (Adams-Moulton of order 2) are unconditionally stable in this case for the positive step h. 3. equivalently.

For any h > 0.Inverting the matrix.   = 1 − h/2 1 + h/2 k  y0 −y0  for all k ≥ 0. in this case. the numerical solution will decrease in magnitude at each step consistently with the exact solution y(x) = y0 e−x . The method takes the form         h pk h pk+1 yk+1 yk = + + pk+1 pk 2 yk 2 yk+1 or.  yk pk  1 = (1 + h)k   y0 −y0 for all k ≥ 0. in this case. the numerical solution will decrease in magnitude at each step consistently with the exact solution y(x) = y0 e−x .  1 −h/2 −h/2 1  yk+1 pk+1   1 h/2 h/2 1 =  yk pk   1 h/2 h/2 1 Inverting the matrix. For any value h > 0. the original system is underdetermined and can admit infinitely many solutions. the original system can admit infinitely many solutions. 4 . The case of the trapezoidal method is analyzed analogously. equivalently. p(x) = −y0 e−x . p(x) = −y0 e−x . we can express the method in the explicit form  yk+1 pk+1  −1  1 −h/2 1 = −h/2 1 h/2 " # 2 1 1 + h4 h = 2 2 h 1 + h4 1 − h4  h/2 1 yk pk  yk pk  y0 −y0  = 1 2 1 − h4 2  yk pk   The first step yields  y1 p1  = 1 " 1 + h4 h  yk pk 2 1 − h4 2 h 2 1 + h4 # 1 − h/2 = 1 + h/2  y0 −y0  By induction. We need to select a stable solution in the special case h = 1. we can express Euler’s method for this case in the explicit form   yk+1 pk+1 The first step yields   1 −h −h 1 = y1 p1  1 = 1 − h2  −1  yk pk 1 h h 1   1 = 1 − h2 y0 −y0   1 h h 1 1 = 1+h   yk pk   y0 −y0 By induction. because. because. We need to select a stable solution in the special case h = 2.

100 0.01 and h = 0. const double* y.010 0. int nstep.39661 × 10−7 Solution: C program: #include <stdio.storage slope(x.1. y2[n] . we approximated the number π by computing the integral Z1 2dx 1 + x2 (8) −1 A similar solution can be obtained from the initial-value problem   2  y 00 (x) = − y 0 (x) x y(−1) = 0  0 y (−1) = 1 (9) Solve this problem numerically on the interval x ∈ [−1.number of steps h .y.53020 × 10−5 6. (Programming) In Homework 9.001. f2[n] . h = 0.03666 × 10−3 6.number of equations in the system nstep .function pointer for the right-hand side */ void midpoint (int n.20849 × 10−5 6. step=0.f) . 1] using the following methods: (a) Adams-Bashforth of order 2 (b) Adams-Bashforth of order 2 as predictor followed by one correction step of AdamsMoulton of order 2 (c) Adams-Moulton of order 2 solving the quadratic equation for yk+1 Initialize each of these methods with the midpoint step (Runge-Kutta of order 2). double* f)) { int k.001 Adams-Bashforth 2. double h. Output the absolute error in approximating π = y(1) with the step sizes h = 0.14736 × 10−4 3. double* y.h" /* Function: midpoint -----------------Solves a system of ODEs by the midpoint method n .h> /* for output */ #include "ode. void (*slope)(double x. double* f1. 5 . double* y2.function values f1[n]. double x. Answer: Step size 0.46844 × 10−3 6.4.starting value of the variable y[n]. double* f2.step size x .18631 × 10−6 Adams-Bashforth-Moulton 5.78036 × 10−2 3.36360 × 10−7 Adams-Moulton 7.

double* y. for (k=0.function values f1[n]. y2[n] .y. step < nstep. for (k=0./* print initial conditions */ printf("%f ".*f2[k]-f1[k]). step < nstep. printf("%f ".number of steps ncorr . k < n. double h. k < n.y. for (step=0. x+=h. for (corr=0. k++) { y[k] += h*f2[k].f1).starting value of the variable y[n]. double* f2.step size x . int nstep. k < n.5*h*(3. void (*slope)(double x. } 6 /* Adams-Moulton */ /* corrector */ .y2. k++) { printf("%f ". } printf("\n").f1).y. k++) { /* Adams-Bashforth */ y2[k] = y[k] + 0.5*h*f1[k]. double* f1.y[k]). int ncorr. for (k=0. /* corrector */ } } /* Function: adams --------------Solves a system of ODEs by second-order Adams-Bashforth-Moulton method n . double* y2. k++) { y2[k] = y[k] + 0. for (step=0.x).f) .y[k]). for (k=0.x). double x. k++) { y2[k] = y[k] + 0.f2). f2[n] .number of equations in the system nstep . corr++) { slope (x. step++) { slope(x.function pointer for the right-hand side */ void adams (int n. corr. double* f)) { int k. const double* y. corr < ncorr. k < n.5*h. k < n.storage slope(x.number of correction steps h . for (k=0. /* predictor */ } x += h.5*h*(f2[k]+f1[k]). printf("%f ".y2. step.f2). step++) { slope(x. /* predictor */ } slope(x+0. } printf("\n").

).+h[k]. printf("%f ". pi_ode). step++) { t2 = t+h. f1. y."ABM error with h=%f: %g\n". double* f) { f[0] = y[1].-h*t*y1)/(sqrt(1.).h[k]. adams(2.} printf("%f ".+h*t2*y1*(2. f1. nstep[k]-1. } /* Adams-Moulton specialized for the pi ODE system */ void pi_moulton(int nstep. y2. 1.t.. for (k=0. adams(2. double* y) { int step.200. } } #include <stdio. h[k]. k < n. printf("%f %f %f\n".t. y. double t. fprintf(stderr. double h. f2. y. h[k].h> /* for output */ #include <math. f1[k] = f2[k].y[1]). h[k].. /* solve the quadratic equation */ y[1] = y1*(2. y1. y2[2].5*h*(y1+y[1]). -1. k++) { y[k] = y2[k]. midpoint(2. nstep[k]-1.. double pi. y[1] = 1. 7 .h> /* for math functions */ #include "ode. const double* y. y[0] = 0. y[2].y[1]). } } /* main program */ int main (void) { int k. y2..1. pi_ode). for (step=0.y[k]). -1. f1.x).01. y[1] = 1. h[]={0.h" /* right-hand side for the pi ODE system */ void pi_ode (double x.h[k]. k++) { y[0] = 0.y[0]. f1. pi_ode).+h[k]. step < nstep.001}. y2.fabs(pi-y[0])).-h*t*y1))+1. fprintf(stderr. } printf("\n"). double t2. 0. pi = acos(-1. f2.. 1.fabs(pi-y[0])). midpoint(2.y[0].0."AB error with h=%f: %g\n". nstep[]={20. k < 3. y. for (k=0. printf("%f %f %f\n". y[0] += 0. f2[2]. f1[2]. 1. f2. y2. t = t2. f[1] = -y[1]*y[1]*x. y1 = y[1].. pi_ode). -1.2000}.0. f2. h[k]. -1.

y2. (11) y(0) = 0 . y 00 (t) = −  G M y(t) 3/2 ..h[k]."AM error with h=%f: %g\n". A more direct approach to the same problem involves the equations of Newton’s mechanics for the two-body problem: x 00 (t) = −  G M x(t) x 2 (t) + y 2 (t) 3/2 . It is more stable in the case of the Adams-Bashforth-Moluton method. Time 1 2 3 Adams-Bashforth x error y error -0.00870902 -0. we studied the motion of a planet. f2. -1.108425 . 3. 2.628241 -0. midpoint(2. Does the periodicity hold? Output the error x(k) − x(0) and y(k) − y(0) for k = 1. -1.00446057 -0.fabs(pi-y[0])). x and y are the planet coordinates with respect to the star. f1. the step size h = 360 year. } return 0. h[k].. 1.130388 0.+h[k]. The appropriate initial conditions (for the planet position “in July”) are x(0) = a (1 − ) . G is the gravitational constant.572406 0. pi_moulton(nstep[k]-1. (Programming) In Homework 3. y (0) = a ω 1− where  is the orbit eccentricity. y. (12) x 0 (0) = 0 r 1+ 0 . pi_ode).748445 8 Adams-Bashforth-Moulton x error y error -0.112335 -0. fprintf(stderr. a = 1 AU. and M is the mass of the star. In terms of the orbit characteristics. x 2 (t) + y 2 (t) (10) where t is time.y[0] = 0. y). 1]. G M = ω2 a. Answer: The period of the numerical solutions is erroneous compared to the exact period of one year. } 5. h[k].6. where ω is angular frequency. y[1] = 1. Plot the solution (planet trajectory) for t ∈ [0.00954070 -0.399762 -0.360284 0..0766191 -0. ω = 2 π year . and a is the major semi-axis of the orbit. Solve the initial-value problem numerically using the following methods: (a) Adams-Bashforth of order 2 (b) Adams-Bashforth of order 2 as predictor followed by one correction step of AdamsMoulton of order 2 1 1 Take  = 0.

2 0 −0.2 0.4 −1.6 9 −0.6 −0.2 0 0.6 −1.8 −1.2 0 0.4 −0.4 −0.2 −0.2 −1 −0.2 0 −0.2 0.8 0.6 −0.4 0.2 −1 −0.8 −1.8 −0.4 −0.4 .8 −0.4 0.Adams-Bashforth: 0.2 −0.6 −1.6 0.4 −0.4 −1.6 −0.6 0.8 0.4 Adams-Bashforth-Moulton: 0.

y2. static double w. f2[4]. y0[2] = 0. double* f) { double r.Solution: C program: #include <stdio. h. y2. y2. y. double h.6. f[2] = . y0[1] = 0.y[1]-y0[1]). y. /* right-hand side for the newton ODE system */ void newton (double x. y2[4].+eps)/(1."Error at t=%d: %g %g\n". f1. ncorr. newton). newton). nstep=360. for (k=1.-eps).y[0]-y0[0]. k < 3.. f[3] = . y0[3] = a*w*sqrt((1.y[0]-y0[0]. f2. } midpoint(4. r *= sqrt(r). const double* y. r = y[0]*y[0]+y[1]*y[1]. newton)."Error at t=1: %g %g\n". } } return 0.. h.k+1. f1. f[1] = y[3]. fprintf(stderr. ncorr++) { for (k=0.. w = 2. 0. for (ncorr=0.*acos(-1.h> /* for output */ #include <math. f[0] = y[2].h" static const double a=1. k < 4. ncorr. f2. f2.y[1]-y0[1])..-eps)).). ncorr < 2.w*w*a*y[1]/r. static const double eps=0. f1. y[4]. y. nstep-1. 1./(double) nstep. k++) { adams(4. h. } /* main program */ int main (void) { int k. 0. ncorr.h> /* for math functions */ #include "ode. y0[0] = a*(1. f1[4].. k++) { y[k] = y0[k]. adams(4. fprintf(stderr.w*w*a*y[0]/r. } 10 . h. h = 1. nstep. y0[4].