Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab 为什么我的龙格库塔实现中的数字错误没有像N^a那样减少?_Matlab_Runge Kutta - Fatal编程技术网

Matlab 为什么我的龙格库塔实现中的数字错误没有像N^a那样减少?

Matlab 为什么我的龙格库塔实现中的数字错误没有像N^a那样减少?,matlab,runge-kutta,Matlab,Runge Kutta,我试图确定(“RK4”)需要多少步才能在常微分方程精确解的0.01%以内。我把这个和这个做比较。两者都应在对数图上形成一条直线。我的欧拉解似乎是正确的,但我得到了RK的曲线解。它们基于相同的代码,所以我对这个问题完全感到困惑 编辑:很抱歉删除维基百科链接。因为我是新用户,所以它不会让我保留多个链接。然而,这两种方法在维基百科上的详细说明与我的实现类似 如果有人想解决我的问题,代码在下面,图表在下面。是的,这是一个家庭作业问题;我之所以发布这篇文章,是因为我想了解我思考过程中的错误 f = @(x

我试图确定(“RK4”)需要多少步才能在常微分方程精确解的0.01%以内。我把这个和这个做比较。两者都应在对数图上形成一条直线。我的欧拉解似乎是正确的,但我得到了RK的曲线解。它们基于相同的代码,所以我对这个问题完全感到困惑

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

如果有人想解决我的问题,代码在下面,图表在下面。是的,这是一个家庭作业问题;我之所以发布这篇文章,是因为我想了解我思考过程中的错误

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);
这是我的Euler代码:

%# 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
见:

表达式[…]主体中指定的变量必须指定一个值 在构造使用它们的匿名函数时,将其添加到。在上面 构建时,MATLAB捕获中指定的每个变量的当前值 该功能的主体。该函数将继续关联此值 即使值应该在工作区中更改或消失,也使用变量 范围有限

k1
k4
中的
h
值保持不变,即使在
while
循环中更改
h

一种解决方案是向匿名函数添加
h

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

函数
f
是如何定义的?您好,正如stardt所说,您应该告诉我们您应该使用哪个
f
。另外,你能确保我添加的维基百科文章链接正确反映了你正在使用的RK4版本吗?你发布的代码有很多问题
h
在定义之前用于匿名函数。您应该在
while
条件中使用
abs()
,因为我不知道如何保证估计值总是小于精确解。在计算
for
循环中的值后,访问
y
向量的错误元素。
end
后面的行应该是
RK4(N)=y(N+1)
。euler代码中也存在同样的错误。此外,在
while
循环中更改
h
不会影响k1…k4函数中使用的
h
。考虑:
>h=1;>>g=@(x)x+h;>>g(0)ans=1>>h=2;>>g(0)ans=1
关于索引和for循环变量范围问题,我错了。更改
h
仍有问题。此处发布的代码将不会运行,因为
h
未定义。要查看此信息,请使用
清除所有
,而不是仅清除特定变量。
k
函数中的
h
是定义这些函数时
h
的值。我建议显式Euler代码使用N=N*2,以更快地得到结果。谢谢!这就解释了这些函数是如何工作的。加上h作为函数的变量要比用标量h重写LOP容易得多。我可以使用一种解释,我用
k1=@(x,y,h)h*f(x,y)运行代码
k1=@(x,y,h)h*f(x(i),y(i))和两者都起作用。MATLAB似乎将i识别为索引而不是标量(因为我还没有定义i)。这是正确的解释还是我遗漏了输出中的差异?@Dominik我的猜测是,在定义匿名函数时,您的
I
为1。如果未定义
i
,则调用
k1()
时会出现错误。我喜欢在脚本顶部使用
清除所有
,以确保没有意外变量。