matlab - 朗之万方程的 ode45

标签 matlab numerical-integration stochastic stochastic-process ode45

我有一个关于使用 Matlab 计算随机微分方程解的问题。方程式是第 3 页的 2.2a、b,在 this paper 中(PDF)。

我的教授建议使用时间步长较小的ode45,但结果与文章中的不符。特别是时间序列和pdf。我对函数中白噪声的定义也有疑问。

这里是集成函数的代码:

function dVdt = R_Lang( t,V )

global  sigma lambda alpha

W1=sigma*randn(1,1); 
W2=sigma*randn(1,1);
dVdt=[alpha*V(1)+lambda*V(1)^3+1/V(1)*0.5*sigma^2+W1;
        sigma/V(1)*W2];

end

主要脚本:

clear variables
close all
global  sigma lambda alpha
sigma=sqrt(2*0.0028);
alpha=3.81;
lambda=-5604;

tspan=[0,10];
options = odeset('RelTol',1E-6,'AbsTol',1E-6,'MaxStep',0.05);

A0=random('norm',0,0.5,[2,1]);
[t,L]=ode45(@(t,L) R_Lang(t,L),tspan,A0,options);

如果您有任何建议,我将不胜感激。

这里是对抗我的 EM 方法和“sde_euler”的新代码。

lambda = -5604; 
sigma=sqrt(2*0.0028) ; 
Rzero = 0.03;    % problem parameters
phizero=-1;
dt=1e-5;
T = 0:dt:10;
N=length(T);
Xi1 = sigma*randn(1,N);         % Gaussian Noise with variance=sigma^2
 Xi2 = sigma*randn(1,N);
alpha=3.81;

Rem = zeros(1,N);                 % preallocate for efficiency
Rtemp = Rzero;
phiem = zeros(1,N);                 % preallocate for efficiency
phitemp = phizero;
for j = 1:N
     Rtemp = Rtemp + dt*(alpha*Rtemp+lambda*Rtemp^3+sigma^2/(2*Rtemp)) + sigma*Xi1(j);
   phitemp=phitemp+sigma/Rtemp*Xi2(j);
   phiem(j)=phitemp;
   Rem(j) = Rtemp;

end

f = @(t,V)[alpha*V(1)+lambda*V(1)^3+0.5*sigma^2/V(1)/2;
           0];                 % Drift function
g = @(t,V)[sigma;
           sigma/V(1)];        % Diffusion function
A0 = [0.03;0];                % 2-by-1 initial condition
opts = sdeset('RandSeed',1,'SDEType','Ito'); % Set random seed, use Ito formulation
L = sde_euler(f,g,T,A0,opts);       

plot(T,Rem,'r')
hold on
plot(T,L(:,1),'b')

再次感谢您的帮助!

最佳答案

ODE 和 SDE 非常不同,不应使用 ODE 工具(例如 ode45)来尝试求解 SDE。查看您链接到的论文,他们使用了基本的 Euler-Maruyama系统集成方案。这是一个非常简单的求解器,可以自己实现。

在继续之前,您(和您的教授!)应该花一些时间阅读 SDE 以及如何用数值求解它们。我推荐这篇论文,其中包含许多 Matlab 示例:

Desmond J. Higham, 2001, An Algorithmic Introduction to Numerical Simulation of Stochastic Differential Equations, SIAM Rev. (Educ. Sect.), 43 525–46. http://dx.doi.org/10.1137/S0036144500378302

论文中 Matlab 文件的 URL 无效; use this one .请注意,由于这是一篇已有 15 年历史的论文,一些与随机数生成相关的代码已过时(使用 rng(1) 而不是 randn('state',1 ) 为生成器播种)。

如果您熟悉 ode45,您可能会看看我的 SDETools Matlab toolbox在 GitHub 上。它的设计速度很快,并且具有与 Matlab 的 ODE 套件非常相似的界面。以下是使用 Euler-Maruyma 求解器编写示例代码的方法:

sigma = 1e-1*sqrt(2*0.0028);
lambda = -5604;
alpha = 3.81;
f = @(t,V)[alpha*V(1)+lambda*V(1)^3+0.5*sigma^2/V(1);
           0];                 % Drift function
g = @(t,V)[sigma;
           sigma/V(1)];        % Diffusion function
dt = 1e-3;                     % Time step
t = 0:dt:10;                   % Time vector
A0 = [0.03;-2];                % 2-by-1 initial condition
opts = sdeset('RandSeed',1,'SDEType','Ito'); % Set random seed, use Ito formulation
L = sde_euler(f,g,t,A0,opts);                % Integrate

figure;
subplot(211);
plot(t,L(:,2));
ylabel('\phi');
subplot(212);
plot(t,L(:,1));
ylabel('r');
xlabel('t');

我不得不减小 sigma 的大小,否则噪声太大以至于可能导致半径变量变为负数。我不确定这篇论文是否讨论了他们如何处理这种奇点。您可以尝试 sdeset 中的 'NonNegative' 选项来尝试处理此问题,或者您可能需要构建自己的求解器。我也找不到论文使用的积分时间步长。您还应该考虑直接联系论文的作者。

更新

这是一个与上面的 sde_euler 代码匹配的 Euler-Maruyama 实现:

sigma = 1e-1*sqrt(2*0.0028);
lambda = -5604;
alpha = 3.81;
f = @(t,V)[alpha*V(1)+lambda*V(1)^3+0.5*sigma^2/V(1);
           0];                 % Drift function
g = @(t,V)[sigma;
           sigma/V(1)];        % Diffusion function
dt = 1e-3;                     % Time step
t = 0:dt:10;                   % Time vector
A0 = [0.03;-2];                % 2-by-1 initial condition

% Create and initialize state vector (L here is transposed relative to sde_euler output)
lt = length(t);
n = length(A0);
L = zeros(n,lt);
L(:,1) = A0;

% Set seed and pre-calculate Wiener increments with order matching sde_euler
rng(1);
r = sqrt(dt)*randn(lt-1,n).';

% General Euler-Maruyama integration loop
for i = 1:lt-1
    L(:,i+1) = L(:,i)+f(t(i),L(:,i))*dt+r(:,i).*g(t(i),L(:,i));
end

figure;
subplot(211);
plot(t,L(2,:));
ylabel('\phi');
subplot(212);
plot(t,L(1,:));
ylabel('r');
xlabel('t');

关于matlab - 朗之万方程的 ode45,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37704418/

相关文章:

matlab - 我想围绕值选择随机子矩阵。

python - 如何在 numpy 中创建一个 n 维网格来评估任意 n 的函数?

java - 随机爬山法

java - 生成具有给定概率的随机 boolean 值

c++ - 将特征复矩阵返回到 mex 函数中的 matlab,无需额外复制

matlab - QuickHull 最坏情况

java - 如何在 java 中加载/打开/读取 matlab 文件 *.mat?

c++ - 集成三个变量的函数 C++

matlab - 集成一个不直接按元素操作的函数

algorithm - 在什么情况下,[0,1) 上生成的随机数与 [0,1] 上生成的随机数之间的差异会产生影响?