dccp icon indicating copy to clipboard operation
dccp copied to clipboard

IndexError with sum_smallest

Open nicklar opened this issue 3 years ago • 2 comments

I am having trouble with an index error when using sum smallest. I am on an m1 Mac using cvxpy 1.2.1 and dccp 1.0.4.

If I just use following constraint my problem converges

x = cp.Variable((3, 3), nonneg = True) constr = [cp.sum_smallest(x, 2) <= 1] obj = cp.sum_squares(x) prob = cp.Problem(cp.Minimize(obj), constr) prob.solve(method = 'dccp')

While if swap the constraint to grab ndexes: constr = [cp.sum_smallest(x[0], 2) <= 1]

I get this error.

IndexError Traceback (most recent call last) /Users/nicholaslarson/Documents/code/auc/dls_mix.ipynb Cell 3' in <cell line: 8>() 6 print(prob.is_dpp()) 7 print(dccp.is_dccp(prob)) ----> 8 prob.solve(method = 'dccp')

File ~/miniconda3/envs/dccp_env/lib/python3.9/site-packages/cvxpy/problems/problem.py:481, in Problem.solve(self, *args, **kwargs) 479 else: 480 solve_func = Problem._solve --> 481 return solve_func(self, *args, **kwargs)

File ~/miniconda3/envs/dccp_env/lib/python3.9/site-packages/dccp/problem.py:54, in dccp(self, max_iter, tau, mu, tau_max, solver, ccp_times, max_slack, ep, **kwargs) 50 dccp_ini( 51 self, random=(ccp_times > 1), solver=solver, **kwargs 52 ) # initialization; random initial value is mandatory if ccp_times>1 53 # iterations ---> 54 result_temp = iter_dccp( 55 self, max_iter, tau, mu, tau_max, solver, ep, max_slack, **kwargs 56 ) 57 # first iteration 58 if t == 0:

File ~/miniconda3/envs/dccp_env/lib/python3.9/site-packages/dccp/problem.py:241, in iter_dccp(self, max_iter, tau, mu, tau_max, solver, ep, max_slack_tol, **kwargs) 239 count_slack = 0 240 for arg in self.constraints: --> 241 temp = convexify_constr(arg) 242 if not arg.is_dcp(): 243 while temp is None: 244 # damping File ~/miniconda3/envs/dccp_env/lib/python3.9/site-packages/dccp/constraint.py:66, in convexify_constr(constr) 64 # left hand concave 65 if constr.args[0].curvature == "CONCAVE": ---> 66 left = linearize(constr.args[0]) 67 if left is None: 68 return None

File ~/miniconda3/envs/dccp_env/lib/python3.9/site-packages/dccp/linearize.py:58, in linearize(expr) 54 if tangent is None: 55 raise ValueError( 56 "Cannot linearize non-affine expression with missing variable values." 57 ) ---> 58 grad_map = expr.grad 59 for var in expr.variables(): 60 if grad_map[var] is None:

File ~/miniconda3/envs/dccp_env/lib/python3.9/site-packages/cvxpy/atoms/atom.py:408, in Atom.grad(self) 404 result = {} 405 for idx, arg in enumerate(self.args): 406 # A dictionary of gradients w.r.t. variables 407 # Partial argument / Partial x. --> 408 grad_arg = arg.grad 409 for key in grad_arg: 410 # None indicates gradient is not defined. 411 if grad_arg[key] is None or grad_self[idx] is None:

File ~/miniconda3/envs/dccp_env/lib/python3.9/site-packages/cvxpy/atoms/atom.py:402, in Atom.grad(self) 399 arg_values.append(arg.value) 401 # A list of gradients w.r.t. arguments --> 402 grad_self = self._grad(arg_values) 403 # The Chain rule. 404 result = {}

File ~/miniconda3/envs/dccp_env/lib/python3.9/site-packages/cvxpy/atoms/sum_largest.py:62, in sum_largest._grad(self, values) 60 value = intf.from_2D_to_1D(values[0].flatten().T) 61 indices = np.argsort(-value)[:int(self.k)] ---> 62 D = np.zeros((self.args[0].shape[0]*self.args[0].shape[1], 1)) 63 D[indices] = 1 64 return [sp.csc_matrix(D)]

IndexError: tuple index out of range

Any ideas? Thanks for the help!

Nick

nicklar avatar Jul 13 '22 03:07 nicklar

Hi @nicklar, thanks for reporting the error. It is from the gradient computation, and while we're fixing it, a quick workaround for your case is to write the constraint as follows.

constr = [cp.sum_smallest(cp.reshape(x[0], (3, 1)), 2) <= 1]

xinyueshen avatar Jul 13 '22 03:07 xinyueshen

Thanks for the quick reply and workaround! The workaround has fixed my problem for now!

Really appreciate the help.

nicklar avatar Jul 13 '22 03:07 nicklar