將ode與scipy集成時,ode接受的函數參數比t和y更多。例如:scipy ode update set_f_params函數內部設置爲set_solout
def fun(t, y, param1, param2):
以及這些參數的值可以使用set_f_params
方法設置。
但是,如果還使用set_solout
方法並嘗試在此函數內更新set_f_params
的參數,則集成將保持不變,就像參數未被修改一樣。
如何使用sol_out修改參數? 我想受益於dopri5密集輸出,但我需要在每個時間步驟更新非均勻項。
一個簡單的例子如下所示。
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import ode
def fun(t, x, param):
return x - param
def f_param(t):
return t
ode1 = ode(fun).set_integrator('dopri5').set_initial_value([10.0])
ode1.set_f_params(f_param(0))
results1 = ([], [])
ode2 = ode(fun).set_integrator('dopri5').set_initial_value([10.0])
ode2.set_f_params(f_param(0))
results2 = ([], [])
def callback1(t, x):
results1[0].append(t)
results1[1].append(x.copy())
def callback2(t, x):
results2[0].append(t)
results2[1].append(x.copy())
ode2.set_f_params(f_param(t))
ode1.set_solout(callback1)
ode2.set_solout(callback2)
ode1.integrate(3)
ode2.integrate(3)
plt.plot(results1[0], results1[1], 'o-', alpha=0.7, label='ode1')
plt.plot(results2[0], results2[1], '.--', label='ode2')
plt.legend()
,結果如下所示:
請注意,您最有可能通過完全不使用參數來解決此問題,而是在計算導數時執行您需要執行的任何操作來獲取時間相關參數。在你的例子中,你可以使用'def fun(t,x):return x - f_param(t)'。顧名思義,'set_solout'就是在每個自適應整合步驟之後想要類似輸出的東西。另請注意,每個集成步驟都包含不同時間的多個功能評估。因此,使用'set_solout'會比我建議的選擇更少地改變你的參數。 – Wrzlprmft
你說得對,使用'set_solout'來更新參數並不是最好的選擇,因爲它們將被固定用於自適應集成步驟。但是,直接調用函數來設置要整合的函數內的參數並不總是一個選項。不過,該函數可以作爲參數本身傳遞,並且永遠不需要更新! –