为什么我的Runge-Kutta实现中的数字错误不会像N ^ a那样减少?

时间:2011-10-09 21:07:54

标签: matlab runge-kutta

我正在尝试确定Runge-Kutta Method(“RK4”)需要多少步才能在常微分方程的精确解的0.01%范围内。我将其与Euler method进行比较。两者都应该在loglog图上产生一条直线。我的欧拉解决方案似乎是正确的,但我正在为RK获得一个弯曲的解决方案。它们基于相同的代码,所以我对这个问题完全感到困惑。

编辑:很抱歉删除维基百科链接。因为我是新用户,所以不会让我保留多个链接。但是,这两种方法都在维基百科上详细说明,类似于我的实现。

如果有人希望解决我的问题,代码如下,图表位于this Word file on dropbox.com。是的,这是一个家庭作业问题;我发布这个是因为我想了解我的思考过程中出了什么问题。

f = @(x,y) x+y; %this is the eqn (the part after the @(t,y)

这是我的RK4代码:

k1=@(x,y) h*f(x,y);
k2=@(x,y) h*f(x+1/2*h,y+1/2*k1(x,y));
k3=@(x,y) h*f(x+1/2*h,y+1/2*k2(x,y));
k4=@(x,y) h*f(x+h,y+k3(x,y));

clear y x exact i
x(1)=0;
y(1)=2;
xn=1;
x0=0;

exact=3*exp(xn)-xn-1; %exact solution at x=1
%# Evaluate RK4 with 1 step for x=0...1
N=1; %# number of steps
h=(xn-x0)/N; %# step size
i=1;
y(i+1)=y(i)+1/6*k1(x(i),y(i))+1/3*k2(x(i),y(i))+1/3*k3(x(i),y(i))+1/6*k4(x(i),y(i));
RK4(N)=y(i+1);  %# store result of RK4 in vector RK4(# of steps)
E_RK4(N)=-(RK4(N)-exact)/exact*100;%keep track of %error for each N
Nsteps_RK4(N)=N;


%# repeat for increasing N until error is less than 0.01%
while -(RK4(N)-exact)/exact > 0.0001
    i=1;
    N=N+1;
    h=(xn-x0)/N;
    for i=1:N
        y(i+1)=y(i)+1/6*k1(x(i),y(i))+1/3*k2(x(i),y(i))+1/3*k3(x(i),y(i))+1/6*k4(x(i),y(i));
        x(i+1)=x(i)+h;
    end
    RK4(N)=y(i+1);
    Nsteps_RK4(N)=N;
    E_RK4(N)=-(RK4(N)-exact)/exact*100; %# keep track of %error for each N
end

Nsteps_RK4(end);

这是我的欧拉代码:

%# Evaluate Euler with 1 step for x=0...1
clear y x i
x(1)=0;
y(1)=2;
N=1; %# number of steps
h=(xn-x0)/N; %# step size
i=1;
y(i+1)= y(i)+h*f(x(i),y(i));
Euler(N)=y(i+1); %# store result of Euler in vector Euler(# of steps)
E_Euler(N)=-(Euler(N)-exact)/exact*100;%# keep track of %error for each N
Nsteps_Euler(N)=N;
%# repeat for increasing N until error is less than 0.01%
while -(Euler(N)-exact)/exact > 0.0001
    i=1;
    N=N+1;
    h=(xn-x0)/N;
    for i=1:N
        y(i+1)= y(i)+h*f(x(i),y(i));   
        x(i+1)=x(i)+h;
    end
    Euler(N)=y(i+1);
    Nsteps_Euler(N)=N;
    E_Euler(N)=-(Euler(N)-exact)/exact*100; %# keep track of %error for each N
end

1 个答案:

答案 0 :(得分:1)

请参阅:http://www.mathworks.com/help/techdoc/matlab_prog/f4-70115.html#f4-71621

  

表达式[...]正文中指定的变量必须赋值   在构造使用它们的匿名函数时对它们。上   构造,MATLAB捕获指定的每个变量的当前值   那个功能的主体。该函数将继续关联此值   即使值应在工作区中更改或外出,也要使用变量   范围。

即使您在h循环中更改了k1k4 ... hwhile的值仍然保持不变。

一种解决方案是将h添加到匿名函数:

k1=@(x,y,h) h*f(x,y);