Handle unsimplified QubitOperator sparse terms#1350
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
There was a problem hiding this comment.
Code Review
This pull request introduces a helper function _iter_simplified_qubit_operator_terms to ensure that QubitOperator terms are simplified (resolving repeated qubit factors) when generating sparse operators or calculating diagonals. Unit tests have been added to verify this behavior. The reviewer noted that calling _simplify on every term introduces a significant performance overhead for large operators and suggested an optimization to bypass _simplify when terms are already simplified.
| def _iter_simplified_qubit_operator_terms(qubit_operator): | ||
| """Yield terms after applying QubitOperator's Pauli simplification.""" | ||
| for qubit_term, coefficient in qubit_operator.terms.items(): | ||
| coefficient, qubit_term = qubit_operator._simplify(qubit_term, coefficient) | ||
| yield qubit_term, coefficient |
There was a problem hiding this comment.
Calling _simplify on every term of the QubitOperator introduces a significant performance overhead (due to sorting, dictionary lookups, and tuple allocations), especially for large operators with tens of thousands of terms. Since the vast majority of QubitOperator instances are already simplified, we can optimize this by first checking if the term is already simplified (i.e., indices are strictly increasing and there are no identity 'I' operators). If it is already simplified, we can yield it directly and bypass _simplify entirely.
def _iter_simplified_qubit_operator_terms(qubit_operator):
"""Yield terms after applying QubitOperator's Pauli simplification."""
for qubit_term, coefficient in qubit_operator.terms.items():
is_simplified = True
prev_index = -1
for index, action in qubit_term:
if action == 'I' or index <= prev_index:
is_simplified = False
break
prev_index = index
if is_simplified:
yield qubit_term, coefficient
else:
coefficient, qubit_term = qubit_operator._simplify(qubit_term, coefficient)
yield qubit_term, coefficient
Fixes #880.
Summary
Tests