ValueError: object too deep for desired array in optimize.curve_fit

北战南征 提交于 2019-12-11 08:13:28

问题


I am trying to fit a kinetic model for population growth and decay of four variables A,B,C,D in a chemical system. I am trying to solve the following set of equations, which I have attached in matrix form:

Matrix form of equations

where t is a time step and k1,k2,k3 are constants in an exponential function. I want to fit curves based on these equations to solve for k1,k2, and k3 given my populations of A,B,C,D.

For this I am using optimize.curve_fit, t is the time step in a (1000,) array, X is a (4,1000) matrix and where u and w are the two matrices:

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')

When I run this piece of code, I get the following output:

ValueError: object too deep for desired array

error: Result from function call is not a proper array of floats.

I have seen in a similar post that the shapes of the arrays in important, but as far as I can tell these are correct.

Could anyone suggest where the problem may be in this code and how I can best go about solving for k1,k2,k3 using the curve fit function?

Thanks


回答1:


As I mentioned in my comment, you don't need to pass X onto func. @WarrenWeckesser briefly explains why. So here is how func should be:

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()

The output at the end is flattened because otherwise it would give an error with curve_fit. Now we test it:

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)

The optimised values are pretty close to the original ones and the fit seems good



来源:https://stackoverflow.com/questions/51522103/valueerror-object-too-deep-for-desired-array-in-optimize-curve-fit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!