Python 我是否实施了Milstein';s方法/Euler Maruyama正确吗?

Python 我是否实施了Milstein';s方法/Euler Maruyama正确吗?,python,numerical-methods,differential-equations,stochastic,Python,Numerical Methods,Differential Equations,Stochastic,我有一个随机微分方程(SDE),我试图用Milsteins方法求解,但得到的结果与实验不符 SDE是 我把它分解成两个一阶方程: eq1: eq2: 然后我使用了Ito形式: 因此,对于eq1: 对于eq2: 我用来解决这个问题的python代码如下: # set constants from real data Gamma0 = 4000 # defines enviromental damping Omega0 = 75e3*2*np.pi # defines the angula

我有一个随机微分方程(SDE),我试图用Milsteins方法求解,但得到的结果与实验不符

SDE是

我把它分解成两个一阶方程:

eq1:

eq2:

然后我使用了Ito形式:

因此,对于eq1:

对于eq2:

我用来解决这个问题的python代码如下:

# set constants from real data
Gamma0 = 4000  # defines enviromental damping
Omega0 = 75e3*2*np.pi # defines the angular frequency of the motion
eta = 0 # set eta 0 => no effect from non-linear p*q**2 term
T_0 = 300 # temperature of enviroment
k_b = scipy.constants.Boltzmann 
m = 3.1e-19 # mass of oscillator

# set a and b functions for these 2 equations
def a_p(t, p, q):
    return -(Gamma0 - Omega0*eta*q**2)*p

def b_p(t, p, q):
    return np.sqrt(2*Gamma0*k_b*T_0/m)

def a_q(t, p, q):
    return p

# generate time data
dt = 10e-11
tArray = np.arange(0, 200e-6, dt)

# initialise q and p arrays and set initial conditions to 0, 0
q0 = 0
p0 = 0
q = np.zeros_like(tArray)
p = np.zeros_like(tArray)
q[0] = q0
p[0] = p0

# generate normally distributed random numbers
dwArray = np.random.normal(0, np.sqrt(dt), len(tArray)) # independent and identically distributed normal random variables with expected value 0 and variance dt

# iterate through implementing Milstein's method (technically Euler-Maruyama since b' = 0
for n, t in enumerate(tArray[:-1]):
    dw = dwArray[n]
    p[n+1] = p[n] + a_p(t, p[n], q[n])*dt + b_p(t, p[n], q[n])*dw + 0
    q[n+1] = q[n] + a_q(t, p[n], q[n])*dt + 0
在这种情况下,p是速度,q是位置

然后我得到q和p的以下曲线图:

我希望得到的位置图看起来像下面这样,这是我从实验数据中得到的(模型中使用的常数是由实验数据确定的):

我是否正确地实施了Milstein的方法


如果我有,我求解SDE的过程中还有什么错误导致了与实验的不一致?

你遗漏了漂移系数中的一个项,请注意,
dp
右侧有两个
dt
项。因此

def a_p(t, p, q):
    return -(Gamma0 - Omega0*eta*q**2)*p - Omega0**2*q
这实际上是使振荡器变成振荡器的部分。修正后,解决方案如下所示

不,您没有实施Milstein方法,因为没有将Milstein与Euler Maruyama区分开来的
b_p
的导数,缺少的项是
+0.5*b'(X)*b(X)*(dW**2-dt)


Milsteins方法也有一个无导数版本,作为两阶段的Runge-Kutta方法,记录在或原始记录在中

这一步是(基于向量,复制成
X=[p,q]
K1=[K1\u p,K1\u q]
等,以接近您的约定)


多好的眼睛啊。回答得很好。@duffymo:谢谢。我(重新)输入了原始的order 1公式,因此已经有了一些见解。我也投票赞成。大量使用乳胶-美丽。是现在就允许了,还是你创建了图像?@duffymo:不,没有数学支持,所以图像来自math.SE中的渲染公式。谢谢,真不敢相信我错过了。我曾经为latex方程生成html,然后可以在stackoverflow上使用。
S = random_choice_of ([-1,1])
K1 = a(X )*dt + b(X )*(dW - S*sqrt(dt))
Xh = X + K1
K2 = a(Xh)*dt + b(Xh)*(dW + S*sqrt(dt))

X = X + 0.5 * (K1+K2)