刚性方程的隐式Euler

时间:2015-11-23 12:58:14

标签: matlab numerical-methods differential-equations numerical-integration

问题:解决僵硬的不同方程
方法:隐式Euler
计划:我通过solvin非线性方程使用割线方法计算下一个'y'。我的功能是dy/dx = sin(x+y)

有正确的解决方案。我用牛顿法

的main.m

h=0.01;
x(1)=0;
y_expl(1)=0;  
y_impl(1)=0+h;  
dy(1)=0;
eps=1.0e-6;

for i=1:1000

    x(i+1)=x(i)+h;

    y_impl(i+1)=newton(x(i),y_impl(i),y_impl(i));

    y_expl(i+1)=y_expl(i)+h*f(x(i),y_expl(i));

end

plot(x,y_impl,'r',x,y_expl,'b')
legend('Implicit Euler','Explicit Euler');

newton.m

function [ yn ] = newton( x,y,yi )

    eps=1.0e-6;
    err=1;
    step=0;
    step_max=100;
    h=0.01;
    xn=x+h;

    while (err > eps) && (step < step_max)

        step=step+1;

        yn=y-(F(xn,y,yi,h))/(J(xn,y,h));

        err=abs(y-yn)/(abs(yn)+1.0e-10);

        y=yn;

    end

end

f.m

function [ res ] = f( x,y )

res = sin(x+y);

end

G.M

function [ res ] = J( xn,y,h )

res = h*f(xn,y)-1;

end

F.m

function [ res ] = F( a,y,yn,h )

res = h*f(a,y)-y+yn;

end

感谢关注

1 个答案:

答案 0 :(得分:0)

问题是你不应该解决F(x,y)=0,而是由隐式欧拉步y=y0+h*F(x,y)产生的等式。因此定义

function [res] = G(x,y,y0,h)
    res = y - y0 - h*F(x,y)
end

并使用牛顿或割线方法G

一般代码评论:

  • matlab中没有x(0)
  • 隐式Euler是一步法,无需为索引2和3初始化。
  • x值的迭代为x(i+1)=x(i)+h

在割线方法中:已知值为x0=x(i)y0=y(i)h

  • 在开始循环之前需要x1=x0+hy1的初始值。这可以作为显式Euler步骤的结果,y1=y0+h*F(x0,y0)作为预测器。割线方法用作校正器。

  • 如果单独计算G的值,它会使代码更具可读性。请注意,G(x1,y,y0,h)中的变量为y,其他变量为固定参数。因此,为正割公式G0=G(x1,y0,y0,h)或更对称G1=G(x1,y1,y0,h)计算y2=y1-G1*(y1-y0)/(G1-G0)y2=(y0*G1-y1*G0)/(G1-G0)

  • 原则上,您可以通过调用

    使用带有接口secant(func, a, b, tol)的通用割线方法
    x(i+1) = x(i)+h;
    y(i+1) = secant(@(y) G(x(i+1),y,y(i),h), y(i), y(i)+h*F(x(i),y(i)), delt)