From b896f4cab1b3f755001a28fbb9dcf4a0e69569b0 Mon Sep 17 00:00:00 2001 From: Jim Garrison Date: Tue, 27 Jun 2023 13:26:08 -0400 Subject: [PATCH] Add support for cut `CYGate`s and `CHGate`s (#290) * Add support for cut `CYGate`s * Fix release note syntax * Add support for cut `CHGate`s * Update docstring * Fix number in docstring * DRY --- circuit_knitting/cutting/qpd/qpd.py | 25 +++++++++++++------ .../additional-gates-f4ed6c0e8dc3a9be.yaml | 6 +++++ test/cutting/qpd/test_qpd.py | 4 ++- test/cutting/test_cutting_roundtrip.py | 4 +++ 4 files changed, 31 insertions(+), 8 deletions(-) create mode 100644 releasenotes/notes/additional-gates-f4ed6c0e8dc3a9be.yaml diff --git a/circuit_knitting/cutting/qpd/qpd.py b/circuit_knitting/cutting/qpd/qpd.py index 995f5d781..6771798c0 100644 --- a/circuit_knitting/cutting/qpd/qpd.py +++ b/circuit_knitting/cutting/qpd/qpd.py @@ -37,7 +37,9 @@ RYGate, RZGate, CXGate, + CYGate, CZGate, + CHGate, RXXGate, RYYGate, RZZGate, @@ -191,7 +193,7 @@ def qpdbasis_from_gate(gate: Gate) -> QPDBasis: """ Generate a QPDBasis object, given a supported operation. - This method currently supports 8 operations: + This method currently supports 10 operations: - :class:`~qiskit.circuit.library.RXXGate` - :class:`~qiskit.circuit.library.RYYGate` - :class:`~qiskit.circuit.library.RZZGate` @@ -199,7 +201,9 @@ def qpdbasis_from_gate(gate: Gate) -> QPDBasis: - :class:`~qiskit.circuit.library.CRYGate` - :class:`~qiskit.circuit.library.CRZGate` - :class:`~qiskit.circuit.library.CXGate` + - :class:`~qiskit.circuit.library.CYGate` - :class:`~qiskit.circuit.library.CZGate` + - :class:`~qiskit.circuit.library.CHGate` Returns: The newly-instantiated :class:`QPDBasis` object @@ -304,8 +308,8 @@ def _(gate: RXXGate | RYYGate | RZZGate | CRXGate | CRYGate | CRZGate): return QPDBasis(maps, coeffs) -@_register_qpdbasis_from_gate("cz", "cx") -def _(gate: CZGate | CXGate): +@_register_qpdbasis_from_gate("cx", "cy", "cz", "ch") +def _(gate: CXGate | CYGate | CZGate | CHGate): # Constructing a virtual two-qubit gate by sampling single-qubit operations - Mitarai et al # https://iopscience.iop.org/article/10.1088/1367-2630/abd7bc/pdf measurement_0 = [SdgGate(), QPDMeasure()] @@ -323,12 +327,19 @@ def _(gate: CZGate | CXGate): ([ZGate()], measurement_1), ] - if gate.name == "cx": - # Modify `maps` to sandwich the target operations inside of Hadamards + if gate.name != "cz": + # Modify `maps` to sandwich the target operations inside of basis rotations for operations in {id(m[1]): m[1] for m in maps}.values(): if operations: - operations.insert(0, HGate()) - operations.append(HGate()) + if gate.name in ("cx", "cy"): + operations.insert(0, HGate()) + operations.append(HGate()) + if gate.name == "cy": + operations.insert(0, SdgGate()) + operations.append(SGate()) + elif gate.name == "ch": + operations.insert(0, RYGate(-np.pi / 4)) + operations.append(RYGate(np.pi / 4)) coeffs = [0.5, 0.5, 0.5, -0.5, 0.5, -0.5] diff --git a/releasenotes/notes/additional-gates-f4ed6c0e8dc3a9be.yaml b/releasenotes/notes/additional-gates-f4ed6c0e8dc3a9be.yaml new file mode 100644 index 000000000..a69953cc8 --- /dev/null +++ b/releasenotes/notes/additional-gates-f4ed6c0e8dc3a9be.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + This release adds support for additional cut gates: + - :class:`~qiskit.circuit.library.CHGate` + - :class:`~qiskit.circuit.library.CYGate` diff --git a/test/cutting/qpd/test_qpd.py b/test/cutting/qpd/test_qpd.py index 56f4fc555..144b2849d 100644 --- a/test/cutting/qpd/test_qpd.py +++ b/test/cutting/qpd/test_qpd.py @@ -282,4 +282,6 @@ def test_qpdbasis_from_gate_unique_maps( def test_supported_gates(self): gates = supported_gates() - self.assertEqual({"rxx", "ryy", "rzz", "crx", "cry", "crz", "cx", "cz"}, gates) + self.assertEqual( + {"rxx", "ryy", "rzz", "crx", "cry", "crz", "cx", "cy", "cz", "ch"}, gates + ) diff --git a/test/cutting/test_cutting_roundtrip.py b/test/cutting/test_cutting_roundtrip.py index be6eeea13..be36cbacd 100644 --- a/test/cutting/test_cutting_roundtrip.py +++ b/test/cutting/test_cutting_roundtrip.py @@ -21,7 +21,9 @@ RXXGate, RYYGate, RZZGate, + CHGate, CXGate, + CYGate, CZGate, CRXGate, CRYGate, @@ -49,7 +51,9 @@ def append_random_unitary(circuit: QuantumCircuit, qubits): @pytest.fixture( params=[ [CXGate()], + [CYGate()], [CZGate()], + [CHGate()], [RYYGate(0.0)], [RZZGate(np.pi)], [RXXGate(np.pi / 3)],