I have a relatively simple optimisation problem, but am not particularly well-versed in scipy and cannot figure out how to apply the necessary constraints. My objective function is to minimise the absolute distance between a 10-element vector y and x, where x is a weighted row-sum of the 10x3 parameter matrix p
x = p[:,0] + 2 * p[:,1] + 3 * p[:,2]
I need to add the following constraints to the parameter matrix p:
- Each element of p, but be >=0 and <=1
- The sum of each column of p must sum to 1
- The sum of each row of p must not exceed 1
I have attempted to implement constraints based on other SO questions, although I confess I don't fully understand it, nor the errors it generates.
# import packages
import numpy as np
from scipy.optimize import minimize
# create objective function
def objective(p, y):
x = p[:,0] + 2*p[:,1] + 3*p[:,2]
return np.sum(np.abs(y-x))
# define constraints
cons = [{'type':'ineq', 'fun': lambda x: x},
{'type':'ineq', 'fun': lambda x: np.sum(x, 0)}, # row sum >= 0
{'type':'ineq', 'fun': lambda x: 1 - np.sum(x, 0)}, # row sum <= 1
{'type':'ineq', 'fun': lambda x: np.sum(x, 1) - 1}, # row sum >= 1
{'type':'ineq', 'fun': lambda x: 1 - np.sum(x, 1)}] # row sum <= 1
# generate target data (y)
y = np.array([2.48, 1.75, 1.13, 0.20, 0.20, 0.20, 0.0, 0.0, 0.0, 0.0])
# initialise starting param values
p0 = np.zeros((44,3))
p0[:,:] = 1/44
# solve
sol = minimize(objective, p0, method='SLSQP', constraints=cons)
Upon running this code, I get the following error message:
AxisError: axis 1 is out of bounds for array of dimension 1
Any help is much appreciated.