在Python

时间:2016-09-02 10:28:37

标签: python numpy scipy odeint

我想以矩阵形式为两组变量(即{y}和{m})求解一个耦合的ODE系统,其形式如下:

  

y'_n =((m_n)** 2)* y_n +(C * y)_n,m'_n = -4 * m_n * y_n

其中C是矩阵[2 1, -1 3]

另一方面,我想解决这些方程:

  

y'1 = m1 ** 2 * y1 + 2 * y1 + y2
   y'2 = m2 ** 2 * y2-y1 + 3 * y3
   m'1 = -4 * m1 * y1,
  m'2 = -4 * m2 * y2
   Y1(0)= Y2(0)= - 15。并且m1(0)= m2(0)= 0.01

最终能够通过矩阵形式绘制ys和ms与时间的关系。我写了以下程序:

import numpy as np
from pylab import plot,show
from scipy.integrate import odeint

C=np.array([[2,1],[-1,3]])
dt=0.001
def dy_dt(Y,time):
 y,m=Y
 m=m+dt*(-4.*m*y)
 dy=m**2*y+np.dot(C,y)
 return dy

m_init=np.ones(2)*0.01
y_init=np.ones(2)*-15.
time=np.linspace(0,4,1/dt)
y0=np.hstack((y_init, m_init))
y_tot=odeint(dy_dt,y0,time)



plot(time,y_tot[0])#y_1
plot(time,y_tot[1])#y_2
plot(time,y_tot[2])#m_1
plot(time,y_tot[3])#m_2
show()

但是我遇到了以下错误:

 y,m=Y   
 ValueError: too many values to unpack 

任何人都可以帮助我!

2 个答案:

答案 0 :(得分:1)

看看这个,了解发生了什么:

# we have a collection of different containers, namely list, tuple, set & dictionary
master = [[1, 2], (1, 2), {1, 2}, {1: 'a', 2: 'b'}]

for container in master:
    a, b = container  # python will automatically try to unpack the container to supply a & b with values
    print(a, b)  # all print: 1 2 since a = 1 and b = 2 after the unpacking

如果我的容器的值多于我想要提供的变量,我会得到“解压的值太多”错误,例如:

container = [1, 2, 3]
a, b = container  # this raises an error, the value 3 has nowhere to go
然而,你可以通过以下方式说“将所有其余部分转储到b”:

a, *b = container 
print(a, b)  # -> 1 [2, 3] so a = 1 and b = [2, 3]

回到你的意思,当你说:y, m = Y时,你必须确保Y是一个只有2个对象的容器,而这似乎并非如此。最后,正如我在评论中所说,您似乎无法在任何地方调用您的函数dy_dt

答案 1 :(得分:0)

odeint适用于一维数组。在您的函数dy_dt中,Y将作为一维numpy数组传入,长度为4.要将其拆分为ym,您可以编写

y = Y[:2]
m = Y[2:]

函数dy_dt还必须返回长度为4的序列,包含[y [0]',y [1]',m [0]',m [1]'](即这四个数量)。看起来您的函数目前只返回dy中的两个数量,因此您也必须修复它。

这一行

m=m+dt*(-4.*m*y)

看起来像欧拉的方法一样可疑。这不是你想要的。根据你在问题中写的内容,你可以写:

dm = -4. * m * y

然后你可以返回np.hstack((dy, dm))

总而言之,您可以这样写dy_dt

def dy_dt(Y, time):
    y = Y[:2]
    m = Y[2:]
    dy = m**2 * y + np.dot(C, y)
    dm = -4 * m * y
    return np.hstack((dy, dm))  # or:  return [dy[0], dy[1], dm[0], dm[1]]