我试图确定龙格-库塔方法("RK4")在常微分方程精确解的0.01%以内需要多少步骤。我把它和欧拉法做比较。两者都应该在对数图上得到一条直线。我的欧拉解似乎是正确的但我得到的是RK的曲线解。它们基于相同的代码,所以我对这个问题完全感到困惑。
编辑:很抱歉删除维基百科的链接。它不会让我保留多个链接,因为我是一个新用户。然而,这两种方法在维基百科上都有详细说明,与我的实现类似。如果有人想解决我的问题,下面的代码和图表是在这个Word文件在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
参见:http://www.mathworks.com/help/techdoc/matlab_prog/f4-70115.html#f4-71621
表达式体中指定的变量[…]]必须赋值构造一个使用它们的匿名函数。在构造时,MATLAB捕获中指定的每个变量的当前值函数体。函数将继续关联这个值使用该变量,即使该值应该在工作空间中更改或删除的范围。
k1
中h
的值…即使在while
循环中改变h
, k4
仍保持不变。
一个解决方案是将h
添加到匿名函数中:
k1=@(x,y,h) h*f(x,y);