From 011083eee0669052022151943f632c13f52e2a7e Mon Sep 17 00:00:00 2001 From: Glanz Date: Mon, 5 Aug 2024 09:55:18 -0400 Subject: [PATCH] Support basic single qubit controlled gates (#89) * Support basic single qubit controlled gates - The single controlled gate sets are supported but requires a slight modification - The multicontrolled gates can be considered in future versions * Lint fixes * Remove string based comparision and move to dict * Add test cases * Lint: Single qubit gates * Update tests/pyquil_convert_test.py --------- Co-authored-by: cqc-melf <70640934+cqc-melf@users.noreply.github.com> --- pytket/extensions/pyquil/pyquil_convert.py | 13 +++++++++++- tests/pyquil_convert_test.py | 23 ++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/pytket/extensions/pyquil/pyquil_convert.py b/pytket/extensions/pyquil/pyquil_convert.py index 74bbd4a..7d7e17d 100644 --- a/pytket/extensions/pyquil/pyquil_convert.py +++ b/pytket/extensions/pyquil/pyquil_convert.py @@ -71,11 +71,16 @@ "PHASE": OpType.U1, "SWAP": OpType.SWAP, "XY": OpType.ISWAP, + "CH": OpType.CH, + "CY": OpType.CY, } _known_quil_gate_rev = {v: k for k, v in _known_quil_gate.items()} +# Gates with single controlled operation +_single_control_gates = {"CH": "H", "CY": "Y"} + def param_to_pyquil(p: Union[float, Expr]) -> Union[float, Expression]: ppi = p * pi @@ -302,7 +307,13 @@ def tk_to_pyquil( "Cannot convert tket Op to pyQuil gate: " + op.get_name() ) from error params = [param_to_pyquil(p) for p in op.params] - g = Gate(gatetype, params, qubits) + if gatetype in _single_control_gates: + g = Gate(_single_control_gates[gatetype], params, [qubits[1]]).controlled( + qubits[0] + ) + else: + g = Gate(gatetype, params, qubits) + p += g for m in measures: p += m diff --git a/tests/pyquil_convert_test.py b/tests/pyquil_convert_test.py index cd0fc39..b9ee8ec 100644 --- a/tests/pyquil_convert_test.py +++ b/tests/pyquil_convert_test.py @@ -132,6 +132,29 @@ def test_from_tket() -> None: ) # 5 gates, 2 measures, and an initial declaration of classical register +def test_conversion_of_controlled_y() -> None: + single_controlled_gates_attributes = [ + {"name": "Y", "qubits": [0, 1]}, + {"name": "H", "qubits": [1, 0]}, + ] + c = Circuit(2, 2) + c.CY(*single_controlled_gates_attributes[0]["qubits"]) + c.CH(*single_controlled_gates_attributes[1]["qubits"]) + + p = tk_to_pyquil(c) + + for i, attributes in enumerate(single_controlled_gates_attributes): + Instruction = p.instructions[i + 1] + for attribute in attributes: + expected_attribute_value = attributes[attribute] + value = getattr(Instruction, attribute) + if attribute == "qubits": + for i, expected_qubit_index in enumerate(expected_attribute_value): + assert value[i].index == expected_qubit_index + else: + assert value == expected_attribute_value + + def test_measure() -> None: p = get_test_program(True) m_map = {}