diff --git a/qiskit/circuit/random/utils.py b/qiskit/circuit/random/utils.py index 71809735aa8e..8e4ff1043298 100644 --- a/qiskit/circuit/random/utils.py +++ b/qiskit/circuit/random/utils.py @@ -18,6 +18,7 @@ from qiskit.circuit import Reset from qiskit.circuit.library import standard_gates from qiskit.circuit.exceptions import CircuitError +from qiskit.quantum_info.operators.symplectic.clifford_circuits import _BASIS_1Q, _BASIS_2Q def random_circuit( @@ -207,3 +208,76 @@ def random_circuit( qc.measure(qc.qubits, cr) return qc +<<<<<<< HEAD +======= + + +def random_clifford_circuit(num_qubits, num_gates, gates="all", seed=None): + """Generate a pseudo-random Clifford circuit. + + This function will generate a Clifford circuit by randomly selecting the chosen amount of Clifford + gates from the set of standard gates in :mod:`qiskit.circuit.library.standard_gates`. For example: + + .. plot:: + :include-source: + + from qiskit.circuit.random import random_clifford_circuit + + circ = random_clifford_circuit(num_qubits=2, num_gates=6) + circ.draw(output='mpl') + + Args: + num_qubits (int): number of quantum wires. + num_gates (int): number of gates in the circuit. + gates (list[str]): optional list of Clifford gate names to randomly sample from. + If ``"all"`` (default), use all Clifford gates in the standard library. + seed (int | np.random.Generator): sets random seed/generator (optional). + + Returns: + QuantumCircuit: constructed circuit + """ + + gates_1q = list(set(_BASIS_1Q.keys()) - {"v", "w", "id", "iden", "sinv"}) + gates_2q = list(_BASIS_2Q.keys()) + + if gates == "all": + if num_qubits == 1: + gates = gates_1q + else: + gates = gates_1q + gates_2q + + instructions = { + "i": (standard_gates.IGate(), 1), + "x": (standard_gates.XGate(), 1), + "y": (standard_gates.YGate(), 1), + "z": (standard_gates.ZGate(), 1), + "h": (standard_gates.HGate(), 1), + "s": (standard_gates.SGate(), 1), + "sdg": (standard_gates.SdgGate(), 1), + "sx": (standard_gates.SXGate(), 1), + "sxdg": (standard_gates.SXdgGate(), 1), + "cx": (standard_gates.CXGate(), 2), + "cy": (standard_gates.CYGate(), 2), + "cz": (standard_gates.CZGate(), 2), + "swap": (standard_gates.SwapGate(), 2), + "iswap": (standard_gates.iSwapGate(), 2), + "ecr": (standard_gates.ECRGate(), 2), + "dcx": (standard_gates.DCXGate(), 2), + } + + if isinstance(seed, np.random.Generator): + rng = seed + else: + rng = np.random.default_rng(seed) + + samples = rng.choice(gates, num_gates) + + circ = QuantumCircuit(num_qubits) + + for name in samples: + gate, nqargs = instructions[name] + qargs = rng.choice(range(num_qubits), nqargs, replace=False).tolist() + circ.append(gate, qargs, copy=False) + + return circ +>>>>>>> 41267ecf5 (Add clifford gates to collect_cliffords (#12750)) diff --git a/qiskit/transpiler/passes/optimization/collect_cliffords.py b/qiskit/transpiler/passes/optimization/collect_cliffords.py index c0e9641923cd..40acd21c6855 100644 --- a/qiskit/transpiler/passes/optimization/collect_cliffords.py +++ b/qiskit/transpiler/passes/optimization/collect_cliffords.py @@ -22,6 +22,7 @@ ) from qiskit.quantum_info.operators import Clifford +from qiskit.quantum_info.operators.symplectic.clifford_circuits import _BASIS_1Q, _BASIS_2Q class CollectCliffords(CollectAndCollapse): @@ -69,21 +70,11 @@ def __init__( ) -clifford_gate_names = [ - "x", - "y", - "z", - "h", - "s", - "sdg", - "cx", - "cy", - "cz", - "swap", - "clifford", - "linear_function", - "pauli", -] +clifford_gate_names = ( + list(_BASIS_1Q.keys()) + + list(_BASIS_2Q.keys()) + + ["clifford", "linear_function", "pauli", "permutation"] +) def _is_clifford_gate(node): diff --git a/releasenotes/notes/fix-collect-clifford-83af26d98b8c69e8.yaml b/releasenotes/notes/fix-collect-clifford-83af26d98b8c69e8.yaml new file mode 100644 index 000000000000..48eac19acc9d --- /dev/null +++ b/releasenotes/notes/fix-collect-clifford-83af26d98b8c69e8.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + Add more Clifford gates to the :class:`.CollectCliffords()` transpiler pass. + In particular, we have added the gates :class:`ECRGate()`, :class:`DCXGate()`, + :class:`iSWAPGate()`, :class:`SXGate()` and :class:`SXdgGate()` to this transpiler pass.