Skip to content

Commit

Permalink
standard interface for setting default qubits to conjugate
Browse files Browse the repository at this point in the history
  • Loading branch information
perlinm committed Sep 17, 2024
1 parent e873250 commit bd1adb1
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 28 deletions.
8 changes: 4 additions & 4 deletions qldpc/codes/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -643,10 +643,10 @@ def from_stabilizers(cls, *stabilizers: str, field: int | None = None) -> QuditC

return QuditCode(matrix.reshape(num_checks, 2 * num_qudits), field)

def conjugated(self, qudits: slice | Sequence[int]) -> QuditCode:
"""Apply local Fourier (Hadamard) transforms to the given qudits.
This is equivalent to swapping X-type and Z-type operators."""
def conjugated(self, qudits: slice | Sequence[int] | None = None) -> QuditCode:
"""Apply local Fourier transforms to data qudits, swapping X-type and Z-type operators."""
if qudits is None:
qudits = self._default_conjugate if hasattr(self, "_default_conjugate") else ()
num_checks = len(self.matrix)
matrix = np.reshape(self.matrix.copy(), (num_checks, 2, -1))
matrix[:, :, qudits] = np.roll(matrix[:, :, qudits], 1, axis=1)
Expand Down
1 change: 1 addition & 0 deletions qldpc/codes/common_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ def test_deformations(num_qudits: int = 5, num_checks: int = 3, field: int = 3)
"""Apply Pauli deformations to a qudit code."""
qudits = tuple(qubit for qubit in range(num_qudits) if np.random.randint(2))
code = get_random_qudit_code(num_qudits, num_checks, field).conjugated(qudits)
assert np.array_equal(code.matrix, code.conjugated().matrix)

matrix = np.reshape(code.matrix, (num_checks, 2, num_qudits))
for node_check, node_qubit, data in code.graph.edges(data=True):
Expand Down
34 changes: 10 additions & 24 deletions qldpc/codes/quantum.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,9 @@ def __init__(
[code_b.num_bits, code_b.num_checks],
)

# if Hadamard-transforming qudits, conjugate those in the (1, 1) sector by default
self._default_conjugate = slice(self.sector_size[0, 0], None)

CSSCode.__init__(
self, matrix_x.astype(int), matrix_z.astype(int), field, skip_validation=True
)
Expand Down Expand Up @@ -627,11 +630,6 @@ def get_product_node_map(

return node_map

def conjugated(self, qudits: slice | Sequence[int] | None = None) -> QuditCode:
"""Hadamard-transform to the qudits in sector (1, 1)."""
qudits = qudits if qudits is not None else slice(self.sector_size[0, 0], None)
return QuditCode.conjugated(self, qudits)


class LPCode(CSSCode):
"""Lifted product (LP) code.
Expand Down Expand Up @@ -680,6 +678,9 @@ def __init__(
protograph_b.shape[::-1],
)

# if Hadamard-transforming qudits, conjugate those in the (1, 1) sector by default
self._default_conjugate = slice(self.sector_size[0, 0], None)

CSSCode.__init__(
self,
abstract.Protograph(matrix_x.astype(object)).lift(),
Expand All @@ -688,11 +689,6 @@ def __init__(
skip_validation=True,
)

def conjugated(self, qudits: slice | Sequence[int] | None = None) -> QuditCode:
"""Hadamard-transform to the qudits in sector (1, 1)."""
qudits = qudits if qudits is not None else slice(self.sector_size[0, 0], None)
return QuditCode.conjugated(self, qudits)


################################################################################
# quantum Tanner code
Expand Down Expand Up @@ -959,7 +955,7 @@ def __init__(
if rotated:
# rotated surface code
matrix_x, matrix_z = SurfaceCode.get_rotated_checks(rows, cols)
self._qudits_to_conjugate: list[int] | slice = [
self._default_conjugate: list[int] | slice = [
idx
for idx, (row, col) in enumerate(np.ndindex(self.rows, self.cols))
if (row + col) % 2
Expand All @@ -972,7 +968,7 @@ def __init__(
code_ab = HGPCode(code_a, code_b, field)
matrix_x = code_ab.matrix_x
matrix_z = code_ab.matrix_z
self._qudits_to_conjugate = slice(code_ab.sector_size[0, 0], None)
self._default_conjugate = slice(code_ab.sector_size[0, 0], None)

CSSCode.__init__(self, matrix_x, matrix_z, field=field, skip_validation=True)

Expand Down Expand Up @@ -1038,11 +1034,6 @@ def get_check(

return np.array(checks_x), np.array(checks_z)

def conjugated(self, qudits: slice | Sequence[int] | None = None) -> QuditCode:
"""Hadamard-transform qudits in a checkerboard pattern."""
qudits = qudits if qudits is not None else self._qudits_to_conjugate
return QuditCode.conjugated(self, qudits)


class ToricCode(CSSCode):
"""Surface code with periodic bounary conditions, encoding two logical qudits.
Expand Down Expand Up @@ -1073,7 +1064,7 @@ def __init__(

# rotated toric code
matrix_x, matrix_z = ToricCode.get_rotated_checks(rows, cols)
self._qudits_to_conjugate: list[int] | slice = [
self._default_conjugate: list[int] | slice = [
idx
for idx, (row, col) in enumerate(np.ndindex(self.rows, self.cols))
if (row + col) % 2
Expand All @@ -1086,7 +1077,7 @@ def __init__(
code_ab = HGPCode(code_a, code_b, field)
matrix_x = code_ab.matrix_x
matrix_z = code_ab.matrix_z
self._qudits_to_conjugate = slice(code_ab.sector_size[0, 0], None)
self._default_conjugate = slice(code_ab.sector_size[0, 0], None)

CSSCode.__init__(self, matrix_x, matrix_z, field=field, skip_validation=True)

Expand Down Expand Up @@ -1122,11 +1113,6 @@ def get_check(

return np.array(checks_x), np.array(checks_z)

def conjugated(self, qudits: slice | Sequence[int] | None = None) -> QuditCode:
"""Hadamard-transform qudits in a checkerboard pattern."""
qudits = qudits if qudits is not None else self._qudits_to_conjugate
return QuditCode.conjugated(self, qudits)


class GeneralizedSurfaceCode(CSSCode):
"""Surface or toric code defined on a multi-dimensional hypercubic lattice.
Expand Down

0 comments on commit bd1adb1

Please sign in to comment.