我有一个随机微分方程(SDE),我试图用Milsteins方法解决但是得到的结果不同意实验。
SDE
我将其分解为2个一阶方程式:
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的过程还有什么不对,这会引起对实验的不同意见?
答案 0 :(得分:3)
您错过了漂移系数中的一个词,请注意dp
右侧有两个dt
项。因此
def a_p(t, p, q):
return -(Gamma0 - Omega0*eta*q**2)*p - Omega0**2*q
实际上是使振荡器成为振荡器的部分。经过更正后,解决方案看起来像
不,你没有实现Milstein方法,因为没有b_p
的衍生物是Milstein与Euler-Maruyama的区别,缺少的术语是+0.5*b'(X)*b(X)*(dW**2-dt)
。
还有一个免衍生版本的Milsteins方法作为两阶段Runge-Kutta方法,记录在wikipedia或原始arxiv.org (PDF)中。
其中的步骤(基于矢量,复制到X=[p,q]
,K1=[k1_p,k1_q]
等,以接近您的约定)
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)