# Mirror Benchmarking¶

## Introduction¶

Mirror Benchmarking (MB) is a noise benchmarking method that works as follows: one prepares a state, performs the circuit, followed by its inverse, then measures the result. Ideally, the system returns to its initial state. However, due to gate errors, this is not guaranteed. The result of the test is the success probability, which is the probability we arrive at the initial state. Including the state preparation in the circuit $$G$$, it is given by

$p\left(G\right) = \langle 0| \mathcal{E} \left(G ^ \dagger\right) \mathcal{E} \left(G\right) | 0 \rangle$

This technique is inspired by similar approaches with random circuits referred to as Mirror Benchmarking or Mirror Circuit Benchmarking [1-2]. To leverage the full capabilities of Classiq's synthesis engine, MB is done on a functional level model, rather than a low-level circuit, enabling application-oriented benchmarking. That way, hardware-aware synthesis is possible, making sure the program is optimized for each hardware, and that the test indeed measures how well the hardware suites a specific program.

## Usage¶

To use the MB package, simply import the MirrorBenchmarking object, and construct it from a model. The object has a synthesize method, and code execution is the same as in any other circuit.

from classiq.applications.benchmarking import MirrorBenchmarking

circuit = MirrorBenchmarking(model).synthesize()


## Example¶

The following example contains code performing a MB test on the IBM Quantum's "Quito" device, with hardware settings defined automatically for the device. The measured success probability is 11.65%. Note that to run the example ACCESS_TOKEN must be assigned a valid value.

from classiq.execution import IBMBackendPreferences
from classiq.applications.benchmarking import MirrorBenchmarking
from classiq.model import Preferences
from classiq.builtin_functions import QFT
from classiq import Executor, Model

model = Model(
preferences=Preferences(
backend_service_provider="IBM Quantum", backend_name="quito"
)
)

num_qubits = 5
qft_params = QFT(num_qubits=num_qubits)
model.QFT(qft_params)

circuit = MirrorBenchmarking(model).synthesize()
program = circuit.to_program()

res = Executor(
num_shots=10000,
backend_preferences=IBMBackendPreferences(
backend_name="ibmq_quito", access_token=ACCESS_TOKEN
),
).execute(program)
counts = res.counts

success_probability = counts["0" * num_qubits] / sum(counts.values())
print(success_probability)


## References¶

[1] T. Proctor, K. Rudinger, K. Young, E. Nielsen, R. Blume-Kohout, "Measuring the capabilities of quantum computers". Available: https://www.nature.com/articles/s41567-021-01409-7

[2] K. Mayer, A. Hall. T. Gatterman. S. K. Halit, K. Lee, J. Bohnet, D. Gresh, A. Hankin, K. Gilmore, J. Gerber, J. Gaebler, "Theory of mirror benchmarking and demonstration on a quantum computer". Available: https://arxiv.org/pdf/2108.10431.pdf