我试图在Python中使用scipy
中的solve_ivp
来求解IVP。我将solve_ivp
的tspan
参数指定为(0,10)
,如下所示。然而,由于某种原因,我得到的解总是在t=2.5附近停止。
from scipy.integrate import solve_ivp
import numpy as np
import matplotlib.pyplot as plt
import scipy.optimize as optim
def dudt(t, u):
return u*(1-u/12)-4*np.heaviside(-(t-5), 1)
ic = [2,4,6,8,10,12,14,16,18,20]
sol = solve_ivp(dudt, (0, 10), ic, t_eval=np.linspace(0, 10, 10000))
for solution in sol.y:
y = [y for y in solution if y >= 0]
t = sol.t[:len(y)]
plt.plot(t, y)
1条答案
按热度按时间0ejtzxu11#
哪里出了问题
您应该始终查看求解程序返回的内容。在本例中,它给出了
消息:“所需的步长小于数字之间的间距。”
把求解
scipy.integrate.solve_ivp
初值问题的过程想象成反复估计一个方向,然后朝那个方向前进一小步,上述误差意味着方程的解变化太快,采用尽可能小的步长太远了。但是你的方程足够简单,至少对于t =< 5
,其中4*np.heaviside(-(t-5), 1)
总是得到4,它可以精确地/象征性地解出来。符号解决方案
Sympy可以解微分方程。虽然你可以给它一个初始值,但对每个初始值解一次要花更长的时间。因此,我告诉它给予我所有的解,然后我分别计算初始值的参数
C1
。乍一看,这幅图看起来很奇怪。特别是蓝色和橙子的直线部分。这只是因为值位于掩码范围之外,所以
matplotlib
直接将它们连接起来。实际上发生的是一个突然的跳跃。这个跳跃提前提示了数值模式求解器。当你让sympy打印第一个解时,你可以看得更清楚。已知切线在pi/4处有一个跳跃,如果你解出上面的切线的自变量,你会得到
2.47241377386575
,这可能是你的绘图停止的地方。那么
t>5
又是什么呢?不幸的是,你的方程在
t=5
上是不连续的。一种方法是分别解t>5
的方程,初始值由第一个方程的解给出。但这是另一个问题。