-
Notifications
You must be signed in to change notification settings - Fork 706
Added support to convert Sparse matrix to a pauli sum #8612
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Updated the functions to support scipy sparse matrices by converting them to dense format internally. Added relevant documentation for handling sparse matrices in the decomposition functions.
Added tests for sparse matrix decomposition and related functionalities.
Added entry for new feature allowing scipy sparse matrices to be passed directly to pauli_decompose. Updated contributors list with Jacob Kitchen.
albi3ro
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for opening this PR @jk20342 .
Unfortunately, the goal of the feature request is to natively calculate the pauli decomposition without converting to a dense matrix. This would allow us to push the algorithm up to larger sizes as the issue requests. This may be a non-trivial task, as the current implementation uses things like math.array, math.stack, and other dense logic that would need to be completely rewritten.
Ah thanks! going to convert this to a draft and continue working with new understanding of the problem |
Added sparse matrix support for generalized Pauli decomposition, enabling efficient handling of large sparse matrices without converting to dense format.
Add tests for sparse matrix decomposition scenarios including handling of empty matrices, non-Hermitian matrices, and matrices with duplicate entries.
Sparse matrices are now processed natively in pauli_decompose for efficient decomposition of large matrices.
|
Hi @albi3ro I think i've implemented the desired functionality if you wouldnt mind taking a look thanks 😄 |
obliviateandsurrender
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot @jk20342, this is really impressive work! Overall, it already looks great, just leaving a few minor suggestions for further improvements.
| * Scipy sparse matrices can now be passed directly to :func:`~pennylane.pauli_decompose` without | ||
| manual conversion to dense arrays. Sparse matrices are processed natively allowing efficient | ||
| decomposition of large sparse matrices that cannot fit in memory as dense arrays. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| * Scipy sparse matrices can now be passed directly to :func:`~pennylane.pauli_decompose` without | |
| manual conversion to dense arrays. Sparse matrices are processed natively allowing efficient | |
| decomposition of large sparse matrices that cannot fit in memory as dense arrays. | |
| * The :func:`~pennylane.pauli_decompose` now supports decomposing scipy's sparse matrices, | |
| allowing for efficient decomposition of large matrices that cannot fit in memory when written as | |
| dense arrays. |
| from pennylane.math.utils import is_abstract | ||
| from pennylane.ops import Identity, LinearCombination, PauliX, PauliY, PauliZ, Prod, SProd, Sum | ||
| from pennylane.ops.qubit.matrix_ops import _walsh_hadamard_transform | ||
| import scipy.sparse as sp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may prefer importing it as sps, as we generally use sp for scipy.
| import scipy.sparse as sp | |
| import scipy.sparse as sps |
| matrix (tensor_like[complex] or scipy.sparse matrix): any matrix M, the keyword argument ``padding=True`` | ||
| should be provided if the dimension of M is not :math:`2^n\times 2^n`. Scipy sparse | ||
| matrices are also supported and are processed natively without converting to dense format, | ||
| enabling efficient decomposition of large sparse matrices. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| matrix (tensor_like[complex] or scipy.sparse matrix): any matrix M, the keyword argument ``padding=True`` | |
| should be provided if the dimension of M is not :math:`2^n\times 2^n`. Scipy sparse | |
| matrices are also supported and are processed natively without converting to dense format, | |
| enabling efficient decomposition of large sparse matrices. | |
| matrix (tensor_like[complex] or scipy.sparse matrix): any matrix M given with a dense or sparse representation. | |
| The keyword argument ``padding=True`` should be provided if the dimension of M is not :math:`2^n\times 2^n`. |
| Scipy sparse matrices are also supported: | ||
| >>> import scipy.sparse as sp | ||
| >>> sparse_matrix = sp.csr_matrix([[0, 1], [1, 0]]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should try to have a slightly more non-trivial example for the example here.
| the ``pauli`` flag. | ||
| Args: | ||
| matrix (scipy.sparse matrix): Any sparse matrix. If its dimension is not |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| matrix (scipy.sparse matrix): Any sparse matrix. If its dimension is not | |
| matrix (scipy.sparse.spmatrix | scipu.sparse.sparray): Any sparse matrix. If its dimension is not |
| if word not in coeffs_map: | ||
| continue | ||
| coeff = coeffs_map[word] | ||
| if abs(coeff) <= tolerance: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am slightly concerned about this static tolerance value. Do we really need it?
| H (tensor_like[complex] or scipy.sparse matrix): a Hermitian matrix of dimension :math:`2^n\times 2^n`. | ||
| Scipy sparse matrices are also supported and are processed natively without converting to dense format, | ||
| enabling efficient decomposition of large sparse matrices. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| H (tensor_like[complex] or scipy.sparse matrix): a Hermitian matrix of dimension :math:`2^n\times 2^n`. | |
| Scipy sparse matrices are also supported and are processed natively without converting to dense format, | |
| enabling efficient decomposition of large sparse matrices. | |
| H (tensor_like[complex] | scipy.sparse.spmatrix): a Hermitian matrix of dimension :math:`2^n\times 2^n` with dense or sparse representation. |
| coefficients for each of the :math:`4^n` Pauli words are computed while accounting for the | ||
| phase from each ``PauliY`` term occurring in the word. | ||
| Scipy sparse matrices are also supported: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Scipy sparse matrices are also supported: | |
| Scipy sparse matrices are also supported and processed natively without converting to | |
| dense format, enabling efficient decomposition of large sparse matrices. For example: |
| >>> terms | ||
| [X(0)] | ||
| """ | ||
| sparse_matrix = sp.coo_matrix(matrix) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the coo_matrix the best choice?
| Example: | ||
| >>> import pennylane as qml | ||
| >>> import scipy.sparse as sp | ||
| >>> sparse_matrix = sp.csr_matrix([[0, 1], [1, 0]]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we use a non-trivial example here?
Context:
qml.pauli_decompose()currently requires manual conversion of scipy sparse matrices to dense arrays, which defeats the purpose of using sparse matrices for large systems (e.g., 16+ qubits).Forum discussion: https://discuss.pennylane.ai/t/how-to-pauli-decompose-a-sparse-matrix/8436/8
Description of the Change:
Added automatic sparse matrix detection and conversion in
qml.pauli_decompose(). Sparse matrices are converted to dense internally using.toarray().Benefits:
qml.pauli_decompose()Possible Drawbacks:
None - sparse matrices are converted to dense internally anyway.
Related GitHub Issues:
n/a