我编写了一个程序,将欧拉法和RK4方法在一个简单的问题中进行比较,该问题是将球以已知的角度和速度投掷,并且只有重力。我计算了绝对误差,并用时间步长(h)将其绘制到x轴。欧拉的绝对误差被证明是正确的(与h ^ 2成比例),但是RK4的绝对误差给出了从0到10 ^ -15的值。但是我认为预期结果与h ^ 4成正比。 这是代码:
hr=0.1:0.05:1;h=0.1/4:0.05/4:1/4; %Chosen step for each method
d1=zeros(1,19);d2=zeros(1,19); %difference between calculated and actual value for the two methods
ne=0;nrk=0;
for j=1:19%j counting the number of the step-sizes (19 different step-sizes)
n=2500*hr(j);
x=zeros(1,n);xrunge=zeros(1,n);
y=zeros(1,n);yrunge=zeros(1,n);
uy=zeros(1,n);uyrunge=zeros(1,n);
t=zeros(1,n);tr=zeros(1,n);
%Initializing
uy(1)=20*sin(pi/3);ux=20*cos(pi/3);
uyrunge(1)=20*sin(pi/3);
a=-10;
%Theoritical equations of motion for position and velocity to the y axis
function [y]=f(t)
y=20*sin(pi/3).*t-5*t.^2;
end
%Euler
for i=2:n
if y(i-1)+h(j)*uy(i-1)<0
break;
end
if h(j)==0.1
ne=ne+1;%number of calculations for uy with step-size 0.1
end
t(i)=t(i-1)+h(j);
y(i)=y(i-1)+h(j)*uy(i-1);
x(i)=x(i-1)+h(j)*ux;
uy(i)=uy(i-1)+h(j)*a;
if i==2
d1(j)=abs(y(i)-f(t(i))); %number of operations done to calculate y with step-size 0.1
end
end
%RK4
for i=2:n
tr(i)=tr(i-1)+hr(j);
xrunge(i)=xrunge(i-1)+hr(j)*ux;
uyrunge(i)=uyrunge(i-1)+hr(j)*a;
k1y=uyrunge(i-1);
k2y=uyrunge(i-1)+hr(j)*a/2;
k3y=uyrunge(i-1)+hr(j)*a/2;
k4y=uyrunge(i-1)+hr(j)*a;
if yrunge(i-1)+hr(j)*(k1y+2*k2y+2*k3y+k4y)/6<0
break;
end
yrunge(i)=yrunge(i-1)+hr(j)*(k1y+2*k2y+2*k3y+k4y)/6;
if i==2
d2(j)=abs(yrunge(i)-f(tr(i))); %difference at each step-size for the first iteration
end
end
end
%function to fit |y-f(t)| according to least squares
function [d]=f2(h)
d=5*h.^2-5.621*10^(-7)*h+3.125*10^(-8);
end
figure(3)
plot(h,d1,'r.',hr,d2,'k.',h,f2(h))
xlabel('h')
legend('Euler', 'RK4','Least squares fitting')
ylabel( 'y-f(t)')
title('Accuracy with step')
disp(d2)
答案 0 :(得分:0)
没什么好奇怪的,您正在将常数函数(两次)与4阶方法相集成,所得到的线性和二次函数恰好在浮点算术的范围内。
要获得非平凡的方法错误,您将需要构造一个示例,该示例不是像当前示例那样简单的积分,最简单的示例是x'=x
,下一个标准示例是谐波振荡器{{ 1}}。
您也可以在空气摩擦下进行弹道射击,但是没有确切的解决方案可与之进行比较。您将需要一个更精确的数值解决方案,例如,以一半的步长再次积分。