python 解决微分方程的操作(数值解法)


Posted in Python onMay 26, 2021

Python求解微分方程(数值解法)

对于一些微分方程来说,数值解法对于求解具有很好的帮助,因为难以求得其原方程。

比如方程:

python 解决微分方程的操作(数值解法)

但是我们知道了它的初始条件,这对于我们叠代求解很有帮助,也是必须的。

python 解决微分方程的操作(数值解法)

那么现在我们也用Python去解决这一些问题,一般的数值解法有欧拉法、隐式梯形法等,我们也来看看这些算法对叠代的精度有什么区别?

```python
```python
import numpy as np
from scipy.integrate import odeint
from matplotlib import pyplot as plt
import os
#先从odeint函数直接求解微分方程
#创建欧拉法的类
class Euler:
    #构造方法,当创建对象的时候,自动执行的函数
    def __init__(self,h,y0):
        #将对象与对象的属性绑在一起
        self.h = h
        self.y0 = y0
        self.y = y0
        self.n = 1/self.h
        self.x = 0
        self.list = [1]
        #欧拉法用list列表,其x用y叠加储存
        self.list2 = [1]
        self.y1 = y0
        #改进欧拉法用list2列表,其x用y1叠加储存
        self.list3 = [1]
        self.y2 = y0
        #隐式梯形法用list3列表,其x用y2叠加储存
    #欧拉法的算法,算法返回t,x
    def countall(self):
        for i in range(int(self.n)):
            y_dere = -20*self.list[i]
            #欧拉法叠加量y_dere = -20 * x
            y_dere2 = -20*self.list2[i] + 0.5*400*self.h*self.list2[i]
            #改进欧拉法叠加量 y_dere2 = -20*x(k) + 0.5*400*delta_t*x(k)
            y_dere3 = (1-10*self.h)*self.list3[i]/(1+10*self.h)
            #隐式梯形法计算 y_dere3 = (1-10*delta_t)*x(k)/(1+10*delta_t)
            self.y += self.h*y_dere
            self.y1 += self.h*y_dere2
            self.y2 =y_dere3
            self.list.append(float("%.10f" %self.y))
            self.list2.append(float("%.10f"%self.y1))
            self.list3.append(float("%.10f"%self.y2))
        return np.linspace(0,1,int(self.n+1)), self.list,self.list2,self.list3
step = input("请输入你需要求解的步长:")
step = float(step)
work1 = Euler(step,1)
ax1,ay1,ay2,ay3 = work1.countall()
#画图工具plt
plt.figure(1)
plt.subplot(1,3,1)
plt.plot(ax1,ay1,'s-.',MarkerFaceColor = 'g')
plt.xlabel('横坐标t',fontproperties = 'simHei',fontsize =20)
plt.ylabel('纵坐标x',fontproperties = 'simHei',fontsize =20)
plt.title('欧拉法求解微分线性方程步长为'+str(step),fontproperties = 'simHei',fontsize =20)
plt.subplot(1,3,2)
plt.plot(ax1,ay2,'s-.',MarkerFaceColor = 'r')
plt.xlabel('横坐标t',fontproperties = 'simHei',fontsize =20)
plt.ylabel('纵坐标x',fontproperties = 'simHei',fontsize =20)
plt.title('改进欧拉法求解微分线性方程步长为'+str(step),fontproperties = 'simHei',fontsize =20)
plt.subplot(1,3,3)
plt.plot(ax1,ay3,'s-.',MarkerFaceColor = 'b')
plt.xlabel('横坐标t',fontproperties = 'simHei',fontsize =20)
plt.ylabel('纵坐标x',fontproperties = 'simHei',fontsize =20)
plt.title('隐式梯形法求解微分线性方程步长为'+str(step),fontproperties = 'simHei',fontsize =20)
plt.figure(2)
plt.plot(ax1,ay1,ax1,ay2,ax1,ay3,'s-.',MarkerSize = 3)
plt.xlabel('横坐标t',fontproperties = 'simHei',fontsize =20)
plt.ylabel('纵坐标x',fontproperties = 'simHei',fontsize =20)
plt.title('三合一图像步长为'+str(step),fontproperties = 'simHei',fontsize =20)
ax = plt.gca()
ax.legend(('$Eular$','$fixed Eular$','$trapezoid$'),loc = 'lower right',title = 'legend')
plt.show()
os.system("pause")

对于欧拉法,它的叠代方法是:

python 解决微分方程的操作(数值解法)

改进欧拉法的叠代方法:

python 解决微分方程的操作(数值解法)

隐式梯形法:

python 解决微分方程的操作(数值解法)

对于不同的步长,其求解的精度也会有很大的不同,我先放一几张结果图:

python 解决微分方程的操作(数值解法)python 解决微分方程的操作(数值解法)

补充:基于python的微分方程数值解法求解电路模型

安装环境包

安装numpy(用于调节range) 和 matplotlib(用于绘图)

在命令行输入

pip install numpy 
pip install matplotlib

电路模型和微分方程

模型1

无损害,电容电压为5V,电容为0.01F,电感为0.01H的并联谐振电路

电路模型1

python 解决微分方程的操作(数值解法)

微分方程1

python 解决微分方程的操作(数值解法)

模型2

带电阻损耗的电容电压为5V,电容为0.01F,电感为0.01H的的并联谐振

电路模型2

python 解决微分方程的操作(数值解法)

 

 

微分方程2

python 解决微分方程的操作(数值解法)

python代码

模型1

import numpy as np
import matplotlib.pyplot as plt
 
L = 0.01  #电容的值 F
C = 0.01  #电感的值 L
u_0 = 5   #电容的初始电压
u_dot_0 = 0
 
def equition(u,u_dot):#二阶方程
    u_double_dot = -u/(L*C)
    return u_double_dot
 
def draw_plot(time_step,time_scale):#时间步长和范围
    u = u_0
    u_dot = u_dot_0  #初始电压和电压的一阶导数
    time_list = [0] #时间lis
    Votage = [u] #电压list
    plt.figure()
    for time in np.arange(0,time_scale,time_step):#使用欧拉数值计算法 一阶近似
        u_double_dot = equition(u,u_dot) #二阶导数
        u_dot = u_dot + u_double_dot*time_step #一阶导数
        u = u + u_dot*time_step #电压
        time_list.append(time) #结果添加
        Votage.append(u) #结果添加
        print(u)
    plt.plot(time_list,Votage,"b--",linewidth=1) #画图
    plt.show()
    plt.savefig("easyplot.png")
 
if __name__ == '__main__':
    draw_plot(0.0001,1)

模型2

import numpy as np
import matplotlib.pyplot as plt
 
L = 0.01  #电容的值 F
C = 0.01  #电感的值 L
R = 0.1   #电阻值
u_0 = 5   #电容的初始电压
u_dot_0 = 0
 
def equition(u,u_dot):#二阶方程
    u_double_dot =(-R*C*u_dot -u)/(L*C)
    return u_double_dot
 
def draw_plot(time_step,time_scale):#时间步长和范围
    u = u_0
    u_dot = u_dot_0  #初始电压和电压的一阶导数
    time_list = [0] #时间lis
    Votage = [u] #电压list
    plt.figure()
    for time in np.arange(0,time_scale,time_step):#使用欧拉数值计算法 一阶近似
        u_double_dot = equition(u,u_dot) #二阶导数
        u_dot = u_dot + u_double_dot*time_step #一阶导数
        u = u + u_dot*time_step #电压
        time_list.append(time) #结果添加
        Votage.append(u) #结果添加
        print(u)
    plt.plot(time_list,Votage,"b-",linewidth=1) #画图
    plt.show()
    plt.savefig("result.png")
 
if __name__ == '__main__':
    draw_plot(0.0001,1)

数值解结果

模型1

python 解决微分方程的操作(数值解法)

纵轴为电容两端电压,横轴为时间与公式计算一致​​

模型2结果

python 解决微分方程的操作(数值解法)

纵轴

为电容两端电压,横轴为时间标题

最后我们可以根据调节电阻到达不同的状态

python 解决微分方程的操作(数值解法)

R=0.01,欠阻尼

python 解决微分方程的操作(数值解法)

R=1.7,临界阻尼

python 解决微分方程的操作(数值解法)

R=100,过阻尼

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
按日期打印Python的Tornado框架中的日志的方法
May 02 Python
在Windows系统上搭建Nginx+Python+MySQL环境的教程
Dec 25 Python
python生成式的send()方法(详解)
May 08 Python
Python简单读取json文件功能示例
Nov 30 Python
python+matplotlib演示电偶极子实例代码
Jan 12 Python
50行Python代码实现人脸检测功能
Jan 23 Python
PyTorch线性回归和逻辑回归实战示例
May 22 Python
利用python循环创建多个文件的方法
Oct 25 Python
让你的Python代码实现类型提示功能
Nov 19 Python
Python中实现一行拆多行和多行并一行的示例代码
Sep 06 Python
Python爬虫之App爬虫视频下载的实现
Dec 08 Python
Django模型层实现多表关系创建和多表操作
Jul 21 Python
python 实现体质指数BMI计算
May 26 #Python
Python 如何解决稀疏矩阵运算
Python selenium模拟网页点击爬虫交管12123违章数据
python scipy 稀疏矩阵的使用说明
python中os.path.join()函数实例用法
May 26 #Python
python实现简单的井字棋
May 26 #Python
python 办公自动化——基于pyqt5和openpyxl统计符合要求的名单
You might like
php中限制ip段访问、禁止ip提交表单的代码分享
2014/08/22 PHP
PHP错误处理函数
2016/04/03 PHP
PHP实现支持CURL字符串证书传输的方法
2019/03/23 PHP
PHP 实现 WebSocket 协议原理与应用详解
2020/04/22 PHP
基于jsTree的无限级树JSON数据的转换代码
2010/07/27 Javascript
Knockoutjs的环境搭建教程
2012/11/26 Javascript
一个页面放2段图片滚动代码出现冲突的问题如何解决
2012/12/21 Javascript
js判断浏览器类型的方法
2013/08/07 Javascript
javascript判断网页是关闭还是刷新
2015/09/12 Javascript
全面解析Javascript无限添加QQ好友原理
2016/06/15 Javascript
jQuery simpleModal插件的使用介绍
2016/08/30 Javascript
前端框架Vue.js中Directive知识详解
2016/09/12 Javascript
基于JavaScript实现无限加载瀑布流
2017/07/21 Javascript
VueJs单页应用实现微信网页授权及微信分享功能示例
2017/07/26 Javascript
node中koa中间件机制详解
2017/08/22 Javascript
基于Vue2x实现响应式自适应轮播组件插件VueSliderShow功能
2018/05/16 Javascript
详解微信小程序的 request 封装示例
2018/08/21 Javascript
微信小程序实现音乐播放页面布局
2020/12/11 Javascript
python中stdout输出不缓存的设置方法
2014/05/29 Python
使用Python编写一个简单的tic-tac-toe游戏的教程
2015/04/16 Python
Python连接mysql数据库的正确姿势
2016/02/03 Python
Python格式化日期时间操作示例
2018/06/28 Python
Python 给某个文件名添加时间戳的方法
2018/10/16 Python
python根据文本生成词云图代码实例
2019/11/15 Python
Django filter动态过滤与排序实现过程解析
2020/11/26 Python
美国知名的女性服饰品牌:LOFT(洛芙特)
2016/08/05 全球购物
英国领先的酒杯和水晶玻璃器皿制造商:Dartington Crystal
2019/06/23 全球购物
总务岗位职责
2013/11/19 职场文书
大专毕业自我鉴定
2014/02/04 职场文书
学生喝酒检讨书
2014/02/06 职场文书
七匹狼男装广告词
2014/03/21 职场文书
2014大学生党员评议个人总结
2014/09/22 职场文书
2014收银员工作总结范文
2014/12/16 职场文书
2015年销售内勤工作总结
2015/04/27 职场文书
2016初一新生军训心得体会
2016/01/11 职场文书
导游词之阳朔遇龙河
2019/12/16 职场文书