Skip to content

Commit 6282e30

Browse files
committed
Merge branch 'add-ode-numerical-methods' of https://github.com/sauriopqno/Python into add-ode-numerical-methods
Edit theordinary_differential_ecuations.py file
2 parents a123c2a + aa1e89d commit 6282e30

1 file changed

Lines changed: 60 additions & 43 deletions

File tree

Lines changed: 60 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,31 @@
11
"""
2-
Numerical methods for solving Ordinary Differential Equations (ODEs) of the form y' = f(x, y).
2+
Numerical methods for solving Ordinary Differential Equations (ODEs)
3+
of the form y' = f(x, y).
34
This module implements the Euler method and Heun's method.
45
56
References:
67
- Euler Method: https://en.wikipedia.org/wiki/Euler_method
78
- Heun's Method: https://en.wikipedia.org/wiki/Heun%27s_method
8-
99
"""
1010

11-
from typing import Callable, List, Tuple
11+
from collections.abc import Callable
1212

1313

1414
def euler_method(
15-
f: Callable[[float, float], float], x0: float, y0: float, h: float, steps: int
16-
) -> Tuple[List[float], List[float]]:
15+
differential_function: Callable[[float, float], float],
16+
x_initial: float,
17+
y_initial: float,
18+
step_size: float,
19+
total_steps: int,
20+
) -> tuple[list[float], list[float]]:
1721
"""
1822
Approximates the solution of a first-order ODE y' = f(x, y) using Euler's method.
1923
20-
:param f: The differential equation function f(x, y).
21-
:param x0: Initial value of x.
22-
:param y0: Initial value of y (y(x0) = y0).
23-
:param h: Step size.
24-
:param steps: Number of iterations to perform.
24+
:param differential_function: The differential equation function f(x, y).
25+
:param x_initial: Initial value of x.
26+
:param y_initial: Initial value of y (y(x_initial) = y_initial).
27+
:param step_size: Step size.
28+
:param total_steps: Number of iterations to perform.
2529
:return: A tuple containing lists of x and y coordinates.
2630
2731
>>> def f_ode(x: float, y: float) -> float: return y - x**2 + 1
@@ -31,56 +35,69 @@ def euler_method(
3135
>>> [round(i, 4) for i in y_vals]
3236
[0.5, 0.875, 1.3281]
3337
"""
34-
x = [0.0] * (steps + 1)
35-
y = [0.0] * (steps + 1)
36-
x[0], y[0] = x0, y0
38+
x_estimates = [0.0] * (total_steps + 1)
39+
y_estimates = [0.0] * (total_steps + 1)
40+
x_estimates[0], y_estimates[0] = x_initial, y_initial
3741

38-
for i in range(steps):
39-
y[i + 1] = y[i] + f(x[i], y[i]) * h
40-
x[i + 1] = x[i] + h
42+
for i in range(total_steps):
43+
y_estimates[i + 1] = (
44+
y_estimates[i]
45+
+ differential_function(x_estimates[i], y_estimates[i]) * step_size
46+
)
47+
x_estimates[i + 1] = x_estimates[i] + step_size
4148

42-
return x, y
49+
return x_estimates, y_estimates
4350

4451

4552
def heuns_method(
46-
f: Callable[[float, float], float], x0: float, y0: float, h: float, steps: int
47-
) -> Tuple[List[float], List[float]]:
53+
differential_function: Callable[[float, float], float],
54+
x_initial: float,
55+
y_initial: float,
56+
step_size: float,
57+
total_steps: int,
58+
) -> tuple[list[float], list[float]]:
4859
"""
49-
Approximates the solution of a firs -order ODE y' = f(x, y) using Heun's method
60+
Approximates the solution of a first-order ODE y' = f(x, y) using Heun's method
5061
(also known as the improved Euler method).
5162
52-
:param f: The differential equation function f(x, y).
53-
:param x0: Initial value of x.
54-
:param y0: Initial value of y.
55-
:param h: Step size.
56-
:param steps: Number of iterations to perform.
63+
:param differential_function: The differential equation function f(x, y).
64+
:param x_initial: Initial value of x.
65+
:param y_initial: Initial value of y.
66+
:param step_size: Step size.
67+
:param total_steps: Number of iterations to perform.
5768
:return: A tuple containing lists of x and y coordinates.
5869
5970
>>> def f_ode(x: float, y: float) -> float: return y - x**2 + 1
6071
>>> x_vals, y_vals = heuns_method(f_ode, 0.0, 0.5, 0.25, 2)
6172
>>> [round(i, 4) for i in y_vals]
6273
[0.5, 0.9141, 1.4114]
6374
"""
64-
x = [0.0] * (steps + 1)
65-
y = [0.0] * (steps + 1)
66-
x[0], y[0] = x0, y0
67-
68-
for i in range(steps):
69-
y_predictor = y[i] + f(x[i], y[i]) * h
70-
x[i + 1] = x[i] + h
71-
y[i + 1] = y[i] + ((f(x[i], y[i]) + f(x[i + 1], y_predictor)) / 2.0) * h
72-
73-
return x, y
75+
x_estimates = [0.0] * (total_steps + 1)
76+
y_estimates = [0.0] * (total_steps + 1)
77+
x_estimates[0], y_estimates[0] = x_initial, y_initial
78+
79+
for i in range(total_steps):
80+
y_predictor = (
81+
y_estimates[i]
82+
+ differential_function(x_estimates[i], y_estimates[i]) * step_size
83+
)
84+
x_estimates[i + 1] = x_estimates[i] + step_size
85+
y_estimates[i + 1] = (
86+
y_estimates[i]
87+
+ (
88+
(
89+
differential_function(x_estimates[i], y_estimates[i])
90+
+ differential_function(x_estimates[i + 1], y_predictor)
91+
)
92+
/ 2.0
93+
)
94+
* step_size
95+
)
96+
97+
return x_estimates, y_estimates
7498

7599

76100
if __name__ == "__main__":
77101
import doctest
78102

79-
doctest.testmod()
80-
81-
# example
82-
def example_ode(x: float, y: float) -> float:
83-
return y - x**2 + 1
84-
85-
x_res, y_res = heuns_method(example_ode, 0.0, 0.5, 0.25, 4)
86-
print(f"Final heuns methot y value at x={x_res[-1]}: {round(y_res[-1], 4)}")
103+
doctest.testmod()

0 commit comments

Comments
 (0)