Search code examples
python-3.xscipyminimizationscipy-optimizescipy-optimize-minimize

TypeError with scipy.optimize when minimizing Cost func


I want to optimize 9 variables in W((1×9)matrix) by using scipy.optimize.

from scipy.optimize import minimize

def func(W):
    W = W.reshape(1,9) #(1,9)
    Y = df0.values.reshape(49,1) #(49,1)
    X = df1.values.reshape(49,1) #(49,9)
    Z = np.dot(X, W.T) #(49, 1)
    Z = np.abs(Z - Y) #(49, 1)
    Cost = np.sum(Z ,axis=0, keepdims=True)
    return Cost[0][0]  #float

W = np.array([2,3,4,5,6,7,8,9,10])
cons = ({'type': 'ineq', 'fun': W[1]-W[0]})

result = minimize(func, x0=W0, constraints=cons, method="SLSQP")

But I get a TypeError like this

'numpy.int32' object is not callable

I changed the 'cons' to

def cons(W):
    return W

cons = (
    {'type': 'ineq', 'fun': cons}
)

Then it worked fine and I got a result

     fun: 125.4977648197736
     jac: array([26.3666687 , 39.73333454, 46.56666756, 32.76666737, 38.23333454,
       25.20000076,  9.        ,  5.        ,  5.76666737])
 message: 'Optimization terminated successfully.'
    nfev: 332
     nit: 24
    njev: 24
  status: 0
 success: True
       x: array([7.36486798e-03, 8.29918593e-03, 9.61602518e-02, 9.17950729e-03,
       2.98795999e-12, 3.73831662e-12, 3.59100171e-12, 4.73656828e-01,
       1.77345002e+00])

I can't reach out to a good solution.


Solution

  • It is due to the fact, that scipy's minimize needs an actual function (not output of it) to minimize properly. See this question. Your above code works, because you pass function reference to the callable one (cons, not cons(W)). You can try creating a lambda function for it, for example:

    cons = ({'type': 'ineq', 'fun': lambda *args: W[1]-W[0]})