Skip to content

Commit e5f2856

Browse files
Preserve StatePreparation width in inverse (#16431) (#16681)
* Preserve StatePreparation width in inverse * Strengthen StatePreparation inverse regression * Address StatePreparation inverse review * Respect StatePreparation inverse input contract (cherry picked from commit d94420a) Co-authored-by: Peter Chen J. <34339487+peter941221@users.noreply.github.com>
1 parent a59109a commit e5f2856

3 files changed

Lines changed: 41 additions & 1 deletion

File tree

qiskit/circuit/library/data_preparation/state_preparation.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,10 @@ def inverse(self, annotated: bool = False):
207207
None if self._label in ("State Preparation", "State Preparation Dg") else self._label
208208
)
209209

210-
return StatePreparation(self._params_arg, inverse=not self._inverse, label=label)
210+
num_qubits = self.num_qubits if self._from_int else None
211+
return StatePreparation(
212+
self._params_arg, num_qubits=num_qubits, inverse=not self._inverse, label=label
213+
)
211214

212215
def broadcast_arguments(self, qargs, cargs):
213216
flat_qargs = [qarg for sublist in qargs for qarg in sublist]
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
fixes:
3+
- |
4+
Fixed :meth:`.StatePreparation.inverse` for integer-bitmap inputs with an
5+
explicit ``num_qubits`` so the inverse gate preserves the original qubit
6+
width.
7+
Fixed `#16430 <https://github.com/Qiskit/qiskit/issues/16430>`__.

test/python/circuit/library/test_state_preparation.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,31 @@ def test_inverse(self, state):
8181
qc.append(stateprep.inverse(), [0, 1])
8282
self.assertTrue(np.allclose(Operator(qc).data, np.identity(2**qc.num_qubits)))
8383

84+
def test_inverse_preserves_integer_bitmap_width(self):
85+
"""Test inverse preserves explicit width for integer-bitmap inputs."""
86+
stateprep = StatePreparation(1, num_qubits=2)
87+
inverse = stateprep.inverse()
88+
qc = QuantumCircuit(2)
89+
qc.append(stateprep, [0, 1])
90+
qc.append(inverse, [0, 1])
91+
92+
self.assertEqual(inverse.num_qubits, 2)
93+
self.assertTrue(np.allclose(Operator(qc).data, np.identity(2**qc.num_qubits)))
94+
95+
def test_inverse_integer_bitmap_matches_vector_form(self):
96+
"""Test integer-bitmap inverse matches the equivalent vector-form semantics."""
97+
int_stateprep = StatePreparation(1, num_qubits=2)
98+
vector_stateprep = StatePreparation([0, 1, 0, 0])
99+
100+
for stateprep, inverse in (
101+
(int_stateprep, vector_stateprep.inverse()),
102+
(vector_stateprep, int_stateprep.inverse()),
103+
):
104+
qc = QuantumCircuit(2)
105+
qc.append(stateprep, [0, 1])
106+
qc.append(inverse, [0, 1])
107+
self.assertTrue(Statevector(qc) == Statevector.from_label("00"))
108+
84109
def test_double_inverse(self):
85110
"""Test twice inverse of StatePreparation"""
86111
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):
96121
with self.assertRaises(QiskitError):
97122
qc.prepare_state("11")
98123

124+
def test_num_qubits_with_non_integer_params(self):
125+
"""Test number of qubits is rejected for non-integer state arguments."""
126+
with self.assertRaises(QiskitError):
127+
StatePreparation([1, 0], num_qubits=1)
128+
99129
def test_incompatible_int_state_and_qubit_args(self):
100130
"""Test error raised if number of qubits not compatible with integer state arg"""
101131
with self.assertRaises(QiskitError):

0 commit comments

Comments
 (0)