如何使用python计算常微分方程?常用形式
odeint(func, y0, t,args,Dfun)
一般这种形式就够用了 。
下面是官方的例子 , 求解的是
D(D(y1))-t*y1=0
为了方便,采取D=d/dt 。如果我们令初值
y1(0) = 1.0/3**(2.0/3.0)/gamma(2.0/3.0)
D(y1)(0) = -1.0/3**(1.0/3.0)/gamma(1.0/3.0)
这个微分方程的解y1=airy(t) 。
令D(y1)=y0,就有这个常微分方程组 。
D(y0)=t*y1
D(y1)=y0
Python求解该微分方程 。
from scipy.integrate import odeint
from scipy.special import gamma, airy
y1_0 = 1.0/3**(2.0/3.0)/gamma(2.0/3.0)
y0_0 = -1.0/3**(1.0/3.0)/gamma(1.0/3.0)
y0 = [y0_0, y1_0]
def func(y, t):
...return [t*y[1],y[0]]
def gradient(y,t):
...return [[0,t],[1,0]]
x = arange(0,4.0, 0.01)
t = x
ychk = airy(x)[0]
y = odeint(func, y0, t)
y2 = odeint(func, y0, t, Dfun=gradient)
print ychk[:36:6]
[ 0.3550280.3395110.3240680.3087630.2936580.278806]
print y[:36:6,1]
[ 0.3550280.3395110.3240670.3087630.2936580.278806]
print y2[:36:6,1]
[ 0.3550280.3395110.3240670.3087630.2936580.278806]
得到的解与精确值相比,误差相当小 。
=======================================================================================================
args是额外的参数 。
用法请参看下面的例子 。这是一个洛仑兹曲线的求解,并且用matplotlib绘出空间曲线图 。(来自《python科学计算》)
from scipy.integrate import odeint
import numpy as np
def lorenz(w, t, p, r, b):
# 给出位置矢量w , 和三个参数p, r, b 计算出
# dx/dt, dy/dt, dz/dt 的值
x, y, z = w
# 直接与lorenz 的计算公式对应
return np.array([p*(y-x), x*(r-z)-y, x*y-b*z])
t = np.arange(0, 30, 0.01) # 创建时间点
# 调用ode 对lorenz 进行求解, 用两个不同的初始值
track1 = odeint(lorenz, (0.0, 1.00, 0.0), t, args=(10.0, 28.0, 3.0))
track2 = odeint(lorenz, (0.0, 1.01, 0.0), t, args=(10.0, 28.0, 3.0))
# 绘图
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
fig = plt.figure()
ax = Axes3D(fig)
ax.plot(track1[:,0], track1[:,1], track1[:,2])
ax.plot(track2[:,0], track2[:,1], track2[:,2])
plt.show()
===========================================================================
scipy.integrate.odeint(func, y0, t, args=(), Dfun=None, col_deriv=0, full_output=0, ml=None, mu=None, rtol=None, atol=None, tcrit=None, h0=0.0, hmax=0.0, hmin=0.0, ixpr=0, mxstep=0, mxhnil=0, mxordn=12, mxords=5, printmessg=0)
计算常微分方程(组)
使用 FORTRAN库odepack中的lsoda解常微分方程 。这个函数一般求解初值问题 。
参数:
func : callable(y, t0, ...)计算y在t0 处的导数 。
y0 : 数组y的初值条件(可以是矢量)
t : 数组为求出y,这是一个时间点的序列 。初值点应该是这个序列的第一个元素 。
args : 元组func的额外参数
Dfun : callable(y, t0, ...)函数的梯度(Jacobian) 。即雅可比多项式 。
col_deriv : boolean.True,Dfun定义列向导数(更快),否则Dfun会定义横排导数
full_output : boolean可选输出,如果为True 则返回一个字典 , 作为第二输出 。
printmessg : boolean是否打印convergence 消息 。
返回: y : array, shape (len(y0), len(t))
数组 , 包含y值,每一个对应于时间序列中的t 。初值y0 在第一排 。
infodict : 字典,只有full_output == True 时,才会返回 。
字典包含额为的输出信息 。
键值:
‘hu’vector of step sizes successfully used for each time step.
‘tcur’ vector with the value of t reached for each time step. (will always be at least as large as the input times).
推荐阅读
- 电脑照片合照怎么操作,电脑上合成照片
- js实现点击按钮,js实现点击按钮的方法
- linux代码库打包命令,linux常用命令打包
- mysql怎么获取年 mysql 获取年
- 最好的ChatGPT,最好的茶台
- 怎样申请发布文章的公众号,怎么申请公众号发文章
- 吉林小程序商城代理平台,吉林小程序开发
- 用户控件vb.net 用户控件和窗体的区别
- 石材店如何营销,石材的销售渠道方案