簡體   English   中英

MATLAB代碼幫助。 后向歐拉法

[英]MATLAB code help. Backward Euler method

這是我使用后向Euler方法以數值方式求解ODEMATLAB / FreeMat代碼。 但是,結果與我的教科書結果不一致,有時甚至很荒謬。 代碼有什么問題?

function [x,y] = backEuler(f,xinit,yinit,xfinal,h)

    %f - this is your y prime
    %xinit - initial X
    %yinit - initial Y
    %xfinal - final X
    %h - step size

    n = (xfinal-xinit)/h; %Calculate steps

    %Inititialize arrays...
    %The first elements take xinit and yinit corespondigly, the rest fill with 0s.
    x = [xinit zeros(1,n)];
    y = [yinit zeros(1,n)];

    %Numeric routine
    for i = 1:n
        x(i+1) = x(i)+h;
        ynew = y(i)+h*(f(x(i),y(i)));
        y(i+1) = y(i)+h*f(x(i+1),ynew);
    end
end

您的方法是一種新方法。 歐拉既不向前也不向后。 :-)

正向歐拉: y1 = y0 + h*f(x0,y0)

solve in y1: y1 - h*f(x1,y1) = y0向后歐拉solve in y1: y1 - h*f(x1,y1) = y0

您的方法: y1 = y0 +h*f(x0,x0+h*f(x0,y0))

您的方法落后於歐拉。

您無需在y1求解,只需使用正向Euler方法估算y1 我不想對您的方法進行分析,但是我相信,即使與正向Euler相比,它的表現也確實很差,因為您在錯誤的點評估了函數f

這也是我能想到的最接近您的方法的方法,也是顯式的,它應能提供更好的結果。 這是Heun的方法

y1 = y0 + h/2*(f(x0,y0) + f(x1,x0+h*f(x0,y0)))

我能發現的唯一問題是該行:

n=(xfinal-xinit)/h

應該:

n = abs((xfinal-xinit)/h)

避免負步數。 如果沿負x方向移動,請確保為該函數提供負的步長。

您的答案可能會有所不同,因為您對答案的近似程度較高。 為了獲得半准確的結果,deltaX必須非常小,步長必須非常非常小。

PS。 這不是“后向歐拉方法”,而只是常規的舊歐拉方法。

如果這是家庭作業,請給它加上標簽。

看一下數值配方 ,特別是第16章,常微分方程的積分。 已知Euler方法存在問題:

不建議在實際應用中使用Euler方法的原因有很多,其中:(i)與其他同等方法相比,該方法不太精確,並且以相同的步長運行;(ii)也不很穩定

因此,除非您知道教科書使用的是Euler方法,否則我不會期望結果匹配。 即使是,您也可能必須使用相同的步長才能獲得相同的結果。

除非您真的想通過自己編寫的Euler方法求解ODE,否則應該看一下內置的ODE求解器

附帶說明:您無需像這樣在循環內創建x(i)x(i+1) = x(i)+h; 相反,您可以簡單地編寫x = xinit:h:xfinal; 另外,您可能需要寫n = round(xfinal-xinit)/h); 避免警告。


這是由MATLAB實現的求解器。

ode45基於顯式的Runge-Kutta(4,5)公式,即Dormand-Prince對。 它是一步式求解器–在計算y(tn)時,只需要前一個時間點y(tn-1)的解即可。 通常,ode45是最適合第一次嘗試解決大多數問題的最佳功能。

ode23是Bogacki和Shampine的顯式Runge-Kutta(2,3)對的實現。 在粗公差和中等強度的情況下,它可能比ode45更有效。 像ode45一樣,ode23是一步式求解器。

ode113是變量階Adams-Bashforth-Moulton PECE求解器。 在嚴格的公差以及ODE文件功能的評估成本特別高的情況下,它可能比ode45更有效。 ode113是一個多步求解器-通常需要在幾個前面的時間點求解這些問題,才能計算出當前解決方案。

以上算法旨在解決非剛性系統。 如果它們似乎過慢,請嘗試使用以下剛性求解器之一。

ode15s是一個基於數值微分公式(NDF)的變階求解器。 可選地,它使用通常效率較低的后向微分公式(BDF,也稱為Gear方法)。 像ode113一樣,ode15s是一個多步求解器。 當ode45出現故障或效率很低時,如果您懷疑問題很嚴重,或者在解決微分代數問題時,請嘗試ode15。

ode23s基於2階經過修改的Rosenbrock公式。由於它是單步求解器,因此在粗公差下,它可能比ode15s更有效。 它可以解決ode15無效的一些僵化問題。

ode23t是使用“自由”插值的梯形規則的實現。 如果問題只是中等程度的剛性,並且您需要一個沒有數值阻尼的解決方案,請使用此求解器。 ode23t可以解決DAE。

ode23tb是TR-BDF2的實現,TR-BDF2是一個隱式Runge-Kutta公式,其第一級為梯形規則步,第二級為二階向后微分公式。 通過構造,相同的迭代矩陣用於評估兩個階段。 像ode23一樣,此求解器在原始公差下可能比ode15更有效率。

我認為這段代碼可以工作。 嘗試這個。

for i =1:n
    t(i +1)=t(i )+dt;
    y(i+1)=solve('y(i+1)=y(i)+dt*f(t(i+1),y(i+1)');
    end 

代碼很好。 只是您必須在for循環中添加另一個循環。 檢查一致性級別。

if abs((y(i+1) - ynew)/ynew) > 0.0000000001 
    ynew = y(i+1);
    y(i+1) = y(i)+h*f(x(i+1),ynew);
end

我檢查了一個虛擬函數,結果令人鼓舞。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM