Skip to content

Commit

Permalink
Implementing Bivariate Bicycle Codes using 2BGA as the parent via Hec…
Browse files Browse the repository at this point in the history
…ke's Group Algebra (#399)



Co-authored-by: Stefan Krastanov <[email protected]>
Co-authored-by: Stefan Krastanov <[email protected]>
  • Loading branch information
3 people authored Nov 5, 2024
1 parent 40924b8 commit 5f2ef93
Show file tree
Hide file tree
Showing 5 changed files with 250 additions and 4 deletions.
11 changes: 11 additions & 0 deletions docs/src/references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -523,3 +523,14 @@ @article{lin2024quantum
year={2024},
publisher={APS}
}

@article{bravyi2024high,
title={High-threshold and low-overhead fault-tolerant quantum memory},
author={Bravyi, Sergey and Cross, Andrew W and Gambetta, Jay M and Maslov, Dmitri and Rall, Patrick and Yoder, Theodore J},
journal={Nature},
volume={627},
number={8005},
pages={778--782},
year={2024},
publisher={Nature Publishing Group UK London}
}
2 changes: 2 additions & 0 deletions docs/src/references.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ For quantum code construction routines:
- [steane1999quantum](@cite)
- [campbell2012magic](@cite)
- [anderson2014fault](@cite)
- [lin2024quantum](@cite)
- [bravyi2024high](@cite)

For classical code construction routines:
- [muller1954application](@cite)
Expand Down
39 changes: 36 additions & 3 deletions ext/QuantumCliffordHeckeExt/lifted_product.jl
Original file line number Diff line number Diff line change
Expand Up @@ -150,14 +150,18 @@ code_n(c::LPCode) = size(c.repr(zero(c.GA)), 2) * (size(c.A, 2) * size(c.B, 1) +
code_s(c::LPCode) = size(c.repr(zero(c.GA)), 1) * (size(c.A, 1) * size(c.B, 1) + size(c.A, 2) * size(c.B, 2))

"""
Two-block group algebra (2GBA) codes, which are a special case of lifted product codes
Two-block group algebra (2BGA) codes, which are a special case of lifted product codes
from two group algebra elements `a` and `b`, used as `1x1` base matrices.
## Examples of 2BGA code subfamilies
### `C₄ x C₂`
Here is an example of a [[56, 28, 2]] 2BGA code from Table 2 of [lin2024quantum](@cite)
with direct product of `C₄ x C₂`.
```jldoctest
julia> import Hecke: group_algebra, GF, abelian_group, gens;
julia> import Hecke: group_algebra, GF, abelian_group, gens
julia> GA = group_algebra(GF(2), abelian_group([14,2]));
Expand All @@ -175,7 +179,36 @@ julia> code_n(c), code_k(c)
(56, 28)
```
See also: [`LPCode`](@ref), [`generalized_bicycle_codes`](@ref), [`bicycle_codes`](@ref)
### Bivariate Bicycle codes
Bivariate Bicycle codes are a class of Abelian 2BGA codes formed by the direct product
of two cyclic groups `ℤₗ × ℤₘ`. The parameters `l` and `m` represent the orders of the
first and second cyclic groups, respectively.
The ECC Zoo has an [entry for this family](https://errorcorrectionzoo.org/c/qcga).
A [[756, 16, ≤ 34]] code from Table 3 of [bravyi2024high](@cite):
```jldoctest
julia> import Hecke: group_algebra, GF, abelian_group, gens
julia> l=21; m=18;
julia> GA = group_algebra(GF(2), abelian_group([l, m]));
julia> x, y = gens(GA);
julia> A = x^3 + y^10 + y^17;
julia> B = y^5 + x^3 + x^19;
julia> c = two_block_group_algebra_codes(A,B);
julia> code_n(c), code_k(c)
(756, 16)
```
See also: [`LPCode`](@ref), [`generalized_bicycle_codes`](@ref), [`bicycle_codes`](@ref).
"""
function two_block_group_algebra_codes(a::GroupAlgebraElem, b::GroupAlgebraElem)
LPCode([a;;], [b;;])
Expand Down
29 changes: 28 additions & 1 deletion test/test_ecc_base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,41 @@ A[LinearAlgebra.diagind(A, 5)] .= GA(1)
B = reshape([1 + x + x^6], (1, 1))
push!(other_lifted_product_codes, LPCode(A, B))

# Bivariate Bicycle codes
# A [[72, 12, 6]] code from Table 3 of [bravyi2024high](@cite).
l=6; m=6
GA = group_algebra(GF(2), abelian_group([l, m]))
x, y = gens(GA)
A = x^3 + y + y^2
B = y^3 + x + x^2
bb1 = two_block_group_algebra_codes(A,B)

# A [[90, 8, 10]] code from Table 3 of [bravyi2024high](@cite).
l=15; m=3
GA = group_algebra(GF(2), abelian_group([l, m]))
x, y = gens(GA)
A = x^9 + y + y^2
B = 1 + x^2 + x^7
bb2 = two_block_group_algebra_codes(A,B)

# A [[360, 12, ≤ 24]] code from Table 3 of [bravyi2024high](@cite).
l=30; m=6
GA = group_algebra(GF(2), abelian_group([l, m]))
x, y = gens(GA)
A = x^9 + y + y^2
B = y^3 + x^25 + x^26
bb3 = two_block_group_algebra_codes(A,B)

test_bb_codes = [bb1, bb2, bb3]

const code_instance_args = Dict(
:Toric => [(3,3), (4,4), (3,6), (4,3), (5,5)],
:Surface => [(3,3), (4,4), (3,6), (4,3), (5,5)],
:Gottesman => [3, 4, 5],
:CSS => (c -> (parity_checks_x(c), parity_checks_z(c))).([Shor9(), Steane7(), Toric(4, 4)]),
:Concat => [(Perfect5(), Perfect5()), (Perfect5(), Steane7()), (Steane7(), Cleve8()), (Toric(2, 2), Shor9())],
:CircuitCode => random_circuit_code_args,
:LPCode => (c -> (c.A, c.B)).(vcat(LP04, LP118, test_gb_codes, other_lifted_product_codes)),
:LPCode => (c -> (c.A, c.B)).(vcat(LP04, LP118, test_gb_codes, test_bb_codes, other_lifted_product_codes)),
:QuantumReedMuller => [3, 4, 5]
)

Expand Down
173 changes: 173 additions & 0 deletions test/test_ecc_bivaraite_bicycle_as_twobga.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
@testitem "ECC Bivaraite Bicycle as 2BGA" begin
using Hecke
using Hecke: group_algebra, GF, abelian_group, gens, one
using QuantumClifford.ECC: two_block_group_algebra_codes, code_k, code_n

@testset "Reproduce Table 3 bravyi2024high" begin
# [[72, 12, 6]]
l=6; m=6
GA = group_algebra(GF(2), abelian_group([l, m]))
x, y = gens(GA)
A = x^3 + y + y^2
B = y^3 + x + x^2
c = two_block_group_algebra_codes(A,B)
@test code_n(c) == 72 && code_k(c) == 12

# [[90, 8, 10]]
l=15; m=3
GA = group_algebra(GF(2), abelian_group([l, m]))
x, y = gens(GA)
A = x^9 + y + y^2
B = 1 + x^2 + x^7
c = two_block_group_algebra_codes(A,B)
@test code_n(c) == 90 && code_k(c) == 8

# [[108, 8, 10]]
l=9; m=6
GA = group_algebra(GF(2), abelian_group([l, m]))
x, y = gens(GA)
A = x^3 + y + y^2
B = y^3 + x + x^2
c = two_block_group_algebra_codes(A,B)
@test code_n(c) == 108 && code_k(c) == 8

# [[144, 12, 12]]
l=12; m=6
GA = group_algebra(GF(2), abelian_group([l, m]))
x, y = gens(GA)
A = x^3 + y + y^2
B = y^3 + x + x^2
c = two_block_group_algebra_codes(A,B)
@test code_n(c) == 144 && code_k(c) == 12

# [[288, 12, 12]]
l=12; m=12
GA = group_algebra(GF(2), abelian_group([l, m]))
x, y = gens(GA)
A = x^3 + y^2 + y^7
B = y^3 + x + x^2
c = two_block_group_algebra_codes(A,B)
@test code_n(c) == 288 && code_k(c) == 12

# [[360, 12, ≤ 24]]
l=30; m=6
GA = group_algebra(GF(2), abelian_group([l, m]))
x, y = gens(GA)
A = x^9 + y + y^2
B = y^3 + x^25 + x^26
c = two_block_group_algebra_codes(A,B)
@test code_n(c) == 360 && code_k(c) == 12

# [[756, 16, ≤ 34]]
l=21; m=18
GA = group_algebra(GF(2), abelian_group([l, m]))
x, y = gens(GA)
A = x^3 + y^10 + y^17
B = y^5 + x^3 + x^19
c = two_block_group_algebra_codes(A,B)
@test code_n(c) == 756 && code_k(c) == 16
end

@testset "Reproduce Table 1 berthusen2024toward" begin
# [[72, 8, 6]]
l=12; m=3
GA = group_algebra(GF(2), abelian_group([l, m]))
x, y = gens(GA)
A = x^9 + y + y^2
B = 1 + x + x^11
c = two_block_group_algebra_codes(A,B)
@test code_n(c) == 72 && code_k(c) == 8

# [[90, 8, 6]]
l=9; m=5
GA = group_algebra(GF(2), abelian_group([l, m]))
x, y = gens(GA)
A = x^8 + y^4 + y
B = y^5 + x^8 + x^7
c = two_block_group_algebra_codes(A,B)
@test code_n(c) == 90 && code_k(c) == 8

# [[120, 8, 8]]
l=12; m=5
GA = group_algebra(GF(2), abelian_group([l, m]))
x, y = gens(GA)
A = x^10 + y^4 + y
B = 1 + x + x^2
c = two_block_group_algebra_codes(A,B)
@test code_n(c) == 120 && code_k(c) == 8

# [[150, 8, 8]]
l=15; m=5
GA = group_algebra(GF(2), abelian_group([l, m]))
x, y = gens(GA)
A = x^5 + y^2 + y^3
B = y^2 + x^7 + x^6
c = two_block_group_algebra_codes(A,B)
@test code_n(c) == 150 && code_k(c) == 8

# [[196, 12, 8]]
l=14; m=7
GA = group_algebra(GF(2), abelian_group([l, m]))
x, y = gens(GA)
A = x^6 + y^5 + y^6
B = 1 + x^4 + x^13
c = two_block_group_algebra_codes(A,B)
@test code_n(c) == 196 && code_k(c) == 12
end

@testset "Reproduce Table 1 wang2024coprime" begin
# [[54, 8, 6]]
l=3; m=9
GA = group_algebra(GF(2), abelian_group([l, m]))
x, y = gens(GA)
A = 1 + y^2 + y^4
B = y^3 + x + x^2
c = two_block_group_algebra_codes(A,B)
@test code_n(c) == 54 && code_k(c) == 8

# [[98, 6, 12]]
l=7; m=7
GA = group_algebra(GF(2), abelian_group([l, m]))
x, y = gens(GA)
A = x^3 + y^5 + y^6
B = y^2 + x^3 + x^5
c = two_block_group_algebra_codes(A,B)
@test code_n(c) == 98 && code_k(c) == 6

# [[126, 8, 10]]
l=3; m=21
GA = group_algebra(GF(2), abelian_group([l, m]))
x, y = gens(GA)
A = 1 + y^2 + y^10
B = y^3 + x + x^2
c = two_block_group_algebra_codes(A,B)
@test code_n(c) == 126 && code_k(c) == 8

# [[150, 16, 8]]
l=5; m=15
GA = group_algebra(GF(2), abelian_group([l, m]))
x, y = gens(GA)
A = 1 + y^6 + y^8
B = y^5 + x + x^4
c = two_block_group_algebra_codes(A,B)
@test code_n(c) == 150 && code_k(c) == 16

# [[162, 8, 14]]
l=3; m=27
GA = group_algebra(GF(2), abelian_group([l, m]))
x, y = gens(GA)
A = 1 + y^10 + y^14
B = y^12 + x + x^2
c = two_block_group_algebra_codes(A,B)
@test code_n(c) == 162 && code_k(c) == 8

# [[180, 8, 16]]
l=6; m=15
GA = group_algebra(GF(2), abelian_group([l, m]))
x, y = gens(GA)
A = x^3 + y + y^2
B = y^6 + x^4 + x^5
c = two_block_group_algebra_codes(A,B)
@test code_n(c) == 180 && code_k(c) == 8
end
end

0 comments on commit 5f2ef93

Please sign in to comment.