diff --git a/cvxpy/atoms/sign.py b/cvxpy/atoms/sign.py index d16cb5eca0..51160ddc30 100644 --- a/cvxpy/atoms/sign.py +++ b/cvxpy/atoms/sign.py @@ -56,12 +56,12 @@ def is_atom_concave(self) -> bool: def is_atom_quasiconvex(self) -> bool: """Is the atom quasiconvex? """ - return True + return self.args[0].is_scalar() def is_atom_quasiconcave(self) -> bool: """Is the atom quasiconvex? """ - return True + return self.args[0].is_scalar() def is_incr(self, idx) -> bool: """Is the composition non-decreasing in argument idx? diff --git a/cvxpy/tests/test_dqcp.py b/cvxpy/tests/test_dqcp.py index 90e446a757..5a694b9409 100644 --- a/cvxpy/tests/test_dqcp.py +++ b/cvxpy/tests/test_dqcp.py @@ -429,6 +429,14 @@ def test_sign(self) -> None: cp.sign(variable).value self.assertItemsAlmostEqual(value, variable.value) + # sign is only QCP for univariate input. + # See issue #1828 + x = cp.Variable(2) + obj = cp.sum_squares(np.ones(2) - x) + constr = [cp.sum(cp.sign(x)) <= 1] + prob = cp.Problem(cp.Minimize(obj), constr) + assert not prob.is_dqcp() + def test_dist_ratio(self) -> None: x = cp.Variable(2) a = np.ones(2)