Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/qldpc/codes/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -1887,10 +1887,11 @@ def conjugated(self, qudits: slice | Sequence[int] | None = None) -> QuditCode:
qudits = range(len(self))

def transform_ops(ops: galois.FieldArray) -> galois.FieldArray:
"""Fourier-transform the given Pauli strings."""
ops_reshaped = ops.copy().reshape(-1, 2, len(self))
ops_reshaped[:, :, qudits] = ops_reshaped[:, ::-1, qudits]
return ops_reshaped.reshape(-1, 2 * len(self)).view(self.field)
"""Fourier-transform the given Pauli strings on the chosen qudits."""
result = ops.copy().reshape(-1, 2, len(self))
conjugated = math.symplectic_conjugate(ops).reshape(-1, 2, len(self))
result[:, :, qudits] = conjugated[:, :, qudits]
return result.reshape(-1, 2 * len(self)).view(self.field)

# transform the parity check matrix, and any other operators that are already known
code = QuditCode(transform_ops(self.matrix), is_subsystem_code=self._is_subsystem_code)
Expand Down
17 changes: 17 additions & 0 deletions src/qldpc/codes/common_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,23 @@ def swap_xz(ops: galois.FieldArray) -> galois.FieldArray:
assert code.is_equiv_to(code.deformed("H 0 1 2 3 4 5 6", preserve_logicals=True))


def test_conjugated_over_qudits() -> None:
"""conjugated() is a symplectic map, so it preserves code structure over every field."""
conj = math.symplectic_conjugate
for base in [codes.BaconShorCode(3, field=3), codes.ToricCode(4, field=4)]:
code = codes.QuditCode(base.matrix)
code.get_logical_ops() # populate the cache so conjugated() transforms it too
conjugated = code.conjugated([0, 5, 7])
# the transform preserves every symplectic product, so the parity checks keep their
# commutation relations and the code stays the same size
assert np.array_equal(
code.matrix @ conj(code.matrix).T, conjugated.matrix @ conj(conjugated.matrix).T
)
assert codes.QuditCode(conjugated.matrix).dimension == code.dimension
# the transformed logical operators are still a valid symplectic basis for the new code
conjugated.set_logical_ops(conjugated.get_logical_ops())


def get_codes_for_testing_ops() -> Iterator[codes.CSSCode]:
"""Iterate over some codes for testing operator constructions."""
# Bacon-Shor code and toric codes
Expand Down