用Python实现四阶龙格-库塔(Runge-Kutta)方法求解高阶微分方程

用Python实现四阶龙格-库塔(Runge-Kutta)方法求解高阶微分方程

问题

应用四阶龙格-库塔(Runge-Kutta)方法求解如下二阶初值问题:

\begin{equation}
\left\{
\begin{aligned}
t^2x''(t)-2tx'(t)+2x(t) & = t^3\ln t, &  t\in [1,5]\\
x(t) & = 1, &  t=1 \\
x'(t) & = 0. &  t=1
\end{aligned}
\right.
\end{equation}

要求:取步长h=0.01,给出解x(t)的图像和在t=0,0.5,1,1.5,2,2.5,3,3.5,4,4.5,5处的近似解.

求解步骤

  • Step1. 将原问题归结为其等价问题

    引进新的变量y(t)=x'(t)高阶微分方程的初值问题归结为如下一阶微分方程组的初值问题来求解.

    \begin{equation}
    \left\{
    \begin{aligned}
    x'(t) & = y, &  t\in [1,5]\\
    y'(t) & = \frac{t^3\ln t +2ty -2x}{t^2}, &  t\in [1,5]\\
    x(t) & = y, &  t=1\\
    y(t) & = 0. &  t=1
    \end{aligned}
    \right.
    \end{equation}
    
  • Step2. 四阶龙格-库塔方法的离散格式

    针对以上一阶微分方程组的初值问题应用四阶龙格-库塔方法构造得到以下离散格式:

    \begin{equation}
    \left\{
    \begin{aligned}
    x_{n+1} & = x_n +\frac{h}{6}(K_1 + 2K_2 + 2K_3 + K_4),\\
    y_{n+1} & = y_n +\frac{h}{6}(L_1 + 2L_2 + 2L_3 + L_4).
    \end{aligned}
    \right.
    \end{equation}
    

    其中

    \begin{equation}
    \left\{
    \begin{aligned}
    K_1 & = f(t_n,x_n,y_n),\\
    K_2 & = f(t_n + \frac{h}{2},x_n + \frac{h}{2}K_1,y_n + \frac{h}{2}L_1),\\
    K_3 & = f(t_n + \frac{h}{2},x_n + \frac{h}{2}K_2,y_n + \frac{h}{2}L_2),\\
    K_4 & = f(t_n + h,x_n + hK_3,y_n + hL_3),\\
    L_1 & = g(t_n,x_n,y_n),\\
    L_2 & = g(t_n + \frac{h}{2},x_n + \frac{h}{2}K_1,y_n + \frac{h}{2}L_1),\\
    L_3 & = g(t_n + \frac{h}{2},x_n + \frac{h}{2}K_2,y_n + \frac{h}{2}L_2),\\
    L_4 & = f(t_n + h,x_n + hK_3,y_n + hL_3).
    \end{aligned}
    \right.
    \end{equation}
    

    这是一步法,利用节点t_n上的值x_n,y_n,由 (4) 式顺序计算 K_1,L_1,K_2,L_2,K_3,L_3,K_4,L_4,然后代入(3)式即可求得节点t_{n+1}上的 x_{n+1},y_{n+1}.

    • Step3. 利用龙格-库塔法求解高阶微分方程的Python代码如下:
    # 开发者:    Leo 刘
    # 开发环境: macOs Big Sur
    # 开发时间: 2021/9/28 4:31 下午
    # 邮箱  : 517093978@qq.com
    # @Software: PyCharm
    # ----------------------------------------------------------------------------------------------------------
    import math
    import matplotlib.pyplot as plt
    
    
    def f(t, x, y):
        a = y
        return a
    
    
    def g(t, x, y):
        a = (t ** 3 * math.log(t) + 2 * t * y - 2 * x) / t ** 2
        return a
    
    
    def RK4(t, x, y, h):
        """
        :param t: t 的初始值
        :param x: x 的初始值
        :param y: y 的初始值
        :param h: 时间步长
        :return: 迭代新解
        """
        tarray, xarray, yarray = [], [], []
        while t <= 5:
            tarray.append(t)
            xarray.append(x)
            yarray.append(y)
            t += h
    
            K_1 = f(t, x, y)
            L_1 = g(t, x, y)
            K_2 = f(t + h / 2, x + h / 2 * K_1, y + h / 2 * L_1)
            L_2 = g(t + h / 2, x + h / 2 * K_1, y + h / 2 * L_1)
            K_3 = f(t + h / 2, x + h / 2 * K_2, y + h / 2 * L_2)
            L_3 = g(t + h / 2, x + h / 2 * K_2, y + h / 2 * L_2)
            K_4 = f(t + h, x + h * K_3, y + h * L_3)
            L_4 = g(t + h, x + h * K_3, y + h * L_3)
    
            x = x + (K_1 + 2 * K_2 + 2 * K_3 + K_4) * h / 6
            y = y + (L_1 + 2 * L_2 + 2 * L_3 + L_4) * h / 6
        return tarray, xarray, yarray
    
    
    def main():
        tarray, xarray, yarray = RK4(1, 1, 0, 0.01)
        print("龙格-库塔 数值结果".center(168))
        print('-' * 178)
        print("对象\\时刻\t", "t=0\t\t", "  t=0.5\t\t", "  t=1\t\t\t", "  t=1.5\t\t", "  t=2\t\t\t", " t=2.5\t\t\t",
              "  t=3\t\t\t", "  t=3.5\t\t", "  t=4\t\t\t", " t=4.5\t\t\t", "  t=5")
        print('-' * 178)
        print("x:", end='')
        for i in range(len(xarray)):
            if i % 40 == 0:
                print("\t\t", "%8.4f" % xarray[i], end='')
        print('\n', '-' * 177)
        print("y:", end='')
        for i in range(len(yarray)):
            if i % 40 == 0:
                print("\t\t", "%8.4f" % yarray[i], end='')
        print('\n', '-' * 177)
        plt.figure('龙格-库塔 数值结果')
        plt.subplot(221)
        # plt.plot(tarray, xarray, label='x_runge_kutta')
        plt.scatter(tarray, xarray, label='x_scatter', s=1, c='#DC143C', alpha=0.6)
        # plt.xlabel('t')
        plt.legend()
        plt.subplot(222)
        # plt.plot(tarray, yarray, label='y_runge_kutta')
        plt.scatter(tarray, yarray, label='y_scatter', s=1, c='#DC143C', alpha=0.6)
        # plt.xlabel('t')
        plt.legend()
        plt.subplot(212)
        # plt.plot(tarray, xarray, label='runge_kutta')
        plt.scatter(tarray, xarray, label='Numerical solution scatter', s=1, c='#DC143C', alpha=0.6)
        plt.xlabel('t')
        plt.legend()
        plt.show()
    
    
    if __name__ == "__main__":
        main()
    
    
    
    • Step4. 代码的运行结果如下:
                                                                                        龙格-库塔 数值结果                                                                               
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    对象\时刻    t=0           t=0.5           t=1             t=1.5           t=2            t=2.5            t=3             t=3.5           t=4            t=4.5            t=5
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    x:         1.0000          0.8579          0.5080          0.1042         -0.1564         -0.0416          0.7105          2.3875          5.2995          9.7769         16.1685
     ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    y:         0.0000         -0.6689         -1.0161         -0.9205         -0.2855          0.9689          2.9116          5.6026          9.0952         13.4374         18.6728
     ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    
    

问题来源: 《微分方程数值解》-M.Ran

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容