2013-05-07 82 views
4

編輯:這個問題是由於一個bug,修復SciPy的0.15暫停SciPy的odeint

因爲我開發和測試代碼,我可以做一個簡單的錯誤,就像一個NameError。當我使用scipy.integrate.odeint時,odeint將打印錯誤消息,但是保持整合,無論我請求多少次時間步,因此我得到許多相同的錯誤消息。我認爲它具有這種行爲,以便在算術錯誤發生時(例如,除以零)可以繼續進行,但這對編程錯誤沒有幫助。

有沒有辦法讓scipy在第一個錯誤信息後停止?如果我能夠阻止錯誤而不是算術例外,那將是最好的。

+2

此錯誤已被報告https://github.com/scipy/scipy/issues/2570 – astrojuanlu 2013-06-24 10:09:48

+2

這在SciPy 0.15 https://github.com/scipy/scipy/pull/4052中已修復。 – Ben 2015-02-10 11:18:23

回答

2

odeint是C代碼的Python包裝,它調用調用C代碼來調用我的Python回調代表dy/dt的LSODA(Fortran子例程)。 LSODA不會傳遞Python異常,並且從C代碼的一位跳到另一位很難實現。

我在使用ode而不是odeint找到了令人滿意的解決方案。我發現ode開始使用起來比較複雜,但在Python中拋出異常時,它的行爲是正確的。下面的fake_odeint()函數是一個開始於使我的目的足夠好的odeint函數,以便我可以在我現有的代碼中進行交換。使用ode而不是odeint的缺點是LSODA每個時步調用一次;這個調用在C中使用odeint,而在Python中使用ode更慢。

import numpy as np 
from scipy.integrate import ode 

def fake_odeint(func, y0, t, Dfun=None): 
    ig = ode(func, Dfun) 
    ig.set_integrator('lsoda', 
         method='adams') 
    ig.set_initial_value(y0, t=0.) 
    y = [] 
    for tt in t: 
     y.append(ig.integrate(tt)) 
    return np.array(y) 

我看着的的Fortran,C,和Python代碼如何被用來允許odeintthis SO question與LSODA通信的機制。

+0

我想我正在使用你的'fake_odeint'函數,直到bug解決! – astrojuanlu 2013-07-01 21:50:37