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 相关文章推荐
Python3指定路径寻找符合匹配模式文件
May 22 Python
Python数据分析之双色球中蓝红球分析统计示例
Feb 03 Python
Python实现的序列化和反序列化二叉树算法示例
Mar 02 Python
pytorch索引查找 index_select的例子
Aug 18 Python
Python Django 添加首页尾页上一页下一页代码实例
Aug 21 Python
python django生成迁移文件的实例
Aug 31 Python
Python使用grequests(gevent+requests)并发发送请求过程解析
Sep 25 Python
python中对_init_的理解及实例解析
Oct 11 Python
Python搭建代理IP池实现接口设置与整体调度
Oct 27 Python
Python 面向对象部分知识点小结
Mar 09 Python
详解Python中import机制
Sep 11 Python
Python带你从浅入深探究Tuple(基础篇)
May 15 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 addslashes及其他清除空格的方法是不安全的
2012/01/25 PHP
PHP查询网站的PR值
2013/10/30 PHP
Drupal读取Excel并导入数据库实例
2014/03/02 PHP
php中错误处理操作实例分析
2019/08/23 PHP
javascript prototype 原型链
2009/03/12 Javascript
jquery 学习笔记 传智博客佟老师附详细注释
2020/09/12 Javascript
jQuery中add实现同时选择两个id对象
2010/10/22 Javascript
浏览器窗口大小变化时使用resize事件对框架不起作用的解决方法
2014/05/11 Javascript
jquery中EasyUI实现异步树
2015/03/01 Javascript
Javascript中的arguments与重载介绍
2015/03/15 Javascript
基于jQuery和CSS3制作数字时钟附源码下载(jquery篇)
2015/11/24 Javascript
[原创]JQuery 在表单提交之前修改 提交的值
2016/04/14 Javascript
jQuery操作之效果详解
2017/05/19 jQuery
nodejs实现简单的gulp打包
2017/12/21 NodeJs
JavaScript数组,JSON对象实现动态添加、修改、删除功能示例
2018/05/26 Javascript
使用json-server简单完成CRUD模拟后台数据的方法
2018/07/12 Javascript
详解easyui基于 layui.laydate日期扩展组件
2018/07/18 Javascript
在 Vue 应用中使用 Netlify 表单功能的方法详解
2019/06/03 Javascript
vue实现移动端项目多行文本溢出省略
2020/07/29 Javascript
教你用python3根据关键词爬取百度百科的内容
2016/08/18 Python
Django框架教程之正则表达式URL误区详解
2018/01/28 Python
用Cython加速Python到“起飞”(推荐)
2019/08/01 Python
Python3 解决读取中文文件txt编码的问题
2019/12/20 Python
python批量处理txt文件的实例代码
2020/01/13 Python
Python Scrapy框架第一个入门程序示例
2020/02/05 Python
基于Python计算圆周率pi代码实例
2020/03/25 Python
Python实现PS滤镜中的USM锐化效果
2020/12/04 Python
PyChon中关于Jekins的详细安装(推荐)
2020/12/28 Python
草莓网官网:StrawberryNET
2019/08/21 全球购物
网吧消防安全制度
2014/01/28 职场文书
征婚广告词
2014/03/17 职场文书
党在我心中的演讲稿
2014/09/13 职场文书
党的群众路线教育实践活动个人整改措施范文
2014/11/04 职场文书
狮子林导游词
2015/02/03 职场文书
2015年行政人事部工作总结
2015/05/13 职场文书
Python进阶学习之带你探寻Python类的鼻祖-元类
2021/05/08 Python