Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit444dfb0

Browse files
ravi-ivar-7pre-commit-ci[bot]cclauss
authored
Added adams-bashforth method of order 2, 3, 4, 5 (TheAlgorithms#10969)
* added runge kutta gills method* added adams-bashforth method of order 2, 3, 4, 5* [pre-commit.ci] auto fixes from pre-commit.com hooksfor more information, seehttps://pre-commit.ci* Update adams_bashforth.py* Deleted extraneous file, maths/numerical_analysis/runge_kutta_gills.py* Added doctests to each function adams_bashforth.py* [pre-commit.ci] auto fixes from pre-commit.com hooksfor more information, seehttps://pre-commit.ci* Update adams_bashforth.py---------Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>Co-authored-by: Christian Clauss <cclauss@me.com>
1 parentd80ee90 commit444dfb0

File tree

1 file changed

+230
-0
lines changed

1 file changed

+230
-0
lines changed
Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
"""
2+
Use the Adams-Bashforth methods to solve Ordinary Differential Equations.
3+
4+
https://en.wikipedia.org/wiki/Linear_multistep_method
5+
Author : Ravi Kumar
6+
"""
7+
fromcollections.abcimportCallable
8+
fromdataclassesimportdataclass
9+
10+
importnumpyasnp
11+
12+
13+
@dataclass
14+
classAdamsBashforth:
15+
"""
16+
args:
17+
func: An ordinary differential equation (ODE) as function of x and y.
18+
x_initials: List containing initial required values of x.
19+
y_initials: List containing initial required values of y.
20+
step_size: The increment value of x.
21+
x_final: The final value of x.
22+
23+
Returns: Solution of y at each nodal point
24+
25+
>>> def f(x, y):
26+
... return x + y
27+
>>> AdamsBashforth(f, [0, 0.2, 0.4], [0, 0.2, 1], 0.2, 1) # doctest: +ELLIPSIS
28+
AdamsBashforth(func=..., x_initials=[0, 0.2, 0.4], y_initials=[0, 0.2, 1], step...)
29+
>>> AdamsBashforth(f, [0, 0.2, 1], [0, 0, 0.04], 0.2, 1).step_2()
30+
Traceback (most recent call last):
31+
...
32+
ValueError: The final value of x must be greater than the initial values of x.
33+
34+
>>> AdamsBashforth(f, [0, 0.2, 0.3], [0, 0, 0.04], 0.2, 1).step_3()
35+
Traceback (most recent call last):
36+
...
37+
ValueError: x-values must be equally spaced according to step size.
38+
39+
>>> AdamsBashforth(f,[0,0.2,0.4,0.6,0.8],[0,0,0.04,0.128,0.307],-0.2,1).step_5()
40+
Traceback (most recent call last):
41+
...
42+
ValueError: Step size must be positive.
43+
"""
44+
45+
func:Callable[[float,float],float]
46+
x_initials:list[float]
47+
y_initials:list[float]
48+
step_size:float
49+
x_final:float
50+
51+
def__post_init__(self)->None:
52+
ifself.x_initials[-1]>=self.x_final:
53+
raiseValueError(
54+
"The final value of x must be greater than the initial values of x."
55+
)
56+
57+
ifself.step_size<=0:
58+
raiseValueError("Step size must be positive.")
59+
60+
ifnotall(
61+
round(x1-x0,10)==self.step_size
62+
forx0,x1inzip(self.x_initials,self.x_initials[1:])
63+
):
64+
raiseValueError("x-values must be equally spaced according to step size.")
65+
66+
defstep_2(self)->np.ndarray:
67+
"""
68+
>>> def f(x, y):
69+
... return x
70+
>>> AdamsBashforth(f, [0, 0.2], [0, 0], 0.2, 1).step_2()
71+
array([0. , 0. , 0.06, 0.16, 0.3 , 0.48])
72+
73+
>>> AdamsBashforth(f, [0, 0.2, 0.4], [0, 0, 0.04], 0.2, 1).step_2()
74+
Traceback (most recent call last):
75+
...
76+
ValueError: Insufficient initial points information.
77+
"""
78+
79+
iflen(self.x_initials)!=2orlen(self.y_initials)!=2:
80+
raiseValueError("Insufficient initial points information.")
81+
82+
x_0,x_1=self.x_initials[:2]
83+
y_0,y_1=self.y_initials[:2]
84+
85+
n=int((self.x_final-x_1)/self.step_size)
86+
y=np.zeros(n+2)
87+
y[0]=y_0
88+
y[1]=y_1
89+
90+
foriinrange(n):
91+
y[i+2]=y[i+1]+ (self.step_size/2)* (
92+
3*self.func(x_1,y[i+1])-self.func(x_0,y[i])
93+
)
94+
x_0=x_1
95+
x_1+=self.step_size
96+
97+
returny
98+
99+
defstep_3(self)->np.ndarray:
100+
"""
101+
>>> def f(x, y):
102+
... return x + y
103+
>>> y = AdamsBashforth(f, [0, 0.2, 0.4], [0, 0, 0.04], 0.2, 1).step_3()
104+
>>> y[3]
105+
0.15533333333333332
106+
107+
>>> AdamsBashforth(f, [0, 0.2], [0, 0], 0.2, 1).step_3()
108+
Traceback (most recent call last):
109+
...
110+
ValueError: Insufficient initial points information.
111+
"""
112+
iflen(self.x_initials)!=3orlen(self.y_initials)!=3:
113+
raiseValueError("Insufficient initial points information.")
114+
115+
x_0,x_1,x_2=self.x_initials[:3]
116+
y_0,y_1,y_2=self.y_initials[:3]
117+
118+
n=int((self.x_final-x_2)/self.step_size)
119+
y=np.zeros(n+4)
120+
y[0]=y_0
121+
y[1]=y_1
122+
y[2]=y_2
123+
124+
foriinrange(n+1):
125+
y[i+3]=y[i+2]+ (self.step_size/12)* (
126+
23*self.func(x_2,y[i+2])
127+
-16*self.func(x_1,y[i+1])
128+
+5*self.func(x_0,y[i])
129+
)
130+
x_0=x_1
131+
x_1=x_2
132+
x_2+=self.step_size
133+
134+
returny
135+
136+
defstep_4(self)->np.ndarray:
137+
"""
138+
>>> def f(x,y):
139+
... return x + y
140+
>>> y = AdamsBashforth(
141+
... f, [0, 0.2, 0.4, 0.6], [0, 0, 0.04, 0.128], 0.2, 1).step_4()
142+
>>> y[4]
143+
0.30699999999999994
144+
>>> y[5]
145+
0.5771083333333333
146+
147+
>>> AdamsBashforth(f, [0, 0.2, 0.4], [0, 0, 0.04], 0.2, 1).step_4()
148+
Traceback (most recent call last):
149+
...
150+
ValueError: Insufficient initial points information.
151+
"""
152+
153+
iflen(self.x_initials)!=4orlen(self.y_initials)!=4:
154+
raiseValueError("Insufficient initial points information.")
155+
156+
x_0,x_1,x_2,x_3=self.x_initials[:4]
157+
y_0,y_1,y_2,y_3=self.y_initials[:4]
158+
159+
n=int((self.x_final-x_3)/self.step_size)
160+
y=np.zeros(n+4)
161+
y[0]=y_0
162+
y[1]=y_1
163+
y[2]=y_2
164+
y[3]=y_3
165+
166+
foriinrange(n):
167+
y[i+4]=y[i+3]+ (self.step_size/24)* (
168+
55*self.func(x_3,y[i+3])
169+
-59*self.func(x_2,y[i+2])
170+
+37*self.func(x_1,y[i+1])
171+
-9*self.func(x_0,y[i])
172+
)
173+
x_0=x_1
174+
x_1=x_2
175+
x_2=x_3
176+
x_3+=self.step_size
177+
178+
returny
179+
180+
defstep_5(self)->np.ndarray:
181+
"""
182+
>>> def f(x,y):
183+
... return x + y
184+
>>> y = AdamsBashforth(
185+
... f, [0, 0.2, 0.4, 0.6, 0.8], [0, 0.02140, 0.02140, 0.22211, 0.42536],
186+
... 0.2, 1).step_5()
187+
>>> y[-1]
188+
0.05436839444444452
189+
190+
>>> AdamsBashforth(f, [0, 0.2, 0.4], [0, 0, 0.04], 0.2, 1).step_5()
191+
Traceback (most recent call last):
192+
...
193+
ValueError: Insufficient initial points information.
194+
"""
195+
196+
iflen(self.x_initials)!=5orlen(self.y_initials)!=5:
197+
raiseValueError("Insufficient initial points information.")
198+
199+
x_0,x_1,x_2,x_3,x_4=self.x_initials[:5]
200+
y_0,y_1,y_2,y_3,y_4=self.y_initials[:5]
201+
202+
n=int((self.x_final-x_4)/self.step_size)
203+
y=np.zeros(n+6)
204+
y[0]=y_0
205+
y[1]=y_1
206+
y[2]=y_2
207+
y[3]=y_3
208+
y[4]=y_4
209+
210+
foriinrange(n+1):
211+
y[i+5]=y[i+4]+ (self.step_size/720)* (
212+
1901*self.func(x_4,y[i+4])
213+
-2774*self.func(x_3,y[i+3])
214+
-2616*self.func(x_2,y[i+2])
215+
-1274*self.func(x_1,y[i+1])
216+
+251*self.func(x_0,y[i])
217+
)
218+
x_0=x_1
219+
x_1=x_2
220+
x_2=x_3
221+
x_3=x_4
222+
x_4+=self.step_size
223+
224+
returny
225+
226+
227+
if__name__=="__main__":
228+
importdoctest
229+
230+
doctest.testmod()

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp