-
Notifications
You must be signed in to change notification settings - Fork 575
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
Partition the Pauli group into qubit-wise commuting terms #2185
Conversation
Hello. You may have forgotten to update the changelog!
|
[sc-14640] |
Codecov Report
@@ Coverage Diff @@
## master #2185 +/- ##
=======================================
Coverage 99.21% 99.21%
=======================================
Files 231 231
Lines 17873 17901 +28
=======================================
+ Hits 17732 17760 +28
Misses 141 141
Continue to review full report at Codecov.
|
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 awesome, thanks @trbromley !
I've left a minor Q and suggestion. Approved ✔️
@@ -250,3 +253,80 @@ def pauli_mult_with_phase(pauli_1, pauli_2, wire_map=None): | |||
phase *= -1j | |||
|
|||
return pauli_product, phase | |||
|
|||
|
|||
@lru_cache() |
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.
how did you know to use this decorator here? I don't really understand how caching works and when to take advantage of it!
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.
There's probably better explanations out there, but from my perspective partition_pauli_group
fits the criteria nicely of:
- simple inputs that can be hashed
- function takes a long time to compute
- restricted set of inputs that may be called multiple times (e.g., in circuit cutting we might have a few fragments with 3-wire measure nodes)
# We know that I and Z always commute on a given qubit. The following generates all product | ||
# sequences of len(n_qubits) over "FXYZ", with F indicating a free slot that can be swapped for | ||
# the product over I and Z, and all other terms fixed to the given X/Y/Z. For example, if | ||
# ``n_qubits = 3`` our first value for ``string`` will be ``('F', 'F', 'F')``. We then expand | ||
# the product of I and Z over the three free slots, giving | ||
# ``['III', 'IIZ', 'IZI', 'IZZ', 'ZII', 'ZIZ', 'ZZI', 'ZZZ']``, which is our first group. The | ||
# next element of ``string`` will be ``('F', 'F', 'X')`` which we use to generate our second | ||
# group ``['IIX', 'IZX', 'ZIX', 'ZZX']``. |
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.
Nice explanation! Makes sense and useful to have it here 👌
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 @anthayes92!
@@ -250,3 +253,80 @@ def pauli_mult_with_phase(pauli_1, pauli_2, wire_map=None): | |||
phase *= -1j | |||
|
|||
return pauli_product, phase | |||
|
|||
|
|||
@lru_cache() |
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.
There's probably better explanations out there, but from my perspective partition_pauli_group
fits the criteria nicely of:
- simple inputs that can be hashed
- function takes a long time to compute
- restricted set of inputs that may be called multiple times (e.g., in circuit cutting we might have a few fragments with 3-wire measure nodes)
Context:
As part of the QCut module, we need to efficiently measure over the full N-qubit Pauli group. Although there are
4^N
terms, we can measure only3^N
groups.Description of the Change:
Added the
partition_pauli_group
function to thegrouping
module.Possible Drawbacks:
The function returns Pauli words expressed as simple strings. This is sufficient for the QCut module's needs but some users may prefer the Pauli words as PL observables/tensors. Since the current implementation is sufficient for now, I propose to leave returning PL observables/tensors as a follow up addition.
Example:
>>> qml.grouping.partition_pauli_group(3) [['III', 'IIZ', 'IZI', 'IZZ', 'ZII', 'ZIZ', 'ZZI', 'ZZZ'], ['IIX', 'IZX', 'ZIX', 'ZZX'], ['IIY', 'IZY', 'ZIY', 'ZZY'], ['IXI', 'IXZ', 'ZXI', 'ZXZ'], ['IXX', 'ZXX'], ['IXY', 'ZXY'], ['IYI', 'IYZ', 'ZYI', 'ZYZ'], ['IYX', 'ZYX'], ['IYY', 'ZYY'], ['XII', 'XIZ', 'XZI', 'XZZ'], ['XIX', 'XZX'], ['XIY', 'XZY'], ['XXI', 'XXZ'], ['XXX'], ['XXY'], ['XYI', 'XYZ'], ['XYX'], ['XYY'], ['YII', 'YIZ', 'YZI', 'YZZ'], ['YIX', 'YZX'], ['YIY', 'YZY'], ['YXI', 'YXZ'], ['YXX'], ['YXY'], ['YYI', 'YYZ'], ['YYX'], ['YYY']]