私はscipy.integrate.odeint
を使用していましたが、bdf
の方法に切り替えたときに問題になりました(システムが堅く見えるため)。残念ながら、bdf
はヤコビ行列を計算する必要があります。私のシステムは数十万の方程式を持っているので、これはPythonを殺します(セグメンテーションフォールト!!)Adamsを使ってscipyを統合する方法を教えてください。
私はアダムスがこのシステムでうまくいくと信じるべき十分な理由があります。だから私はscipyにそれを使うよう強制したい。 odeint
で可能とは思わないので、ode
を使用しようとしています。私はodeint
と同じ入力を取るべき自分の関数を書いた。
def my_odeint(dfunc, V0, times, args=()):
r = integrate.ode(dfunc)
r.set_integrator('vode', method='adams')
r.set_initial_value(V0,times[0]).set_f_params(*args)
V=[V0]
for time in times[1:]:
V.append(r.integrate(time))
V = scipy.array(V)
return V
私はそれをテストするとき、私はエラーを取得する: - どのようにして
def dx(X, t):
x=X[0]
y=X[1]
return (-x, x+y)
X0 = [1,1]
times = scipy.linspace(0,2,10)
my_odeint(dx, X0, times)
> capi_return is NULL
> Call-back cb_f_in_dvode__user__routines failed.
TypeError Traceback (most recent call last)
<ipython-input-6-cc286a9956a2> in <module>()
----> 1 my_odeint(dx, X0, times)
in my_odeint(dfunc, V0, times, args)
1352 V=[V0]
1353 for time in times[1:]:
-> 1354 V.append(r.integrate(time))
in integrate(self, t, step, relax)
406 self._y, self.t = mth(self.f, self.jac or (lambda: None),
407 self._y, self.t, t,
--> 408 self.f_params, self.jac_params)
in run(self, f, jac, y0, t0, t1, f_params, jac_params)
863 args = ((f, jac, y0, t0, t1) + tuple(self.call_args) +
864 (f_params, jac_params))
--> 865 y1, t, istate = self.runner(*args)
<ipython-input-4-1770d3974ec9> in dx(X, t)
1 def dx(X, t):
----> 2 x=X[0]
3 y=X[1]
> TypeError: 'float' object has no attribute '__getitem__'
だから私の質問は何かがちょうど私のコードではないように見えます私はodeint
と同じ入力を受け取りますが、adams
を使用し、bdf
に決して切り替わることのないように、コードを修正しますか?
これは1つのエラーを修正するようですが、まだ問題があるようです。私の 'dfunc'は' 7'引数を必要とします。私は 'args'の長さが5であることを確認しました。しかし、エラーが発生しました。 r = integrate.ode(lambda t、X、* args:dfunc(X、t、* args)) TypeError :dfunc()は正確に7つの引数(与えられた2つ)をとります。私はこれが 'set_f_params'で世話されることを期待しましたが、明らかにそうではありません。 –
Joel
面白いエラー。私もこれを見て、 'set_f_params'は完全に無視されているようです。しかし、簡単な緩和策があります。私の編集を参照してください。 – Phillip