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实现的简单抽奖系统实例
May 22 Python
python中enumerate函数遍历元素用法分析
Mar 11 Python
Python基于matplotlib实现绘制三维图形功能示例
Jan 18 Python
Python实现的FTP通信客户端与服务器端功能示例
Mar 28 Python
Flask框架URL管理操作示例【基于@app.route】
Jul 23 Python
python单线程文件传输的实例(C/S)
Feb 13 Python
python打造爬虫代理池过程解析
Aug 15 Python
pytorch 固定部分参数训练的方法
Aug 17 Python
浅谈python opencv对图像颜色通道进行加减操作溢出
Jun 03 Python
基于opencv实现简单画板功能
Aug 02 Python
python脚本第一行如何写
Aug 30 Python
关于Python字符编码与二进制不得不说的一些事
Oct 04 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实现移除数组中为空或为某值元素的方法
2017/01/07 PHP
php curl操作API接口类完整示例
2019/05/21 PHP
jquery 最简单的属性菜单
2009/10/08 Javascript
jquery select下拉框操作的一些说明
2010/04/02 Javascript
移动节点的jquery代码
2014/01/13 Javascript
javascript实现百度地图鼠标滑动事件显示、隐藏
2015/04/02 Javascript
Jquery全屏相册插件zoomvisualizer具有调节放大与缩小功能
2015/11/02 Javascript
JS实现的表格行鼠标点击高亮效果代码
2015/11/27 Javascript
第一次接触JS require.js模块化工具
2016/04/17 Javascript
举例讲解如何判断JavaScript中对象的类型
2016/04/22 Javascript
JavaScript String 对象常用方法总结
2016/04/28 Javascript
js选择器全面解析
2016/06/27 Javascript
Bootstrap基本插件学习笔记之轮播幻灯片(23)
2016/12/08 Javascript
JavaScript实现的斑马线表格效果【隔行变色】
2017/09/18 Javascript
微信小程序实现的自定义分享功能示例
2019/02/12 Javascript
vue项目打包上传github并制作预览链接(pages)
2019/04/19 Javascript
Vue.js 中制作自定义选择组件的代码附演示demo
2020/02/28 Javascript
vant 时间选择器--开始时间和结束时间实例
2020/11/04 Javascript
[04:26]2014DOTA2国际邀请赛-Newbee顺利进入胜者组决赛 独家专访战神7
2014/07/19 DOTA
Python使用bs4获取58同城城市分类的方法
2015/07/08 Python
python 实现自动远程登陆scp文件实例代码
2017/03/13 Python
pandas.DataFrame选取/排除特定行的方法
2018/07/03 Python
使用k8s部署Django项目的方法步骤
2019/01/14 Python
Python Numpy 实现交换两行和两列的方法
2019/06/26 Python
Python lxml模块的基本使用方法分析
2019/12/21 Python
详解Pandas 处理缺失值指令大全
2020/07/30 Python
django 获取字段最大值,最新的记录操作
2020/08/09 Python
python 利用matplotlib在3D空间中绘制平面的案例
2021/02/06 Python
DJI全球:DJI Global
2021/03/15 全球购物
什么是WEB控件?使用WEB控件有哪些优势?
2012/01/21 面试题
优秀通讯员事迹材料
2014/01/28 职场文书
社区健康教育实施方案
2014/03/18 职场文书
幼师求职自荐信
2014/05/31 职场文书
机电专业毕业生自我鉴定2014
2014/10/04 职场文书
2016中秋晚会开幕词
2016/03/03 职场文书
redis击穿 雪崩 穿透超详细解决方案梳理
2022/03/17 Redis