Due in Room 244 Math Bldg, 3:29pm Friday, Feb 19.
(a) 1pt Rewrite the fourth order equation y''''(x) = x as a 1st order system.
(b) 3pts By hand, solve the IVP y'=t-y, y(0)=0 for y(1) using 4 Backward-Euler steps (each of size h=1/4). Show all the steps of the calculation.
Euler and Backward Euler applied to xyz system with c=10000
This code, xyz_with_euler.py tries to solve the "xyz" system using Euler's method.
(a) 2pts Verify that Euler's method on this IVP is unstable with the number of steps n=49970, and stable with n=50030.
(b) 2pts Compute the value of "ah" for this problem with the two different n-values, and relate your results in part (a) to our stability analysis of Euler's method. (Warning: the "a" in the stability analysis is not the "a" in parameters of this ODE.)
print '"ha" =', -h*c
(c) 5pts Modify the code to implement Backward Euler. Use scipy.optimize.fsolve to solve the implicit formula for w[i+1]. Verify that this method is stable, and also reasonably accurate, on this IVP with even as few steps as n=10000.
def eulerstep(f,t,w,h,*args): return w + h*f(t,w,*args) from scipy.optimize import fsolve def backwardeulerstep(f,t,w,h,*args): def g(u): return -u + w + h*f(t,u,*args) u = fsolve( g, w ) return u
(d) 1pt Why does z oscillate at twice the frequency that x and y do?
(a) (2pts) Take this code, multistep_stability.py, which plots, as a function of ha, the moduli ("magnitudes") of the eigenvalues for any explicit linear 2-step method of order 2 (local error O(h^3)), and try various values of the parameter, a1.
(b) (2pts) Discuss the differences seen in (a), and try to explain why only the choice a1=1 has a name! (I.e., Adams-Bashforth.) Note that the "correct" behavior on the linear model is shown in black in the plot.
(6pts) Solve the BVP
over the t-interval [0,4], by linear shooting (not by a general nonlinear iteration). Use the scipy.integrate.ode vode Adams IVP solver. Plot your solution (both y and y').
from scipy.integrate import ode import sys from numpy import * import matplotlib.pyplot as pl def myf(t,yyp,homog=False): global fcount fcount += 1 y,yp = yyp if homog: return array([ yp, (2.*t/(1.+t**2))*yp - (2./(1+t**2))*y ]) else: return array([ yp, (2.*t/(1.+t**2))*yp - (2./(1+t**2))*y + 1. ]) def myjac(t,yyp): global jcount jcount += 1 #y,yp = yyp return array([[ 0. , 1. ], [ - (2./(1+t**2)), (2.*t/(1.+t**2)) ]] ) r = ode(myf, myjac).set_integrator('vode', method='adams',atol=1.e-10) t1 = 1. alpha = 1.3 beta = -0.95 # first shot r.set_initial_value([alpha,0.],0.) fcount = 0 jcount = 0 y1,yp1 = r.integrate(t1) t = r.t print t,y1,yp1, fcount, jcount # 2nd shot r.set_initial_value([0.,1.],0.) r.set_f_params(True) y2,yp2 = r.integrate(t1) t = r.t print t,y2,yp2, fcount, jcount c = (beta-y1)/y2 print c # check, with dense output n = 100 dt = 4./float(n) data = empty((2,n+1)) data[:,0] = [alpha,c] r.set_initial_value([alpha,c],0.) r.set_f_params(False) print r.integrate(1.) r.set_initial_value([alpha,c],0.) for i in range(n): if r.successful(): data[:,i+1] = r.integrate((i+1)*dt) else: print 'r not successful', i*dt break pl.plot( linspace(0,4,n+1), data[0,:], 'r', label='$y$') pl.plot( linspace(0,4,n+1), data[1,:], 'b', label='$y^\prime$') print r.t, data[:,-1], fcount, jcount pl.plot([1,1],[-10,2],'k',alpha=0.5) pl.plot([0,1],[alpha,alpha],'k',alpha=0.5) pl.plot([0,1],[beta ,beta ],'k',alpha=0.5) pl.legend() pl.xlabel('t') pl.show()
(6pts) Solve the (nonlinear) BVP
on the t-interval [0,1] by shooting. Use any accurate method you like for the IVP solving, and I recommend you use scipy.optimize.brentq to solve the boundary condition. Caution: there may be more than one solution of this BVP, so you may need to scan the IVP parameter to find them all. Plot your solution(s).
y'(0) y(1) -50.0 1.0 [ 7.7988061 53.94341216] 100 2 -45.5 1.0 [ 5.47938211 46.58661811] 196 4 -41.0 1.0 [ 3.31243535 40.65608372] 288 5 -36.5 1.0 [ 1.26943966 35.63473797] 388 7 -32.0 1.0 [ -0.66107601 30.97192949] 482 8 -27.5 1.0 [ -2.45894355 26.01775077] 575 9 -23.0 1.0 [ -4.03436313 19.97177019] 661 10 -18.5 1.0 [ -5.13048865 11.94703006] 745 11 -14.0 1.0 [-5.04371212 1.79217216] 810 12 -9.5 1.0 [-1.69388574 -4.57259925] 863 13 -5.0 1.0 [ 12.24636619 42.39281379] 940 14
from scipy.integrate import ode import sys from numpy import * import matplotlib.pyplot as pl from scipy.optimize import brentq def myf(t,yyp,homog=False): global fcount fcount += 1 y,yp = yyp return array([ yp, 3.*y**2/2. ]) def myjac(t,yyp): global jcount jcount += 1 y,yp = yyp return array([[ 0. , 1. ], [ 3.*y, 0. ]] ) r = ode(myf, myjac).set_integrator('vode', method='adams',atol=1.e-10) fcount = 0 jcount = 0 t1 = 1. alpha = 4.01 beta = 1. def deviation(s): r.set_initial_value([alpha,s],0.) y,yp = r.integrate(t1) return y-beta s1 = brentq(deviation,-36.5,-32.) print s1 s2 = brentq(deviation,-9.5,-5.) print s2 print fcount, jcount svals = [s1,s2] reds = ['r','m'] blues = ['b','c'] n = 100 dt = t1/float(n) data = empty((2,n+1)) for j,s in enumerate(svals): data[:,0] = [alpha,s] r.set_initial_value([alpha,s],0.) for i in range(n): data[:,i+1] = r.integrate((i+1)*dt) pl.subplot(211) pl.plot( linspace(0,t1,n+1), data[0,:], color=reds[j] , label='$y ^\prime (0)='+str(s)+'$') pl.subplot(212) pl.plot( linspace(0,t1,n+1), data[1,:], color=blues[j], label='$y ^\prime (0)='+str(s)+'$') print s, r.t, data[:,-1], fcount, jcount pl.subplot(211) pl.plot([1,1],[-10,10],'k',alpha=0.5) pl.plot([0,1],[alpha,alpha],'k',alpha=0.5) pl.plot([0,1],[beta ,beta ],'k',alpha=0.5) pl.ylabel('$y$') pl.legend(loc='upper left') pl.subplot(212) pl.xlabel('t') pl.ylabel("$y^\prime$") pl.title("y'(0) = "+' '.join(map(str,svals))) pl.legend(loc='upper left') pl.show()