Skip to content

Commit

Permalink
Pauli Twirling (PT) User Guide (#1848)
Browse files Browse the repository at this point in the history
* 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
3 people authored Sep 30, 2023
1 parent b6cb5c1 commit 0c0b7a0
Show file tree
Hide file tree
Showing 11 changed files with 855 additions and 3 deletions.
1 change: 1 addition & 0 deletions docs/source/guide/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ cdr.md
shadows.md
ddd.md
rem.md
pt.md
error-mitigation.md
glossary.md
```
109 changes: 109 additions & 0 deletions docs/source/guide/pt-1-intro.md
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.
35 changes: 35 additions & 0 deletions docs/source/guide/pt-2-use-case.md
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.
21 changes: 21 additions & 0 deletions docs/source/guide/pt-3-options.md
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!
137 changes: 137 additions & 0 deletions docs/source/guide/pt-4-low-level.md
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,
# )
```
45 changes: 45 additions & 0 deletions docs/source/guide/pt-5-theory.md
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.
38 changes: 38 additions & 0 deletions docs/source/guide/pt.md
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.
Binary file added docs/source/img/pt_workflow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 0c0b7a0

Please sign in to comment.