赞
踩
大三时候在跳蚤市场闲逛,从一位数学院的学长那里买了一些闲书,最近翻出来刚好有李荣华、刘播老师的《微分方程数值解法》和王仁宏老师的《数值逼近》,结合周善贵老师的《计算物理》课程,整理一下笔记。
本文整理常微分方程数值求解的欧拉法与龙格-库塔法。
一般地,动力学系统的时间演化可以用常微分方程的初值问题来描述,例如设一维简谐运动的回复力:
因此本文主要整理一阶常微分方程初值问题的数值解法。
设
存在常数L,使得
假设
将区间
1、根据泰勒展开式:
略去二阶小量,得:
以此类推,得到递推公式:
2、数值积分推导
由
以此类推,可得到:
为了提高精度,可以使用梯形积分代替矩形积分,即:
以此类推,得到改进的欧拉法:
以
- import math
- from matplotlib import pyplot as plt
-
-
- t_0 = 0
- y_0 = 1
- tau = 0.1
- i = 1
- solve = []
- Euler = []
- t = []
- while i < 100:
- if i == 1:
- y_n = y_0
- t_n = t_0
- Euler.append(y_n)
- solve.append(math.exp(t_n))
- t.append(t_n)
- func = y_n
- y_n = y_n + tau * func
- t_n = t_n + tau
- i += 1
-
- plt.plot(t, Euler, c='green', label=' Euler method')
- plt.plot(t, solve, c='red', label=' accuracy')
- plt.fill_between(t, solve, Euler, facecolor='blue', alpha=0.2)
- plt.title('Euler method', fontsize=19)
- plt.xlabel('t', fontsize=19)
- plt.ylabel('y', fontsize=19)
- plt.legend()
- plt.show()
作图可以看到,当迭代步数较多后,欧拉法的结果逐渐落后于精确指数解的增长速度。下面分析欧拉法的误差来源。
在
在计算中,我们更关心精确解和数值解之间的误差
根据Lipschitz条件,可得:
由
局部截断误差
如果计算的初值不能精确给定,例如存在测量、舍入误差等,在计算过程中,每一步传递的误差连续依赖于初始误差,则称算法稳定,否则该算法不稳定。
对于不同的初值
两式相减,得:
根据Lipschitz条件,可得:
龙格库塔法的主要思想:在
将
令
以此类推,可以得到:
同时,我们可以写出泰勒展开的形式解:
其中:
通项为:
基本思路是,利用当前点的函数值
现在把
将
将
与泰勒展开式
2个方程有3个未知数,因此有无穷多个解,可采用
令
此即为二阶龙格-库塔法。
与上一节的欧拉法公式对比:
Python计算实例
仍以
- import math
- from matplotlib import pyplot as plt
-
-
- t_0 = 0
- y_0 = 1
- z_0 = 1
- tau = 0.1
- i = 1
- j = 1
- solve = []
- Euler = []
- R_K = []
- t = []
- while i < 100:
- if i == 1:
- y_n = y_0
- t_n = t_0
- R_K.append(y_n)
- solve.append(math.exp(t_n))
- t.append(t_n)
- func_n = y_n
- func_m = y_n + tau * func_n
- y_n = y_n + 0.5 * tau * (func_n + func_m)
- t_n = t_n + tau
- i += 1
- t = []
- while j < 100:
- if j == 1:
- z_n = z_0
- t_n = t_0
- Euler.append(z_n)
- t.append(t_n)
- func = z_n
- z_n = z_n + tau * func
- t_n = t_n + tau
- j += 1
-
-
- plt.scatter(t, R_K, marker='^', c='blue', s=70, label=' R-K method')
- plt.plot(t, Euler, c='green', label=' Euler method')
- plt.plot(t, solve, c='red', label=' accuracy')
- plt.fill_between(t, solve, Euler, facecolor='yellow', alpha=0.2)
- plt.title('Euler method & R-K method', fontsize=19)
- plt.xlabel('t', fontsize=19)
- plt.ylabel('y', fontsize=19)
- plt.legend()
- plt.show()
黄色部分表示数值解和精确解的偏离,可以看到,二阶龙格-库塔法(改进的欧拉法)精确度得到了很大的提升。
二阶龙格-库塔法中,泰勒展开到了
Reference:
1、周善贵,《计算物理》课程讲义
2、李荣华,刘播,《微分方程数值解法》
3、王仁宏,《数值逼近》
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。