Scipy odeint打破了不连续动态函数,例如xdot = -sgn(x)

时间:2016-04-07 19:48:00

标签: python numpy scipy numerical

我正在尝试使用Pythonscipy.integrate.odeint来模拟以下动态系统:

enter image description here

但是这种整合在Python中以数字方式破坏,导致以下和类似的图像(通常甚至比这更糟):

enter image description here

使用iPython/Jupyter notebook中的以下内容生成:

import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
%matplotlib inline

f = lambda x,t: -np.sign(x)
x0 = 3
ts = np.linspace(0,10,1000)
xs = odeint(f,x0,ts)
plt.plot(ts,xs)
plt.show()

如何更好地模拟具有不连续动态的系统?

编辑#1:

以较小的时间步长ts = np.linspace(0,10,1000000)运行时的示例结果,以回应@Hun的回答。根据我的期望,这也是一个不正确的结果。

enter image description here

3 个答案:

答案 0 :(得分:0)

我完全按照显示运行你的代码,这就是我得到的。

enter image description here

答案 1 :(得分:0)

我也完全如图所示运行它并得到:

enter image description here

答案 2 :(得分:0)

一种可以更好地工作的方法是实现一个自定义sgn()函数,该函数的epsilon容差大约为零,而不是期望与零精确相等。

import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
%matplotlib inline

sgn = lambda x,eps: (x<-eps)*(-1) + (x>=-eps and x<eps)*0 + (x>=eps)*1
f = lambda x,t: -sgn(x,1e-7)
x0 = 3
ts = np.linspace(0,10,1000)
xs = odeint(f,x0,ts)
plt.plot(ts,xs)
plt.show()

请注意,1e-7的eps参数对我来说很好,但小于此似乎崩溃了。似乎从numpy.finfo并证明here numpy.float32的机器epsilon约为1e-7,而float约为1e-16。