From 6cec9124955ec175512616f728d9d5eedab3b4c0 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Mon, 20 Mar 2023 13:26:41 -0400 Subject: [PATCH] Fix non-complex dtypes in OneQubitEulerDecomposer methods (#9828) * Fix non-complex dtypes in OneQubitEulerDecomposer methods This commit fixes a regression introduced in the rewrite of the internals of the OneQubitEulerDecomposer class to be in rust. Previously the angles() and angles_and_phase() methods of OneQubitEulerDecomposer would work with a non-complex dtype in the input, however because the rust component of the module is strictly typed to only work with a complex128 dtype passing the array to rust to compute the angles and phase of the unitary would fail. To address this limitation this commit casts the input matrix to be complex before passing it to the rust function. Fixes #9827 * Cleanup release note * Update test/python/quantum_info/test_synthesis.py Co-authored-by: Jake Lishman --------- Co-authored-by: Jake Lishman --- .../synthesis/one_qubit_decompose.py | 2 + ...gles-euler-decompose-233e5cee7205ed03.yaml | 10 +++++ test/python/quantum_info/test_synthesis.py | 38 +++++++++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 releasenotes/notes/fix-type-angles-euler-decompose-233e5cee7205ed03.yaml diff --git a/qiskit/quantum_info/synthesis/one_qubit_decompose.py b/qiskit/quantum_info/synthesis/one_qubit_decompose.py index cffa0b05682a..4df6613f5484 100644 --- a/qiskit/quantum_info/synthesis/one_qubit_decompose.py +++ b/qiskit/quantum_info/synthesis/one_qubit_decompose.py @@ -252,6 +252,7 @@ def angles(self, unitary): Returns: tuple: (theta, phi, lambda). """ + unitary = np.asarray(unitary, dtype=complex) theta, phi, lam, _ = self._params(unitary) return theta, phi, lam @@ -264,6 +265,7 @@ def angles_and_phase(self, unitary): Returns: tuple: (theta, phi, lambda, phase). """ + unitary = np.asarray(unitary, dtype=complex) return self._params(unitary) _params_zyz = staticmethod(euler_one_qubit_decomposer.params_zyz) diff --git a/releasenotes/notes/fix-type-angles-euler-decompose-233e5cee7205ed03.yaml b/releasenotes/notes/fix-type-angles-euler-decompose-233e5cee7205ed03.yaml new file mode 100644 index 000000000000..ce25e4697997 --- /dev/null +++ b/releasenotes/notes/fix-type-angles-euler-decompose-233e5cee7205ed03.yaml @@ -0,0 +1,10 @@ +--- +fixes: + - | + Fixed an issue with the :class:`~.OneQubitEulerDecomposer` class's methods + :meth:`~.OneQubitEulerDecomposer.angles` and :meth:`~.OneQubitEulerDecomposer.angles_and_phase` + would error if the input matrix was of a dtype other than ``complex``/``np.cdouble``. In earlier + releases this worked fine but this stopped working in Qiskit Terra 0.23.0 + when the internals of :class:`~.OneQubitEulerDecomposer` were re-written + in Rust. + Fixed `#9827 `__ diff --git a/test/python/quantum_info/test_synthesis.py b/test/python/quantum_info/test_synthesis.py index ac5119604591..099ffb87191e 100644 --- a/test/python/quantum_info/test_synthesis.py +++ b/test/python/quantum_info/test_synthesis.py @@ -591,6 +591,44 @@ def test_psx_zsx_special_cases(self): self.assertTrue(np.allclose(unitary, Operator(qc_zsx).data)) self.assertTrue(np.allclose(unitary, Operator(qc_zsxx).data)) + def test_float_input_angles_and_phase(self): + """Test angles and phase with float input.""" + decomposer = OneQubitEulerDecomposer("PSX") + input_matrix = np.array( + [ + [0.70710678, 0.70710678], + [0.70710678, -0.70710678], + ], + dtype=np.float64, + ) + (theta, phi, lam, gamma) = decomposer.angles_and_phase(input_matrix) + expected_theta = 1.5707963267948966 + expected_phi = 0.0 + expected_lam = 3.141592653589793 + expected_gamma = -0.7853981633974483 + self.assertAlmostEqual(theta, expected_theta) + self.assertAlmostEqual(phi, expected_phi) + self.assertAlmostEqual(lam, expected_lam) + self.assertAlmostEqual(gamma, expected_gamma) + + def test_float_input_angles(self): + """Test angles with float input.""" + decomposer = OneQubitEulerDecomposer("PSX") + input_matrix = np.array( + [ + [0.70710678, 0.70710678], + [0.70710678, -0.70710678], + ], + dtype=np.float64, + ) + (theta, phi, lam) = decomposer.angles(input_matrix) + expected_theta = 1.5707963267948966 + expected_phi = 0.0 + expected_lam = 3.141592653589793 + self.assertAlmostEqual(theta, expected_theta) + self.assertAlmostEqual(phi, expected_phi) + self.assertAlmostEqual(lam, expected_lam) + # FIXME: streamline the set of test cases class TestTwoQubitWeylDecomposition(CheckDecompositions):