From f5fdf1f79172a7300ecd5bfe7594d0297c55baaa Mon Sep 17 00:00:00 2001 From: "Peter Chen J." <34339487+peter941221@users.noreply.github.com> Date: Wed, 29 Jul 2026 17:15:38 +0800 Subject: [PATCH] Preserve StatePreparation width in inverse (#16431) * Preserve StatePreparation width in inverse * Strengthen StatePreparation inverse regression * Address StatePreparation inverse review * Respect StatePreparation inverse input contract (cherry picked from commit d94420ad3e41ddb8bff94cc5f4d41ec74cecbc82) --- .../data_preparation/state_preparation.py | 5 +++- ...e-preserve-int-width-3e184153a463f3dd.yaml | 7 +++++ .../circuit/library/test_state_preparation.py | 30 +++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/stateprep-inverse-preserve-int-width-3e184153a463f3dd.yaml diff --git a/qiskit/circuit/library/data_preparation/state_preparation.py b/qiskit/circuit/library/data_preparation/state_preparation.py index a96b6354154e..782201d725e2 100644 --- a/qiskit/circuit/library/data_preparation/state_preparation.py +++ b/qiskit/circuit/library/data_preparation/state_preparation.py @@ -207,7 +207,10 @@ def inverse(self, annotated: bool = False): None if self._label in ("State Preparation", "State Preparation Dg") else self._label ) - return StatePreparation(self._params_arg, inverse=not self._inverse, label=label) + num_qubits = self.num_qubits if self._from_int else None + return StatePreparation( + self._params_arg, num_qubits=num_qubits, inverse=not self._inverse, label=label + ) def broadcast_arguments(self, qargs, cargs): flat_qargs = [qarg for sublist in qargs for qarg in sublist] diff --git a/releasenotes/notes/stateprep-inverse-preserve-int-width-3e184153a463f3dd.yaml b/releasenotes/notes/stateprep-inverse-preserve-int-width-3e184153a463f3dd.yaml new file mode 100644 index 000000000000..2c022e3b8428 --- /dev/null +++ b/releasenotes/notes/stateprep-inverse-preserve-int-width-3e184153a463f3dd.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + Fixed :meth:`.StatePreparation.inverse` for integer-bitmap inputs with an + explicit ``num_qubits`` so the inverse gate preserves the original qubit + width. + Fixed `#16430 `__. diff --git a/test/python/circuit/library/test_state_preparation.py b/test/python/circuit/library/test_state_preparation.py index 4218e8b55a72..90f6f36698dd 100644 --- a/test/python/circuit/library/test_state_preparation.py +++ b/test/python/circuit/library/test_state_preparation.py @@ -81,6 +81,31 @@ def test_inverse(self, state): qc.append(stateprep.inverse(), [0, 1]) self.assertTrue(np.allclose(Operator(qc).data, np.identity(2**qc.num_qubits))) + def test_inverse_preserves_integer_bitmap_width(self): + """Test inverse preserves explicit width for integer-bitmap inputs.""" + stateprep = StatePreparation(1, num_qubits=2) + inverse = stateprep.inverse() + qc = QuantumCircuit(2) + qc.append(stateprep, [0, 1]) + qc.append(inverse, [0, 1]) + + self.assertEqual(inverse.num_qubits, 2) + self.assertTrue(np.allclose(Operator(qc).data, np.identity(2**qc.num_qubits))) + + def test_inverse_integer_bitmap_matches_vector_form(self): + """Test integer-bitmap inverse matches the equivalent vector-form semantics.""" + int_stateprep = StatePreparation(1, num_qubits=2) + vector_stateprep = StatePreparation([0, 1, 0, 0]) + + for stateprep, inverse in ( + (int_stateprep, vector_stateprep.inverse()), + (vector_stateprep, int_stateprep.inverse()), + ): + qc = QuantumCircuit(2) + qc.append(stateprep, [0, 1]) + qc.append(inverse, [0, 1]) + self.assertTrue(Statevector(qc) == Statevector.from_label("00")) + def test_double_inverse(self): """Test twice inverse of StatePreparation""" desired_sv = Statevector([1 / math.sqrt(2), 0, 0, 1 / math.sqrt(2)]) @@ -96,6 +121,11 @@ def test_incompatible_state_and_qubit_args(self): with self.assertRaises(QiskitError): qc.prepare_state("11") + def test_num_qubits_with_non_integer_params(self): + """Test number of qubits is rejected for non-integer state arguments.""" + with self.assertRaises(QiskitError): + StatePreparation([1, 0], num_qubits=1) + def test_incompatible_int_state_and_qubit_args(self): """Test error raised if number of qubits not compatible with integer state arg""" with self.assertRaises(QiskitError):