Week5: Wrap up: MultiStep
This commit is contained in:
parent
374cef0784
commit
40f3d9f969
1 changed files with 74 additions and 15 deletions
89
week5/ex1.py
89
week5/ex1.py
|
@ -4,7 +4,11 @@
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
# Integrations Schemes #
|
||||||
|
########################
|
||||||
|
|
||||||
|
# Single Step
|
||||||
|
#------------
|
||||||
def mk_phi_euler(f):
|
def mk_phi_euler(f):
|
||||||
""" Return a Phi computed for the Euler Method. """
|
""" Return a Phi computed for the Euler Method. """
|
||||||
def phi_euler(x, y, h):
|
def phi_euler(x, y, h):
|
||||||
|
@ -12,7 +16,6 @@ def mk_phi_euler(f):
|
||||||
|
|
||||||
return phi_euler
|
return phi_euler
|
||||||
|
|
||||||
|
|
||||||
def mk_phi_euler_mod(f):
|
def mk_phi_euler_mod(f):
|
||||||
""" Return a Phi computed for the Modified Euler (Collatz) Method. """
|
""" Return a Phi computed for the Modified Euler (Collatz) Method. """
|
||||||
def phi_euler_mod(x, y, h):
|
def phi_euler_mod(x, y, h):
|
||||||
|
@ -20,7 +23,6 @@ def mk_phi_euler_mod(f):
|
||||||
|
|
||||||
return phi_euler_mod
|
return phi_euler_mod
|
||||||
|
|
||||||
|
|
||||||
def mk_phi_heun(f):
|
def mk_phi_heun(f):
|
||||||
""" Return a Phi computed for the Heun Method. """
|
""" Return a Phi computed for the Heun Method. """
|
||||||
def phi_heun(x, y, h):
|
def phi_heun(x, y, h):
|
||||||
|
@ -40,6 +42,31 @@ def mk_phi_rk4(f):
|
||||||
|
|
||||||
return phi_rk4
|
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):
|
def integrator(x, y_0, phi):
|
||||||
x = np.asarray(x)
|
x = np.asarray(x)
|
||||||
if isinstance(y_0, (list,np.ndarray)):
|
if isinstance(y_0, (list,np.ndarray)):
|
||||||
|
@ -54,26 +81,24 @@ def integrator(x, y_0, phi):
|
||||||
y[0] = y_0
|
y[0] = y_0
|
||||||
|
|
||||||
h = x[1]-x[0]
|
h = x[1]-x[0]
|
||||||
for i, x_i in enumerate(x):
|
for i in range(1,N):
|
||||||
# Skip the first iteration
|
|
||||||
if not i:
|
|
||||||
continue
|
|
||||||
|
|
||||||
y[i] = y[i-1] + h*phi(x[:i], y[:i], h)
|
y[i] = y[i-1] + h*phi(x[:i], y[:i], h)
|
||||||
|
|
||||||
return y
|
return y
|
||||||
|
|
||||||
|
|
||||||
|
# Math Test Functions #
|
||||||
|
#######################
|
||||||
|
def ODEF(x, y):
|
||||||
|
return y - x**2 + 1
|
||||||
|
|
||||||
def test_integrator():
|
def ODEF_sol(x):
|
||||||
np.random.seed(0)
|
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
|
test_func = ODEF
|
||||||
exact_sol = ODEF_sol
|
exact_sol = ODEF_sol
|
||||||
|
@ -110,5 +135,39 @@ def test_integrator():
|
||||||
|
|
||||||
pyplot.show()
|
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__":
|
if __name__ == "__main__":
|
||||||
test_integrator()
|
np.random.seed(0)
|
||||||
|
#test_integrator_singlestep()
|
||||||
|
test_integrator_multistep()
|
||||||
|
|
Reference in a new issue