-
-
Notifications
You must be signed in to change notification settings - Fork 166
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New QEM benchmarking method: "rotated" RB circuits (#2028)
* Initial sketch of benchmarking method * Add functions and tests; remove `.md` file * Remove deleted markdown file from TOC * Format __init__.py * Ignore broken links * Fix math rendering * Allow user to set `theta` Allow user to set `theta` instead of randomly selecting in the function. * Use set values of theta for tests * Make `theta` an optional arg * Remove unnecessary `convert_to_mitiq` call * Apply rotation only on first qubit * Remove unused import * Add check for "pathological" circuit Add check for pathological circuit Remove unused `seed` argument Wordsmith the docstring * Add an optional seed to `generate_rb_circuits` * Remove recursion, unneeded with rb circuit seed * Cirq `qubit_characterization` authors, fix format Add Cirq `qubit_characterization` author names Fix formatting * Add seed in `generate_rotated_rb_circuits` Add optional seed for rb circuits in `generate_rotated_rb_circuits` * Update mitiq/benchmarks/rotated_randomized_benchmarking.py Co-authored-by: Andrea Mari <[email protected]> * Use local random state in `generate_rb_circuits` Define local random state from optional seed in `generate_rb_circuits` * Update mitiq/benchmarks/randomized_benchmarking.py Co-authored-by: nate stemen <[email protected]> --------- Co-authored-by: Andrea Mari <[email protected]> Co-authored-by: nate stemen <[email protected]>
- Loading branch information
1 parent
0c0b7a0
commit 10ecabf
Showing
6 changed files
with
193 additions
and
18 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
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
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
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
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,80 @@ | ||
# Copyright (C) Unitary Fund | ||
# | ||
# This source code is licensed under the GPL license (v3) found in the | ||
# LICENSE file in the root directory of this source tree. | ||
|
||
"""Functions for generating rotated randomized benchmarking circuits.""" | ||
from typing import List, Optional, cast | ||
|
||
import cirq | ||
import numpy as np | ||
|
||
from mitiq import QPROGRAM | ||
from mitiq.benchmarks import generate_rb_circuits | ||
from mitiq.interface import convert_from_mitiq | ||
|
||
|
||
def generate_rotated_rb_circuits( | ||
n_qubits: int, | ||
num_cliffords: int, | ||
theta: Optional[float] = None, | ||
trials: int = 1, | ||
return_type: Optional[str] = None, | ||
seed: Optional[int] = None, | ||
) -> List[QPROGRAM]: | ||
r""" | ||
Generates a list of "rotated" randomized benchmarking circuits. | ||
This benchmarking method enables testing QEM techniques in more general | ||
scenarios, closer to real-world applications in which expectation values | ||
can take arbitrary values. | ||
Rotated randomized bencmarking circuits are randomized benchmarking | ||
circuits with an :math:`R_z(\theta)` rotation inserted in the middle, such | ||
that: | ||
.. math:: | ||
C(\theta) = G_n \dots G_{n/2 +1} R_z(\theta)G_{n/2} \dots G_2 G_1 | ||
where :math:`G_j` are Clifford elements or Clifford gates. | ||
For most values of the seed, the probability of the zero state is a | ||
sinusoidal function of :math:`\theta`. For some values of the seed | ||
the probability of the zero state is 1 for all :math:`\theta`. | ||
Since (up to factors of 2) we have | ||
:math:`R_z(\theta) =cos(\theta) I + i \ sin(\theta) Z`, the rotated | ||
Clifford circuit :math:`C(\theta)` can be written as a linear combination | ||
of just two Clifford circuits, and therefore it is still easy to | ||
classically simulate. | ||
Args: | ||
n_qubits: The number of qubits. Can be either 1 or 2. | ||
num_cliffords: The number of Clifford group elements in the | ||
random circuits. This is proportional to the depth per circuit. | ||
theta: The rotation angle about the :math:`Z` axis. | ||
trials: The number of random circuits to return. | ||
return_type: String which specifies the type of the | ||
returned circuits. See the keys of | ||
``mitiq.SUPPORTED_PROGRAM_TYPES`` for options. If ``None``, the | ||
returned circuits have type ``cirq.Circuit``. | ||
seed: A seed for generating radomzed benchmarking circuits. | ||
Returns: | ||
A list of rotated randomized benchmarking circuits. | ||
""" | ||
|
||
circuits = cast( | ||
List[cirq.Circuit], | ||
generate_rb_circuits(n_qubits, num_cliffords, trials, seed=seed), | ||
) | ||
|
||
if theta is None: | ||
theta = 2 * np.pi * np.random.rand() | ||
|
||
for circ in circuits: | ||
qubits = list(circ.all_qubits()) | ||
circ.insert(len(circ) // 2, cirq.Rz(rads=theta).on(qubits[0])) | ||
|
||
return_type = "cirq" if not return_type else return_type | ||
return [convert_from_mitiq(circuit, return_type) for circuit in circuits] |
57 changes: 57 additions & 0 deletions
57
mitiq/benchmarks/tests/test_rotated_randomized_benchmarking.py
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,57 @@ | ||
# Copyright (C) Unitary Fund | ||
# | ||
# This source code is licensed under the GPL license (v3) found in the | ||
# LICENSE file in the root directory of this source tree. | ||
|
||
"""Tests for rotated randomized benchmarking circuits.""" | ||
|
||
import cirq | ||
import numpy as np | ||
import pytest | ||
|
||
from mitiq import SUPPORTED_PROGRAM_TYPES | ||
from mitiq.benchmarks.rotated_randomized_benchmarking import ( | ||
generate_rotated_rb_circuits, | ||
) | ||
|
||
|
||
@pytest.mark.parametrize("n_qubits", (1, 2)) | ||
@pytest.mark.parametrize("theta", [0, np.pi / 2, np.pi]) | ||
def test_rotated_rb_circuits(n_qubits, theta): | ||
depth = 10 | ||
for trials in [2, 3]: | ||
circuits = generate_rotated_rb_circuits( | ||
n_qubits=n_qubits, num_cliffords=depth, theta=theta, trials=trials | ||
) | ||
for circ in circuits: | ||
zero_prob = ( | ||
cirq.DensityMatrixSimulator() | ||
.simulate(circ) | ||
.final_density_matrix[0, 0] | ||
.real | ||
) | ||
assert -1.0001 <= zero_prob <= 1.0001 | ||
|
||
|
||
@pytest.mark.parametrize("n_qubits", (1, 2)) | ||
@pytest.mark.parametrize("theta", [0, np.pi / 2, np.pi]) | ||
@pytest.mark.parametrize("return_type", SUPPORTED_PROGRAM_TYPES.keys()) | ||
def test_rotated_rb_conversion(n_qubits, theta, return_type): | ||
depth = 10 | ||
for trials in [2, 3]: | ||
circuits = generate_rotated_rb_circuits( | ||
n_qubits=n_qubits, | ||
num_cliffords=depth, | ||
theta=theta, | ||
trials=trials, | ||
return_type=return_type, | ||
) | ||
for circ in circuits: | ||
assert return_type in circ.__module__ | ||
|
||
|
||
def test_rotated_rb_circuit_no_theta(): | ||
circuit = generate_rotated_rb_circuits(n_qubits=1, num_cliffords=5)[0] | ||
assert ( | ||
len(list(circuit.findall_operations_with_gate_type(cirq.ops.Rz))) > 0 | ||
) |