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)

Commits related to this issue

Most upvoted comments

@phschiele what software did you use to make this graph? Very cool!

image

@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.py would be a good place to house this function.