ValueError:对象过深,无法在optimize.curve_fit

时间:2018-07-25 14:59:44

标签: python scipy chemistry

我正在尝试建立一个用于化学系统中种群增长和四个变量A,B,C,D衰减的动力学模型。我正在尝试解决以下以矩阵形式附加的方程组:

Matrix form of equations

其中t是时间步长,k1,k2,k3是指数函数中的常数。我想根据这些方程式拟合曲线,以便在给定A,B,C,D人口的情况下求解k1,k2和k3。

为此,我使用了optimize.curve_fit,t是(1000,)数组中的时间步,X是(4,1000)矩阵,其中u和w是两个矩阵:

from scipy import optimize

def func(t,X,k1,k2,k3):

    u = np.array([[1,0,0],
                  [-k1/(k1+k2-k3),k1/(k1+k2-k3),0],
                  [(k1*k3)/((k1+k2-k3)*(k1+k2)),-k1/(k1+k2k3),k1/(k1+k2)],
                  [-k2/(k1+k2),0,k2/(k2+k1)]],dtype=float)

    w = np.array([[np.exp(-t*(k1+k2))],
                 [np.exp(-t*k3)],
                 [1]])

    return X*np.dot(u,w)


X = np.array([A,B,C,D]) # A,B,C,D are (1000,) arrays
# X.shape = (4, 1000)
# t.shape = (1000,)

optimize.curve_fit(func,t,X,method='lm')

运行这段代码时,得到以下输出:

  

ValueError:对象太深,无法放入所需的数组

     

错误:函数调用的结果不是正确的浮点数组。

我在similar帖子中看到,数组的形状很重要,但据我所知它们是正确的。

有人可以建议代码中的问题在哪里,以及我如何才能最好地使用曲线拟合函数来解决k1,k2,k3?

谢谢

1 个答案:

答案 0 :(得分:0)

正如我在评论中提到的那样,您无需将X传递到func上。 @WarrenWeckesser简要解释了原因。因此,func应该是这样的:

def func(t,k1,k2,k3):

    u = np.array([[1,0,0],
                  [-k1/(k1+k2-k3),k1/(k1+k2-k3),0],
                  [(k1*k3)/((k1+k2-k3)*(k1+k2)),-k1/(k1+k2*k3),k1/(k1+k2)],
                  [-k2/(k1+k2),0,k2/(k2+k1)]],dtype=float)

    w = np.array([np.exp(-t*(k1+k2)),
                 np.exp(-t*k3),
                 np.ones_like(t)]) # must match shapes with above 

    return np.dot(u,w).flatten()

末尾的输出被展平,因为否则将产生curve_fit错误。现在我们对其进行测试:

from scipy.optimize import curve_fit
t = np.arange(1000)*0.01
data = func(t, *[0.5, 2, 1])
data +=np.random.normal(size=data.shape)*0.01 # add some noise
po, pcov = curve_fit(func,t, data.flatten(), method='lm') #data must also be flattened
print(po)
#[ 0.50036411  2.00393807  0.99694513]
plt.plot(t, data.reshape(4,-1).T, t, func(t, *po).reshape(4,-1).T)

优化后的值与原始值非常接近,拟合度似乎很好 fit