来自
https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.solve_ivp.html
使用
sol = scipy.integrate.solve_ivp(fun, t_span, y0, method='RK45', t_eval=None, dense_output=False, events=None, vectorized=False, **options)
t_eval
对于指定时间的商店解决方案是可选的。
覆盖时间步长会由RK45
选择吗?
答案 0 :(得分:1)
它不会覆盖时间步。验证这一点的一种方法是使用dense_output=True
,它会保存每个时间步的数据以供以后插值。
sol
属性在ts
属性中包含有关时间步长的其他信息。在这里,您可以看到使用t_eval
会更改sol3.t
的返回值,但不会影响时间步长。
import numpy as np
from scipy.integrate import solve_ivp
# To make readable
np.set_printoptions(precision=2)
method = 'RK45'
def dy(t, y):
return y
sol = solve_ivp(dy, (0, 10), [1], method=method)
print(f"No options : {sol.t}")
sol2 = solve_ivp(dy, (0, 10), [1], method=method, dense_output=True)
print(f"Dense output : {sol2.t}")
print(f" Interpolants: {sol2.sol.ts}")
t_eval = [5]
sol3 = solve_ivp(dy, (0, 10), [1], method=method, t_eval=t_eval, dense_output=True)
print(f"t_eval return : {sol3.t}")
print(f" Interpolants: {sol3.sol.ts}")
返回
No options : [ 0. 0.1 1.07 2.3 3.65 5.03 6.43 7.83 9.24 10. ]
Dense output : [ 0. 0.1 1.07 2.3 3.65 5.03 6.43 7.83 9.24 10. ]
Interpolants: [ 0. 0.1 1.07 2.3 3.65 5.03 6.43 7.83 9.24 10. ]
t_eval return : [5]
Interpolants: [ 0. 0.1 1.07 2.3 3.65 5.03 6.43 7.83 9.24 10. ]
我建议不要使用t_eval
,而应该只使用dense_output=True
,然后在事实之后构造y_eval。这是一种更加灵活和透明的用法。
sol = solve_ivp(dy, (0, 10), [1], method=method, dense_output=True)
y_eval = sol.sol(t_eval)
答案 1 :(得分:0)
,不!它不会覆盖RK45的时间步长,因为函数scipy.integrate.solve_ivp
将对t
中的每个t_eval
使用插值。 RK45仍然使用自己的时间步长。
经过一些调查,我发现了。 根据{{3}}!
在函数solve_ivp
中的第156行。在第477行。
solver = method(fun, t0, y0, tf, vectorized=vectorized, **options)
求解器不使用t_eval
作为参数。
在第511行。
t = solver.t
求解器返回自己的t
。
在第545行。
if solver.direction > 0:
t_eval_i_new = np.searchsorted(t_eval, t, side='right')
t_eval_step = t_eval[t_eval_i:t_eval_i_new]
t_eval_i_new
是t_eval
的新索引,在使用t
之间有np.searchsorted
,而t_eval_step
是ode之间t_eval
的时间步长求解器步骤。
if t_eval_step.size > 0:
if sol is None:
sol = solver.dense_output()
ts.append(t_eval_step)
ys.append(sol(t_eval_step))
t_eval_i = t_eval_i_new
这意味着我们将t_eval_step
附加到ts
上,并使用solver.dense_output()
对步进行插值,并为t_eval_step
中的每个特定时间提供近似值
完成集成后,在第585行,然后返回程序输出。
return OdeResult(t=ts, y=ys, sol=sol, t_events=t_events, nfev=solver.nfev,
njev=solver.njev, nlu=solver.nlu, status=status,
message=message, success=status >= 0)