簡體   English   中英

模擬 Python 中的隨機微分方程

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM