diff --git a/week5/ex1.py b/week5/ex1.py index f2c29a1..e50b779 100755 --- a/week5/ex1.py +++ b/week5/ex1.py @@ -4,7 +4,11 @@ import numpy as np +# Integrations Schemes # +######################## +# Single Step +#------------ def mk_phi_euler(f): """ Return a Phi computed for the Euler Method. """ def phi_euler(x, y, h): @@ -12,7 +16,6 @@ def mk_phi_euler(f): return phi_euler - def mk_phi_euler_mod(f): """ Return a Phi computed for the Modified Euler (Collatz) Method. """ def phi_euler_mod(x, y, h): @@ -20,7 +23,6 @@ def mk_phi_euler_mod(f): return phi_euler_mod - def mk_phi_heun(f): """ Return a Phi computed for the Heun Method. """ def phi_heun(x, y, h): @@ -40,6 +42,31 @@ def mk_phi_rk4(f): return phi_rk4 + +# Multi Step +#----------- +def mk_phi_AB3(f, phi_short): + steps = 3 + def phi_AB3(x, y, h): + if len(x) <= steps: + return phi_short(x, y, h) + else: + return ( 23*f(x[-1], y[-1]) - 16*f(x[-2], y[-2]) + 5*f(x[-3], y[-3]) )/12 + + return phi_AB3 + +def mk_phi_AB4(f, phi_short): + steps = 4 + def phi_AB4(x, y, h): + if len(x) <= steps: + return phi_short(x, y, h) + else: + return ( 55*f(x[-1], y[-1]) - 59*f(x[-2], y[-2]) + 37*f(x[-3], y[-3]) -9*f(x[-4],y[-4]))/24 + + return phi_AB4 + +# Integrator # +############## def integrator(x, y_0, phi): x = np.asarray(x) if isinstance(y_0, (list,np.ndarray)): @@ -54,26 +81,24 @@ def integrator(x, y_0, phi): y[0] = y_0 h = x[1]-x[0] - for i, x_i in enumerate(x): - # Skip the first iteration - if not i: - continue - + for i in range(1,N): y[i] = y[i-1] + h*phi(x[:i], y[:i], h) return y +# Math Test Functions # +####################### +def ODEF(x, y): + return y - x**2 + 1 -def test_integrator(): - np.random.seed(0) +def ODEF_sol(x): + return (x+1)**2 - 0.5*np.exp(x) - def ODEF(x, y): - return y - x**2 + 1 - - def ODEF_sol(x): - return (x+1)**2 - 0.5*np.exp(x) +# Testing # +########### +def test_integrator_singlestep(): test_func = ODEF exact_sol = ODEF_sol @@ -110,5 +135,39 @@ def test_integrator(): pyplot.show() +def test_integrator_multistep(): + test_func = ODEF + exact_sol = ODEF_sol + + N = 2e1 + M = 1 + + # Domain on which to do the integration + x = np.linspace(0, 1, N) + + # Calculate Initial Values using RK4 + y_0 = 0.5 + schemes = [ + ["AB3", mk_phi_AB3], + ["AB4", mk_phi_AB4], + ] + + # Show Plot + from matplotlib import pyplot + pyplot.subplots() + + for name, func in schemes: + pyplot.plot(x, integrator(x, y_0, func(test_func, mk_phi_rk4(test_func))), '--o', label=name) + + pyplot.plot(x, exact_sol(x), '-', label="Exact Solution") + pyplot.xlabel("x") + pyplot.ylabel("y") + + pyplot.legend() + + pyplot.show() + if __name__ == "__main__": - test_integrator() + np.random.seed(0) + #test_integrator_singlestep() + test_integrator_multistep()