-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNumerical_Method_ODE.py
104 lines (81 loc) · 3.16 KB
/
Numerical_Method_ODE.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import math
def function(x, y):
return (-2*x-y)
def euler_explicit_1(x_0, y_0, x, h):
n = int((x - x_0)//h + 1)
y = y_0
for i in range(1, n+1):
del_y = h*function(x_0, y)
y = y + del_y
x_0 = x_0 + h
print(f"y' = {function(x_0,y)}\nh*y' = {h*function(x_0,y)}")
print(f"y for {i}th iteration with {round(x_0,3)} is {y}\n")
print("=========================================")
print("*** Euler Explicit Method ***")
print("#############################################")
def euler_modified(x_0, y_0, x, h):
n = int((x - x_0)//h + 1)
y = y_0
for i in range(1, n+1):
y_p = y + h*function(x_0, y)
initial_slope = function(x_0, y)
final_slope = function(x_0+h, y_p)
del_y = 0.5*h*(initial_slope + final_slope)
y = y + del_y
x_0 = x_0 + h
print(
f"Initial Slope= {initial_slope}\ny_predicted = {y_p}\nFinal Slope = {final_slope}")
print(f"h*y'_avg = {del_y}")
print(f"y for {i}th iteration with {round(x_0,3)} is {y}\n")
print("=========================================")
print("*** Euler Modified (Heun) Method ***")
print("#############################################")
# Generic 2nd order Runge Kutta method with a=0.5, b=0.5, alpha=1, beta=1 denotes Euler Modified Method or Heun Method
# Another variation of Runge Kutta Method is explicit midpoint method
def rungeKutta_2(x_0, y_0, x, h, a=0.5, b=0.5, alpha=1, beta=1):
n = int((x - x_0)//h + 1)
y = y_0
for i in range(1, n+1):
k1 = h * function(x_0, y)
# Generic method below is commented for now.
# k2 = h * function(x_0 + alpha*h, y + beta*k1)
# k_avg = a*k1 + b*k2
# The below method is used by online solvers and is midpoint method
k2 = h * function(x_0 + 0.5*h, y + 0.5*k1)
k_avg = k2
y = y + k_avg
x_0 = x_0 + h
print(f"h*k1 = {k1}\nh*k2 = {k2}")
print(f"h*k_avg ={k_avg}")
print(f"y for {i}th iteration with {round(x_0,3)} is {y}\n")
print("=========================================")
print("*** Runge Kutta 2nd order (midpoint method) ***")
print("#############################################")
def rungeKutta_4(x_0, y_0, x, h):
n = int((x - x_0)//h + 1)
y = y_0
for i in range(1, n+1):
k1 = h * function(x_0, y)
k2 = h * function(x_0 + 0.5*h, y + 0.5*k1)
k3 = h * function(x_0 + 0.5*h, y + 0.5*k2)
k4 = h * function(x_0 + h, y + k3)
k_avg = (1/6)*(k1 + 2*k2 + 2*k3 + k4)
y = y + k_avg
x_0 = x_0 + h
print(f"h*k1 = {k1}\nh*k2 = {k2}\nh*k3 = {k3}\nh*k4 = {k4}")
print(f"h*k_avg ={k_avg}")
print(f"y for {i}th iteration with {round(x_0,3)} is {y}\n")
print("=========================================")
print("*** Runge Kutta 4th order ***")
print("#############################################")
def main():
x_0 = 0
y_0 = -1
x = 0.6
h = 0.1
euler_explicit_1(x_0, y_0, x, h)
#euler_modified(x_0, y_0, x, h)
#rungeKutta_4(x_0, y_0, x, h)
#rungeKutta_2(x_0, y_0, x, h)
if __name__ == "__main__":
main()