當前位置:編程學習大全網 - 編程語言 - matlab實現歐拉法和RK-4方法的數值計算

matlab實現歐拉法和RK-4方法的數值計算

程序已經寫了,不過步長妳得自己調,當步長較小時,計算時間會很長

另外,tend是時間的終值,妳可以設小壹些。因為解析解為10*cos(x),我設成pi,就是計算半個周期。

x''(t)=-x(t)

引入y1=x,y2=x',則

y1'=y2

y2'=-x=-y1

初始條件為:

y1(0)=10;

y2(0)=0;

將下面兩行百分號之間的內容,保存成DiffEulerRk4.m

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function MaxDiffX=DiffEulerRk4(dt,PlotFlag)

%dt是步長

%PlotFlag是否作圖

if nargin<1

dt=0.01;

end

if nargin<2

PlotFlag=0;

end

f=inline('[y(2);-y(1)]','t','y'); %微分方程的右邊項

t0=0; %初始時刻

tend=pi; %計算的點數

tt=t0:dt:tend; %壹系列離散的點

N=length(tt); %點數

y0=[10;0];

%%(1)歐拉法

EulerY=y0;

for i=2:N

EulerY(:,i)=EulerY(:,i-1)+dt*f(tt(i-1),EulerY(:,i-1));

end

EulerX=EulerY(1,:); %取x

%%(2)龍格庫塔法

RkY=y0;

for i=2:N

k1=f(tt(i-1), RkY(:,i-1));

k2=f(tt(i-1)+dt/2, RkY(:,i-1)+k1*dt/2);

k3=f(tt(i-1)+dt/2, RkY(:,i-1)+k2*dt/2);

k4=f(tt(i-1)+dt, RkY(:,i-1)+k3*dt);

RkY(:,i)=RkY(:,i-1)+(k1+2*k2+2*k3+k4)*dt/6;

end

RkX=RkY(1,:); %取x

%精確解

syms t

analytic=dsolve('D2x=-x','x(0)=10','Dx(0)=0','t');

rightdata=subs(analytic,t,tt);

if PlotFlag

plot(tt,EulerX,'b-',tt,RkX,'r--',tt,rightdata,'g-.')

legend('Euler','Runge-Kutta','analytic')

end

MaxDiffX=[max(abs(RkX-rightdata)),max(abs(EulerX-rightdata))];

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

所有題,都得妳自己調步長。

輸入:

DiffEulerRk4(0.01,1) %步長取0.01的計算結果,參數為1代表作圖,自己得修改步長

%%下面是變化

Error=[];

Dt=[5e-4,1e-3,2e-3,5e-3,0.01,0.05,0.1];

for dt=Dt %幾種步長,自行修改

dt %查看dt,步長小,計算量大

Error_1=DiffEulerRk4(dt); %不作圖

Error=[Error;Error_1]; %保存歐拉法誤差

end

semilogx(Dt,Error)

legend('Euler','RK4')

xlabel('步長')

ylabel('誤差')

title('與理論值誤差')

  • 上一篇:我們所有人壹定要有壹個***識:未來從來不只是壹個樣子
  • 下一篇:cnc操機步驟
  • copyright 2024編程學習大全網