python:求解微分方程的初始条件

Mey*_*ina 5 python numpy scipy differential-equations

我想用初始条件求解这个微分方程:y??+2y?+2y=cos(2x):

  1. y(1)=2,y?(2)=0.5

  2. y?(1)=1,y?(2)=0.8

  3. y(1)=0,y(2)=1

它的代码是:

import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
def dU_dx(U, x):
    return [U[1], -2*U[1] - 2*U[0] + np.cos(2*x)]
U0 = [1,0]
xs = np.linspace(0, 10, 200)
Us = odeint(dU_dx, U0, xs)
ys = Us[:,0]
plt.xlabel("x")
plt.ylabel("y")
plt.title("Damped harmonic oscillator")
plt.plot(xs,ys);
Run Code Online (Sandbox Code Playgroud)

我怎样才能实现它?

Dr.*_*ann 8

您的初始条件不是,因为它们在两个不同的点给出值。这些都是边界条件。

def bc1(u1,u2): return [u1[0]-2.0,u2[1]-0.5]
def bc2(u1,u2): return [u1[1]-1.0,u2[1]-0.8]
def bc3(u1,u2): return [u1[0]-0.0,u2[0]-1.0]
Run Code Online (Sandbox Code Playgroud)

您需要一个 BVP 求解器来解决这些边界值问题。

您可以使用拍摄方法制作自己的求解器,在情况 1 为

def shoot(b): return odeint(dU_dx,[2,b],[1,2])[-1,1]-0.5

b = fsolve(shoot,0) 

T = linspace(1,2,N)
U = odeint(dU_dx,[2,b],T)
Run Code Online (Sandbox Code Playgroud)

或者使用割线方法而不是scipy.optimize.fsolve,因为问题是线性的,这应该收敛于 1,最多 2 步。

或者您可以使用scipy.integrate.solve_bvp求解器(它可能比问题更新?)。您的任务类似于记录的示例。请注意,ODE 函数中的参数顺序会在所有其他求解器中切​​换,即使odeint您可以提供选项tfirst=True

def shoot(b): return odeint(dU_dx,[2,b],[1,2])[-1,1]-0.5

b = fsolve(shoot,0) 

T = linspace(1,2,N)
U = odeint(dU_dx,[2,b],T)
Run Code Online (Sandbox Code Playgroud)

用 生成的解solve_bvp,节点是积分区间的自动生成的细分,它们的密度表明 ODE 在该区域中的“非平坦”程度。 在此处输入图片说明

def dudx(x,u): return [u[1], np.cos(2*x)-2*(u[1]+u[0])]
Run Code Online (Sandbox Code Playgroud)

使用射击方法生成的解使用初始值x=0作为未知参数,然后获得该区间的解轨迹[0,3]

在此处输入图片说明

xplot=np.linspace(1,2,161)
for k,bc in enumerate([bc1,bc2,bc3]):
    res = solve_bvp(dudx, bc, [1.0,2.0], [[0,0],[0,0]], tol=1e-5)
    print res.message
    l,=plt.plot(res.x,res.y[0],'x')
    c = l.get_color()
    plt.plot(xplot, res.sol(xplot)[0],c=c, label="%d."%(k+1))
Run Code Online (Sandbox Code Playgroud)


Ale*_*rRD 0

您可以使用scipy.integrate.ode函数,这与 scipy.integrate.odeint 类似,但允许使用 df/dy 或给定 ODE df/dx 的 jac 参数