简体   繁体   English

用迭代参数求解微分方程

[英]solve differential equation with iterated parameter

I'm lerning to solve Differential equation using (scipy.integrate.odeint) and (scipy.integrate.ode).我正在学习使用 (scipy.integrate.odeint) 和 (scipy.integrate.ode) 来求解微分方程。 I have a simple example:我有一个简单的例子:

dy/dt=f[i]*t

and f is parameter corresponding to t[i], same like the example in code ; f为t[i]对应的参数,同代码示例; ie IE

t[0]=0.0, f[0]=0.0

t[1]=0.1, f[1]=0.1

... ...

t[10]=1.0, f[1]=1.0

the manually result should be:手动结果应该是:

y=1/2*f[i]*t**2 , because the initial value of y is zero y=1/2*f[i]*t**2 ,因为y的初始值为零

then, numerical result of y should be [0.0, 0.0005, 0.004, 0.0135, 0.032, 0.0625, 0.108, 0.1715, 0.256, 0.3645, 0.5] .那么,y 的数值结果应该是[0.0, 0.0005, 0.004, 0.0135, 0.032, 0.0625, 0.108, 0.1715, 0.256, 0.3645, 0.5] But when i use scipy.integrate.ode, i have got a different result.但是当我使用 scipy.integrate.ode 时,我得到了不同的结果。 My question is: 1. Have i used ode wrong?我的问题是: 1. 我用错了吗? How can i reduce the errors?我怎样才能减少错误? 2. Can i use odeint or other method to solve this problem? 2.我可以使用odeint或其他方法来解决这个问题吗?

The code is like:代码是这样的:

import matplotlib.pyplot as pl
import numpy as np
import sympy as sp
from scipy.integrate import odeint
from scipy.integrate import ode
import numpy as np

def func(t, y, f):
    return f*t

t=np.linspace(0.0, 1.0, 11)
f=np.linspace(0.0, 1.0, 11)
dt = t[1]-t[0]

sol= np.empty_like(t)
r = ode(func).set_integrator("dopri5")
r.set_initial_value(0, 0).set_f_params(f[0])

# result of ode
for i in xrange(len(t)):
    r.set_f_params(f[i])
    r.integrate(r.t+dt)
    sol[i] = r.y

res=[]
# result of t**3/3
for a in np.linspace(0.0, 1, 11):
    f=(a**3)/3
    print f
    res.append(f)

# result3
res2=[]
for n in range(0, 11):
    dt=0.1
    y= t[n]**3/3 - dt*t[n]**2/4 - dt**2*t[n]/12
    res2.append(y)

pl.plot(sol)
pl.plot(res)  
pl.plot(res2)
pl.show()

I have extend this example to 2-dimensional-differential equations:我已将此示例扩展到二维微分方程:

du/dt=-u(vf[i])

dv/dt=v(f[i]-u)

with initial values: u(0)=v(0)=1.初始值:u(0)=v(0)=1。 And below is the code:下面是代码:

import matplotlib.pyplot as pl
import numpy as np
import sympy as sp
from scipy.integrate import odeint
from scipy.integrate import ode
from numpy import array

def func(t, y, f):
    u,v=y
    dotu=-u*(v-f)
    dotv=v*(f-u)
    return array([dotu, dotv])

t=np.linspace(0.0, 10, 11)
f=np.linspace(0.0, 20, 11)

dt = t[1]-t[0]

# result correct
y0=array([1.0, 1.0])
sol= np.empty([11, 2])

sol[0] = array([1.0, 1.0])
r = ode(func).set_integrator("dopri5")
r.set_initial_value(t[0], sol[0]).set_f_params(f[0])

for i in range(len(t)-1):
    r.set_f_params(f[i])
    r.integrate(r.t+dt)
    sol[i+1] = r.y

pl.plot(sol[:,0])

But i get a error message:但我收到一条错误消息:

Traceback (most recent call last): File "C:\\Users\\odeint test.py", line 26, in <module> sol[0] = array([1.0, 1.0]) ValueError: setting an array element with a sequence.

What you are doing is closer to integrating y'(t)=t^2, y(0)=0, resulting in y(t)=t^3/3.你正在做的更接近于整合 y'(t)=t^2, y(0)=0,导致 y(t)=t^3/3。 That you factor t^2 as f*t and hack f into a step function version of t only adds a small perturbation to that.您将 t^2 分解为 f*t 并将 f 转换为 t 的阶跃函数版本只会增加一个小的扰动。


The integral of t[i]*t over t[i]..t[i+1] is t[i]*tt[i]..t[i+1]上的积分是

y[i+1]-y[i] = t[i]/2*(t[i+1]^2-t[i]^2) 
= (t[i+1]^3-t[i]^3)/3 - (t[i+1]-t[i])^2*(t[i]+2t[i+1])/6
= (t[i+1]^3-t[i]^3)/3 - dt*(t[i+1]^2-t[i]^2)/4 - dt^2*(t[i+1]-t[i])/12

which sums up to about总结起来大约

y[n] = t[n]^3/3 - dt*t[n]^2/4 - dt^2*t[n]/12

How to get the correct solution如何获得正确的解决方案

sol= np.empty_like(t)

set the initial value设置初始值

sol[0] = 0
r = ode(func).set_integrator("dopri5")

use the initial point as initial point, both to make explicit that the point at index 0 is fixed and "used up"使用初始点作为初始点,两者都明确表示索引0处的点是固定的并且“用完”

r.set_initial_value(sol[0],t[0]).set_f_params(f[0])

# result of ode

go from point at t[i] to point at t[i+1] .t[i]点到t[i+1] Ends with i+1=len(t) or i=len(t)-1i+1=len(t)i=len(t)-1结尾

for i in xrange(len(t)-1):
    r.set_f_params(f[i])
    r.integrate(r.t+dt)

value at t[i]+dt is value at t[i+1] t[i]+dt处的值是t[i+1]

    sol[i+1] = r.y

With these changes the numerical solution coincides with the manually computed solution.通过这些更改,数值解与手动计算的解一致。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM