2013-06-03 109 views
1

在Numpy中使用odeint進行模擬期間保存中間變量的最簡單方法是什麼?NumPy odeint輸出額外變量

例如:

def dy(y,t) 
    x = np.rand(3,1) 
    return y + x.sum() 

sim = odeint(dy,0,np.arange(0,1,0.1)) 

什麼是保存仿真期間存儲在x數據最簡單的方法?理想情況下,在t參數中指定的點傳遞給odeint

+0

你能舉出一個與你實際想要做的更接近的例子嗎?通常,計算中的中間值可以在後期處理中恢復,並且考慮到'dy'可能會以您請求的時間步以外的時間步進行評估,並且'dy'可能會對同一時間值進行多次評估,後處理中的x通常是最好的選擇。 –

+0

我正在模擬一個類型爲x'= u的系統,其中u是不同力的總和(例如u = u1 + u2 + u3)。我希望能夠隨着時間的推移與國家軌跡一起繪製力量。 –

+1

考慮到狀態y,計算u(或u1,u2,u3)在後處理中的代價有多高? –

回答

5

一種方便的方法破解odeint,有一些需要注意的,是來包裝你的呼叫方法odeint的一類,與dy作爲另一種方法,並通過self作爲參數傳遞給您的dy功能。例如,

class WrapODE(object): 
    def __init__(self): 
     self.y_0 = 0. 
     self.L_x = [] 
     self.timestep = 0 
     self.times = np.arange(0., 1., 0.1) 

    def run(self): 
     self.L_y = odeint(
      self.dy, 
      self.y_0, self.times, 
      args=(self,)) 

    @staticmethod 
    def dy(y, t, self): 
     """" 
     Discretized application of dudt 

     Watch out! Because this is a staticmethod, as required by odeint, self 
     is the third argument 
     """ 
     x = np.random.rand(3,1) 
     if t >= self.times[self.timestep]: 
      self.timestep += 1 
      self.L_x.append(x) 
     else: 
      self.L_x[-1] = x 
     return y + x.sum() 

要清楚的是,這是一個容易出錯的黑客攻擊。例如,除非odeint正在進行歐拉步進,否則dy將被調用的次數超過指定的次數。爲確保每個y獲得一個xif t >= self.times[self.timestep]:塊中的猴業務會在陣列中選取一個點以存儲來自times向量的每個時間值的數據。您的特定應用程序可能導致其他瘋狂的問題。確保爲您的應用程序徹底驗證此方法。

+1

這個答案總的來說很好。但是,對於我的應用程序來說,只需重新計算y的內部變量(比如你所建議的)就容易了,因爲它在計算上相當便宜。謝謝! –