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实现删除文件与目录的方法
Nov 10 Python
Python中动态检测编码chardet的使用教程
Jul 06 Python
在Python中pandas.DataFrame重置索引名称的实例
Nov 06 Python
python 读取鼠标点击坐标的实例
Dec 29 Python
python调用外部程序的实操步骤
Mar 04 Python
在python中画正态分布图像的实例
Jul 08 Python
Python实现某论坛自动签到功能
Aug 20 Python
Python如何用filter函数筛选数据
Mar 05 Python
Python如何使用bokeh包和geojson数据绘制地图
Mar 21 Python
Django静态资源部署404问题解决方案
May 11 Python
Python基于unittest实现测试用例执行
Nov 25 Python
PyCharm2020.3.2安装超详细教程
Feb 08 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微信支付通知的处理方式
2014/05/25 PHP
详解WordPress中给链接添加查询字符串的方法
2015/12/18 PHP
php 根据URL下载远程图片、压缩包、pdf等文件到本地
2019/07/26 PHP
Javascript延迟执行实现方法(setTimeout)
2010/12/30 Javascript
html5的自定义data-*属性和jquery的data()方法的使用示例
2013/08/21 Javascript
详解JS面向对象编程
2016/01/24 Javascript
Javascript闭包与函数柯里化浅析
2016/06/22 Javascript
js中使用使用原型(prototype)定义方法的好处详解
2016/07/04 Javascript
浅谈在js传递参数中含加号(+)的处理方式
2016/10/11 Javascript
纯js实现手风琴效果代码
2020/04/17 Javascript
整理一下常见的IE错误
2016/11/18 Javascript
jQuery插件FusionCharts绘制ScrollColumn2D图效果示例【附demo源码下载】
2017/03/22 jQuery
JavaWeb表单及时验证功能在输入后立即验证(含用户类型,性别,爱好...的验证)
2017/06/09 Javascript
vue中tab选项卡的实现思路
2018/11/25 Javascript
jQuery实现动态操作table行
2020/11/23 jQuery
Vue+scss白天和夜间模式切换功能的实现方法
2021/01/05 Vue.js
[02:08]什么藏在DOTA2 TI9“小紫本”里?斧王历险记告诉你!
2019/05/17 DOTA
[57:31]DOTA2-DPC中国联赛 正赛 SAG vs CDEC BO3 第一场 2月1日
2021/03/11 DOTA
python实现类似ftp传输文件的网络程序示例
2014/04/08 Python
python在linux中输出带颜色的文字的方法
2014/06/19 Python
Python创建文件和追加文件内容实例
2014/10/21 Python
python面试题之列表声明实例分析
2019/07/08 Python
解决Alexnet训练模型在每个epoch中准确率和loss都会一升一降问题
2020/06/17 Python
Python实现区域填充的示例代码
2021/02/03 Python
html5 的a标签 Href 拨电话的写法
2013/11/04 HTML / CSS
Vans(范斯)德国官网:美国南加州的原创极限运动潮牌
2017/05/02 全球购物
比利时香水网上商店:NOTINO
2018/03/28 全球购物
美国女士内衣在线折扣商店:One Hanes Place
2019/03/24 全球购物
Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?用contains来区分是否有重复的对象。还是都不用
2013/07/30 面试题
学习新党章思想汇报
2014/01/09 职场文书
总经理岗位职责描述
2014/02/08 职场文书
3分钟演讲稿
2014/04/30 职场文书
银行求职信怎么写
2014/05/26 职场文书
实训报告范文大全
2014/11/04 职场文书
婚礼父母致辞
2015/07/28 职场文书
python实现简单的三子棋游戏
2022/04/28 Python