在Matlab中使用改进的Euler方法

时间:2014-05-01 13:36:03

标签: matlab ode

我试图在Matlab中求解二阶微分方程。我能够使用前向欧拉方法做到这一点,但由于这需要相当短的时间步骤来获得准确的结果,我已经研究了其他一些选项。更具体地说,改进的欧拉方法(Heun'方法)。

我理解改进欧拉方法的原理,它首先估计速度,然后使用该信息将其校正到当前条件。但我不完全确定我所写的内容是否完全正确。

1)你能检查我的代码是否正确使用了改进的Euler方法吗?

2)在我的代码中,end之前的最后一行,第二个B(ii)应为B(ii+1)

我为这两个选项编写了一个简化代码。这是:

t = 0:0.01:100;
dt = t(2)-t(1);                     % Time step

%Constants%
M  = 20000;
m_a = 10000;
c= 15000;
k_spring = 40000;

B = rand(1,length(t)+1);

%% Forward Euler Method %%
x = zeros(1,length(t)+1);           % Pre-allocation
u = zeros(1,length(t)+1);           % Pre-allocation

x(1) = 1;                              % Initial condition
u(1) = 0;                              % Initial condition

for ii = 1:length(t)
    x(ii+1) = x(ii) + dt*u(ii);
    u(ii+1) = u(ii) + dt * ((1/(M+m_a)) * -(c+k_spring+B(ii))*x(ii));
end


%% Improved Euler Method %%

x1 = zeros(1,length(t)+1);           % Pre-allocation
u1 = zeros(1,length(t)+1);           % Pre-allocation

x1(1) = 1;                              % Initial condition
u1(1) = 0;                              % Initial condition

for ii = 1:length(t)
    x1(ii+1) = x1(ii) + dt*u1(ii);
    u1(ii+1) = u1(ii) + dt * ((1/(M+m_a)) * -(c+k_spring+B(ii))*x1(ii));                                                                      %Estimate
    u1(ii+1) = u1(ii) + (dt/2) * ( ((1/(M+m_a)) * -(c+k_spring+B(ii))*x1(ii)) + ((1/(M+m_a)) * -(c+k_spring+B(ii))*x1(ii+1)) );               %Correction
end

谢谢!

1 个答案:

答案 0 :(得分:0)

你应该遵循主要的编程思想,将重复使用的东西制作成额外的程序。假设你这样做了,评估ODE函数的函数叫做odefunc。

function [dotx, dotu] = odefunc(x,u,B)
    dotx = u;
    dotu =(1/(M+m_a)) * -(c+k_spring+B)*x);
end

然后

for ii = 1:length(t)
    %% Predictor
    [dotx1,dotu1] = odefunc(x1(ii), u1(ii), B(ii));
    %% One corrector step
    [dotx2,dotu2] = odefunc(x1(ii)+dotx1*dt, u1(ii)+dotu1*dt, B(ii+1));
    x1(ii+1) = x1(ii) + 0.5*(dotx1+dotx2)*dt;
    u1(ii+1) = u1(ii) + 0.5*(dotu1+dotu2)*dt;  
end