diff --git a/qiskit/circuit/library/standard_gates/equivalence_library.py b/qiskit/circuit/library/standard_gates/equivalence_library.py index 9793dc0202a8..c4619ca27858 100644 --- a/qiskit/circuit/library/standard_gates/equivalence_library.py +++ b/qiskit/circuit/library/standard_gates/equivalence_library.py @@ -850,6 +850,56 @@ def _cnot_rxx_decompose(plus_ry: bool = True, plus_rxx: bool = True): def_swap.append(inst, qargs, cargs) _sel.add_equivalence(SwapGate(), def_swap) +# SwapGate +# +# q_0: ─X─ +# │ ≡ +# q_1: ─X─ +# +# ┌──────────┐┌──────┐ ┌────┐ ┌──────┐┌──────────┐┌──────┐ +# q_0: ┤ Rz(-π/2) ├┤0 ├───┤ √X ├───┤1 ├┤ Rz(-π/2) ├┤0 ├ +# └──┬────┬──┘│ Ecr │┌──┴────┴──┐│ Ecr │└──┬────┬──┘│ Ecr │ +# q_1: ───┤ √X ├───┤1 ├┤ Rz(-π/2) ├┤0 ├───┤ √X ├───┤1 ├ +# └────┘ └──────┘└──────────┘└──────┘ └────┘ └──────┘ +# +q = QuantumRegister(2, "q") +def_swap_ecr = QuantumCircuit(q) +def_swap_ecr.rz(-pi / 2, 0) +def_swap_ecr.sx(1) +def_swap_ecr.ecr(0, 1) +def_swap_ecr.rz(-pi / 2, 1) +def_swap_ecr.sx(0) +def_swap_ecr.ecr(1, 0) +def_swap_ecr.rz(-pi / 2, 0) +def_swap_ecr.sx(1) +def_swap_ecr.ecr(0, 1) +_sel.add_equivalence(SwapGate(), def_swap_ecr) + +# SwapGate +# +# q_0: ─X─ +# │ ≡ +# q_1: ─X─ +# +# global phase: 3π/2 +# ┌────┐ ┌────┐ ┌────┐ +# q_0: ┤ √X ├─■─┤ √X ├─■─┤ √X ├─■─ +# ├────┤ │ ├────┤ │ ├────┤ │ +# q_1: ┤ √X ├─■─┤ √X ├─■─┤ √X ├─■─ +# └────┘ └────┘ └────┘ +q = QuantumRegister(2, "q") +def_swap_cz = QuantumCircuit(q, global_phase=-pi / 2) +def_swap_cz.sx(0) +def_swap_cz.sx(1) +def_swap_cz.cz(0, 1) +def_swap_cz.sx(0) +def_swap_cz.sx(1) +def_swap_cz.cz(0, 1) +def_swap_cz.sx(0) +def_swap_cz.sx(1) +def_swap_cz.cz(0, 1) +_sel.add_equivalence(SwapGate(), def_swap_cz) + # iSwapGate # # ┌────────┐ ┌───┐┌───┐ ┌───┐ diff --git a/test/python/circuit/test_gate_definitions.py b/test/python/circuit/test_gate_definitions.py index 8e608a163900..38bf7046cae5 100644 --- a/test/python/circuit/test_gate_definitions.py +++ b/test/python/circuit/test_gate_definitions.py @@ -21,6 +21,7 @@ from qiskit import QuantumCircuit, QuantumRegister from qiskit.quantum_info import Operator from qiskit.circuit import ParameterVector, Gate, ControlledGate +from qiskit.circuit.singleton import SingletonGate, SingletonControlledGate from qiskit.circuit.library import standard_gates from qiskit.circuit.library import ( HGate, @@ -260,7 +261,12 @@ class TestGateEquivalenceEqual(QiskitTestCase): """Test the decomposition of a gate in terms of other gates yields the same matrix as the hardcoded matrix definition.""" - class_list = Gate.__subclasses__() + ControlledGate.__subclasses__() + class_list = ( + SingletonGate.__subclasses__() + + SingletonControlledGate.__subclasses__() + + Gate.__subclasses__() + + ControlledGate.__subclasses__() + ) exclude = { "ControlledGate", "DiagonalGate", @@ -313,7 +319,11 @@ def test_equivalence_phase(self, gate_class): with self.subTest(msg=gate.name + "_" + str(ieq)): op1 = Operator(gate) op2 = Operator(equivalency) - self.assertEqual(op1, op2) + msg = ( + f"Equivalence entry from '{gate.name}' to:\n" + f"{str(equivalency.draw('text'))}\nfailed" + ) + self.assertEqual(op1, op2, msg) @ddt diff --git a/test/qpy_compat/test_qpy.py b/test/qpy_compat/test_qpy.py index 58ee1abc2a2f..438b002f11bd 100755 --- a/test/qpy_compat/test_qpy.py +++ b/test/qpy_compat/test_qpy.py @@ -661,7 +661,7 @@ def generate_annotated_circuits(): CXGate(), [InverseModifier(), ControlModifier(1), PowerModifier(1.4), InverseModifier()] ) op2 = AnnotatedOperation(XGate(), InverseModifier()) - qc = QuantumCircuit(6, 1) + qc = QuantumCircuit(6, 1, name="Annotated circuits") qc.cx(0, 1) qc.append(op1, [0, 1, 2]) qc.h(4)