From d86f9958516ee7f48359ddc7364050bb791602d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elena=20Pe=C3=B1a=20Tapia?= <57907331+ElePT@users.noreply.github.com> Date: Tue, 9 Jul 2024 12:25:54 +0200 Subject: [PATCH] Fix `C3SXGate` `to_matrix` method (#12742) * Fix c3sx matrix * Apply Jake's suggestion --- qiskit/circuit/library/standard_gates/x.py | 2 ++ .../notes/fix-c3sx-gate-matrix-050cf9f9ac3b2b82.yaml | 5 +++++ test/python/circuit/test_controlled_gate.py | 6 ++++++ test/python/circuit/test_rust_equivalence.py | 4 ---- 4 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 releasenotes/notes/fix-c3sx-gate-matrix-050cf9f9ac3b2b82.yaml diff --git a/qiskit/circuit/library/standard_gates/x.py b/qiskit/circuit/library/standard_gates/x.py index 5605038680d1..614b4f4d2dd6 100644 --- a/qiskit/circuit/library/standard_gates/x.py +++ b/qiskit/circuit/library/standard_gates/x.py @@ -22,6 +22,7 @@ from qiskit._accelerate.circuit import StandardGate _X_ARRAY = [[0, 1], [1, 0]] +_SX_ARRAY = [[0.5 + 0.5j, 0.5 - 0.5j], [0.5 - 0.5j, 0.5 + 0.5j]] @with_gate_array(_X_ARRAY) @@ -571,6 +572,7 @@ def __eq__(self, other): return isinstance(other, RCCXGate) +@with_controlled_gate_array(_SX_ARRAY, num_ctrl_qubits=3, cached_states=(7,)) class C3SXGate(SingletonControlledGate): """The 3-qubit controlled sqrt-X gate. diff --git a/releasenotes/notes/fix-c3sx-gate-matrix-050cf9f9ac3b2b82.yaml b/releasenotes/notes/fix-c3sx-gate-matrix-050cf9f9ac3b2b82.yaml new file mode 100644 index 000000000000..accd20de4ae5 --- /dev/null +++ b/releasenotes/notes/fix-c3sx-gate-matrix-050cf9f9ac3b2b82.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Fixed a missing decorator in :class:`.C3SXGate` that made it fail if :meth:`.Gate.to_matrix` was called. + The gate matrix is now return as expected. diff --git a/test/python/circuit/test_controlled_gate.py b/test/python/circuit/test_controlled_gate.py index c845077d32dc..e36ee04e2162 100644 --- a/test/python/circuit/test_controlled_gate.py +++ b/test/python/circuit/test_controlled_gate.py @@ -230,6 +230,12 @@ def test_special_cases_equivalent_to_controlled_base_gate(self): # Ensure that both the array form (if the gate overrides `__array__`) and the # circuit-definition form are tested. self.assertTrue(Operator(special_case_gate).equiv(naive_operator)) + if not isinstance(special_case_gate, (MCXGate, MCPhaseGate, MCU1Gate)): + # Ensure that the to_matrix method yields the same result + np.testing.assert_allclose( + special_case_gate.to_matrix(), naive_operator.to_matrix(), atol=1e-8 + ) + if not isinstance(special_case_gate, CXGate): # CX is treated like a primitive within Terra, and doesn't have a definition. self.assertTrue(Operator(special_case_gate.definition).equiv(naive_operator)) diff --git a/test/python/circuit/test_rust_equivalence.py b/test/python/circuit/test_rust_equivalence.py index c344ff309964..29cc0723bb60 100644 --- a/test/python/circuit/test_rust_equivalence.py +++ b/test/python/circuit/test_rust_equivalence.py @@ -26,7 +26,6 @@ SKIP_LIST = {"rx", "ry", "ecr"} CUSTOM_NAME_MAPPING = {"mcx": C3XGate()} -MATRIX_SKIP_LIST = {"c3sx"} class TestRustGateEquivalence(QiskitTestCase): @@ -141,9 +140,6 @@ def test_matrix(self): """Test matrices are the same in rust space.""" for name, gate_class in self.standard_gates.items(): standard_gate = getattr(gate_class, "_standard_gate", None) - if name in MATRIX_SKIP_LIST: - # to_matrix not defined for type - continue if standard_gate is None: # gate is not in rust yet continue