How do I use PEA?#
Probabilistic error amplification (PEA) estimates expectation values by probabilistically sampling noise-amplified circuits at several noise levels and extrapolating back to the zero-noise limit.
In Mitiq, this can be executed in a single call to execute_with_pea() or step-by-step using mitiq.experimental.pea.pea.construct_circuits() and mitiq.experimental.pea.pea.combine_results().
As with all techniques, PEA is compatible with any frontend supported by Mitiq:
import mitiq
mitiq.SUPPORTED_PROGRAM_TYPES.keys()
['braket', 'cirq', 'pennylane', 'pyquil', 'qibo', 'qiskit', 'openqasm']
Problem setup#
We first define the circuit of interest. For simplicity, in this example we use a randomized-benchmarking circuit whose ideal execution is equivalent to the identity operation.
from mitiq import benchmarks
circuit = benchmarks.generate_rb_circuits(
n_qubits=1, num_cliffords=2, return_type="cirq",
)[0]
print(circuit)
0: ───X^-0.5───Y^0.5───X^-0.5───Y^-0.5───(Z^0.5-X^0.5)───
Note
PEA also requires that the circuit can be decomposed into one- and two-qubit operations. If your circuit contains larger operations, pre-compile it to a one- and two-qubit gate set before applying PEA.
As an example, below we define a simple executor function which inputs a circuit, executes it 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, depolarize
from mitiq.interface import convert_to_mitiq
def execute(circuit, noise_level=0.01):
"""Returns Tr[rho |0><0|] where rho is the state prepared by the circuit
executed with depolarizing noise.
"""
# Replace with code based on your frontend/backend.
mitiq_circuit, _ = convert_to_mitiq(circuit)
noisy_circuit = mitiq_circuit.with_noise(depolarize(p=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) :.3f}")
Error without mitigation: 0.032
Apply PEA#
PEA can be implemented with a single call to
execute_with_pea().
from mitiq.experimental import pea
from mitiq.zne.inference import LinearFactory
scale_factors = [1.0, 1.6, 2.4]
mitigated_result = pea.execute_with_pea(
circuit,
execute,
scale_factors=scale_factors,
noise_model="local_depolarizing",
epsilon=0.01,
extrapolation_method=LinearFactory.extrapolate,
random_state=1,
)
/tmp/ipykernel_3931/333637230.py:1: FutureWarning: mitiq.experimental.pea is experimental and its API may change without notice in future releases. It is not covered by mitiq's semantic versioning guarantees.
from mitiq.experimental import pea
print(f"Error with PEA: {abs(ideal_value - mitigated_result):.3f}")
Error with PEA: 0.030
Here we observe that the application of PEA reduces the estimation error when compared to the unmitigated result.
In the example above, both the noise amplification and extrapolation steps were taken behind the scenes thanks to the default options of execute_with_pea().
In the following pages, we describe additional options and show how to apply the two steps of PEA independently.
Two-stage PEA workflow#
If you want more control over the process, you can split PEA into two stages:
Construct noise-amplified circuits and execute them.
Combine the results and extrapolate to the zero-noise limit.
from mitiq import Executor
from mitiq.experimental import pea
from mitiq.zne.inference import LinearFactory
scale_factors = [1.0, 1.6, 2.4]
scaled_circuits, scaled_signs, scaled_norms = pea.construct_circuits(
circuit,
scale_factors=scale_factors,
noise_model="local_depolarizing",
epsilon=0.01,
precision=0.1,
random_state=1,
)
executor = Executor(execute)
scaled_results = [executor.evaluate(sc) for sc in scaled_circuits]
pea_value = pea.combine_results(
scale_factors,
scaled_results,
scaled_norms,
scaled_signs,
extrapolation_method=LinearFactory.extrapolate,
)
print(f"Error with PEA (two-stage): {abs(ideal_value - pea_value):.3f}")
Error with PEA (two-stage): 0.030