Search code examples
pythonscipyscipy-optimizeindex-errorscipy-optimize-minimize

"IndexError: too many indices for array" when trying to use scipy.optimize.minimize


I want to use Scipy minimize function to find the optimal values that achieve the minimum error function. I used scipy.optimize.minimize, which requires me to specify the rubber and lower bound and any constraint to be passed to the minimization function. I wanted to add an inequality constraint such that A*x < b, so here is my code:

from scipy.optimize import minimize, LinearConstraint
import numpy as np

def error_func(theta):
  return theta[0] - theta[1]

theta0 = [100, 0]
A = np.array([[1, 0], [0, 1]])
b = np.array([[100], [0]])
bnds = ((0, 100), (0, 0))

constraint = LinearConstraint(A, lb=-np.inf, ub=b)
theta = minimize(error_func, theta0, method='trust-constr',constraints=constraint, bounds=bnds, options={'maxiter': 500})

But, when I run the code, I receive the following error on the optimization function line:

/usr/local/lib/python3.7/dist-packages/scipy/optimize/_constraints.py in __init__(self, constraint, x0, sparse_jacobian, finite_diff_bounds)
    259         mask = keep_feasible & (lb != ub)
    260         f0 = fun.f
--> 261         if np.any(f0[mask] < lb[mask]) or np.any(f0[mask] > ub[mask]):
    262             raise ValueError("`x0` is infeasible with respect to some "
    263                              "inequality constraint with `keep_feasible` "

IndexError: too many indices for array: array is 1-dimensional, but 2 were indexed

So can anyone please explain why I receive such an error? what I'm doing wrong here?


Solution

  • I just figured out the solution. The constraint I added will find a solution such that A*x <= b. Therefore, there will be a comparison between A*x and b. The output of the comparison is of shape (2,2) (I don't understand why although the shape of the matrix multiplication is (2,1) and so is b). Long story short, the minimization function expects the return of the constraint comparison to being a list containing two values as same as I defined initial theta. Therefore, I needed to change my constraint function such that it returns the same shape as the initial theta. Here is the correct code:

    from scipy.optimize import minimize, NonlinearConstraint
    import numpy as np
    
    def error_func(theta):
      return theta[0] - theta[1]
    
    theta0 = [100, 0]
    A = np.array([[1, 0], [0, 1]])
    b = [100, 0]
    bnds = ((0, 100), (0, 0))
    func = lambda x: A.dot(x).tolist()
    constraint = NonlinearConstraint(func, -np.inf, b)
    theta = minimize(error_func, theta0, method='trust-constr',constraints=constraint, bounds=bnds, options={'maxiter': 500})