From bd60a1f0e81b676de306c4c7be7bac3096e16e6e Mon Sep 17 00:00:00 2001 From: "Kevin J. Sung" Date: Wed, 4 Jan 2023 04:40:32 -0500 Subject: [PATCH] Fix dtype bug in BogoliubovTransform (#1014) * make givens_matrix always return complex * slater: cast to complex * fix typo in release note * fix docstring and comments * undo givens_matrix change; instead, fix bug directly * revert untouched file Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- .../circuit/library/bogoliubov_transform.py | 4 ++-- qiskit_nature/utils/linalg.py | 6 +++--- .../notes/givens-fix-a12cb547cf5a1be4.yaml | 5 +++++ .../circuit/library/test_bogoliubov_transform.py | 15 ++++++++++++++- 4 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 releasenotes/notes/givens-fix-a12cb547cf5a1be4.yaml diff --git a/qiskit_nature/second_q/circuit/library/bogoliubov_transform.py b/qiskit_nature/second_q/circuit/library/bogoliubov_transform.py index 1cce639f6a..72c5e5b09a 100644 --- a/qiskit_nature/second_q/circuit/library/bogoliubov_transform.py +++ b/qiskit_nature/second_q/circuit/library/bogoliubov_transform.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2022. +# (C) Copyright IBM 2022, 2023. # # This code is licensed under the Apache License, Version 2.0. You may # obtain a copy of this license in the LICENSE.txt file in the root directory @@ -244,7 +244,7 @@ def _bogoliubov_transform_num_conserving_jw( # pylint: disable=invalid-name # convert left rotations to right rotations for givens_mat, (i, j) in reversed(left_rotations): - givens_mat = givens_mat.T.conj() + givens_mat = givens_mat.T.conj().astype(complex, copy=False) givens_mat[:, 0] *= current_matrix[i, i] givens_mat[:, 1] *= current_matrix[j, j] new_givens_mat = givens_matrix(givens_mat[1, 1], givens_mat[1, 0]) diff --git a/qiskit_nature/utils/linalg.py b/qiskit_nature/utils/linalg.py index 24ba8ee07f..a76f3f30e3 100644 --- a/qiskit_nature/utils/linalg.py +++ b/qiskit_nature/utils/linalg.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2022. +# (C) Copyright IBM 2022, 2023. # # This code is licensed under the Apache License, Version 2.0. You may # obtain a copy of this license in the LICENSE.txt file in the root directory @@ -129,9 +129,9 @@ def fermionic_gaussian_decomposition_jw( # pylint: disable=invalid-name # compute left_unitary left_unitary = np.eye(n, dtype=complex) for j in range(n - 1): - # Zero out entries in column k + # Zero out entries in column j for i in range(n - 1 - j): - # Zero out entry in row l if needed + # Zero out entry in row i if needed if not np.isclose(current_matrix[i, j], 0.0): givens_mat = givens_matrix(current_matrix[i + 1, j], current_matrix[i, j]) current_matrix = apply_matrix_to_slices(current_matrix, givens_mat, [i + 1, i]) diff --git a/releasenotes/notes/givens-fix-a12cb547cf5a1be4.yaml b/releasenotes/notes/givens-fix-a12cb547cf5a1be4.yaml new file mode 100644 index 0000000000..2389b81680 --- /dev/null +++ b/releasenotes/notes/givens-fix-a12cb547cf5a1be4.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Fixes a bug in which :class:`~.BogoliubovTransform` would sometimes throw an error due to an inability to + cast complex numbers to floats. \ No newline at end of file diff --git a/test/second_q/circuit/library/test_bogoliubov_transform.py b/test/second_q/circuit/library/test_bogoliubov_transform.py index a3de3894e2..ebce5bb618 100644 --- a/test/second_q/circuit/library/test_bogoliubov_transform.py +++ b/test/second_q/circuit/library/test_bogoliubov_transform.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2022. +# (C) Copyright IBM 2022, 2023. # # This code is licensed under the Apache License, Version 2.0. You may # obtain a copy of this license in the LICENSE.txt file in the root directory @@ -98,6 +98,19 @@ def test_bogoliubov_transform_compose_general(self, n_orbitals): self.assertTrue(Operator(circuit).equiv(Operator(bog_circuit_composed), atol=1e-8)) + def test_bogoliubov_transform_jw_inverse_general_identity(self): + """Test Bogoliubov transform for the identity transformation.""" + n_orbitals = 3 + mat = np.eye(n_orbitals, 2 * n_orbitals, k=n_orbitals) + bog = BogoliubovTransform(mat) + + register = QuantumRegister(n_orbitals) + circuit = QuantumCircuit(register) + circuit.append(bog, register) + circuit.append(bog.inverse(), register) + + self.assertTrue(Operator(circuit).equiv(np.eye(2**n_orbitals), atol=1e-8)) + def test_no_side_effects(self): """Test that the routines don't mutate the input array.""" n_orbitals = 5