Sparse contradict converts to dense (`quad_form`, `sparse_cholesky`)
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
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.
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.
Fixed by #2834. Thanks for reporting, @deasmhumhna.