Python/maths/euler_modified.py
Caeden 07e991d553
Add pep8-naming to pre-commit hooks and fixes incorrect naming conventions (#7062)
* ci(pre-commit): Add pep8-naming to `pre-commit` hooks (#7038)

* refactor: Fix naming conventions (#7038)

* Update arithmetic_analysis/lu_decomposition.py

Co-authored-by: Christian Clauss <cclauss@me.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* refactor(lu_decomposition): Replace `NDArray` with `ArrayLike` (#7038)

* chore: Fix naming conventions in doctests (#7038)

* fix: Temporarily disable project euler problem 104 (#7069)

* chore: Fix naming conventions in doctests (#7038)

Co-authored-by: Christian Clauss <cclauss@me.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-10-13 00:54:20 +02:00

55 lines
1.4 KiB
Python

from collections.abc import Callable
import numpy as np
def euler_modified(
ode_func: Callable, y0: float, x0: float, step_size: float, x_end: float
) -> np.array:
"""
Calculate solution at each step to an ODE using Euler's Modified Method
The Euler Method is straightforward to implement, but can't give accurate solutions.
So, some changes were proposed to improve accuracy.
https://en.wikipedia.org/wiki/Euler_method
Arguments:
ode_func -- The ode as a function of x and y
y0 -- the initial value for y
x0 -- the initial value for x
stepsize -- the increment value for x
x_end -- the end value for x
>>> # the exact solution is math.exp(x)
>>> def f1(x, y):
... return -2*x*(y**2)
>>> y = euler_modified(f1, 1.0, 0.0, 0.2, 1.0)
>>> y[-1]
0.503338255442106
>>> import math
>>> def f2(x, y):
... return -2*y + (x**3)*math.exp(-2*x)
>>> y = euler_modified(f2, 1.0, 0.0, 0.1, 0.3)
>>> y[-1]
0.5525976431951775
"""
n = int(np.ceil((x_end - x0) / step_size))
y = np.zeros((n + 1,))
y[0] = y0
x = x0
for k in range(n):
y_get = y[k] + step_size * ode_func(x, y[k])
y[k + 1] = y[k] + (
(step_size / 2) * (ode_func(x, y[k]) + ode_func(x + step_size, y_get))
)
x += step_size
return y
if __name__ == "__main__":
import doctest
doctest.testmod()