cvxpy: cp.sum is inconsistent with np.ndarray
Describe the bug
cp.sum does not apply consistently when the input is a numpy array.
Specifically, if the array is composed of constant values, cp.sum works fine.
Otherwise, it crashes.
I realize that I can wrap the numpy array with an hstack or a vstack but doing so entails heavy performance penalties (upto x3 time).
To Reproduce
cp.sum(npasarray([1,2,3,cp.Variable(),4,5]))
Expected behavior
I think that either cp.sum should not accept numpy arrays or it should forward calls to np.ndarray.sum which also accepts axis and keepdims parameters.
Output
Python 3.7.10 (default, Jun 4 2021, 14:48:32)
[GCC 7.5.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cvxpy as cp
>>> import numpy as np
>>> cp.sum(np.asarray([1,2,3,cp.Variable(),4,5]))
TypeError: float() argument must be a string or a number, not 'Variable'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/michael/opt/miniconda3/envs/roomassignments/lib/python3.7/site-packages/cvxpy/atoms/affine/sum.py", line 114, in sum
return Sum(expr, axis, keepdims)
File "/home/michael/opt/miniconda3/envs/roomassignments/lib/python3.7/site-packages/cvxpy/atoms/affine/sum.py", line 43, in __init__
super(Sum, self).__init__(expr, axis=axis, keepdims=keepdims)
File "/home/michael/opt/miniconda3/envs/roomassignments/lib/python3.7/site-packages/cvxpy/atoms/axis_atom.py", line 36, in __init__
super(AxisAtom, self).__init__(expr)
File "/home/michael/opt/miniconda3/envs/roomassignments/lib/python3.7/site-packages/cvxpy/atoms/atom.py", line 49, in __init__
self.args = [Atom.cast_to_const(arg) for arg in args]
File "/home/michael/opt/miniconda3/envs/roomassignments/lib/python3.7/site-packages/cvxpy/atoms/atom.py", line 49, in <listcomp>
self.args = [Atom.cast_to_const(arg) for arg in args]
File "/home/michael/opt/miniconda3/envs/roomassignments/lib/python3.7/site-packages/cvxpy/expressions/expression.py", line 472, in cast_to_const
return expr if isinstance(expr, Expression) else cvxtypes.constant()(expr)
File "/home/michael/opt/miniconda3/envs/roomassignments/lib/python3.7/site-packages/cvxpy/expressions/constants/constant.py", line 48, in __init__
self._value = intf.DEFAULT_INTF.const_to_matrix(value)
File "/home/michael/opt/miniconda3/envs/roomassignments/lib/python3.7/site-packages/cvxpy/interface/numpy_interface/ndarray_interface.py", line 53, in const_to_matrix
return result.astype(numpy.float64)
ValueError: setting an array element with a sequence.
Version
- OS: Ubuntu 20.04.3
- CVXPY Version: 1.1.17
Additional context
Possible untested fix (in atoms/affine/sum.py):
@wraps(Sum)
def sum(expr, axis: Optional[int] = None, keepdims: bool = False):
"""Wrapper for Sum class.
"""
if isinstance(expr, list):
return __builtins__['sum'](expr)
elif isinstance(expr, np.ndarray):
return expr.sum(axis=axis, keepdims=keepdims)
else:
return Sum(expr, axis, keepdims)
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 17 (7 by maintainers)
@adishavit it’s called snakeviz
Definitely, it’s a very welcome improvement!
I don’t see a big downside to changing it. If the maintainers agree, a PR would be most welcome. Perhaps
utilities/shape.pywould be a good place to house this function.