Source code for mitiq.benchmarks.randomized_clifford_t_circuit

# 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.

from typing import Optional

import cirq
import numpy as np

from mitiq import QPROGRAM
from mitiq.interface import convert_from_mitiq


[docs] def generate_random_clifford_t_circuit( num_qubits: int, num_oneq_cliffords: int, num_twoq_cliffords: int, num_t_gates: int, return_type: Optional[str] = None, seed: Optional[int] = None, ) -> QPROGRAM: r"""Generate a random quantum circuit with the given number of qubits, number of one-qubit Cliffords, number of two-qubit Cliffords and number of T gates. Args: num_qubits: The number of qubits in the generated circuit. num_oneq_cliffords: Number of one-qubit Cliffords to be used. num_twoq_cliffords: Number of two-qubit Cliffords to be used. num_t_gates: Number of T gates to be used. 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 circuit acting on ``num_qubits`` qubits. """ if num_qubits <= 0: raise ValueError( "Cannot prepare a circuit with {} qubits.", num_qubits ) elif num_qubits == 1 and num_twoq_cliffords > 0: raise ValueError( "Need more than 2 qubits for two-qubit Clifford gates." ) rnd_state = np.random.RandomState(seed) oneq_cliffords = [cirq.S, cirq.H] twoq_cliffords = [cirq.CNOT, cirq.CZ] oneq_idx_list = rnd_state.choice(len(oneq_cliffords), num_oneq_cliffords) twoq_idx_list = rnd_state.choice(len(twoq_cliffords), num_twoq_cliffords) oneq_list = [oneq_cliffords[i] for i in oneq_idx_list] twoq_list = [twoq_cliffords[i] for i in twoq_idx_list] t_list = [cirq.T for _ in range(num_t_gates)] all_gates = oneq_list + twoq_list + t_list rnd_state.shuffle(all_gates) qubits = cirq.LineQubit.range(num_qubits) circuit = cirq.Circuit() qubits_idx = list(range(num_qubits)) for gate in all_gates: qubits_for_gate_idx = rnd_state.choice( qubits_idx, size=gate.num_qubits(), replace=False ) qubits_for_gate = [qubits[i] for i in qubits_for_gate_idx] operation = gate.on(*qubits_for_gate) circuit.append(operation) return_type = "cirq" if not return_type else return_type return convert_from_mitiq(circuit, return_type)