-
-
Notifications
You must be signed in to change notification settings - Fork 46.8k
added rkf45 method #10438
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
added rkf45 method #10438
Changes from 11 commits
e3ae1c3
7242a0e
3c7e2f5
c73ffb3
f44e49e
78a4195
1eced8e
2227763
45840ae
2493128
c68b287
48c69b2
4df76d3
f04d1cb
ea86193
b66032c
0779b65
f5c0278
8171e9f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
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 runge_futta_fehlberg_45( | ||
ode: Callable, | ||
x_initial: float, | ||
y_initial: float, | ||
ravi-ivar-7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
step_size: float, | ||
x_final: float, | ||
) -> np.ndarray: | ||
""" | ||
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 | ||
|
||
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. | ||
|
||
Returns: | ||
np.ndarray: 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 | ||
>>> y=runge_futta_fehlberg_45(f, 0, 0, 0.2, 1) | ||
>>> y[1] | ||
0.2027100937470787 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We will need more than one test. What happens if What happens if What happens if What happens if Let's have a test that raises a RangeError. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
""" | ||
if x_initial >= x_final: | ||
raise RangeError("Final value of x should be greater than initial value of x.") | ||
|
||
n = int((x_final - x_initial) / step_size) | ||
y = np.zeros( | ||
(n + 1), | ||
) | ||
x = np.zeros(n + 1) | ||
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( | ||
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() |
Uh oh!
There was an error while loading. Please reload this page.