数值计算方法 Chapter8. 常微分方程的数值解

Posted Espresso Macchiato

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数值计算方法 Chapter8. 常微分方程的数值解相关的知识,希望对你有一定的参考价值。

0. 问题描述

这一章节考察的问题如标题所述,即常微分方程的数值求解:

d y d x = f ( x , y ) y ( x 0 ) = y 0 \\left\\ \\beginaligned \\fracdydx &= f(x, y) \\\\ y(x_0) &= y_0 \\endaligned \\right. dxdyy(x0)=f(x,y)=y0

1. Euler公式

1. 向前Euler公式

Euler公式算是一个求解常微分方程数值解问题的一个比较直接的思路:

d y d x = δ y δ x = f ( x , y ) \\fracdydx = \\frac\\delta y\\delta x = f(x, y) dxdy=δxδy=f(x,y)

从而有:

y + δ y = f ( x , y ) ⋅ δ x y+\\delta y = f(x, y) \\cdot \\delta x y+δy=f(x,y)δx

由此,我们不断地求解就能够近似的得到各个 x x x取值下的 y y y值。

y n + 1 = y n + h ⋅ f ( x n , y n ) y_n+1 = y_n + h\\cdot f(x_n, y_n) yn+1=yn+hf(xn,yn)

给出python伪代码实现如下:

def fwd_euler_fn(f, x0, y0, step=1e-3):
    def fn(x):
        h = step if x >= x0 else -step
        n = math.ceil((x - x0) / h)
        x, y = x0, y0
        for _ in range(n):
            y += h * f(x, y)
            x += h
        return y
    return fn

2. 向后Euler公式

向后Euler公式和向前Euler公式并无本质区别,不过微调公式为:

y n + 1 = y n + h ⋅ f ( x n + 1 , y n + 1 ) y_n+1 = y_n + h\\cdot f(x_n+1, y_n+1) yn+1=yn+hf(xn+1,yn+1)

但是显然的在计算 y n + 1 y_n+1 yn+1时事实上无法得知 f ( x n + 1 , y n + 1 ) f(x_n+1, y_n+1) f(xn+1,yn+1)的值,因此这里需要叠加上迭代的思路:

y n + 1 ( k + 1 ) = y n ( k + 1 ) + h ⋅ f ( x n + 1 , y n + 1 ( k ) ) y_n+1^(k+1) = y_n^(k+1) + h\\cdot f(x_n+1, y_n+1^(k)) yn+1(k+1)=yn(k+1)+hf(xn+1,yn+1(k))

上述迭代公式称为Picard迭代。

可以证明,当 h h h足够小时,Picard迭代收敛。

给出python伪代码如下:

def bwd_euler_fn(f, x0, y0, step=1e-3):
    def fn(x, epsilon = 1e-6):
        h = step if x >= x0 else -step
        n = math.ceil((x - x0) / h)
        xlist = [x0 + i*h for i in range(n)]
        ylist = [y0 for i in range(n)]
        for i in range(n-1):
            ylist[i+1] = ylist[i] + h * f(xlist[i], ylist[i])
        while True:
            zlist = deepcopy(ylist)
            for i in range(n-1):
                zlist[i+1] = zlist[i] + h * f(xlist[i+1], ylist[i+1])
            delta = abs(zlist[-1] - ylist[-1])
            ylist = zlist
            if delta < epsilon:
                break
        return zlist[-1]
    return fn

3. 梯形公式

梯形公式本质上依然还是基于微分差商,不过不同于之前直接使用微分的形式,这里更加严格的使用了积分的表达,即:

y n + 1 = y n + ∫ x n x n + 1 f ( x , y ) d x y_n+1 = y_n + \\int_x_n^x_n+1f(x, y)dx yn+1=yn+xnxn+1f(x,y)dx

然后,这里使用梯形公式来近似掉其中的积分过程,有:

y n + 1 = y n + h 2 ( f ( x n , y n ) + f ( x n + 1 , y n + 1 ) ) y_n+1 = y_n + \\frach2(f(x_n, y_n) + f(x_n+1, y_n+1)) yn+1=yn+2h(f(xn,yn)+f(xn+1,yn+1))

这里同样会涉及到等号右侧的 y n + 1 y_n+1 yn+1的求解问题,不过,不同于向后Euler公式中的纯迭代思路,这里只使用一次迭代来近似,即:

y n + 1 = y n + h 2 ( f ( x n , y n ) + f ( x n + 1 , y n + h ⋅ f ( x n , y n ) ) ) y_n+1 = y_n + \\frach2(f(x_n, y_n) + f(x_n+1, y_n + h\\cdot f(x_n, y_n))) yn+1=yn+2h(f(xmatlab编程问题利用欧拉方法求常微分方程近似数值解

备战数学建模7-MATLAB数值微积分与方程求解

99插值法,函数逼近,曲线拟和,数值积分,数值微分,解线性方程组的直接方法,解线性方程组的迭代法,非线性方程求根,常微分方程的数值解法

Matlab常微分方程数值解法

Matlab常微分方程数值解法

数值计算 --求解连续微分系统和混沌系统