diff --git a/docs/src/references.bib b/docs/src/references.bib index d82fc7440..635ca65ee 100644 --- a/docs/src/references.bib +++ b/docs/src/references.bib @@ -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} +} diff --git a/docs/src/references.md b/docs/src/references.md index 35e944a21..049f222b5 100644 --- a/docs/src/references.md +++ b/docs/src/references.md @@ -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) diff --git a/ext/QuantumCliffordHeckeExt/lifted_product.jl b/ext/QuantumCliffordHeckeExt/lifted_product.jl index 21cd96481..f67bf9d39 100644 --- a/ext/QuantumCliffordHeckeExt/lifted_product.jl +++ b/ext/QuantumCliffordHeckeExt/lifted_product.jl @@ -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])); @@ -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;;]) diff --git a/test/test_ecc_base.jl b/test/test_ecc_base.jl index 26b00c8f3..ca423aa25 100644 --- a/test/test_ecc_base.jl +++ b/test/test_ecc_base.jl @@ -58,6 +58,33 @@ 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)], @@ -65,7 +92,7 @@ const code_instance_args = Dict( :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] ) diff --git a/test/test_ecc_bivaraite_bicycle_as_twobga.jl b/test/test_ecc_bivaraite_bicycle_as_twobga.jl new file mode 100644 index 000000000..ffeac975a --- /dev/null +++ b/test/test_ecc_bivaraite_bicycle_as_twobga.jl @@ -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