我试图用Kronecker delta函数来绘制一个ODE的输出,这个函数只应该在一个特定的时间t1变为“active”。 这应该会给出一个锯齿状的响应,其中初始值呈指数衰减,直到t=t1,在再次衰减之前,它会立即再次上升。 然而,当我绘制这个图时,看起来解算器看到Kronecker delta函数在所有时间t都为零。在Python中有这样做的方法吗?你知道吗
from scipy import KroneckerDelta
import scipy.integrate as sp
import matplotlib.pyplot as plt
import numpy as np
def dy_dt(y,t):
dy_dt = 500*KroneckerDelta(t,t1) - 2y
return dy_dt
t1 = 4
y0 = 500
t = np.arrange(0,10,0.1)
y = sp.odeint(dy_dt,y0,t)
plt.plot(t,y)
在使用时间的简单Kronecker delta的情况下,您可以按如下方式运行ode:
对于复杂情况的另一种选择是solve_ivp的
events
功能。你知道吗我认为问题可能是内部舍入错误,因为0.1不能准确地表示为python
float
。我会努力的此外,
odeint
的文档还建议使用args
参数而不是全局变量来为派生函数提供访问其他参数的权限,并用np.linspace
替换np.arange
:我没有测试代码,所以告诉我是否有什么问题。你知道吗
编辑:
在测试我的代码时,我查看了
t
值,其中dy_dt
是为这些值计算的。我注意到odeint
不仅使用指定的t
值,而且会稍微改变它们:现在用我的方法,我们得到
因为默认公差设置为最多10^(-9)的相对误差,所以
odeint
函数会“忽略”4处导数的凹凸。幸运的是,我们可以通过指定更高的错误阈值来解决这个问题:现在
dy_dt
对于3.99和4.01之间的所有值都非常高。如果linspace
的num
参数增加,则可以使该范围变小。你知道吗TL;DR
你的问题不是python的问题,而是一个数值求解微分方程的问题:你需要在足够长的区间内改变导数,否则解算器很可能会错过有趣的地方。kronecker delta不适用于求解ODEs的数值方法。你知道吗
相关问题 更多 >
编程相关推荐