-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Add SparsePauliOp.sum
#7202
Add SparsePauliOp.sum
#7202
Conversation
- | | ||
Added :meth:`~qiskit.quantum_info.SparsePauliOp.sum` as a specialized function of the builtin | ||
function ``sum`` for a list of :class:`:meth:`~qiskit.quantum_info.SparsePauliOp`. | ||
This method has less overhead of the array stacking of |
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.
This method has less overhead of the array stacking of | |
This method has less overhead than the array stacking of |
LGTM! |
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.
Looks good to me - it's the improvement in asymptotic complexity that's the biggest win here!
In [1]: from qiskit.quantum_info import SparsePauliOp
...: import random
...:
...: def random_pauli(k):
...: phase = "".join([
...: random.choice(['', '+', '-']),
...: random.choice(['', '1']),
...: random.choice(['', 'i', 'j']),
...: ])
...: return phase + "".join(random.choices("IXYZ", k=k))
...:
...: def raw_sum(ops):
...: out, *rest = ops
...: for op in rest:
...: out += op
...: return out
...:
...: per_pauli = 50
...: qubits = 20
...: for n in [10, 30, 100, 300, 1000]:
...: ops = [SparsePauliOp([random_pauli(qubits) for _ in [None]*per_pauli]) for _ in [None]*n]
...: %timeit SparsePauliOp.sum(ops)
...: %timeit raw_sum(ops)
...: print()
...:
56.6 µs ± 1.17 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
265 µs ± 4.69 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
122 µs ± 1.12 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
866 µs ± 22 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
365 µs ± 6.08 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
3.46 ms ± 106 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
1.04 ms ± 10.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
15.9 ms ± 311 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
3.7 ms ± 96.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
109 ms ± 1.2 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
Thank you for revising the reno. |
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.
(By the way, in most cases, you don't need to use the "update branch" button once a PR is tagged "automerge". The bot will take care of that for us, and it's generally more efficient at it as well. If the bot is blocked on a single transient test failure, Matthew, Kevin or I can re-run the failed job to avoid needing to re-run the entire CI suite. It's usually not really a problem to update the branch, just less efficient.)
Sorry. I updated the branch because I noticed the CI failure. I won't do that again. |
No worries! It's not super important, it just helps a bit, because we end up with fewer jobs running on CI in total (we can only have a fairly small number running at any given time). |
Pull Request Test Coverage Report for Build 1413484972
💛 - Coveralls |
Summary
Adds
SparsePauliOp.sum
as a specialized version the builtinsum
for a list ofSparsePauliOp
.The builtin
sum
callsSparsePauliOp._add
N-1 times if there are N items in the list.Each
SparsePauliOp._add
stacks arrays of z, x, phase and coeffs and it is carried out N-1 times.On the other hand, the new method
SparsePauliOp.sum
stacks all arrays at once. So, it can reduce the overhead.Details and comments
Jordan Wigner transformation takes a sum of a list of
SparsePauliOp
and it is one of the bottlenecks.I proposed a workaround to reduce the overhead in this PR qiskit-community/qiskit-nature#397;
but, it is not intuitive.
The specialized method of this PR is more intuitive and more efficient than the workaround.
Microbenchmark of JW transformation with Qiskit nature. (same as one in qiskit-community/qiskit-nature#397)
nature main (qiskit-community/qiskit-nature@7d12a13) + terra main
nature qiskit-community/qiskit-nature#397 + terra main
nature qiskit-community/qiskit-nature#397 + this PR (replace
_sum
withSparsePauliOp.sum
)