Skip to content

Commit

Permalink
Fix casting rules changing in Numpy 2
Browse files Browse the repository at this point in the history
This fixes several places in `quantum_info` that will be affected by the
casting-rule changes coming in Numpy 2.0[^1].  There are several other
places where the casting rules will change the output types of certain
arrays due to the removal of Python-scalar value-dependent casting, but
those do not appear to have an observable effect on our behaviour, so I
have left them.

It is also becoming invalid to set a scalar entry in a Numpy array with
an array-like with a non-zero number of dimensions, even if the sequence
is of length 1.

[^1]: https://numpy.org/neps/nep-0050-scalar-promotion.html
  • Loading branch information
jakelishman committed Sep 25, 2023
1 parent 6a38279 commit ac099e5
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 16 deletions.
2 changes: 1 addition & 1 deletion qiskit/quantum_info/operators/symplectic/base_pauli.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ def _to_matrix(z, x, phase=0, group_phase=False, sparse=False):
phase %= 4

dim = 2**num_qubits
twos_array = 1 << np.arange(num_qubits)
twos_array = 1 << np.arange(num_qubits, dtype=np.uint)
x_indices = np.asarray(x).dot(twos_array)
z_indices = np.asarray(z).dot(twos_array)

Expand Down
23 changes: 15 additions & 8 deletions qiskit/quantum_info/operators/symplectic/pauli_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,22 +338,29 @@ def __setitem__(self, index, value):
"""Update PauliList."""
if isinstance(index, tuple):
if len(index) == 1:
index = index[0]
row, qubit = index[0], None
elif len(index) > 2:
raise IndexError(f"Invalid PauliList index {index}")
else:
row, qubit = index
else:
row, qubit = index, None

# Modify specified rows of the PauliList
if not isinstance(value, PauliList):
value = PauliList(value)

self._z[index] = value._z
self._x[index] = value._x
if not isinstance(index, tuple):
# Row-only indexing
self._phase[index] = value._phase
# It's not valid to set a single item with a sequence, even if the sequence is length 1.
phase = value._phase.item() if isinstance(row, (int, np.integer)) else value._phase

if qubit is None:
self._z[row] = value._z
self._x[row] = value._x
self._phase[row] = phase
else:
# Row and Qubit indexing
self._phase[index[0]] += value._phase
self._z[row, qubit] = value._z
self._x[row, qubit] = value._x
self._phase[row] += phase
self._phase %= 4

def delete(self, ind: int | list, qubit: bool = False) -> PauliList:
Expand Down
11 changes: 6 additions & 5 deletions qiskit/quantum_info/operators/symplectic/pauli_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -1060,18 +1060,19 @@ def count1(i):
z = symp[num_qubits : 2 * num_qubits]

dim = 2**num_qubits
twos_array = 1 << np.arange(num_qubits)
twos_array = 1 << np.arange(num_qubits, dtype=np.uint)
x_indices = np.array(x).dot(twos_array)
z_indices = np.array(z).dot(twos_array)

indptr = np.arange(dim + 1, dtype=np.uint)
indices = indptr ^ x_indices
data = (-1) ** np.mod(count1(z_indices & indptr), 2)
parity = np.mod(count1(z_indices & indptr), 2)
if real_valued:
dtype = float
dtype = np.float64
data = np.where(parity, -1.0, 1.0)
else:
dtype = complex
data = (-1j) ** np.sum(x & z) * data
dtype = np.complex64
data = (-1j) ** np.sum(x & z) * np.where(parity, (-1 + 0j), (1 + 0j))

if sparse:
# Return sparse matrix
Expand Down
5 changes: 3 additions & 2 deletions qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -467,8 +467,9 @@ def to_complex(coeff):
paulis_z = self.paulis.z[non_zero]
nz_coeffs = self.coeffs[non_zero]

# Pack bool vectors into np.uint8 vectors by np.packbits
array = np.packbits(paulis_x, axis=1) * 256 + np.packbits(paulis_z, axis=1)
array = np.packbits(paulis_x, axis=1).astype(np.uint16) * 256 + np.packbits(
paulis_z, axis=1
)
indexes, inverses = unordered_unique(array)

if np.all(non_zero) and indexes.shape[0] == array.shape[0]:
Expand Down

0 comments on commit ac099e5

Please sign in to comment.