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

Implementing Bivariate Bicycle Codes using 2BGA as the parent via Hecke's Group Algebra #399

Merged
merged 9 commits into from
Nov 5, 2024
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
Loading