Skip to content

Commit

Permalink
Add functions and tests; remove .md file
Browse files Browse the repository at this point in the history
  • Loading branch information
Misty-W committed Sep 26, 2023
1 parent 2a04cce commit 3da2973
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 113 deletions.
7 changes: 7 additions & 0 deletions docs/source/apidoc.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@
:members:
```

### Rotated Randomized Benchmarking Circuits

```{eval-rst}
.. automodule:: mitiq.benchmarks.rotated_randomized_benchmarking
:members:
```

### GHZ Circuits
```{eval-rst}
.. automodule:: mitiq.benchmarks.ghz_circuits
Expand Down
113 changes: 0 additions & 113 deletions docs/source/examples/benchmarking_qem.md

This file was deleted.

1 change: 1 addition & 0 deletions mitiq/benchmarks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# LICENSE file in the root directory of this source tree.

from mitiq.benchmarks.randomized_benchmarking import generate_rb_circuits
from mitiq.benchmarks.rotated_randomized_benchmarking import generate_rotated_rb_circuits
from mitiq.benchmarks.mirror_circuits import generate_mirror_circuit
from mitiq.benchmarks.ghz_circuits import generate_ghz_circuit
from mitiq.benchmarks.quantum_volume_circuits import (
Expand Down
83 changes: 83 additions & 0 deletions mitiq/benchmarks/rotated_randomized_benchmarking.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# 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 randomized benchmarking circuits."""
from typing import List, Optional

import numpy as np

import cirq

from mitiq import QPROGRAM
from mitiq.interface import convert_to_mitiq, convert_from_mitiq
from mitiq.benchmarks import generate_rb_circuits


def generate_rotated_rb_circuits(
n_qubits: int,
num_cliffords: int,
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 in which an $R_z(\theta)$ rotation is inserted in the middle, such
that:
$$ C(\theta) = G_n \dots G_{n/2 +1} R_z(\theta)G_{n/2} \dots G_2 G_1 $$
where $G_j$ are Clifford elements or Clifford gates.
The circuits generate expectation values which are sinusoidal functions of
$\theta$, which in the ideal (noiseless) case vary in a continuous interval
of $ E_{\rm ideal} \in [-1, 1] $.
Since (up to factors of 2) we have
$R_z(\theta) =cos(\theta) I + i \ sin(\theta) Z$, the rotated Clifford
circuit $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.
trials: The number of random circuits at each num_cfd.
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: An optional seed for reproducibility of $\theta$ in
$R_z(\theta)$.
Returns:
A list of rotated randomized benchmarking circuits.
"""

circuits = generate_rb_circuits(n_qubits, num_cliffords, 2 * trials)
rotated_circuits = []

rng = np.random.default_rng(seed=seed)

for circ in circuits:
rotated_circ, _ = convert_to_mitiq(circ)
qubits = rotated_circ.all_qubits()
rads = rng.random() * np.pi
rotated_circ.insert(
len(circ) // 2, cirq.Rz(rads=rads).on_each(*qubits)
)
rotated_circuits.append(rotated_circ)

return_type = "cirq" if not return_type else return_type
return [
convert_from_mitiq(circuit, return_type)
for circuit in rotated_circuits
]
44 changes: 44 additions & 0 deletions mitiq/benchmarks/tests/test_rotated_randomized_benchmarking.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# 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 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))
def test_rotated_rb_circuits(n_qubits):
depth = 10
results = []
for trials in [5, 10]:
circuits = generate_rotated_rb_circuits(
n_qubits=n_qubits, num_cliffords=depth, trials=trials
)
for qc in circuits:
# we check the ground state population to ignore any global phase
wvf = qc.final_state_vector()
zero_prob = abs(wvf[0] ** 2)
assert -1.0001 <= zero_prob <= 1.0001
results.append(zero_prob)


@pytest.mark.parametrize("n_qubits", (1, 2))
@pytest.mark.parametrize("return_type", SUPPORTED_PROGRAM_TYPES.keys())
def test_rotated_rb_conversion(n_qubits, return_type):
depth = 10
for trials in [2, 3]:
circuits = generate_rotated_rb_circuits(
n_qubits=n_qubits,
num_cliffords=depth,
trials=trials,
return_type=return_type,
)
for qc in circuits:
assert return_type in qc.__module__

0 comments on commit 3da2973

Please sign in to comment.