2016-10-29 8 views
2

私は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

scipy.odeは、f(t, y, *f_args)という形で右側が必要です。odeintの場合は、f(y, t, *f_args)の形式で入力する必要があります。

だから、これは動作します:

def my_odeint(dfunc, V0, times, args=()): 
    r = integrate.ode(lambda t, X: scipy.array(dfunc(X, t, *args))) 
    r.set_integrator('vode', method='adams') 
    r.set_initial_value(V0,times[0]) 
    V=[V0] 
    for time in times[1:]: 
     V.append(r.integrate(time)) 
    V = scipy.array(V) 
    return V 

注文書によると、vodeはアダムス・モールトン、ないのAdams-Bashforthを実装していること。つまり、暗黙のメソッドがまだあります。統合が失敗し続ける場合は、integrate.odeに実装されているDormand/Princeメソッドも試してみてください。

+0

これは1つのエラーを修正するようですが、まだ問題があるようです。私の 'dfunc'は' 7'引数を必要とします。私は 'args'の長さが5であることを確認しました。しかし、エラーが発生しました。 r = integrate.ode(lambda t、X、* args:dfunc(X、t、* args)) TypeError :dfunc()は正確に7つの引数(与えられた2つ)をとります。私はこれが 'set_f_params'で世話されることを期待しましたが、明らかにそうではありません。 – Joel

+0

面白いエラー。私もこれを見て、 'set_f_params'は完全に無視されているようです。しかし、簡単な緩和策があります。私の編集を参照してください。 – Phillip

関連する問題