From e3ae1c3bb762c28e6d649af1112832570ce648a2 Mon Sep 17 00:00:00 2001 From: ravi-ivar-7 Date: Sat, 14 Oct 2023 20:11:03 +0530 Subject: [PATCH 01/19] added rkf45 method --- maths/rkf45.py | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 maths/rkf45.py diff --git a/maths/rkf45.py b/maths/rkf45.py new file mode 100644 index 000000000000..5549ab1179a1 --- /dev/null +++ b/maths/rkf45.py @@ -0,0 +1,54 @@ +from collections.abc import Callable +import numpy as np + +class RangeError(Exception): + 'Will be raised when initial x is greater than or equal to final x' + pass + +def rkf45(ode:Callable , y0:float,x0:float,step_size:float,xn:float,) ->np.ndarray: + """ + Calculate Numerical-Solution to an ODE at each nodal point using Runge-Kutta-Fehlberg Method (rkf45) of order 5. + + Reference: https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta%E2%80%93Fehlberg_method + + args: + ode (callable): Ordinary Differential Equation as function of x and y. + y0 (float) : Initial value of y. + x0 (float) : Initial value of x. + step_size (float) : Increament value of x (step-size). + xn (float) : Final value of x. + + + Returns: + np.ndarray: Solution of y at each nodal point + + #excact value of y[1] is tan(0.2) = 0.2027100355086 + >>> def f(x,y): + ... return 1+y**2 + >>> y=rkf45(f,0,0,0.2,1) + >>> y[1] + 0.2027100937470787 + """ + if x0>=xn: + raise RangeError("Final value of x should be greater than initial value of x.") + + n=int((xn-x0)/step_size) + y=np.zeros((n+1),) + x=np.zeros(n+1) + y[0]=y0 + x[0]=x0 + for i in range(n): + k1=step_size*ode(x[i],y[i]) + k2=step_size*ode(x[i]+step_size/4,y[i]+k1/4) + k3=step_size*ode(x[i]+(3/8)*step_size,y[i]+(3/32)*k1+(9/32)*k2) + k4=step_size*ode(x[i]+(12/13)*step_size,y[i] +(1932/2197)*k1 -(7200/2197)*k2 +(7296/2197)*k3) + k5=step_size*ode(x[i]+step_size,y[i]+(439/216)*k1-8*k2+(3680/513)*k3-(845/4104)*k4) + k6=step_size*ode(x[i]+step_size/2,y[i]-(8/27)*k1+2*k2-(3544/2565)*k3+(1859/4104)*k4-(11/40)*k5) + y[i+1]=y[i]+(16/135)*k1+(6656/12825)*k3+(28561/56430)*k4-(9/50)*k5+(2/55)*k6 + x[i+1]=step_size+x[i] + return y + +if __name__=='__main__': + import doctest + doctest.testmod() + From 7242a0e656ae3e13a5d1557434c293394de4ee1f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 14 Oct 2023 14:47:33 +0000 Subject: [PATCH 02/19] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- maths/rkf45.py | 76 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 55 insertions(+), 21 deletions(-) diff --git a/maths/rkf45.py b/maths/rkf45.py index 5549ab1179a1..1988292b6954 100644 --- a/maths/rkf45.py +++ b/maths/rkf45.py @@ -1,11 +1,19 @@ from collections.abc import Callable import numpy as np + class RangeError(Exception): - 'Will be raised when initial x is greater than or equal to final x' + "Will be raised when initial x is greater than or equal to final x" pass -def rkf45(ode:Callable , y0:float,x0:float,step_size:float,xn:float,) ->np.ndarray: + +def rkf45( + ode: Callable, + y0: float, + x0: float, + step_size: float, + xn: float, +) -> np.ndarray: """ Calculate Numerical-Solution to an ODE at each nodal point using Runge-Kutta-Fehlberg Method (rkf45) of order 5. @@ -17,9 +25,9 @@ def rkf45(ode:Callable , y0:float,x0:float,step_size:float,xn:float,) ->np.ndarr x0 (float) : Initial value of x. step_size (float) : Increament value of x (step-size). xn (float) : Final value of x. - - Returns: + + Returns: np.ndarray: Solution of y at each nodal point #excact value of y[1] is tan(0.2) = 0.2027100355086 @@ -29,26 +37,52 @@ def rkf45(ode:Callable , y0:float,x0:float,step_size:float,xn:float,) ->np.ndarr >>> y[1] 0.2027100937470787 """ - if x0>=xn: + if x0 >= xn: raise RangeError("Final value of x should be greater than initial value of x.") - - n=int((xn-x0)/step_size) - y=np.zeros((n+1),) - x=np.zeros(n+1) - y[0]=y0 - x[0]=x0 + + n = int((xn - x0) / step_size) + y = np.zeros( + (n + 1), + ) + x = np.zeros(n + 1) + y[0] = y0 + x[0] = x0 for i in range(n): - k1=step_size*ode(x[i],y[i]) - k2=step_size*ode(x[i]+step_size/4,y[i]+k1/4) - k3=step_size*ode(x[i]+(3/8)*step_size,y[i]+(3/32)*k1+(9/32)*k2) - k4=step_size*ode(x[i]+(12/13)*step_size,y[i] +(1932/2197)*k1 -(7200/2197)*k2 +(7296/2197)*k3) - k5=step_size*ode(x[i]+step_size,y[i]+(439/216)*k1-8*k2+(3680/513)*k3-(845/4104)*k4) - k6=step_size*ode(x[i]+step_size/2,y[i]-(8/27)*k1+2*k2-(3544/2565)*k3+(1859/4104)*k4-(11/40)*k5) - y[i+1]=y[i]+(16/135)*k1+(6656/12825)*k3+(28561/56430)*k4-(9/50)*k5+(2/55)*k6 - x[i+1]=step_size+x[i] + k1 = step_size * ode(x[i], y[i]) + k2 = step_size * ode(x[i] + step_size / 4, y[i] + k1 / 4) + k3 = step_size * ode( + x[i] + (3 / 8) * step_size, y[i] + (3 / 32) * k1 + (9 / 32) * k2 + ) + k4 = step_size * ode( + x[i] + (12 / 13) * step_size, + y[i] + (1932 / 2197) * k1 - (7200 / 2197) * k2 + (7296 / 2197) * k3, + ) + k5 = step_size * ode( + x[i] + step_size, + y[i] + (439 / 216) * k1 - 8 * k2 + (3680 / 513) * k3 - (845 / 4104) * k4, + ) + k6 = step_size * ode( + x[i] + step_size / 2, + y[i] + - (8 / 27) * k1 + + 2 * k2 + - (3544 / 2565) * k3 + + (1859 / 4104) * k4 + - (11 / 40) * k5, + ) + y[i + 1] = ( + y[i] + + (16 / 135) * k1 + + (6656 / 12825) * k3 + + (28561 / 56430) * k4 + - (9 / 50) * k5 + + (2 / 55) * k6 + ) + x[i + 1] = step_size + x[i] return y -if __name__=='__main__': + +if __name__ == "__main__": import doctest - doctest.testmod() + doctest.testmod() From 3c7e2f51903f0114be0915e746587fab3207471b Mon Sep 17 00:00:00 2001 From: Ravi Kumar <119737193+ravi-ivar-7@users.noreply.github.com> Date: Sat, 14 Oct 2023 20:35:25 +0530 Subject: [PATCH 03/19] Updated rkf45.py --- maths/rkf45.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/maths/rkf45.py b/maths/rkf45.py index 1988292b6954..194ba69575b8 100644 --- a/maths/rkf45.py +++ b/maths/rkf45.py @@ -1,11 +1,8 @@ from collections.abc import Callable import numpy as np - class RangeError(Exception): "Will be raised when initial x is greater than or equal to final x" - pass - def rkf45( ode: Callable, @@ -15,7 +12,7 @@ def rkf45( xn: float, ) -> np.ndarray: """ - Calculate Numerical-Solution to an ODE at each nodal point using Runge-Kutta-Fehlberg Method (rkf45) of order 5. + Solve ODE using Runge-Kutta-Fehlberg Method (rkf45) of order 5. Reference: https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta%E2%80%93Fehlberg_method @@ -26,7 +23,6 @@ def rkf45( step_size (float) : Increament value of x (step-size). xn (float) : Final value of x. - Returns: np.ndarray: Solution of y at each nodal point From c73ffb3a38bc972696021b497f7c7b6882d24e0c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 14 Oct 2023 15:05:58 +0000 Subject: [PATCH 04/19] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- maths/rkf45.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/maths/rkf45.py b/maths/rkf45.py index 194ba69575b8..3585d30591ed 100644 --- a/maths/rkf45.py +++ b/maths/rkf45.py @@ -1,9 +1,11 @@ from collections.abc import Callable import numpy as np + class RangeError(Exception): "Will be raised when initial x is greater than or equal to final x" + def rkf45( ode: Callable, y0: float, From f44e49e8830cfea703db7bd2d82f73ac4cc00967 Mon Sep 17 00:00:00 2001 From: Ravi Kumar <119737193+ravi-ivar-7@users.noreply.github.com> Date: Sat, 14 Oct 2023 20:45:10 +0530 Subject: [PATCH 05/19] Updated rkf45.py --- maths/rkf45.py | 1 - 1 file changed, 1 deletion(-) diff --git a/maths/rkf45.py b/maths/rkf45.py index 3585d30591ed..8177e7619f6b 100644 --- a/maths/rkf45.py +++ b/maths/rkf45.py @@ -1,7 +1,6 @@ from collections.abc import Callable import numpy as np - class RangeError(Exception): "Will be raised when initial x is greater than or equal to final x" From 78a419552bcace4185fa4127775e0899f77f8a77 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 14 Oct 2023 15:15:50 +0000 Subject: [PATCH 06/19] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- maths/rkf45.py | 1 + 1 file changed, 1 insertion(+) diff --git a/maths/rkf45.py b/maths/rkf45.py index 8177e7619f6b..3585d30591ed 100644 --- a/maths/rkf45.py +++ b/maths/rkf45.py @@ -1,6 +1,7 @@ from collections.abc import Callable import numpy as np + class RangeError(Exception): "Will be raised when initial x is greater than or equal to final x" From 1eced8ef9140f9aa2cf9761e090c737c7f86f206 Mon Sep 17 00:00:00 2001 From: Ravi Kumar <119737193+ravi-ivar-7@users.noreply.github.com> Date: Sat, 14 Oct 2023 20:52:11 +0530 Subject: [PATCH 07/19] Update rkf45.py --- maths/rkf45.py | 1 - 1 file changed, 1 deletion(-) diff --git a/maths/rkf45.py b/maths/rkf45.py index 3585d30591ed..8177e7619f6b 100644 --- a/maths/rkf45.py +++ b/maths/rkf45.py @@ -1,7 +1,6 @@ from collections.abc import Callable import numpy as np - class RangeError(Exception): "Will be raised when initial x is greater than or equal to final x" From 22277638394da1b610d266b4ef36952031b50d99 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 14 Oct 2023 15:22:44 +0000 Subject: [PATCH 08/19] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- maths/rkf45.py | 1 + 1 file changed, 1 insertion(+) diff --git a/maths/rkf45.py b/maths/rkf45.py index 8177e7619f6b..3585d30591ed 100644 --- a/maths/rkf45.py +++ b/maths/rkf45.py @@ -1,6 +1,7 @@ from collections.abc import Callable import numpy as np + class RangeError(Exception): "Will be raised when initial x is greater than or equal to final x" From 45840aee807f38156c392f8d7b53cf8125aabf50 Mon Sep 17 00:00:00 2001 From: Ravi Kumar <119737193+ravi-ivar-7@users.noreply.github.com> Date: Sat, 14 Oct 2023 21:19:41 +0530 Subject: [PATCH 09/19] Update rkf45.py with suggestions --- maths/rkf45.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/maths/rkf45.py b/maths/rkf45.py index 3585d30591ed..4e795c4eccf1 100644 --- a/maths/rkf45.py +++ b/maths/rkf45.py @@ -1,12 +1,12 @@ from collections.abc import Callable + import numpy as np class RangeError(Exception): "Will be raised when initial x is greater than or equal to final x" - -def rkf45( +def runge_futta_fehlberg_45( ode: Callable, y0: float, x0: float, From 2493128f2b3f58d17d4a08cbcaeb1f6b7e2bf0c1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 14 Oct 2023 15:50:14 +0000 Subject: [PATCH 10/19] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- maths/rkf45.py | 1 + 1 file changed, 1 insertion(+) diff --git a/maths/rkf45.py b/maths/rkf45.py index 4e795c4eccf1..b08ba91266a9 100644 --- a/maths/rkf45.py +++ b/maths/rkf45.py @@ -6,6 +6,7 @@ class RangeError(Exception): "Will be raised when initial x is greater than or equal to final x" + def runge_futta_fehlberg_45( ode: Callable, y0: float, From c68b28766eda84c6e35bbf7c17d71155660fa308 Mon Sep 17 00:00:00 2001 From: Ravi Kumar <119737193+ravi-ivar-7@users.noreply.github.com> Date: Sun, 15 Oct 2023 11:30:52 +0530 Subject: [PATCH 11/19] Improved Code Quality rkf45.py --- maths/rkf45.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/maths/rkf45.py b/maths/rkf45.py index b08ba91266a9..1028f9a23282 100644 --- a/maths/rkf45.py +++ b/maths/rkf45.py @@ -9,10 +9,10 @@ class RangeError(Exception): def runge_futta_fehlberg_45( ode: Callable, - y0: float, - x0: float, + x_initial: float, + y_initial: float, step_size: float, - xn: float, + x_final: float, ) -> np.ndarray: """ Solve ODE using Runge-Kutta-Fehlberg Method (rkf45) of order 5. @@ -20,32 +20,32 @@ def runge_futta_fehlberg_45( Reference: https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta%E2%80%93Fehlberg_method args: - ode (callable): Ordinary Differential Equation as function of x and y. - y0 (float) : Initial value of y. - x0 (float) : Initial value of x. - step_size (float) : Increament value of x (step-size). - xn (float) : Final value of x. + ode : Ordinary Differential Equation as function of x and y. + x_initial : Initial value of x. + y_initial : Initial value of y. + step_size : Increment value of x. + x_final : Final value of x. Returns: np.ndarray: Solution of y at each nodal point - #excact value of y[1] is tan(0.2) = 0.2027100355086 + # exact value of y[1] is tan(0.2) = 0.2027100355086 >>> def f(x,y): ... return 1+y**2 - >>> y=rkf45(f,0,0,0.2,1) + >>> y=runge_futta_fehlberg_45(f, 0, 0, 0.2, 1) >>> y[1] 0.2027100937470787 """ - if x0 >= xn: + if x_initial >= x_final: raise RangeError("Final value of x should be greater than initial value of x.") - n = int((xn - x0) / step_size) + n = int((x_final - x_initial) / step_size) y = np.zeros( (n + 1), ) x = np.zeros(n + 1) - y[0] = y0 - x[0] = x0 + y[0] = y_initial + x[0] = x_initial for i in range(n): k1 = step_size * ode(x[i], y[i]) k2 = step_size * ode(x[i] + step_size / 4, y[i] + k1 / 4) From 48c69b2cbb70cbf339fd13d934634bbf184c353b Mon Sep 17 00:00:00 2001 From: Ravi Kumar <119737193+ravi-ivar-7@users.noreply.github.com> Date: Sun, 15 Oct 2023 12:24:48 +0530 Subject: [PATCH 12/19] Added more test cases and exception rkf45.py --- maths/rkf45.py | 48 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/maths/rkf45.py b/maths/rkf45.py index 1028f9a23282..dd8ffdbb272e 100644 --- a/maths/rkf45.py +++ b/maths/rkf45.py @@ -1,5 +1,10 @@ +""" +Module contains an implementation of the Runge-Kutta-Fehlberg method to solve ODEs. +""" + from collections.abc import Callable + import numpy as np @@ -7,6 +12,10 @@ class RangeError(Exception): "Will be raised when initial x is greater than or equal to final x" +class IncrementError(Exception): + "Will be raised when value of stepsize (Increment of x) is not positive." + + def runge_futta_fehlberg_45( ode: Callable, x_initial: float, @@ -32,12 +41,35 @@ def runge_futta_fehlberg_45( # exact value of y[1] is tan(0.2) = 0.2027100355086 >>> def f(x,y): ... return 1+y**2 - >>> y=runge_futta_fehlberg_45(f, 0, 0, 0.2, 1) + >>> y = runge_futta_fehlberg_45(f, 0, 0, 0.2, 1) >>> y[1] 0.2027100937470787 + >>> def f(x,y): + ... return 5 + >>> y = runge_futta_fehlberg_45(f, 0, 0, 0.1, 1) + >>> y[1] + 0.5 + >>> def f(x,y): + ... return x + >>> y = runge_futta_fehlberg_45(f, -1, 0, 0.2, 0) + >>> y[1] + -0.18000000000000002 + >>> def f(x,y): + ... return x + >>> y = runge_futta_fehlberg_45(f, -1, 0, -0.2, 0) + Traceback (most recent call last): + IncrementError: Increament of x (step size) should be positve. + >>> def f(x,y): + ... return x + y + >>> y = runge_futta_fehlberg_45(f, 0, 0, 0.2, -1) + Traceback (most recent call last): + RangeError: Final x should be greater than initial x. """ if x_initial >= x_final: - raise RangeError("Final value of x should be greater than initial value of x.") + raise RangeError("Final x should be greater than initial x.") + + if step_size == 0 or step_size < 0: + raise IncrementError("Increament of x (step size) should be positve.") n = int((x_final - x_initial) / step_size) y = np.zeros( @@ -54,11 +86,13 @@ def runge_futta_fehlberg_45( ) k4 = step_size * ode( x[i] + (12 / 13) * step_size, - y[i] + (1932 / 2197) * k1 - (7200 / 2197) * k2 + (7296 / 2197) * k3, + y[i] + (1932 / 2197) * k1 - (7200 / 2197) * + k2 + (7296 / 2197) * k3, ) k5 = step_size * ode( x[i] + step_size, - y[i] + (439 / 216) * k1 - 8 * k2 + (3680 / 513) * k3 - (845 / 4104) * k4, + y[i] + (439 / 216) * k1 - 8 * k2 + + (3680 / 513) * k3 - (845 / 4104) * k4, ) k6 = step_size * ode( x[i] + step_size / 2, @@ -81,6 +115,12 @@ def runge_futta_fehlberg_45( return y +if __name__ == "__main__": + import doctest + + + doctest.testmod() + if __name__ == "__main__": import doctest From 4df76d381049f1affdc8f38dd006109569e9432d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 15 Oct 2023 06:55:21 +0000 Subject: [PATCH 13/19] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- maths/rkf45.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/maths/rkf45.py b/maths/rkf45.py index dd8ffdbb272e..834cdc0d22b7 100644 --- a/maths/rkf45.py +++ b/maths/rkf45.py @@ -86,13 +86,11 @@ def runge_futta_fehlberg_45( ) k4 = step_size * ode( x[i] + (12 / 13) * step_size, - y[i] + (1932 / 2197) * k1 - (7200 / 2197) * - k2 + (7296 / 2197) * k3, + y[i] + (1932 / 2197) * k1 - (7200 / 2197) * k2 + (7296 / 2197) * k3, ) k5 = step_size * ode( x[i] + step_size, - y[i] + (439 / 216) * k1 - 8 * k2 + - (3680 / 513) * k3 - (845 / 4104) * k4, + y[i] + (439 / 216) * k1 - 8 * k2 + (3680 / 513) * k3 - (845 / 4104) * k4, ) k6 = step_size * ode( x[i] + step_size / 2, @@ -118,7 +116,6 @@ def runge_futta_fehlberg_45( if __name__ == "__main__": import doctest - doctest.testmod() if __name__ == "__main__": From f04d1cb650c54d91df8a3499f38fbdc01a177ea5 Mon Sep 17 00:00:00 2001 From: Ravi Kumar <119737193+ravi-ivar-7@users.noreply.github.com> Date: Sun, 15 Oct 2023 12:28:23 +0530 Subject: [PATCH 14/19] Update rkf45.py --- maths/rkf45.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/maths/rkf45.py b/maths/rkf45.py index 834cdc0d22b7..757d8e2d141a 100644 --- a/maths/rkf45.py +++ b/maths/rkf45.py @@ -117,8 +117,3 @@ def runge_futta_fehlberg_45( import doctest doctest.testmod() - -if __name__ == "__main__": - import doctest - - doctest.testmod() From ea8619332dec3c2df7c644814ec2a6755f425240 Mon Sep 17 00:00:00 2001 From: Ravi Kumar <119737193+ravi-ivar-7@users.noreply.github.com> Date: Sun, 15 Oct 2023 12:41:10 +0530 Subject: [PATCH 15/19] corrected some spellings. rkf45.py --- maths/rkf45.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/maths/rkf45.py b/maths/rkf45.py index 757d8e2d141a..10e15f31ed09 100644 --- a/maths/rkf45.py +++ b/maths/rkf45.py @@ -58,7 +58,7 @@ def runge_futta_fehlberg_45( ... return x >>> y = runge_futta_fehlberg_45(f, -1, 0, -0.2, 0) Traceback (most recent call last): - IncrementError: Increament of x (step size) should be positve. + IncrementError: Increment of x (step size) should be positive. >>> def f(x,y): ... return x + y >>> y = runge_futta_fehlberg_45(f, 0, 0, 0.2, -1) @@ -69,7 +69,7 @@ def runge_futta_fehlberg_45( raise RangeError("Final x should be greater than initial x.") if step_size == 0 or step_size < 0: - raise IncrementError("Increament of x (step size) should be positve.") + raise IncrementError("Increment of x (step size) should be positive.") n = int((x_final - x_initial) / step_size) y = np.zeros( @@ -116,4 +116,6 @@ def runge_futta_fehlberg_45( if __name__ == "__main__": import doctest + doctest.testmod() + From b66032cea4b329d1b38b5e71ceb7299ddd8e3483 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 15 Oct 2023 07:11:43 +0000 Subject: [PATCH 16/19] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- maths/rkf45.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/maths/rkf45.py b/maths/rkf45.py index 10e15f31ed09..8b8c47327ef9 100644 --- a/maths/rkf45.py +++ b/maths/rkf45.py @@ -116,6 +116,4 @@ def runge_futta_fehlberg_45( if __name__ == "__main__": import doctest - doctest.testmod() - From 0779b65ff5c75ed30d34d03844efd0056c5c36b7 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sun, 15 Oct 2023 10:58:33 +0200 Subject: [PATCH 17/19] Update rkf45.py --- maths/rkf45.py | 79 +++++++++++++++++++++++--------------------------- 1 file changed, 37 insertions(+), 42 deletions(-) diff --git a/maths/rkf45.py b/maths/rkf45.py index 8b8c47327ef9..3614ca137769 100644 --- a/maths/rkf45.py +++ b/maths/rkf45.py @@ -1,75 +1,68 @@ """ -Module contains an implementation of the Runge-Kutta-Fehlberg method to solve ODEs. +Use the Runge-Kutta-Fehlberg method to solve Ordinary Differential Equations. """ from collections.abc import Callable - import numpy as np -class RangeError(Exception): - "Will be raised when initial x is greater than or equal to final x" - - -class IncrementError(Exception): - "Will be raised when value of stepsize (Increment of x) is not positive." - - def runge_futta_fehlberg_45( - ode: Callable, + func: Callable, x_initial: float, y_initial: float, step_size: float, x_final: float, ) -> np.ndarray: """ - Solve ODE using Runge-Kutta-Fehlberg Method (rkf45) of order 5. + Solve an Ordinary Differential Equations using Runge-Kutta-Fehlberg Method (rkf45) + of order 5. - Reference: https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta%E2%80%93Fehlberg_method + https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta%E2%80%93Fehlberg_method args: - ode : Ordinary Differential Equation as function of x and y. - x_initial : Initial value of x. - y_initial : Initial value of y. - step_size : Increment value of x. - x_final : Final value of x. + func: An ordinary differential equation (ODE) as function of x and y. + x_initial: The initial value of x. + y_initial: The initial value of y. + step_size: The increment value of x. + x_final: The final value of x. Returns: - np.ndarray: Solution of y at each nodal point + Solution of y at each nodal point - # exact value of y[1] is tan(0.2) = 0.2027100355086 - >>> def f(x,y): - ... return 1+y**2 + # exact value of y[1] is tan(0.2) = 0.2027100937470787 + >>> def f(x, y): + ... return 1 + y**2 >>> y = runge_futta_fehlberg_45(f, 0, 0, 0.2, 1) >>> y[1] 0.2027100937470787 - >>> def f(x,y): - ... return 5 - >>> y = runge_futta_fehlberg_45(f, 0, 0, 0.1, 1) - >>> y[1] - 0.5 + >>> y = runge_futta_fehlberg_45(5, 0, 0, 0.1, 1) + Traceback (most recent call last): + ... + TypeError: 'int' object is not callable >>> def f(x,y): ... return x >>> y = runge_futta_fehlberg_45(f, -1, 0, 0.2, 0) >>> y[1] -0.18000000000000002 - >>> def f(x,y): + >>> def f(x, y): ... return x >>> y = runge_futta_fehlberg_45(f, -1, 0, -0.2, 0) Traceback (most recent call last): - IncrementError: Increment of x (step size) should be positive. - >>> def f(x,y): + ... + ValueError: Step size must be positve. + >>> def f(x, y): ... return x + y >>> y = runge_futta_fehlberg_45(f, 0, 0, 0.2, -1) Traceback (most recent call last): - RangeError: Final x should be greater than initial x. + ... + ValueError: The final value x must be greater than initial value of x. """ if x_initial >= x_final: - raise RangeError("Final x should be greater than initial x.") + raise ValueError("The final value x must be greater than initial value of x.") - if step_size == 0 or step_size < 0: - raise IncrementError("Increment of x (step size) should be positive.") + if step_size <= 0: + raise ValueError("Step size must be positve.") n = int((x_final - x_initial) / step_size) y = np.zeros( @@ -79,20 +72,22 @@ def runge_futta_fehlberg_45( y[0] = y_initial x[0] = x_initial for i in range(n): - k1 = step_size * ode(x[i], y[i]) - k2 = step_size * ode(x[i] + step_size / 4, y[i] + k1 / 4) - k3 = step_size * ode( + k1 = step_size * func(x[i], y[i]) + k2 = step_size * func(x[i] + step_size / 4, y[i] + k1 / 4) + k3 = step_size * func( x[i] + (3 / 8) * step_size, y[i] + (3 / 32) * k1 + (9 / 32) * k2 ) - k4 = step_size * ode( + k4 = step_size * func( x[i] + (12 / 13) * step_size, - y[i] + (1932 / 2197) * k1 - (7200 / 2197) * k2 + (7296 / 2197) * k3, + y[i] + (1932 / 2197) * k1 - (7200 / 2197) * + k2 + (7296 / 2197) * k3, ) - k5 = step_size * ode( + k5 = step_size * func( x[i] + step_size, - y[i] + (439 / 216) * k1 - 8 * k2 + (3680 / 513) * k3 - (845 / 4104) * k4, + y[i] + (439 / 216) * k1 - 8 * k2 + + (3680 / 513) * k3 - (845 / 4104) * k4, ) - k6 = step_size * ode( + k6 = step_size * func( x[i] + step_size / 2, y[i] - (8 / 27) * k1 From f5c0278ebe89557d5b80dd7aa18ffa5a7fef99b6 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 15 Oct 2023 08:59:04 +0000 Subject: [PATCH 18/19] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- maths/rkf45.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/maths/rkf45.py b/maths/rkf45.py index 3614ca137769..a053d84deba8 100644 --- a/maths/rkf45.py +++ b/maths/rkf45.py @@ -79,13 +79,11 @@ def runge_futta_fehlberg_45( ) k4 = step_size * func( x[i] + (12 / 13) * step_size, - y[i] + (1932 / 2197) * k1 - (7200 / 2197) * - k2 + (7296 / 2197) * k3, + y[i] + (1932 / 2197) * k1 - (7200 / 2197) * k2 + (7296 / 2197) * k3, ) k5 = step_size * func( x[i] + step_size, - y[i] + (439 / 216) * k1 - 8 * k2 + - (3680 / 513) * k3 - (845 / 4104) * k4, + y[i] + (439 / 216) * k1 - 8 * k2 + (3680 / 513) * k3 - (845 / 4104) * k4, ) k6 = step_size * func( x[i] + step_size / 2, From 8171e9f5f1ef935bffac403d4a7cb23994ff6871 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sun, 15 Oct 2023 11:03:01 +0200 Subject: [PATCH 19/19] Update rkf45.py --- maths/rkf45.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/maths/rkf45.py b/maths/rkf45.py index a053d84deba8..29fd447b61b8 100644 --- a/maths/rkf45.py +++ b/maths/rkf45.py @@ -36,33 +36,33 @@ def runge_futta_fehlberg_45( >>> y = runge_futta_fehlberg_45(f, 0, 0, 0.2, 1) >>> y[1] 0.2027100937470787 - >>> y = runge_futta_fehlberg_45(5, 0, 0, 0.1, 1) - Traceback (most recent call last): - ... - TypeError: 'int' object is not callable >>> def f(x,y): ... return x >>> y = runge_futta_fehlberg_45(f, -1, 0, 0.2, 0) >>> y[1] -0.18000000000000002 - >>> def f(x, y): - ... return x - >>> y = runge_futta_fehlberg_45(f, -1, 0, -0.2, 0) + >>> y = runge_futta_fehlberg_45(5, 0, 0, 0.1, 1) Traceback (most recent call last): ... - ValueError: Step size must be positve. + TypeError: 'int' object is not callable >>> def f(x, y): ... return x + y >>> y = runge_futta_fehlberg_45(f, 0, 0, 0.2, -1) Traceback (most recent call last): ... ValueError: The final value x must be greater than initial value of x. + >>> def f(x, y): + ... return x + >>> y = runge_futta_fehlberg_45(f, -1, 0, -0.2, 0) + Traceback (most recent call last): + ... + ValueError: Step size must be positive. """ if x_initial >= x_final: raise ValueError("The final value x must be greater than initial value of x.") if step_size <= 0: - raise ValueError("Step size must be positve.") + raise ValueError("Step size must be positive.") n = int((x_final - x_initial) / step_size) y = np.zeros(