From 36807d1d6e957585053d6a6d29c63e72f122c7bb Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 20 Mar 2023 19:41:35 +0000 Subject: [PATCH] Fix non-complex dtypes in OneQubitEulerDecomposer methods (#9828) (#9829) * 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 (cherry picked from commit 6cec9124955ec175512616f728d9d5eedab3b4c0) Co-authored-by: Matthew Treinish --- .../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 449b91fd0799..a563fabf031f 100644 --- a/qiskit/quantum_info/synthesis/one_qubit_decompose.py +++ b/qiskit/quantum_info/synthesis/one_qubit_decompose.py @@ -227,6 +227,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 @@ -239,6 +240,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):