Skip to content

Commit 019b67b

Browse files
committed
Initial Commit
1 parent c30bed3 commit 019b67b

8 files changed

+338
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.DS_Store

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,9 @@
11
# ODE-Methods
22
A collection of various methods to find solution to Ordinary Differential Equations.
3+
4+
1. Adams-Bashforth Method: Includes Two, Three, Four, Five Step method and also the Predictor-Corrector method
5+
2. Milne-Simspons Method
6+
3. Euler's Method: Includes the Analytical method, plain Estimation and Modified Euler's Method.
7+
4. Runge-Kutta Fourth-Order: Includes Estimator and Analytical method.
8+
5. Midpoint Method.
9+
6. Taylor's Estimation

ab_methods.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
from math import *
2+
3+
correctors = [
4+
[2, 3, -1],
5+
[12, 23, -16, 5],
6+
[24, 55, -59, 37, -9],
7+
[720, 1901, -2774, 2616, -1274, 251]
8+
]
9+
10+
def abN_actual(f, f_actual, t, y, p, h, N):
11+
corrector = correctors[N-2]
12+
n = int((p-t)/h)
13+
time = [t+h*i for i in range(n+1)]
14+
values = [f_actual(time[i]) for i in range(N)]
15+
16+
for i in range(N, n+1):
17+
fix = 0
18+
for j in range(N):
19+
fix += corrector[j+1] * f(time[i-j-1], values[i-j-1])
20+
y = values[i-1] + h/corrector[0]*fix
21+
values.append(y)
22+
23+
print(f"AB-{N} Method")
24+
print("-"*40)
25+
print(f't\t\t|\tEstimate')
26+
print("-"*40)
27+
28+
for i in range(len(values)):
29+
print(f'{time[i]:.3f}\t\t|\t{values[i]:.9f}')
30+
print("-"*40)
31+
32+
def abN_rk4(f, f_actual, t, y, p, h, N, correction = False):
33+
corrector = correctors[N-2]
34+
n = int((p-t)/h)
35+
time = [t+h*i for i in range(n+1)]
36+
y_values = [y]
37+
38+
for i in range(1,N):
39+
y_values.append(rk4(f, time[i-1], y_values[i-1]))
40+
41+
for i in range(N, n+1):
42+
fix = 0
43+
for j in range(N):
44+
fix += corrector[j+1] * f(time[i-j-1], y_values[i-j-1])
45+
yn = y_values[i-1] + h/corrector[0]*fix
46+
47+
# This is a special case of AB-4 Predictor Corrector, hence the correction parameter for adjustment.
48+
if N == 4 and correction:
49+
fix = 9*f(time[i], yn)
50+
coeffs = [19, -5, 1]
51+
for j in range(len(coeffs)):
52+
fix += coeffs[j] * f(time[i-j-1], y_values[i-j-1])
53+
yn = y_values[i-1] + h/24*fix
54+
55+
y_values.append(yn)
56+
57+
print(f"AB-{N} {'Predictor-Corrector' if correction else ''} Method")
58+
print("-"*70)
59+
print(f't\t\t|\tEstimate\t\t|\tActual')
60+
print("-"*70)
61+
62+
for i in range(len(y_values)):
63+
print(f'{time[i]:.3f}\t\t|\t{y_values[i]:.9f}\t\t|\t{f_actual(time[i]):.9f}')
64+
print("-"*70)
65+
66+
def rk4(f, t, y):
67+
k1 = h*f(t, y)
68+
k2 = h*f(t + h/2, y + k1/2)
69+
k3 = h*f(t + h/2, y + k2/2)
70+
k4 = h*f(t + h, y + k3)
71+
return y + (k1 + 2*k2 + 2*k3 + k4)/6
72+
73+
if __name__ == '__main__':
74+
75+
f = lambda t, y: cos(2*t) + sin(3*t)
76+
77+
f_actual = lambda t: sin(2*t)/2 - cos(3*t)/3 + 4/3
78+
79+
t = float(input("t0: "))
80+
y = float(input("y0: "))
81+
p = float(input("Evaluation point: "))
82+
h = float(input("Step size: "))
83+
N = int(input("Which AB-N method to use? [2-5]: "))
84+
#abN_actual(f, f_actual, t, y, p, h, N)
85+
abN_rk4(f, f_actual, t, y, p, h, N, True)

eulers.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
from math import *
2+
3+
def analytical_eulers(f, f_actual, t, y, p, h = None, n = None):
4+
if h == None:
5+
h = (p-t)/n
6+
if n == None:
7+
n = int((p-t)/h)
8+
9+
print(f't\t\t|\tEstimate\t\t|\tExact\t\t\t|\tError')
10+
print("-"*100)
11+
print(f'{t:.3f}\t\t|\t{y:.9f}\t\t|\t{f_actual(t):.9f}\t\t|\t{abs(f_actual(t)-y):.9f}')
12+
13+
for i in range(n):
14+
y = y + h*f(t, y)
15+
t += h
16+
actual = f_actual(t)
17+
print(f'{t:.3f}\t\t|\t{y:.9f}\t\t|\t{actual:.9f}\t\t|\t{abs(actual-y):.9f}')
18+
19+
print("-"*100)
20+
21+
def modified_eulers(f, f_actual, t, y, p, h = None, n = None):
22+
if h == None:
23+
h = (p-t)/n
24+
if n == None:
25+
n = int((p-t)/h)
26+
27+
print(f't\t\t|\tEstimate\t\t|\tExact\t\t\t|\tError')
28+
print("-"*100)
29+
print(f'{t:.3f}\t\t|\t{y:.9f}\t\t|\t{f_actual(t):.9f}\t\t|\t{abs(f_actual(t)-y):.9f}')
30+
31+
for i in range(n):
32+
func_value = f(t, y)
33+
t += h
34+
next_value = f(t, y + h*func_value)
35+
y = y + h/2*(func_value + next_value)
36+
actual_value = f_actual(t)
37+
print(f'{t:.3f}\t\t|\t{y:.9f}\t\t|\t{actual_value:.9f}\t\t|\t{abs(actual_value-y):.9f}')
38+
print("-"*100)
39+
40+
def eulers_estimate(f, t, y, p, h = None, n = None):
41+
if h == None:
42+
h = (p-t)/n
43+
if n == None:
44+
n = int((p-t)/h)
45+
46+
print(f't\t\t|\tEstimate')
47+
print('-'*40)
48+
49+
print(f'{t:.3f}\t\t|\t{y:.9f}')
50+
51+
for i in range(n):
52+
y = y + h*f(t, y)
53+
t += h
54+
print(f'{t:.3f}\t\t|\t{y:.9f}')
55+
print('-'*40)
56+
57+
def main():
58+
option = int(input("Choose\n1) Euler's Approximation\n2) Euler's Analytical\n3) Modified Euler's\n"))
59+
60+
# Define these functions depending on the problem.
61+
f = lambda t, y: -20*(y-t*t) + 2*t
62+
f_analytical = lambda t: t*t + exp(-20*t)/3
63+
64+
t0 = float(input("t0 = "))
65+
t = t0
66+
y0 = float(input("y0 = "))
67+
p = float(input("Evaluation point = "))
68+
h = ""
69+
n = ""
70+
while h.strip() == "" and n.strip() == "":
71+
h = input("Enter H [Leave blank if you want to enter N]: ")
72+
n = input("Enter N [Leave blank if H already inputted]: ")
73+
if h == "":
74+
n = int(n)
75+
h = None
76+
else:
77+
h = float(h)
78+
n = None
79+
if option == 1:
80+
eulers_estimate(f, t0, y0, p, h, n)
81+
elif option == 2:
82+
analytical_eulers(f, f_analytical, t0, y0, p, h, n)
83+
else:
84+
modified_eulers(f, f_analytical, t0, y0, p, h, n)
85+
86+
if __name__ == '__main__':
87+
main()
88+

midpoint_method_ode.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from math import *
2+
3+
def midpoint(f, f_actual, t, y, p, h = None, n = None):
4+
if h == None:
5+
h = (p-t)/n
6+
if n == None:
7+
n = int((p-t)/h)
8+
9+
print(f't\t\t|\tEstimate\t\t|\tExact\t\t\t|\tError')
10+
print("-"*100)
11+
print(f'{t:.3f}\t\t|\t{y:.9f}\t\t|\t{f_actual(t):.9f}\t\t|\t{abs(f_actual(t)-y):.9f}')
12+
13+
for i in range(n):
14+
y = y + h*f(t + h/2, y + h/2*f(t, y))
15+
t += h
16+
actual = f_actual(t)
17+
print(f'{t:.3f}\t\t|\t{y:.9f}\t\t|\t{actual:.9f}\t\t|\t{abs(actual-y):.9f}')
18+
print("-"*100)
19+
20+
def main():
21+
# Define these functions depending on the problem.
22+
f = lambda t, y: 1 + y/t
23+
f_analytical = lambda t: t*(log(t) + 2)
24+
25+
t0 = float(input("t0 = "))
26+
t = t0
27+
y0 = float(input("y0 = "))
28+
p = float(input("Evaluation point = "))
29+
h = ""
30+
n = ""
31+
while h.strip() == "" and n.strip() == "":
32+
h = input("Enter H [Leave blank if you want to enter N]: ")
33+
n = input("Enter N [Leave blank if H already inputted]: ")
34+
if h == "":
35+
n = int(n)
36+
h = None
37+
else:
38+
h = float(h)
39+
n = None
40+
midpoint(f, f_analytical, t0, y0, p, h, n)
41+
42+
if __name__ == '__main__':
43+
main()

milne_simpsons.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from math import *
2+
3+
def milne_simpson(f, f_actual, t, y, p, h):
4+
n = int((p-t)/h)
5+
time = [t+i*h for i in range(n+1)]
6+
7+
y_values = [0]*(n+1)
8+
y_values[0] = y
9+
10+
for i in range(1, 4):
11+
y_values[i] = rk4(f, time[i-1], y_values[i-1])
12+
13+
for i in range(4, n+1):
14+
milne = y_values[i-4] + 4/3*h*(2*f(time[i-1], y_values[i-1]) - f(time[i-2], y_values[i-2]) + 2*f(time[i-3], y_values[i-3]))
15+
y_values[i] = y_values[i-2] + h/3*(f(time[i],milne) + 4*f(time[i-1], y_values[i-1]) + f(time[i-2], y_values[i-2]))
16+
17+
print(f"Milne-Simpson Method")
18+
print("-"*70)
19+
print(f't\t\t|\tEstimate\t\t|\tActual')
20+
print("-"*70)
21+
22+
for i in range(len(y_values)):
23+
print(f'{time[i]:.3f}\t\t|\t{y_values[i]:.9f}\t\t|\t{f_actual(time[i]):.9f}')
24+
print("-"*70)
25+
26+
def rk4(f, t, y):
27+
k1 = h*f(t, y)
28+
k2 = h*f(t + h/2, y + k1/2)
29+
k3 = h*f(t + h/2, y + k2/2)
30+
k4 = h*f(t + h, y + k3)
31+
return y + (k1 + 2*k2 + 2*k3 + k4)/6
32+
33+
if __name__ == '__main__':
34+
35+
f = lambda t, y: -5*y + 5*t*t + 2*t
36+
37+
f_actual = lambda t: t*t + exp(-5*t)/3
38+
39+
t = float(input("t0: "))
40+
y = float(input("y0: "))
41+
p = float(input("Evaluation point: "))
42+
h = float(input("Step size: "))
43+
44+
milne_simpson(f, f_actual, t, y, p, h)

runge_kutta_4.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from math import *
2+
3+
def rk4(f, f_actual, t, y, p, h, analytical = False):
4+
n = int((p-t)/h)
5+
6+
separator = "-"*100 if analytical else "-"*40
7+
if analytical:
8+
print(f'\nt\t\t|\tEstimate\t\t|\tExact\t\t\t|\tError\n{separator}')
9+
print(f'{t:.3f}\t\t|\t{y:.9f}\t\t|\t{f_actual(t):.9f}\t\t|\t{abs(f_actual(t)-y):.9f}')
10+
else:
11+
print(f'\nt\t\t|\tEstimate\n{separator}')
12+
print(f'{t:.3f}\t\t|\t{y:.9f}')
13+
14+
for i in range(n):
15+
k1 = h*f(t, y)
16+
k2 = h*f(t + h/2, y + k1/2)
17+
k3 = h*f(t + h/2, y + k2/2)
18+
k4 = h*f(t + h, y + k3)
19+
y = y + (k1 + 2*k2 + 2*k3 + k4)/6
20+
t += h
21+
actual = f_actual(t)
22+
print(f'{t:.3f}\t\t|\t{y:.9f}', end = '')
23+
print(f'\t\t|\t{actual:.9f}\t\t|\t{abs(actual-y):.9f}' if analytical else '')
24+
print(separator)
25+
26+
def main():
27+
28+
# Define these functions depending on the problem.
29+
f = lambda t, y: -20*(y-t*t) + 2*t
30+
f_analytical = lambda t: t*t + exp(-20*t)/3
31+
32+
choice = int(input("1) RK-4 Estimator\n2) RK-4 Analytical\n"))
33+
if choice == 2:
34+
print("Make sure you have defined the analytic function correctly.")
35+
36+
t0 = float(input("t0 = "))
37+
y0 = float(input("y0 = "))
38+
p = float(input("Evaluation point = "))
39+
h = float(input("Step-Size = "))
40+
rk4(f, f_analytical, t0, y0, p, h, choice == 2)
41+
42+
if __name__ == '__main__':
43+
main()

taylor_estimation.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from math import *
2+
3+
g = 9.8
4+
kbym = 0.002/0.11
5+
print(kbym)
6+
7+
yp = lambda t, y: -g - kbym*y*abs(y)
8+
ypp = lambda t, y, ypv: -kbym*(ypv*abs(y)+y*abs(ypv))
9+
10+
series = lambda h, y, yp, ypp: y + h*yp + h*h*ypp/2
11+
12+
a = 0
13+
b = 1
14+
t0 = 0
15+
y0 = 8
16+
h = 0.1
17+
n = int((b-t0)/h)
18+
19+
for i in range(n):
20+
d1 = yp(t0, y0)
21+
d2 = ypp(t0, y0, d1)
22+
print(f"y({t0:.3f}) = {y0}\ny'({t0:.3f}) = {d1}\ny''({t0:.3f}) = {d2}")
23+
result = series(h, y0, d1, d2)
24+
t0 += h
25+
print(f'y({t0:.3f}) = {result:.9f}\n')
26+
y0 = result
27+

0 commit comments

Comments
 (0)