How do I use PT?#
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:
import mitiq
mitiq.SUPPORTED_PROGRAM_TYPES.keys()
dict_keys(['cirq', 'pyquil', 'qiskit', 'braket', 'pennylane', 'qibo'])
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
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)
0: ───@───────────
│
1: ───X───@───────
│
2: ───────@───@───
│
3: ───────────X───
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 section for more information on how to define more advanced executors.
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 can be used to evaluate noisy (unmitigated) expectation values.
# 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}")
Error without mitigation: 0.0
Apply PT#
Pauli Twirling can be easily implemented with the function
pauli_twirl_circuit()
.
from mitiq import pt
mitigated_result = pt.pauli_twirl_circuit(
circuit=circuit,
)
# 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.
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? contains information on more advanced ways of applying PT with Mitiq.