cvxpy icon indicating copy to clipboard operation
cvxpy copied to clipboard

Sparse contradict converts to dense (`quad_form`, `sparse_cholesky`)

Open deasmhumhna opened this issue 10 months ago • 2 comments

Describe the bug CVXPY always converts a large, sparse PSD matrix (by construction) to a dense array. I identified the problem with sparsity checking code. It checks if a wrapped Expression

To Reproduce

import scipy as sp
from cvxpy.atoms.affine.wraps import psd_wrap
from cvxpy.utilities.linalg import sparse_cholesky, spar
from cvxpy.expressions.expression import Expression

M = sp.sparse.diags(np.ones(10))
wrapped_M = Expression.cast_to_const(M) # as in first line of quad_form
type(wrapped_M) # <class 'cvxpy.expressions.constants.constant.Constant'>, not spmatrix
sign, L, p = sparse_cholesky(wrapped_M) # fails
sign, L, p = sparse_cholesky(psd_wrap(wrapped_M)) # assume_PSD = True, fails

Expected behavior Identifies sparse matrices, Performs sparse cholesky

Output

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
[<ipython-input-58-4708dd35074b>](https://localhost:8080/#) in <cell line: 0>()
      7 wrapped_M = Expression.cast_to_const(M) # as in first line of quad_form
      8 type(wrapped_M) # <class 'cvxpy.expressions.constants.constant.Constant'>, not spmatrix
----> 9 sign, L, p = sparse_cholesky(wrapped_M) # fails
     10 sign, L, p = sparse_cholesky(psd_wrap(wrapped_M)) # assume_PSD = True, fails

[/usr/local/lib/python3.11/dist-packages/cvxpy/utilities/linalg.py](https://localhost:8080/#) in sparse_cholesky(A, sym_tol, assume_posdef)
    207 
    208     if not isinstance(A, spar.spmatrix):
--> 209         raise ValueError(SparseCholeskyMessages.NOT_SPARSE)
    210     if np.iscomplexobj(A):
    211         raise ValueError(SparseCholeskyMessages.NOT_REAL)

ValueError: Input must be a SciPy sparse matrix.

Version

  • OS: Linux (Google Colab)
  • CVXPY Version: 1.6.0

Additional context

deasmhumhna avatar Feb 26 '25 08:02 deasmhumhna

I think it's because sp.diags is not of type spmatrix? It might be enough to just change the instance check on line 208 to use sp.issparse(A) instead.

Transurgeon avatar Feb 26 '25 17:02 Transurgeon

oh nvm I think I see what you mean. In quad_form there is a try_catch that turns P into a dense array if sparse_cholesky raised a ValueError. But the snippet above shows that this value error is always being raised because P is a cvxpy Constant.

Transurgeon avatar Feb 26 '25 22:02 Transurgeon

Fixed by #2834. Thanks for reporting, @deasmhumhna.

rileyjmurray avatar Jun 18 '25 22:06 rileyjmurray