-
-
Notifications
You must be signed in to change notification settings - Fork 167
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Pauli Twirling (PT) User Guide (#1848)
* first pass at user guide * format fix * wrap up on pt user guide * missed save * missed docs iomport * missed docs import again * missed erroneous var * clarify fourth section and cleanup errors * missed error in save * clarified guide and made consistent * missed save * fix user guide * clean up workflow docs and rename image * make clearer pt expected effect * validate failure * revert back + admonition --------- Co-authored-by: Purva Thakre <[email protected]> Co-authored-by: Purva Thakre <[email protected]>
- Loading branch information
1 parent
b6cb5c1
commit 0c0b7a0
Showing
11 changed files
with
855 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,7 @@ cdr.md | |
shadows.md | ||
ddd.md | ||
rem.md | ||
pt.md | ||
error-mitigation.md | ||
glossary.md | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
--- | ||
jupytext: | ||
text_representation: | ||
extension: .myst | ||
format_name: myst | ||
format_version: 0.13 | ||
jupytext_version: 1.11.1 | ||
kernelspec: | ||
display_name: Python 3 (ipykernel) | ||
language: python | ||
name: python3 | ||
--- | ||
|
||
# How do I use PT? | ||
|
||
```{admonition} Warning: | ||
Pauli Twirling in Mitiq is still under construction. This users guide will change in the future | ||
after some utility functions are introduced. | ||
``` | ||
|
||
As with all techniques, PT is compatible with any frontend supported by Mitiq: | ||
|
||
```{code-cell} ipython3 | ||
import mitiq | ||
mitiq.SUPPORTED_PROGRAM_TYPES.keys() | ||
``` | ||
|
||
|
||
## Problem setup | ||
We first define the circuit of interest. In this example, the circuit has | ||
two CNOT gates and a CZ gate. We can see that when we apply Pauli Twirling, | ||
we will generate | ||
|
||
```{code-cell} ipython3 | ||
from cirq import LineQubit, Circuit, CZ, CNOT | ||
a, b, c, d = LineQubit.range(4) | ||
circuit = Circuit( | ||
CNOT.on(a, b), | ||
CZ.on(b, c), | ||
CNOT.on(c, d), | ||
) | ||
print(circuit) | ||
``` | ||
|
||
Next we define a simple executor function which inputs a circuit, executes | ||
the circuit on a noisy simulator, and returns the probability of the ground | ||
state. See the [Executors](executors.md) section for more information on | ||
how to define more advanced executors. | ||
|
||
```{code-cell} ipython3 | ||
import numpy as np | ||
from cirq import DensityMatrixSimulator, amplitude_damp | ||
from mitiq.interface import convert_to_mitiq | ||
def execute(circuit, noise_level=0.1): | ||
"""Returns Tr[ρ |0⟩⟨0|] where ρ is the state prepared by the circuit | ||
executed with amplitude damping noise. | ||
""" | ||
# Replace with code based on your frontend and backend. | ||
mitiq_circuit, _ = convert_to_mitiq(circuit) | ||
noisy_circuit = mitiq_circuit.with_noise(amplitude_damp(gamma=noise_level)) | ||
rho = DensityMatrixSimulator().simulate(noisy_circuit).final_density_matrix | ||
return rho[0, 0].real | ||
``` | ||
|
||
The [executor](executors.md) can be used to evaluate noisy (unmitigated) | ||
expectation values. | ||
|
||
```{code-cell} ipython3 | ||
# Compute the expectation value of the |0><0| observable. | ||
noisy_value = execute(circuit) | ||
ideal_value = execute(circuit, noise_level=0.0) | ||
print(f"Error without mitigation: {abs(ideal_value - noisy_value) :.3}") | ||
``` | ||
|
||
## Apply PT | ||
Pauli Twirling can be easily implemented with the function | ||
{func}`.pauli_twirl_circuit()`. | ||
|
||
```{code-cell} ipython3 | ||
from mitiq import pt | ||
mitigated_result = pt.pauli_twirl_circuit( | ||
circuit=circuit, | ||
) | ||
``` | ||
|
||
```{code-cell} ipython3 | ||
# print(f"Error with mitigation (PT): {abs(ideal_value - mitigated_result) :.3}") | ||
``` | ||
|
||
Here we observe that the application of PT does not reduce the estimation error when compared | ||
to the unmitigated result. The intended effect was to only tailor the noise. | ||
|
||
```{admonition} Note: | ||
PT is designed to transform the noise simulated in this example, | ||
but it should not be expected to always be a positive effect. | ||
In this sense, it is more of a noise tailoring technique, designed | ||
to be composed with other techniques rather than an error mitigation | ||
technique in and of itself. | ||
``` | ||
|
||
+++ | ||
|
||
The section | ||
[What additional options are available when using PT?](pt-3-options.md) | ||
contains information on more advanced ways of applying PT with Mitiq. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
--- | ||
jupytext: | ||
text_representation: | ||
extension: .myst | ||
format_name: myst | ||
format_version: 0.13 | ||
jupytext_version: 1.10.3 | ||
kernelspec: | ||
display_name: Python 3 (ipykernel) | ||
language: python | ||
name: python3 | ||
--- | ||
|
||
# When should I use PT? | ||
|
||
```{admonition} Warning: | ||
Pauli Twirling in Mitiq is still under construction. This users guide will change in the future | ||
after some utility functions are introduced. | ||
``` | ||
|
||
## Advantages | ||
|
||
Pauli Twirling is a technique devised to tailor noise towards Pauli channels. | ||
|
||
More details on the theory of Pauli Twirling are given in the section [What is the theory behind PT?](pt-5-theory.md). | ||
|
||
Pauli Twirling is agnostic to our knowledge on the type of noise, easy to implement, and useful to better understand and minimize the benchmarking vs performance gap. | ||
|
||
|
||
|
||
## Disadvantages | ||
|
||
Pauli Twirling is generally combined with a compilation pass to maintain circuit depth. Mitiq thus far does not provide this compilation, and so circuit depth is increased by the additional single-qubit gates. | ||
|
||
Though the noise is tailored towards a more mitigable channel, it's possible for this channel to be entirely noisy (i.e. a completely depolarizing channel). In this way, it should not be expected to reduce noise on its own. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
--- | ||
jupytext: | ||
text_representation: | ||
extension: .myst | ||
format_name: myst | ||
format_version: 0.13 | ||
jupytext_version: 1.11.1 | ||
kernelspec: | ||
display_name: Python 3 (ipykernel) | ||
language: python | ||
name: python3 | ||
--- | ||
|
||
# What additional options are available when using PT? | ||
|
||
```{admonition} Warning: | ||
Pauli Twirling in Mitiq is still under construction. This users guide will change in the future | ||
after some utility functions are introduced. | ||
``` | ||
|
||
Currently Pauli Twirling is designed to have relatively few options, in part to make it readily composable with every other Mitiq technique. In the future, we expect a possibility of supporting additional operations as targets (beyond CZ and CNOT gates), with more customization on picking those targets. Stay tuned! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
--- | ||
jupytext: | ||
text_representation: | ||
extension: .myst | ||
format_name: myst | ||
format_version: 0.13 | ||
jupytext_version: 1.11.1 | ||
kernelspec: | ||
display_name: Python 3 | ||
language: python | ||
name: python3 | ||
--- | ||
|
||
# What happens when I use PT? | ||
|
||
```{admonition} Warning: | ||
Pauli Twirling in Mitiq is still under construction. This users guide will change in the future | ||
after some utility functions are introduced. | ||
``` | ||
|
||
The workflow of Pauli Twirling (PT) in Mitiq is represented in the figure below. | ||
|
||
```{figure} ../img/pt_workflow.svg | ||
--- | ||
width: 700px | ||
name: pt-workflow-overview-2 | ||
--- | ||
Workflow of the PT technique in Mitiq, detailed in the [What happens when I use PT?](pt-4-low-level.md) section. | ||
``` | ||
|
||
- The user provides a `QPROGRAM`, (i.e. a quantum circuit defined via any of the supported [frontends](frontends-backends.md)). | ||
- Mitiq modifies the input circuit with the insertion of PT gates on noisy operations. | ||
- The modified circuit is executed via a user-defined [Executor](executors.md). | ||
- The error mitigated expectation value is returned to the user. | ||
|
||
With respect to the workflows of other error-mitigation techniques (e.g. [ZNE](zne-4-low-level.md) or [PEC](pec-4-low-level.md)), | ||
PT involves the generation of a _single_ circuit with random modifications, and subsequently averages over many executions. | ||
For this reason, there is no need for a complex final inference step, which is necessary for other | ||
techniques, and so this average is instead trivial for PT. | ||
|
||
```{note} | ||
When setting the `num_trials` option to a value larger than one, multiple circuits are actually generated by Mitiq and | ||
the associated results are averaged to obtain the final expectation value. This more general case is not shown in the figure since | ||
it can be considered as an average of independent single-circuit workflows. | ||
``` | ||
|
||
As shown in [How do I use PT?](pt-1-intro.md), the function {func}`.pauli_twirl_circuit()` applies PT behind the scenes | ||
and returns the different versions of Pauli Twirled circuits. | ||
In the next sections instead, we show how one can apply PT at a lower level, i.e., by: | ||
|
||
- Twirling CZ and CNOT gates in the circuit; | ||
- Executing the modified circuit (still under construction). | ||
- Estimate expectation value by averaging over randomized twirling circuits | ||
|
||
## Twirling CZ and CNOT gates in the circuit | ||
To twirl about particular gates, we need the Pauli group for those gates. These groups are stored as lookup tables, in {attr}`mitiq.pt.pt.CNOT_twirling_gates` and {attr}`mitiq.pt.pt.CZ_twirling_gates`, so that we can randomly select a tuple from the group. Now we're ready to twirl our gates. | ||
|
||
First let's define our circuit: | ||
```{code-cell} ipython3 | ||
from cirq import LineQubit, Circuit, CZ, CNOT | ||
a, b, c, d = LineQubit.range(4) | ||
circuit = Circuit( | ||
CNOT.on(a, b), | ||
CZ.on(b, c), | ||
CNOT.on(c, d), | ||
) | ||
print(circuit) | ||
``` | ||
Now, we can see what happens when we apply the PT functions, through {func}`.twirl_CNOT_gates()` and the subsequent {func}`.twirl_CZ_gates()` | ||
```{code-cell} ipython3 | ||
from mitiq import pt | ||
circuit_to_twirl = circuit.copy() | ||
CNOT_twirled_circuits = pt.twirl_CNOT_gates(circuit_to_twirl, num_circuits=10) | ||
twirled_circuits = [ | ||
pt.twirl_CZ_gates(c, num_circuits=1)[0] for c in CNOT_twirled_circuits | ||
] | ||
print("Twirling just the CNOT gates: \n", CNOT_twirled_circuits[0], "\n") | ||
print("Twirling both CNOT and CZ gates: \n" ,twirled_circuits[0]) | ||
``` | ||
We see that we return lists of the randomly twirled circuits, and so we must take a simple average over their expectation values. | ||
|
||
## Executing the modified circuits | ||
|
||
```{admonition} Warning: | ||
Pauli Twirling in Mitiq is still under construction. Some lines in the code blocks below are commented out as intended behavior | ||
is currently a WIP. | ||
``` | ||
|
||
Now that we have our twirled circuits, let's simulate some noise and execute those circuits, using the {class}`mitiq.Executor` to collect the results. | ||
```{code-cell} ipython3 | ||
from cirq import DensityMatrixSimulator, amplitude_damp | ||
from mitiq import Executor | ||
def execute(circuit, noise_level=0.003): | ||
"""Returns Tr[ρ |00..⟩⟨00..|] where ρ is the state prepared by the circuit | ||
executed with depolarizing noise. | ||
""" | ||
noisy_circuit = circuit.with_noise(amplitude_damp(noise_level)) | ||
rho = DensityMatrixSimulator().simulate(noisy_circuit).final_density_matrix | ||
return rho[0, 0].real | ||
executor = Executor(execute) | ||
# expvals = executor.evaluate(twirled_circuits, None) | ||
``` | ||
|
||
|
||
## Estimate expectation value by averaging over randomized twirling circuits | ||
Pauli Twirling doesn't require running the circuit at different noise levels or with different noise models. It applies a randomized sequence of Pauli operations within the same quantum circuit and averages the results to reduce the effect of the noise. | ||
|
||
```{code-cell} ipython3 | ||
# import numpy as np | ||
# from typing import cast | ||
# average = cast(float, np.average(expvals)) | ||
# print(average) | ||
``` | ||
|
||
Keep in mind, ths code is for illustration and that the noise level, type of noise (here amplitude damping), and the observable need to be adapted to the specific experiment. | ||
|
||
If executed on a noiseless backend, a given `circuit_with_pt` and `circuit` are equivalent. | ||
On a real backend, they have a different sensitivity to noise. The core idea of the PT technique is that, | ||
`circuits_with_pt` (hopefully) tailors the noise into stochastic Pauli channels, such that a simple average over results | ||
will return a mitigated result. | ||
|
||
As a final remark, we stress that the low-level procedure that we have shown is exactly what {func}`.pauli_twirl_circuit()` does behind the scenes. | ||
Let's verify this fact: | ||
|
||
```{code-cell} ipython3 | ||
# np.isclose( | ||
# pt.pauli_twirl_circuit(circuit, executor), | ||
# average, | ||
# ) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
--- | ||
jupytext: | ||
text_representation: | ||
extension: .myst | ||
format_name: myst | ||
format_version: 0.13 | ||
jupytext_version: 1.11.1 | ||
kernelspec: | ||
display_name: Python 3 | ||
language: python | ||
name: python3 | ||
--- | ||
|
||
# What is the theory behind Pauli Twirling? | ||
|
||
```{admonition} Warning: | ||
Pauli Twirling in Mitiq is still under construction. This users guide will change in the future | ||
after some utility functions are introduced. | ||
``` | ||
|
||
Pauli Twirling (PT) {cite}`Wallman_2016_PRA, Hashim_2021_PRX, Urbanek_2021_PRL, Saki_2023_arxiv` | ||
is a quantum noise tailoring technique designed to transform the noise channel | ||
towards a more manageable stochastic Pauli channel. This tailoring is achieved | ||
by randomly applying a series of Pauli operations to the quantum system, then | ||
averaging over the results, and in doing so can reduce the complexity of the errors. | ||
|
||
1. In general, PT is a noise agnostic tailoring technique, designed to be composed with more direct mitigation | ||
|
||
2. For Markovian noise, PT can make the overall quantum channel more symmetric (analogous to dynamical decoupling {cite}`Viola_1998_PRA, Viola_1999_PRL, Zhang_2014_PRL`) | ||
|
||
Pauli Twirling (PT) can be a powerful tool for noise management in quantum systems. By twirling over the Pauli gates, PT transforms complex noise channels into simpler stochastic Pauli noise channels. | ||
|
||
The success of PT is contingent on various factors, such as the nature of the noise and the specific characteristics of the quantum system. It's worth noting that, while PT generally simplifies the noise channel, there are circumstances where it could transform the noise negatively, for example into a completely depolarizing channel with a corresponding total loss of quantum information. | ||
|
||
For optimal results, Pauli Twirling should be implemented with an understanding of the underlying noise dynamics, and ideally, should be complemented with more direction error mitigation techniques to ensure robust quantum computation. | ||
|
||
In the context of quantum error mitigation, PT is closer to [DDD](ddd-5-theory.md), but stands apart as a noise tailoring technique. PT's peculiarities include: | ||
|
||
- It is not expected to reduce noise on its own, but rather tailor the noise such that it can be properly mitigated by other techniques. | ||
|
||
- It constructs a _single_ circuit with random modifications, and subsequently averages over many executions. | ||
With a single circuit, both the computational cost and complexity are reduced, making the final average of results a relatively straightforward task. That is, there is no need to take a linear combinations of noisy results as in [ZNE](zne-5-theory.md) [PEC](pec-5-theory.md) and [CDR](cdr-5-theory.md). | ||
|
||
- As a consequence of the previous point, the fundamental error mitigation overhead is minimized, | ||
such that there is no increase in statistical uncertainty in the final result, assuming optimal executions. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# Pauli Twirling | ||
|
||
```{admonition} Warning: | ||
Pauli Twirling in Mitiq is still under construction. This users guide will change in the future | ||
after some utility functions are introduced. | ||
``` | ||
|
||
Pauli Twirling (PT) is an noise tailoring technique in which, | ||
in the Mitiq implementation, particularly noisy operations (e.g. CZ and CNOT) | ||
are transformed by independent, random, single-qubit gates inserted into | ||
the circuit such that the effective logical circuit remains unchanged | ||
but the noise is tailored towards stochastic Pauli errors. | ||
For more discussion of the theory of PT, see the section [What is the theory | ||
behind PT?](pt-5-theory.md). | ||
|
||
```{figure} ../img/pt_workflow.svg | ||
--- | ||
width: 700px | ||
name: pt-workflow-overview | ||
--- | ||
Workflow of the PT technique in Mitiq, detailed in the [What happens when I use PT?](pt-4-low-level.md) section. | ||
``` | ||
|
||
Below you can find sections of the documentation that address the following questions: | ||
|
||
```{toctree} | ||
--- | ||
maxdepth: 1 | ||
--- | ||
pt-1-intro.md | ||
pt-2-use-case.md | ||
pt-3-options.md | ||
pt-4-low-level.md | ||
pt-5-theory.md | ||
``` | ||
|
||
You can find many more examples on a variety of error mitigation techniques in the **[Examples](../examples/examples.md)** section of | ||
the documentation. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.