Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lifted and lifted product codes via Hecke's GroupAlgebra #356

Merged
merged 70 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
0e18064
add group ring
royess Jul 5, 2024
6249493
use Nemo for group ring and add lifted code
royess Jul 5, 2024
6ed42ee
update code parameter of lifted codes
royess Jul 7, 2024
d8dd97c
fix lifted code parameter bugs
royess Jul 7, 2024
61a2604
stylistic changes
royess Jul 7, 2024
ebb79ca
fix cached bug with other minor changes
royess Jul 7, 2024
142ced0
stylistic changes
royess Jul 7, 2024
0798fe1
remove MatrixElem type in lifted code
royess Jul 7, 2024
219b6a7
add adjoint and fix a bug
royess Jul 8, 2024
ea61385
remove redundant constructors and improve checkings
royess Jul 8, 2024
0889b2e
fix code_n
royess Jul 8, 2024
9222e89
add lifted product
royess Jul 8, 2024
af0698a
remove the wrong constructor and fix iscss
royess Jul 8, 2024
3557282
add cyclic_permutation function and solve conflicts caused by Nemo
royess Jul 8, 2024
2a859cc
add code parameters for lifted product
royess Jul 8, 2024
df98a8b
fix code_k bug by using mod2 rank
royess Jul 9, 2024
8a905d4
updated support type and related information
royess Jul 9, 2024
1a3ca37
add BP decoder tests for LP codes
royess Jul 9, 2024
68baf77
fix a type ambiguity
royess Jul 9, 2024
3fb0be7
add reference for test LP codes and do formatting
royess Jul 9, 2024
db4dbcf
add docs for group ring
royess Jul 10, 2024
8998b79
remove parameterization of lifted code types
royess Jul 10, 2024
abc2c92
export permutation_repr
royess Jul 10, 2024
87941bb
add docs for lifted and lifted product code
royess Jul 10, 2024
4fd7fc9
update docs for PermGroupRing
royess Jul 10, 2024
ea08481
fix jldoctest
royess Jul 10, 2024
c48f160
fix a type ambiguity
royess Jul 10, 2024
53322b5
add nsample for small LP codes
royess Jul 10, 2024
75c2571
update lifted code for clarity
royess Jul 31, 2024
87ce167
fix decoder pipeline for cases with redundant parity checks; thereby,…
royess Jul 31, 2024
3279381
add power operation
royess Aug 1, 2024
d43e582
add new constructors and functions and refactor lifted product
royess Aug 1, 2024
2707d9b
fix `code_s` and types in lifted
royess Aug 1, 2024
6fb093c
move `LPCode` examples to base; (partially) fix naive syndrome circui…
royess Aug 1, 2024
b8d18ed
weaken code property checks by allowing redundant rows
royess Aug 1, 2024
e6e071f
Merge branch 'master' into lift-dev
royess Aug 4, 2024
6216fc0
fix pframe test
royess Aug 4, 2024
c5c52b2
fix encoding and syndrome circuit tests
royess Aug 4, 2024
029b0a5
update types and tests
royess Aug 27, 2024
f18df82
Replace the group ring with Hecke's GroupAlgebra; also some fixup on …
royess Sep 9, 2024
7be3bfd
import Hecke functions in tests
royess Sep 9, 2024
fe3f78a
add gens imports
royess Sep 9, 2024
a854e6d
Move Hecke-related things to ext
royess Sep 9, 2024
16727f0
fix code parameters for lifted codes
royess Sep 9, 2024
a7d0d8f
enrich docstrings
royess Sep 9, 2024
866ef37
import DocStringExtensions
royess Sep 9, 2024
58c3b0e
add examples
royess Sep 9, 2024
3329c8c
update docs and citations
royess Sep 9, 2024
14d70ef
update refs in ecc test base
royess Sep 9, 2024
d624f14
fix typos
royess Sep 9, 2024
3ae0247
add Hecke to test deps
royess Sep 9, 2024
85a7293
downgrade AbstractAlgebra and Hecke
royess Sep 9, 2024
4d35d69
adjust deps compat
royess Sep 10, 2024
72fa9fa
Set compact according the Hecke v0.28
royess Sep 10, 2024
6c2f755
ignore AbstractAlgebra and Hecke in JET checks
royess Sep 10, 2024
17b0938
Merge branch 'master' into lift-dev-hecke
Krastanov Sep 14, 2024
b73dcf7
make AbstractAlgebra an explicit dep
royess Sep 15, 2024
e24a19b
remove ext checks of some functions for code construction
royess Sep 15, 2024
393bbfc
Merge branch 'master' into lift-dev-hecke
royess Sep 15, 2024
17f6ca5
clarification about code_s
Krastanov Sep 26, 2024
014a77a
reword one of the tests for rank/code_s consistency
Krastanov Sep 26, 2024
a803298
make optional and disable the change to `stab_looks_good`
Krastanov Sep 26, 2024
5cd91a8
remove unnecessary dependency on AbstractAlgebra as Hecke re-exports …
Krastanov Sep 26, 2024
6f33024
do not pirate Nemo.lift, just define a new private lift function
Krastanov Sep 26, 2024
aaa824a
do not pirate Base.adjoint -- this actually does not seem used at all…
Krastanov Sep 26, 2024
162f826
use references only to representable sources, not discussion pages th…
Krastanov Sep 26, 2024
8277803
missing documentation TODOs and minor rewording
Krastanov Sep 26, 2024
776aeac
remove repeated tests
Krastanov Sep 26, 2024
2404eb3
remove a spurious todo
Krastanov Sep 26, 2024
7198b5b
make sure that the package extension content shows as part of the doc…
Krastanov Sep 26, 2024
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
- **(fix)** Bug fix to the `parity_checks(ReedMuller(r, m))` of classical Reed-Muller code (it was returning generator matrix).
- `RecursiveReedMuller` code implementation as an alternative implementation of `ReedMuller`.

## v0.9.10 - 2024-09-26

- **(fix)** `ECC.code_s` now gives the number of parity checks with redundancy. If you want the number of linearly independent parity checks, you can use `LinearAlgebra.rank`.

## v0.9.9 - 2024-08-05

- `inv` is implemented for all Clifford operator types (symbolic, dense, sparse).
Expand Down
5 changes: 4 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ SumTypes = "8e1ec7a9-0e02-4297-b0fe-6433085c89f2"

[weakdeps]
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
Hecke = "3e1990a7-5d81-5526-99ce-9ba3ff248f21"
LDPCDecoders = "3c486d74-64b9-4c60-8b1a-13a564e77efb"
Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
Expand All @@ -33,6 +34,7 @@ QuantumOpticsBase = "4f57444f-1401-5e15-980d-4471b28d5678"

[extensions]
QuantumCliffordGPUExt = "CUDA"
QuantumCliffordHeckeExt = "Hecke"
QuantumCliffordLDPCDecodersExt = "LDPCDecoders"
QuantumCliffordMakieExt = "Makie"
QuantumCliffordPlotsExt = "Plots"
Expand All @@ -46,14 +48,15 @@ Combinatorics = "1.0"
DataStructures = "0.18"
DocStringExtensions = "0.9"
Graphs = "1.9"
Hecke = "0.28, 0.29, 0.30, 0.31, 0.32, 0.33"
HostCPUFeatures = "0.1.6"
ILog2 = "0.2.3"
InteractiveUtils = "1.9"
LDPCDecoders = "0.3.1"
LinearAlgebra = "1.9"
MacroTools = "0.5.9"
Makie = "0.20, 0.21"
Nemo = "0.42, 0.43, 0.44, 0.45, 0.46"
Nemo = "^0.42.1, 0.43, 0.44, 0.45, 0.46"
Plots = "1.38.0"
PrecompileTools = "1.2"
PyQDecoders = "0.2.1"
Expand Down
1 change: 1 addition & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
DocumenterCitations = "daee34ce-89f3-4625-b898-19384cb65244"
GraphMakie = "1ecd5474-83a3-4783-bb4f-06765db800d2"
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
Hecke = "3e1990a7-5d81-5526-99ce-9ba3ff248f21"
LDPCDecoders = "3c486d74-64b9-4c60-8b1a-13a564e77efb"
Nemo = "2edaba10-b0f1-5616-af89-8c11ac63239a"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
Expand Down
8 changes: 7 additions & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ using QuantumClifford
using QuantumClifford.Experimental.NoisyCircuits
using QuantumInterface

ENV["HECKE_PRINT_BANNER"] = "false"
import Hecke

const QuantumCliffordHeckeExt = Base.get_extension(QuantumClifford, :QuantumCliffordHeckeExt)

#DocMeta.setdocmeta!(QuantumClifford, :DocTestSetup, :(using QuantumClifford); recursive=true)

ENV["LINES"] = 80 # for forcing `displaysize(io)` to be big enough
Expand All @@ -20,8 +25,9 @@ doctest = false,
clean = true,
sitename = "QuantumClifford.jl",
format = Documenter.HTML(size_threshold_ignore = ["API.md"]),
modules = [QuantumClifford, QuantumClifford.Experimental.NoisyCircuits, QuantumClifford.ECC, QuantumInterface],
modules = [QuantumClifford, QuantumClifford.Experimental.NoisyCircuits, QuantumClifford.ECC, QuantumInterface, QuantumCliffordHeckeExt],
warnonly = [:missing_docs],
linkcheck = true,
authors = "Stefan Krastanov",
pages = [
"QuantumClifford.jl" => "index.md",
Expand Down
7 changes: 7 additions & 0 deletions docs/src/ECC_API.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,10 @@
Modules = [QuantumClifford.ECC]
Private = false
```

## Implemented in an extension requiring `Hecke.jl`

```@autodocs
Modules = [QuantumCliffordHeckeExt]
Private = true
```
52 changes: 52 additions & 0 deletions docs/src/references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -402,3 +402,55 @@ @inproceedings{brown2013short
pages = {346--350},
doi = {10.1109/ISIT.2013.6620245}
}

@article{panteleev2021degenerate,
title = {Degenerate {{Quantum LDPC Codes With Good Finite Length Performance}}},
author = {Panteleev, Pavel and Kalachev, Gleb},
year = {2021},
month = nov,
journal = {Quantum},
volume = {5},
eprint = {1904.02703},
primaryclass = {quant-ph},
pages = {585},
issn = {2521-327X},
doi = {10.22331/q-2021-11-22-585},
archiveprefix = {arXiv}
}


@inproceedings{panteleev2022asymptotically,
title = {Asymptotically Good {{Quantum}} and Locally Testable Classical {{LDPC}} Codes},
booktitle = {Proceedings of the 54th {{Annual ACM SIGACT Symposium}} on {{Theory}} of {{Computing}}},
author = {Panteleev, Pavel and Kalachev, Gleb},
year = {2022},
month = jun,
pages = {375--388},
publisher = {ACM},
address = {Rome Italy},
doi = {10.1145/3519935.3520017},
isbn = {978-1-4503-9264-8}
}

@article{roffe2023bias,
title = {Bias-Tailored Quantum {{LDPC}} Codes},
author = {Roffe, Joschka and Cohen, Lawrence Z. and Quintavalle, Armanda O. and Chandra, Daryus and Campbell, Earl T.},
year = {2023},
month = may,
journal = {Quantum},
volume = {7},
pages = {1005},
doi = {10.22331/q-2023-05-15-1005}
}

@article{raveendran2022finite,
title = {Finite {{Rate QLDPC-GKP Coding Scheme}} That {{Surpasses}} the {{CSS Hamming Bound}}},
author = {Raveendran, Nithin and Rengaswamy, Narayanan and Rozp{\k e}dek, Filip and Raina, Ankur and Jiang, Liang and Vasi{\'c}, Bane},
year = {2022},
month = jul,
journal = {Quantum},
volume = {6},
pages = {767},
issn = {2521-327X},
doi = {10.22331/q-2022-07-20-767},
}
19 changes: 19 additions & 0 deletions ext/QuantumCliffordHeckeExt/QuantumCliffordHeckeExt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module QuantumCliffordHeckeExt

using DocStringExtensions

import QuantumClifford, LinearAlgebra
import Hecke: Group, GroupElem, AdditiveGroup, AdditiveGroupElem,
GroupAlgebra, GroupAlgebraElem, FqFieldElem, representation_matrix, dim, base_ring,
multiplication_table, coefficients, abelian_group, group_algebra
import Nemo: characteristic, matrix_repr, GF, ZZ

import QuantumClifford.ECC: AbstractECC, CSS, ClassicalCode,
hgp, code_k, code_n, code_s, iscss, parity_checks, parity_checks_x, parity_checks_z, parity_checks_xz,
two_block_group_algebra_codes, generalized_bicycle_codes, bicycle_codes

include("types.jl")
include("lifted.jl")
include("lifted_product.jl")

end # module
101 changes: 101 additions & 0 deletions ext/QuantumCliffordHeckeExt/lifted.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
"""
$TYPEDEF

Classical codes lifted over a group algebra, used for lifted product code construction ([panteleev2021degenerate](@cite), [panteleev2022asymptotically](@cite))

The parity-check matrix is constructed by applying `repr` to each element of `A`,
which is mathematically a linear map from a group algebra element to a binary matrix.
The size of the parity check matrix will enlarged with each element of `A` being inflated into a matrix.
The procedure is called a lift [panteleev2022asymptotically](@cite).

## Constructors

A lifted code can be constructed via the following approaches:

1. A matrix of group algebra elements.

2. A matrix of group elements, where a group element will be considered as a group algebra element by assigning a unit coefficient.

3. A matrix of integers, where each integer represent the shift of a cyclic permutation. The order of the cyclic permutation should be specified.

The default `GA` is the group algebra of `A[1, 1]`, the default representation `repr` is the permutation representation.

## The representation function `repr`

In this struct, we use the default representation function `default_repr` to convert a `GF(2)`-group algebra element to a binary matrix.
The default representation, provided by `Hecke`, is the permutation representation.

We also accept a custom representation function.
Such a customization would be useful to reduce the number of bits required by the code construction.

For example, if we use a D4 group for lifting, our default representation will be `8×8` permutation matrices,
where 8 is the group's order.
However, we can find a `4×4` matrix representation for the group,
e.g. by using the typical [`2×2` representation](https://en.wikipedia.org/wiki/Dihedral_group)
and converting it into binary representation by replacing "1" with the Pauli I, and "-1" with the Pauli X matrix.

See also: [`LPCode`](@ref).

$TYPEDFIELDS
"""
struct LiftedCode <: ClassicalCode
"""the base matrix of the code, whose elements are in a group algebra."""
A::GroupAlgebraElemMatrix
"""the group algebra for which elements in `A` are from."""
GA::GroupAlgebra
"""
a function that converts a group algebra element to a binary matrix;
default to be the permutation representation for GF(2)-algebra."""
repr::Function

function LiftedCode(A::GroupAlgebraElemMatrix; GA::GroupAlgebra=parent(A[1, 1]), repr::Function)
all(elem.parent == GA for elem in A) || error("The base ring of all elements in the code must be the same as the group algebra")
new(A, GA, repr)
end
end

default_repr(y::GroupAlgebraElem{FqFieldElem, <: GroupAlgebra}) = Matrix((x -> Bool(Int(lift(ZZ, x)))).(representation_matrix(y)))

"""
`LiftedCode` constructor using the default `GF(2)` representation (coefficients converted to a permutation matrix by `representation_matrix` provided by Hecke).
""" # TODO doctest example
function LiftedCode(A::Matrix{GroupAlgebraElem{FqFieldElem, <: GroupAlgebra}}; GA::GroupAlgebra=parent(A[1,1]))
!(characteristic(base_ring(A[1, 1])) == 2) && error("The default permutation representation applies only to GF(2) group algebra; otherwise, a custom representation function should be provided")
LiftedCode(A; GA=GA, repr=default_repr)
end

# TODO document and doctest example
function LiftedCode(group_elem_array::Matrix{<: GroupOrAdditiveGroupElem}; GA::GroupAlgebra=group_algebra(GF(2), parent(group_elem_array[1,1])), repr::Union{Function, Nothing}=nothing)
A = zeros(GA, size(group_elem_array)...)
for i in axes(group_elem_array, 1), j in axes(group_elem_array, 2)
A[i, j] = GA[A[i, j]]
end
if repr === nothing
return LiftedCode(A; GA=GA, repr=default_repr)
else
return LiftedCode(A; GA=GA, repr=repr)
end
end

# TODO document and doctest example
function LiftedCode(shift_array::Matrix{Int}, l::Int; GA::GroupAlgebra=group_algebra(GF(2), abelian_group(l)))
A = zeros(GA, size(shift_array)...)
for i in 1:size(shift_array, 1)
for j in 1:size(shift_array, 2)
A[i, j] = GA[shift_array[i, j]%l+1]
end
end
return LiftedCode(A; GA=GA, repr=default_repr)
end

function lift(repr::Function, mat::GroupAlgebraElemMatrix)
vcat([hcat([repr(mat[i, j]) for j in axes(mat, 2)]...) for i in axes(mat, 1)]...)
end

function parity_checks(c::LiftedCode)
return lift(c.repr, c.A)
end

code_n(c::LiftedCode) = size(c.A, 2) * size(zero(c.GA), 2)

code_s(c::LiftedCode) = size(c.A, 1) * size(zero(c.GA), 1)
Loading
Loading