Skip to content

Add sparse_matrix() to PauliString and PauliSum - #8127

Merged
pavoljuhas merged 4 commits into
quantumlib:mainfrom
ToastCheng:i3057-sparse2
Jun 25, 2026
Merged

Add sparse_matrix() to PauliString and PauliSum#8127
pavoljuhas merged 4 commits into
quantumlib:mainfrom
ToastCheng:i3057-sparse2

Conversation

@ToastCheng

@ToastCheng ToastCheng commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

For each PauliString term, row/col indices and phases are computed directly via bitwise ops on basis states to avoid Kron product.

For PauliSum, uses COO triplet accumulation instead of repeated CSR addition to avoid merging multiple sparse matrices.

Fixes #3057

@ToastCheng
ToastCheng requested a review from a team as a code owner June 7, 2026 06:53
@ToastCheng
ToastCheng requested a review from tanujkhattar June 7, 2026 06:53
@github-actions github-actions Bot added the size: M 50< lines changed <250 label Jun 7, 2026
@codecov

codecov Bot commented Jun 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.60%. Comparing base (4738170) to head (a4ac720).
⚠️ Report is 21 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff            @@
##             main    #8127    +/-   ##
========================================
  Coverage   99.60%   99.60%            
========================================
  Files        1118     1118            
  Lines      100957   101215   +258     
========================================
+ Hits       100557   100815   +258     
  Misses        400      400            

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

For each PauliString term, row/col indices and phases are computed
directly via bitwise ops on basis states to avoid Kron product.

For PauliSum, uses COO triplet accumulation instead of repeated CSR
addition to avoid merging multiple sparse matrices.
@mhucka

mhucka commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

@ToastCheng Thank you for this work!

@mhucka mhucka self-assigned this Jun 9, 2026

@mhucka mhucka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for working on this!

I have some very small requests; otherwise, it looks good to me. I think @pavoljuhas had better review this too.

Comment thread cirq-core/cirq/ops/linear_combinations.py Outdated
Comment thread cirq-core/cirq/ops/pauli_string.py Outdated
Comment thread cirq-core/cirq/ops/pauli_string.py Outdated
Comment thread cirq-core/cirq/ops/pauli_string.py Outdated
Comment thread cirq-core/cirq/ops/linear_combinations.py Outdated
Comment thread cirq-core/cirq/ops/pauli_string.py Outdated
Comment thread cirq-core/cirq/ops/pauli_string.py Outdated
Comment thread cirq-core/cirq/ops/pauli_string.py Outdated
Comment thread cirq-core/cirq/ops/pauli_string_test.py Outdated
Comment thread cirq-core/cirq/ops/pauli_string_test.py Outdated
@mhucka
mhucka requested a review from pavoljuhas June 10, 2026 04:43
In addition, update implementation details:
- use np.where parity check for phases
- iterate self.items() directly
Comment thread cirq-core/cirq/ops/pauli_string.py Outdated
@mhucka

mhucka commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

@ToastCheng Thanks again for this contribution. Apart from agreeing with Pavol's point above, about adding an asserion, it's good to go from my perspective.

@pavoljuhas

Copy link
Copy Markdown
Collaborator

Thank you @mhucka. I asked @dstrain115 for a one quick look, so let's allow some time for that. Otherwise this looks good to me too.

@dstrain115 dstrain115 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would recommend tightening up the test for pauli sum sparse matrix a bit, but otherwise I approve.

Comment thread cirq-core/cirq/ops/linear_combinations_test.py Outdated
assert np.allclose(H3, paulisum.matrix([q[1], q[2], q[0]]))


def test_pauli_sum_sparse_matrix() -> None:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would recommend parameterizing this test case and passing in a variety of pauli sums.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dstrain115 when you get a chance, would you review & approve the PR if it's ready?

@pavoljuhas pavoljuhas left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a couple of minor suggestions, otherwise this looks great. Thank you @ToastCheng for contributing this!

Comment thread cirq-core/cirq/ops/linear_combinations_test.py Outdated
Comment thread cirq-core/cirq/ops/linear_combinations_test.py Outdated
Comment thread cirq-core/cirq/ops/linear_combinations_test.py Outdated

Raises:
NotImplementedError: If this `PauliString` is parameterized.
AssertionError: If an unexpected Pauli gate instance is encountered.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit - perhaps we should leave AssertionError from the docstring. Assertions are supposed to be always true regardless of user input; they should only pop up if there is a breaking change in the code or some unexpected code pathway.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pylint checks if the error is documented in the Raise section:

W9006: "AssertionError" not documented as being raised (missing-raises-doc)

The suppression is working at the function level, so it also suppresses checks for other exceptions in this method as well (I can't only suppress the AssertionError):

# This works:
def sparse_matrix(self, qubits) -> sparse.csr_matrix:
   # pylint: disable=missing-raises-doc

# This failed:
raise AssertionError("...") #pylint: disable=missing-raises-doc

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, let us leave it as is. Thank you for checking this.

Comment thread cirq-core/cirq/ops/pauli_string.py Outdated
...and also add annotations, checking values by np.array_equal.

@pavoljuhas pavoljuhas left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, thank you!

@pavoljuhas
pavoljuhas added this pull request to the merge queue Jun 25, 2026
Merged via the queue into quantumlib:main with commit f0e4c73 Jun 25, 2026
49 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size: M 50< lines changed <250

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add sparse_matrix method to PauliSum

4 participants