1

I am trying to solve the classical Least Squares Problem using cvxpy, but I am getting an error due to np.linalg.norm. Any help would be immensely appreciated.

My code is below. As it is, it works. However, if I change cp.sum_squares to np.linalg.norm, it does not work (error message blow).

import cvxpy as cp
import numpy as np

def main(n):
    # Create the data for the least squares problem
    A = np.random.rand(n, n-1)
    b = np.random.rand(n)

    # Introduce the variables
    x = cp.Variable(n-1)

    # Introduce the constraints (no constraints)
    constraints = []

    # Introduce the objective function
    obj = cp.Minimize(cp.sum_squares(A @ x - b))
    
    prob = cp.Problem(obj, constraints)
    prob.solve()

main(4)

Error message:

    "C:\Users\Ovi\Desktop\Python Files\venv\Scripts\python.exe" "C:/Users/Ovi/Desktop/Python Files/Solving Least Squares.py"
C:\Users\Ovi\Desktop\Python Files\venv\lib\site-packages\cvxpy\expressions\expression.py:556: UserWarning: 
This use of ``*`` has resulted in matrix multiplication.
Using ``*`` for matrix multiplication has been deprecated since CVXPY 1.1.
    Use ``*`` for matrix-scalar and vector-scalar multiplication.
    Use ``@`` for matrix-matrix and matrix-vector multiplication.
    Use ``multiply`` for elementwise multiplication.
This code path has been hit 1 times so far.

  warnings.warn(msg, UserWarning)
AttributeError: 'MulExpression' object has no attribute 'sqrt'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\Ovi\Desktop\Python Files\Solving Least Squares.py", line 22, in <module>
    main(4)
  File "C:\Users\Ovi\Desktop\Python Files\Solving Least Squares.py", line 17, in main
    obj = cp.Minimize(np.linalg.norm(A @ x - b))
  File "<__array_function__ internals>", line 5, in norm
  File "C:\Users\Ovi\AppData\Local\Programs\Python\Python39\lib\site-packages\numpy\linalg\linalg.py", line 2530, in norm
    ret = sqrt(sqnorm)
TypeError: loop of ufunc does not support argument 0 of type MulExpression which has no callable sqrt method

Process finished with exit code 1
user56202
  • 299
  • 1
  • 9
  • 1
    Well why would it work? `np.linalg.norm` does not implement methods called internally by CVXPY, so there's no reason it should. Always use cvxpy functions in your objectives, or basic overriden operations like +, *, @, etc. – Literal Jun 01 '21 at 16:16
  • 1
    @Literal Since cvxpy is compatible with numpy, I thought that we could put any numpy functions inside cp.Minimize( ). It did not even cross my mind that this is not possible. But now I know better, thank you very much! – user56202 Jun 01 '21 at 16:25
  • `np.linalg.norm` is Python code which you can read. It first does `x = asarray(x)`, trying to turn the argument, in your case `A@x-b` into a numeric numpy array. Then it does `np.sqrt(np.dot(x,x))`. I don't know anything about `cvxpy`, but I suspect the `cp.Variable` creates a `MulExpression` which can't be evaluated this way. – hpaulj Jun 01 '21 at 19:43
  • @hpaulj If I understood you correctly, `cvxpy` converts `A@x-b` into a format which `np.linalg.norm()` cannot work with. But since the numpy function is the first thing wrapped around `A@x-b`, shouldn't it take action before `cvxpy` has a chance to do anything? – user56202 Jun 01 '21 at 19:49
  • I don't think it's even getting to the `cp.Minimize`. The problem is with passing the `A@x-b` to `norm`. What does `A@x-b` even look like, better yet `np.asarray(A@x-b)`. I've seen similar problems when people try to use `sympy` expressions in `numpy` functions. `numpy` doesn't "know" anything about `cvxpy`. – hpaulj Jun 01 '21 at 20:07

0 Answers0