[英]Simulate Stochastic Differential equation in Python
我正在嘗試解決布朗粒子和朗格文動力學的 SDE。 起初我嘗試用普通隨機數生成器模擬 2D 布朗運動,代碼是:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
dt = .001 # Time step.
T = 2. # Total time.
n = int(T / dt) # Number of time steps.
t = np.linspace(0., T, n) # Vector of times.
sqrtdt = np.sqrt(dt)
y = np.zeros(n)
x = np.zeros(n)
for i in range(n-1):
x[i + 1] = x[i] + np.random.normal(0.0,1.0)
y[i + 1] = y[i] + np.random.normal(0.0,1.0)
fig, axs = plt.subplots(1, 1, figsize=(12, 12))
plt.plot(y, x, label ='Position')
plt.title("Simulation of Brownian motion")
plt.show()
現在,當我嘗試借助正向歐拉法模擬相同的過程時,控制方程為
m dv / dt =η
使用以下代碼,
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
dt = .001 # Time step.
T = 2. # Total time.
n = int(T / dt) # Number of time steps.
t = np.linspace(0., T, n) # Vector of times.
sqrtdt = np.sqrt(dt)
v_x = np.zeros(n)
v_y = np.zeros(n)
y = np.zeros(n)
x = np.zeros(n)
for i in range(n-1):
v_x[i + 1] = v_x[i] + sqrtdt * np.random.normal(0.0,1.0)
v_y[i + 1] = v_y[i] + sqrtdt * np.random.normal(0.0,1.0)
x[i+1] = x[i] + (v_x[i]*dt)
y[i+1] = y[i] + (v_y[i]*dt)
fig, axs = plt.subplots(1, 1, figsize=(12, 8))
plt.plot(y, x, label ='Position')
plt.title("Simulation of Brownian motion")
plt.show()
結果是這樣的,
我想弄清楚我的錯誤。 請幫忙
嗯,這不是一個真正的編程問題。 這些線路
for i in range(n-1):
v_x[i + 1] = v_x[i] + sqrtdt * np.random.normal(0.0,1.0)
v_y[i + 1] = v_y[i] + sqrtdt * np.random.normal(0.0,1.0)
x[i+1] = x[i] + (v_x[i]*dt)
y[i+1] = y[i] + (v_y[i]*dt)
只是不正確,因為它是 SDE。
等式的一般形式是dx = a(t, x)dt + b(t, x)dW
,其中 a(t, x) 是確定性的,b(t, x) 本質上是隨機的(維納過程)。 使它成為數字
x[n+1] = x[n] + dx = x[n] + a(t, x[n])dt + b(t, x[n]) sqrt(dt) ξ
,其中 ξ 服從正態分布均值為 0,方差為 1。 sqrt(dt)
來自維納過程的屬性。
您應該使用Euler-Maruyama而不是使用 Euler 方法。 這些是正確的方程:
for i in range(n - 1):
x[i + 1] = x[i] + b_x(t, x) * sqrtdt * np.random.normal(0.0, 1.0)
y[i + 1] = y[i] + b_y(t, y) * sqrtdt * np.random.normal(0.0, 1.0)
在你的情況下b_x(t, x) = b_y(t, y) = 1
試試 package sdeint。 我認為,它會做你想做的事。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.