From 566d47d2ac55630a7ec06bd49d0dd14985dbec33 Mon Sep 17 00:00:00 2001 From: Imanol Elizondo Perucich Date: Fri, 26 Jun 2026 23:22:34 -0600 Subject: [PATCH 1/4] feat(maths): add numerical methods for solving ordinary differential equations --- .../ordinary_differential_equations.py | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 maths/numerical_analysis/ordinary_differential_equations.py diff --git a/maths/numerical_analysis/ordinary_differential_equations.py b/maths/numerical_analysis/ordinary_differential_equations.py new file mode 100644 index 000000000000..ddedcad0c879 --- /dev/null +++ b/maths/numerical_analysis/ordinary_differential_equations.py @@ -0,0 +1,89 @@ +""" +Numerical methods for solving Ordinary Differential Equations (ODEs) of the form y' = f(x, y). +This module implements the Euler method and Heun's method. + +References: +- Euler Method: https://en.wikipedia.org/wiki/Euler_method +- Heun's Method: https://en.wikipedia.org/wiki/Heun%27s_method + +""" + +from typing import Callable, List, Tuple + + +def euler_method( + f: Callable[[float, float], float], x0: float, y0: float, h: float, steps: int +) -> Tuple[List[float], List[float]]: + """ + Approximates the solution of a first-order ODE y' = f(x, y) using Euler's method. + + :param f: The differential equation function f(x, y). + :param x0: Initial value of x. + :param y0: Initial value of y (y(x0) = y0). + :param h: Step size. + :param steps: Number of iterations to perform. + :return: A tuple containing lists of x and y coordinates. + + >>> def f_ode(x: float, y: float) -> float: return y - x**2 + 1 + >>> x_vals, y_vals = euler_method(f_ode, 0.0, 0.5, 0.25, 2) + >>> [round(i, 4) for i in x_vals] + [0.0, 0.25, 0.5] + >>> [round(i, 4) for i in y_vals] + [0.5, 0.875, 1.3281] + """ + x = [0.0] * (steps + 1) + y = [0.0] * (steps + 1) + x[0], y[0] = x0, y0 + + for i in range(steps): + y[i + 1] = y[i] + f(x[i], y[i]) * h + x[i + 1] = x[i] + h + + return x, y + + +def heuns_method( + f: Callable[[float, float], float], x0: float, y0: float, h: float, steps: int +) -> Tuple[List[float], List[float]]: + """ + Approximates the solution of a firs -order ODE y' = f(x, y) using Heun's method + (also known as the improved Euler method). + + :param f: The differential equation function f(x, y). + :param x0: Initial value of x. + :param y0: Initial value of y. + :param h: Step size. + :param steps: Number of iterations to perform. + :return: A tuple containing lists of x and y coordinates. + + >>> def f_ode(x: float, y: float) -> float: return y - x**2 + 1 + >>> x_vals, y_vals = heuns_method(f_ode, 0.0, 0.5, 0.25, 2) + >>> [round(i, 4) for i in y_vals] + [0.5, 0.9141, 1.4114] + """ + x = [0.0] * (steps + 1) + y = [0.0] * (steps + 1) + x[0], y[0] = x0, y0 + + for i in range(steps): + y_predictor = y[i] + f(x[i], y[i]) * h + x[i + 1] = x[i] + h + y[i + 1] = y[i] + ((f(x[i], y[i]) + f(x[i + 1], y_predictor)) / 2.0) * h + + return x, y + + + + + +if __name__ == "__main__": + import doctest + + doctest.testmod() + + # example + def example_ode(x: float, y: float) -> float: + return y - x**2 + 1 + + x_res, y_res = heuns_method(example_ode, 0.0, 0.5, 0.25, 4) + print(f"Final heuns methot y value at x={x_res[-1]}: {round(y_res[-1], 4)}") \ No newline at end of file From aa1e89de1d5aee7b301e82b1010f1637bb46caad Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 27 Jun 2026 05:36:03 +0000 Subject: [PATCH 2/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- maths/numerical_analysis/ordinary_differential_equations.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/maths/numerical_analysis/ordinary_differential_equations.py b/maths/numerical_analysis/ordinary_differential_equations.py index ddedcad0c879..6fe68e7500ab 100644 --- a/maths/numerical_analysis/ordinary_differential_equations.py +++ b/maths/numerical_analysis/ordinary_differential_equations.py @@ -73,9 +73,6 @@ def heuns_method( return x, y - - - if __name__ == "__main__": import doctest @@ -86,4 +83,4 @@ def example_ode(x: float, y: float) -> float: return y - x**2 + 1 x_res, y_res = heuns_method(example_ode, 0.0, 0.5, 0.25, 4) - print(f"Final heuns methot y value at x={x_res[-1]}: {round(y_res[-1], 4)}") \ No newline at end of file + print(f"Final heuns methot y value at x={x_res[-1]}: {round(y_res[-1], 4)}") From a123c2a28934207e611cad6513e61d0f59b8fa77 Mon Sep 17 00:00:00 2001 From: Imanol Elizondo Perucich Date: Fri, 26 Jun 2026 23:22:34 -0600 Subject: [PATCH 3/4] feat(maths): add numerical methods for solving ordinary differential equations --- .../ordinary_differential_equations.py | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 maths/numerical_analysis/ordinary_differential_equations.py diff --git a/maths/numerical_analysis/ordinary_differential_equations.py b/maths/numerical_analysis/ordinary_differential_equations.py new file mode 100644 index 000000000000..6fe68e7500ab --- /dev/null +++ b/maths/numerical_analysis/ordinary_differential_equations.py @@ -0,0 +1,86 @@ +""" +Numerical methods for solving Ordinary Differential Equations (ODEs) of the form y' = f(x, y). +This module implements the Euler method and Heun's method. + +References: +- Euler Method: https://en.wikipedia.org/wiki/Euler_method +- Heun's Method: https://en.wikipedia.org/wiki/Heun%27s_method + +""" + +from typing import Callable, List, Tuple + + +def euler_method( + f: Callable[[float, float], float], x0: float, y0: float, h: float, steps: int +) -> Tuple[List[float], List[float]]: + """ + Approximates the solution of a first-order ODE y' = f(x, y) using Euler's method. + + :param f: The differential equation function f(x, y). + :param x0: Initial value of x. + :param y0: Initial value of y (y(x0) = y0). + :param h: Step size. + :param steps: Number of iterations to perform. + :return: A tuple containing lists of x and y coordinates. + + >>> def f_ode(x: float, y: float) -> float: return y - x**2 + 1 + >>> x_vals, y_vals = euler_method(f_ode, 0.0, 0.5, 0.25, 2) + >>> [round(i, 4) for i in x_vals] + [0.0, 0.25, 0.5] + >>> [round(i, 4) for i in y_vals] + [0.5, 0.875, 1.3281] + """ + x = [0.0] * (steps + 1) + y = [0.0] * (steps + 1) + x[0], y[0] = x0, y0 + + for i in range(steps): + y[i + 1] = y[i] + f(x[i], y[i]) * h + x[i + 1] = x[i] + h + + return x, y + + +def heuns_method( + f: Callable[[float, float], float], x0: float, y0: float, h: float, steps: int +) -> Tuple[List[float], List[float]]: + """ + Approximates the solution of a firs -order ODE y' = f(x, y) using Heun's method + (also known as the improved Euler method). + + :param f: The differential equation function f(x, y). + :param x0: Initial value of x. + :param y0: Initial value of y. + :param h: Step size. + :param steps: Number of iterations to perform. + :return: A tuple containing lists of x and y coordinates. + + >>> def f_ode(x: float, y: float) -> float: return y - x**2 + 1 + >>> x_vals, y_vals = heuns_method(f_ode, 0.0, 0.5, 0.25, 2) + >>> [round(i, 4) for i in y_vals] + [0.5, 0.9141, 1.4114] + """ + x = [0.0] * (steps + 1) + y = [0.0] * (steps + 1) + x[0], y[0] = x0, y0 + + for i in range(steps): + y_predictor = y[i] + f(x[i], y[i]) * h + x[i + 1] = x[i] + h + y[i + 1] = y[i] + ((f(x[i], y[i]) + f(x[i + 1], y_predictor)) / 2.0) * h + + return x, y + + +if __name__ == "__main__": + import doctest + + doctest.testmod() + + # example + def example_ode(x: float, y: float) -> float: + return y - x**2 + 1 + + x_res, y_res = heuns_method(example_ode, 0.0, 0.5, 0.25, 4) + print(f"Final heuns methot y value at x={x_res[-1]}: {round(y_res[-1], 4)}") From 9fab713e7e5ce7f6c70bba4a6c4aba169f0c465e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 27 Jun 2026 06:07:58 +0000 Subject: [PATCH 4/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- maths/numerical_analysis/ordinary_differential_equations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maths/numerical_analysis/ordinary_differential_equations.py b/maths/numerical_analysis/ordinary_differential_equations.py index cf83d85f8f3e..bad6cc645e5d 100644 --- a/maths/numerical_analysis/ordinary_differential_equations.py +++ b/maths/numerical_analysis/ordinary_differential_equations.py @@ -100,4 +100,4 @@ def heuns_method( if __name__ == "__main__": import doctest - doctest.testmod() \ No newline at end of file + doctest.testmod()