Skip to content

Commit 4a24b6c

Browse files
authored
Merge pull request #1457 from qiboteam/clifford_unpack_fix
Bugfix to matrix unpacking in `CliffordBackend`
2 parents 19f0c7f + 43f6239 commit 4a24b6c

File tree

2 files changed

+21
-16
lines changed

2 files changed

+21
-16
lines changed

src/qibo/backends/_clifford_operations.py

+17-15
Original file line numberDiff line numberDiff line change
@@ -388,10 +388,12 @@ def _rowsum(symplectic_matrix, h, i, nqubits, determined=False):
388388
def _determined_outcome(state, q, nqubits):
389389
state[-1, :] = 0
390390
idx = (state[:nqubits, q].nonzero()[0] + nqubits).astype(np.uint)
391+
if len(idx) == 0:
392+
return state, state[-1, -1]
391393
state = _pack_for_measurements(state, nqubits)
392394
state = _rowsum(
393395
state,
394-
2 * nqubits * np.ones(idx.shape, dtype=np.uint),
396+
_dim_xz(nqubits) * np.ones(idx.shape, dtype=np.uint),
395397
idx,
396398
_packed_size(nqubits),
397399
True,
@@ -427,7 +429,14 @@ def _random_outcome(state, p, q, nqubits):
427429
@cache
428430
def _dim(nqubits):
429431
"""Returns the dimension of the symplectic matrix for a given number of qubits."""
430-
return 2 * nqubits + 1
432+
return _dim_xz(nqubits) + 1
433+
434+
435+
@cache
436+
def _dim_xz(nqubits):
437+
"""Returns the dimension of the symplectic matrix (only the de/stabilizers generators part,
438+
without the phases and scratch row) for a given number of qubits."""
439+
return 2 * nqubits
431440

432441

433442
@cache
@@ -440,8 +449,8 @@ def _packbits(array, axis):
440449
return np.packbits(array, axis=axis)
441450

442451

443-
def _unpackbits(array, axis):
444-
return np.unpackbits(array, axis=axis)
452+
def _unpackbits(array, axis, count):
453+
return np.unpackbits(array, axis=axis, count=count)
445454

446455

447456
def _pack_for_measurements(state, nqubits):
@@ -452,23 +461,16 @@ def _pack_for_measurements(state, nqubits):
452461
return np.hstack((x, z, r[:, None]))
453462

454463

455-
@cache
456-
def _pad_size(n):
457-
"""Returns the size of the pad added to an array of original dimension `n` after unpacking."""
458-
return 8 - (n % 8)
459-
460-
461464
def _unpack_for_measurements(state, nqubits):
462465
"""Unpacks the symplectc matrix that was packed for measurements."""
463-
xz = _unpackbits(state[:, :-1], axis=1)
464-
padding_size = _pad_size(nqubits)
465-
x, z = xz[:, :nqubits], xz[:, nqubits + padding_size : -padding_size]
466+
xz = _unpackbits(state[:, :-1], axis=1, count=_dim_xz(nqubits))
467+
x, z = xz[:, :nqubits], xz[:, nqubits:]
466468
return np.hstack((x, z, state[:, -1][:, None]))
467469

468470

469471
def _init_state_for_measurements(state, nqubits, collapse):
470472
if collapse:
471-
return _unpackbits(state, axis=0)[: _dim(nqubits)]
473+
return _unpackbits(state, axis=0, count=_dim_xz(nqubits))[: _dim(nqubits)]
472474
else:
473475
return state.copy()
474476

@@ -523,7 +525,7 @@ def _clifford_post_execution_reshape(state, nqubits: int):
523525
Returns:
524526
(np.array) The unpacked and reshaped state.
525527
"""
526-
state = _unpackbits(state, axis=0)[: _dim(nqubits)]
528+
state = _unpackbits(state, axis=0, count=_dim(nqubits))[: _dim(nqubits)]
527529
return state
528530

529531

src/qibo/quantum_info/clifford.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,10 @@ def __post_init__(self):
6161
self.symplectic_matrix = self.data
6262
if self.symplectic_matrix.shape[0] % 2 == 0:
6363
self.symplectic_matrix = np.vstack(
64-
(self.symplectic_matrix, np.zeros(self.symplectic_matrix.shape[1]))
64+
(
65+
self.symplectic_matrix,
66+
np.zeros(self.symplectic_matrix.shape[1], dtype=np.uint8),
67+
)
6568
)
6669
self.nqubits = int((self.symplectic_matrix.shape[1] - 1) / 2)
6770
if self._backend is None:

0 commit comments

Comments
 (0)