Search code examples
pythonnumpycvxpy

TypeError in CVXPY: float() argument must be a string or a number, not 'Inequality'


Still playing with CVXPY. This time I get an interesting error. Let us look at this minimal code

import cvxpy as cp
import numpy as np

A = np.random.normal(0, 1, (64,6))
b = np.random.normal(0, 1, (64,1))
theta = cp.Variable(shape = (6,1))

prob = cp.Problem(
    cp.Minimize(cp.max(A*theta -b) <= 5),
    [-10 <= theta, theta <= 10])

Once compiled, I get the following error:

~\Anaconda3\lib\site-packages\cvxpy\expressions\constants\constant.py in init(self, value) 42 self._sparse = True 43 else: ---> 44 self._value = intf.DEFAULT_INTF.const_to_matrix(value) 45 self._sparse = False 46 self._imag = None

~\Anaconda3\lib\site-packages\cvxpy\interface\numpy_interface\ndarray_interface.py in const_to_matrix(self, value, convert_scalars) 48 return result 49 else: ---> 50 return result.astype(numpy.float64) 51 52 # Return an identity matrix.

TypeError: float() argument must be a string or a number, not 'Inequality'


Solution

  • I don't know what you want to model exactly, but here something which works:

    import cvxpy as cp
    import numpy as np
    
    A = np.random.normal(0, 1, (64,6))
    b = np.random.normal(0, 1, (64,1))
    theta = cp.Variable(shape = (6,1))
    
    prob = cp.Problem(
                cp.Minimize(cp.sum(theta)),  # what do you want to minimize?
                [
                    cp.max(A*theta -b) <= 5,
                    -10 <= theta,
                    theta <= 10
                ]
            )
    

    works and should show the problem.

    I would prefer a more clean impl like:

    import cvxpy as cp
    import numpy as np
    
    A = np.random.normal(0, 1, (64,6))
    b = np.random.normal(0, 1, (64,1))
    theta = cp.Variable(shape = (6,1))
    
    obj = cp.Minimize(cp.sum(theta))          # what do you want to minimize?
                                              # feasibility-problem? -> use hardcoded constant: cp.Minimize(0)
    constraints = [
        cp.max(A*theta -b) <= 5,
        -10 <= theta,
        theta <= 10
    ]
    
    prob = cp.Problem(obj, constraints)
    

    The reason: it's easier to read out what's happening exactly.

    Your problem: your objective has a constraint, which is impossible.

    import cvxpy as cp
    import numpy as np
    
    A = np.random.normal(0, 1, (64,6))
    b = np.random.normal(0, 1, (64,1))
    theta = cp.Variable(shape = (6,1))
    
    prob = cp.Problem(
    cp.Minimize(cp.max(A*theta -b) <= 5),  # first argument = objective
                                           # -> minimize (constraint) : impossible!
        [-10 <= theta, theta <= 10])       # second argument = constraints
                                           # -> box-constraints
    

    Shortly speaking:

    • you want to minimize a function
    • you do minimize an inequality

    Towards comment below:

    edit

    obj = cp.Minimize(cp.max(cp.abs(A*theta-b)))
    

    Small check:

    print((A*theta-b).shape)
    (64, 1)
    print((cp.abs(A*theta-b)).shape)
    (64, 1)
    

    Elementwise abs: good

    The final outer max results in a single value, or else cp.Minimize won't accept it. good

    EDIT Or let's make cvxpy and us more happy:

    obj = cp.Minimize(cp.norm(A*theta-b, "inf"))