ODEi​​ntWarning:在此调用上完成的工作过多(可能是错误的 Dfun 类型)

计算科学 Python scipy 微分方程
2021-12-09 04:18:30

我在搞乱一些数值积分函数。我写了一个任意微分方程来测试我的理解,代码如下:

import numpy as np

from scipy.integrate import odeint

intT = np.array([0,1,2,3,4,6,8,10,13,16,19,20,21,22,27,40,80])

def dydt(y,t):
    dydt = np.random.choice([0,1], 1)[0]
    return dydt

yInt = odeint(dydt, 0, intT)
print(yInt)

输出:

[[0.00000000e+000] [0.00000000e+000] [0.00000000e+000] [0.00000000e+000] [0.00000000e+000] [0.00000000e+000] [0.00000000e+76400] [2.21311] 3.22131765e+000] [3.62733355e+000] [0.00000000e+000] [2.42092166e-322] [2.70777855e-316] [2.81469831e-316] [0.00000000e+00450] [0.0000001] -322]]

/usr/lib/python3/dist-packages/scipy/integrate/odepack.py:236:ODEintWarning:此调用完成的工作过多(可能是错误的 Dfun 类型)。以 full_output = 1 运行以获取定量信息。警告.warn(warning_msg, ODEintWarning)

这给了我非常奇怪的结果,这不是我所期望的。如果我将 dydt 的返回值更改为 1,那么这个简单的集成肯定可以正常工作。我实际上想要做的是将预定的窗口函数应用于我的微分方程,上面的代码是我想象的简化版本。但我只是不明白这里有什么问题。我想知道你有没有什么想法。

谢谢!

感谢@Lutz Lehmann。我试图整合一些呼吸功能,每 100 个时间间隔就会出现一次峰值。我有另一个镜头如下,这也不起作用。而且我注意到这似乎很棘手,如果我改变我的窗口函数和微分方程,有时它会起作用,有时它不会。我有点理解平滑度问题,但我只是想知道是否有办法处理这个问题。我最初自己有一个数字集成脚本,但它的工作速度较慢,这就是我转向 scipy 集成库的原因。

intT = (np.arange(1, 1000) + 0.1)

def arbWindow(t):
    w = np.exp(1/t - t/10)
    return w
    
def dydt(y,t):
    dydt = arbWindow(t%100) - 0.01*y**2
    return dydt

yInt = odeint(dydt, 0, intT)
1个回答

数值求解器的这种使用是完全错误的。数值 ODE 求解器适用于具有平滑右侧的问题。只要确保存在精确解,它们也可以应用于右侧分段平滑的问题,但这将趋于减慢不连续处的步长非常小的积分。

但是这里右侧的函数甚至不是函数,因为即使给出相同的参数,值也会随机变化。从算法内部看,这看起来好像函数是高度振荡的,或者在所有尺度上都是不连续的,需要越来越小的步长,却找不到在这个缩放级别上问题看起来平滑的尺度。这会导致Excess work done on this call错误消息。