cvxpy
cvxpy copied to clipboard
Support Expressions of size zero
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.
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.
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).
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).
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).
I also just encountered this issue.
@SteveDiamond @rileyjmurray Could we reopen https://github.com/cvxpy/cvxpy/pull/1174?
@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 Thanks. Do you have an outline of the changes that are needed?
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?