Skip to content

Commit ba2fa20

Browse files
ravi-ivar-7tianyizheng02
authored andcommitted
added runge kutta gills method to maths/ numerical_analysis (TheAlgorithms#10967)
* added runge kutta gills method * Apply suggestions from code review --------- Co-authored-by: Tianyi Zheng <[email protected]>
1 parent f671e7f commit ba2fa20

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed

Diff for: maths/numerical_analysis/runge_kutta_gills.py

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
"""
2+
Use the Runge-Kutta-Gill's method of order 4 to solve Ordinary Differential Equations.
3+
4+
https://www.geeksforgeeks.org/gills-4th-order-method-to-solve-differential-equations/
5+
Author : Ravi Kumar
6+
"""
7+
from collections.abc import Callable
8+
from math import sqrt
9+
10+
import numpy as np
11+
12+
13+
def runge_kutta_gills(
14+
func: Callable[[float, float], float],
15+
x_initial: float,
16+
y_initial: float,
17+
step_size: float,
18+
x_final: float,
19+
) -> np.ndarray:
20+
"""
21+
Solve an Ordinary Differential Equations using Runge-Kutta-Gills Method of order 4.
22+
23+
args:
24+
func: An ordinary differential equation (ODE) as function of x and y.
25+
x_initial: The initial value of x.
26+
y_initial: The initial value of y.
27+
step_size: The increment value of x.
28+
x_final: The final value of x.
29+
30+
Returns:
31+
Solution of y at each nodal point
32+
33+
>>> def f(x, y):
34+
... return (x-y)/2
35+
>>> y = runge_kutta_gills(f, 0, 3, 0.2, 5)
36+
>>> y[-1]
37+
3.4104259225717537
38+
39+
>>> def f(x,y):
40+
... return x
41+
>>> y = runge_kutta_gills(f, -1, 0, 0.2, 0)
42+
>>> y
43+
array([ 0. , -0.18, -0.32, -0.42, -0.48, -0.5 ])
44+
45+
>>> def f(x, y):
46+
... return x + y
47+
>>> y = runge_kutta_gills(f, 0, 0, 0.2, -1)
48+
Traceback (most recent call last):
49+
...
50+
ValueError: The final value of x must be greater than initial value of x.
51+
52+
>>> def f(x, y):
53+
... return x
54+
>>> y = runge_kutta_gills(f, -1, 0, -0.2, 0)
55+
Traceback (most recent call last):
56+
...
57+
ValueError: Step size must be positive.
58+
"""
59+
if x_initial >= x_final:
60+
raise ValueError(
61+
"The final value of x must be greater than initial value of x."
62+
)
63+
64+
if step_size <= 0:
65+
raise ValueError("Step size must be positive.")
66+
67+
n = int((x_final - x_initial) / step_size)
68+
y = np.zeros(n + 1)
69+
y[0] = y_initial
70+
for i in range(n):
71+
k1 = step_size * func(x_initial, y[i])
72+
k2 = step_size * func(x_initial + step_size / 2, y[i] + k1 / 2)
73+
k3 = step_size * func(
74+
x_initial + step_size / 2,
75+
y[i] + (-0.5 + 1 / sqrt(2)) * k1 + (1 - 1 / sqrt(2)) * k2,
76+
)
77+
k4 = step_size * func(
78+
x_initial + step_size, y[i] - (1 / sqrt(2)) * k2 + (1 + 1 / sqrt(2)) * k3
79+
)
80+
81+
y[i + 1] = y[i] + (k1 + (2 - sqrt(2)) * k2 + (2 + sqrt(2)) * k3 + k4) / 6
82+
x_initial += step_size
83+
return y
84+
85+
86+
if __name__ == "__main__":
87+
import doctest
88+
89+
doctest.testmod()

0 commit comments

Comments
 (0)