Source code for mitiq.benchmarks.mirror_qv_circuits

# 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 to create a Mirror Quantum Volume Benchmarking circuit
as defined in https://arxiv.org/abs/2303.02108."""

from typing import Optional, cast

import cirq

from mitiq import QPROGRAM
from mitiq.benchmarks.quantum_volume_circuits import (
    generate_quantum_volume_circuit,
)
from mitiq.interface.conversions import convert_from_mitiq


[docs] def generate_mirror_qv_circuit( num_qubits: int, depth: int, decompose: bool = False, seed: Optional[int] = None, return_type: Optional[str] = None, ) -> QPROGRAM: """Generate a mirror quantum volume circuit with the given number of qubits and depth as defined in :cite:`Amico_2023_arxiv`. The generated circuit consists of a quantum volume circuit up to `depth/2` layers followed by an inverse of the quantum volume portion up to `depth/2` when `depth` is an even number. When `depth` is odd, the layers will be changed to `depth+1`. The ideal output bit-string is a string of zeroes. Args: num_qubits: The number of qubits in the generated circuit. depth: The number of layers in the generated circuit. decompose: Recursively decomposes the randomly sampled (numerical) unitary matrix gates into simpler gates. seed: Seed for generating random circuit. 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``. Returns: A quantum volume circuit acting on ``num_qubits`` qubits. """ if depth <= 0: raise ValueError( "{} is invalid for the generated circuit depth.", depth ) if depth % 2 == 0: first_half_depth = int(depth / 2) else: first_half_depth = int((depth + 1) / 2) qv_circuit, _ = generate_quantum_volume_circuit( num_qubits, first_half_depth, seed=seed, decompose=decompose ) qv_circuit = cast(cirq.Circuit, qv_circuit) mirror_qv_circuit = qv_circuit + cirq.inverse(qv_circuit) if decompose: # Decompose random unitary gates into simpler gates. mirror_qv_circuit = cirq.Circuit(cirq.decompose(mirror_qv_circuit)) return_type = "cirq" if not return_type else return_type return convert_from_mitiq(mirror_qv_circuit, return_type)