用Python實現(xiàn)四階龍格-庫塔(Runge-Kutta)方法求解高階微分方程

用Python實現(xiàn)四階龍格-庫塔(Runge-Kutta)方法求解高階微分方程

問題

應(yīng)用四階龍格-庫塔(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. 將原問題歸結(jié)為其等價問題

    引進(jìn)新的變量y(t)=x'(t)高階微分方程的初值問題歸結(jié)為如下一階微分方程組的初值問題來求解.

    \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. 四階龍格-庫塔方法的離散格式

    針對以上一階微分方程組的初值問題應(yīng)用四階龍格-庫塔方法構(gòu)造得到以下離散格式:

    \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}
    

    這是一步法,利用節(jié)點t_n上的值x_n,y_n,由 (4) 式順序計算 K_1,L_1,K_2,L_2,K_3,L_3,K_4,L_4亥揖,然后代入(3)式即可求得節(jié)點t_{n+1}上的 x_{n+1},y_{n+1}.

    • Step3. 利用龍格-庫塔法求解高階微分方程的Python代碼如下:
    # 開發(fā)者:    Leo 劉
    # 開發(fā)環(huán)境: macOs Big Sur
    # 開發(fā)時間: 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("龍格-庫塔 數(shù)值結(jié)果".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('龍格-庫塔 數(shù)值結(jié)果')
        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. 代碼的運行結(jié)果如下:
                                                                                        龍格-庫塔 數(shù)值結(jié)果                                                                               
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    對象\時刻    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
     ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    
    

問題來源: 《微分方程數(shù)值解》-M.Ran

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市射富,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌粥帚,老刑警劉巖胰耗,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異芒涡,居然都是意外死亡柴灯,警方通過查閱死者的電腦和手機卖漫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赠群,“玉大人羊始,你說我怎么就攤上這事〔槊瑁” “怎么了突委?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長冬三。 經(jīng)常有香客問我匀油,道長,這世上最難降的妖魔是什么勾笆? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任敌蚜,我火速辦了婚禮,結(jié)果婚禮上窝爪,老公的妹妹穿的比我還像新娘钝侠。我一直安慰自己,他們只是感情好酸舍,可當(dāng)我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著里初,像睡著了一般啃勉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上双妨,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天淮阐,我揣著相機與錄音,去河邊找鬼刁品。 笑死泣特,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的挑随。 我是一名探鬼主播状您,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼兜挨!你這毒婦竟也來了膏孟?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤拌汇,失蹤者是張志新(化名)和其女友劉穎柒桑,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體噪舀,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡魁淳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年飘诗,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片界逛。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡昆稿,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出仇奶,到底是詐尸還是另有隱情貌嫡,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布该溯,位于F島的核電站岛抄,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏狈茉。R本人自食惡果不足惜夫椭,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望氯庆。 院中可真熱鬧蹭秋,春花似錦、人聲如沸堤撵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽实昨。三九已至洞豁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間荒给,已是汗流浹背丈挟。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留志电,地道東北人曙咽。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像挑辆,于是被迫代替她去往敵國和親例朱。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容