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 | ||||
| 
 | ||||
| # 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() | ||||
|  |  | |||
		Reference in a new issue
	
	 Eric Teunis de Boone
						Eric Teunis de Boone