cvxpy icon indicating copy to clipboard operation
cvxpy copied to clipboard

Support Expressions of size zero

Open lovasoa opened this issue 4 years ago • 10 comments

Describe the bug Adding or substracting a scalar variable to a numpy array raises an error if the array length is zero.

To Reproduce

import cvxpy as cp
import numpy as np

np.array([1,2,3]) + cp.Variable() # works

np.array([]) + cp.Variable() # fails with ValueError: Invalid dimensions (0,).

Expected behavior

np.array([]) + cp.Variable() should return an expression of shape (0,)

Output

/usr/local/lib/python3.7/dist-packages/cvxpy/expressions/expression.py in cast_op(self, other)
     43         """A wrapped binary operator that can handle non-Expression arguments.
     44         """
---> 45         other = self.cast_to_const(other)
     46         return binary_op(self, other)
     47     return cast_op

/usr/local/lib/python3.7/dist-packages/cvxpy/expressions/expression.py in cast_to_const(expr)
    444         """Converts a non-Expression to a Constant.
    445         """
--> 446         return expr if isinstance(expr, Expression) else cvxtypes.constant()(expr)
    447 
    448     @_cast_other

/usr/local/lib/python3.7/dist-packages/cvxpy/expressions/constants/constant.py in __init__(self, value)
     49         self._herm = None
     50         self._eigvals = None
---> 51         super(Constant, self).__init__(intf.shape(self.value))
     52 
     53     def name(self):

/usr/local/lib/python3.7/dist-packages/cvxpy/expressions/leaf.py in __init__(self, shape, value, nonneg, nonpos, complex, imag, symmetric, diag, PSD, NSD, hermitian, boolean, integer, sparsity, pos, neg)
     94         for d in shape:
     95             if not isinstance(d, numbers.Integral) or d <= 0:
---> 96                 raise ValueError("Invalid dimensions %s." % (shape,))
     97         self._shape = tuple(np.int32(d) for d in shape)
     98 

ValueError: Invalid dimensions (0,).

Version

  • OS: linux
  • CVXPY Version: 1.1

Additional context

The current behavior forces the programmer to check if the array may be of length 0 before any addition of substraction of a variable with an array of unknown size.

lovasoa avatar Jun 29 '21 17:06 lovasoa

Unfortunately, we don't have support for zero-dimensional expressions. This is something we'd like to add, but it will probably take some time.

rileyjmurray avatar Jun 29 '21 18:06 rileyjmurray

I'm not sure this is the exact same thing. I am talking about a 1-dimensional array of 0 elements, not a 0-dimensional array (a scalar).

lovasoa avatar Jun 29 '21 20:06 lovasoa

Yes, that's what I was trying to get at, but I used the wrong terminology. We certainly support scalar-valued expressions (expr for which expr.ndim == 0) but we don't support empty expressions (expr for which expr.size == 0).

rileyjmurray avatar Jun 29 '21 22:06 rileyjmurray

I've renamed the issue and changed it to a feature request. This has been brought up in PR #1174 (which has stagnated for now).

rileyjmurray avatar Sep 30 '21 03:09 rileyjmurray

I also just encountered this issue.

@SteveDiamond @rileyjmurray Could we reopen https://github.com/cvxpy/cvxpy/pull/1174?

carlosgmartin avatar Nov 28 '23 00:11 carlosgmartin

@carlosgmartin It's not possible to reopen the PR, but you can start a new one if you want. Many many more changes are needed for this to work though.

SteveDiamond avatar Nov 28 '23 01:11 SteveDiamond

@SteveDiamond Thanks. Do you have an outline of the changes that are needed?

carlosgmartin avatar Nov 28 '23 01:11 carlosgmartin

Not really, it would touch the entire codebase. @phschiele is there a more limited project that could be framed around adding support for dimensions of size 0 to the SciPy backend?

SteveDiamond avatar Nov 28 '23 01:11 SteveDiamond