From 0bc525684018481ea8da205230f47aa89008e9b1 Mon Sep 17 00:00:00 2001 From: Fe-r-oz Date: Mon, 21 Oct 2024 12:41:18 +0500 Subject: [PATCH] implement Bivaraite Bicycle codes using 2BGA as parent --- docs/src/references.bib | 11 ++ .../QuantumCliffordHeckeExt.jl | 5 +- ext/QuantumCliffordHeckeExt/lifted_product.jl | 44 ++++- src/ecc/ECC.jl | 1 + src/ecc/codes/lifted_product.jl | 3 + test/test_ecc_bivaraite_bicycle_as_twobga.jl | 173 ++++++++++++++++++ 6 files changed, 232 insertions(+), 5 deletions(-) create mode 100644 test/test_ecc_bivaraite_bicycle_as_twobga.jl diff --git a/docs/src/references.bib b/docs/src/references.bib index 29500a034..b8d1116a0 100644 --- a/docs/src/references.bib +++ b/docs/src/references.bib @@ -487,3 +487,14 @@ @article{anderson2014fault year={2014}, 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/ext/QuantumCliffordHeckeExt/QuantumCliffordHeckeExt.jl b/ext/QuantumCliffordHeckeExt/QuantumCliffordHeckeExt.jl index 29e9de8ce..3a3035f72 100644 --- a/ext/QuantumCliffordHeckeExt/QuantumCliffordHeckeExt.jl +++ b/ext/QuantumCliffordHeckeExt/QuantumCliffordHeckeExt.jl @@ -5,13 +5,14 @@ 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 + multiplication_table, coefficients, abelian_group, group_algebra, + FinGenAbGroup, FinGenAbGroupElem, one import Nemo import Nemo: characteristic, matrix_repr, GF, ZZ, lift 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 + two_block_group_algebra_codes, generalized_bicycle_codes, bicycle_codes, bivariate_bicycle_codes include("types.jl") include("lifted.jl") diff --git a/ext/QuantumCliffordHeckeExt/lifted_product.jl b/ext/QuantumCliffordHeckeExt/lifted_product.jl index ef09eddbb..223465f4e 100644 --- a/ext/QuantumCliffordHeckeExt/lifted_product.jl +++ b/ext/QuantumCliffordHeckeExt/lifted_product.jl @@ -153,7 +153,7 @@ code_s(c::LPCode) = size(c.repr(zero(c.GA)), 1) * (size(c.A, 1) * size(c.B, 1) + Two-block group algebra (2GBA) codes, which are a special case of lifted product codes from two group algebra elements `a` and `b`, used as `1x1` base matrices. -See also: [`LPCode`](@ref), [`generalized_bicycle_codes`](@ref), [`bicycle_codes`](@ref) +See also: [`LPCode`](@ref), [`generalized_bicycle_codes`](@ref), [`bicycle_codes`](@ref), [`bivariate_bicycle_codes`](@ref) """ # TODO doctest example function two_block_group_algebra_codes(a::GroupAlgebraElem, b::GroupAlgebraElem) A = reshape([a], (1, 1)) @@ -166,7 +166,7 @@ Generalized bicycle codes, which are a special case of 2GBA codes (and therefore Here the group is chosen as the cyclic group of order `l`, and the base matrices `a` and `b` are the sum of the group algebra elements corresponding to the shifts `a_shifts` and `b_shifts`. -See also: [`two_block_group_algebra_codes`](@ref), [`bicycle_codes`](@ref). +See also: [`two_block_group_algebra_codes`](@ref), [`bicycle_codes`](@ref), [`bivariate_bicycle_codes`](@ref) A [[254, 28, 14 ≤ d ≤ 20]] code from (A1) in Appendix B of [panteleev2021degenerate](@cite). @@ -189,10 +189,48 @@ Bicycle codes are a special case of generalized bicycle codes, where `a` and `b` are conjugate to each other. The order of the cyclic group is `l`, and the shifts `a_shifts` and `b_shifts` are reverse to each other. -See also: [`two_block_group_algebra_codes`](@ref), [`generalized_bicycle_codes`](@ref). +See also: [`two_block_group_algebra_codes`](@ref), [`generalized_bicycle_codes`](@ref), [`bivariate_bicycle_codes`](@ref) """ # TODO doctest example function bicycle_codes(a_shifts::Array{Int}, l::Int) GA = group_algebra(GF(2), abelian_group(l)) a = sum(GA[n÷l+1] for n in a_shifts) two_block_group_algebra_codes(a, group_algebra_conj(a)) end + +""" +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/q-ary_bch). + +See also: [`two_block_group_algebra_codes`](@ref), [`generalized_bicycle_codes`](@ref), +[`bicycle_codes`](@ref), [`LPCode`](@ref) + +A [[756, 16, ≤ 34]] code from Table 3 of [bravyi2024high](@cite). + +```jldoctest +julia> import Hecke: group_algebra, GF, abelian_group, gens; # hide + +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 = bivariate_bicycle_codes(A,B,GA); + +julia> code_n(c), code_k(c) +(756, 16) +``` +""" +function bivariate_bicycle_codes(A::Vector{GroupAlgebraElem{FqFieldElem, GroupAlgebra{FqFieldElem, FinGenAbGroup, FinGenAbGroupElem}}}, B::Vector{GroupAlgebraElem{FqFieldElem, GroupAlgebra{FqFieldElem, FinGenAbGroup, FinGenAbGroupElem}}}, GA::GroupAlgebra{FqFieldElem, FinGenAbGroup, FinGenAbGroupElem}) + a = sum(GA(x) for x in A) + b = sum(GA(x) for x in B) + c = two_block_group_algebra_codes(a,b) + return c +end diff --git a/src/ecc/ECC.jl b/src/ecc/ECC.jl index cdda7742e..5a29f136f 100644 --- a/src/ecc/ECC.jl +++ b/src/ecc/ECC.jl @@ -22,6 +22,7 @@ export parity_checks, parity_checks_x, parity_checks_z, iscss, Shor9, Steane7, Cleve8, Perfect5, Bitflip3, Toric, Gottesman, Surface, Concat, CircuitCode, QuantumReedMuller, LPCode, two_block_group_algebra_codes, generalized_bicycle_codes, bicycle_codes, + bivariate_bicycle_codes, random_brickwork_circuit_code, random_all_to_all_circuit_code, evaluate_decoder, CommutationCheckECCSetup, NaiveSyndromeECCSetup, ShorSyndromeECCSetup, diff --git a/src/ecc/codes/lifted_product.jl b/src/ecc/codes/lifted_product.jl index 338880702..955bc3ff5 100644 --- a/src/ecc/codes/lifted_product.jl +++ b/src/ecc/codes/lifted_product.jl @@ -17,3 +17,6 @@ function generalized_bicycle_codes end """Implemented in a package extension with Hecke.""" function bicycle_codes end + +"""Implemented in a package extension with Hecke.""" +function bivariate_bicycle_codes end 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..cee31f642 --- /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: bivariate_bicycle_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 = bivariate_bicycle_codes(A,B,GA) + @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 = [one(x), x^2 , x^7] + c = bivariate_bicycle_codes(A,B,GA) + @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 = bivariate_bicycle_codes(A,B,GA) + @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 = bivariate_bicycle_codes(A,B,GA) + @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 = bivariate_bicycle_codes(A,B,GA) + @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 = bivariate_bicycle_codes(A,B,GA) + @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 = bivariate_bicycle_codes(A,B,GA) + @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 = [one(x), x , x^11] + c = bivariate_bicycle_codes(A,B,GA) + @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 = bivariate_bicycle_codes(A,B,GA) + @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 = [one(x), x , x^2] + c = bivariate_bicycle_codes(A,B,GA) + @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 = bivariate_bicycle_codes(A,B,GA) + @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 = [one(x), x^4 , x^13] + c = bivariate_bicycle_codes(A,B,GA) + @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 = [one(x), y^2, y^4] + B = [y^3 , x , x^2] + c = bivariate_bicycle_codes(A,B,GA) + @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 = bivariate_bicycle_codes(A,B,GA) + @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 = [one(x), y^2, y^10] + B = [y^3 , x , x^2] + c = bivariate_bicycle_codes(A,B,GA) + @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 = [one(x), y^6, y^8] + B = [y^5 , x , x^4] + c = bivariate_bicycle_codes(A,B,GA) + @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 = [one(x), y^10, y^14] + B = [y^12 , x , x^2] + c = bivariate_bicycle_codes(A,B,GA) + @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 = bivariate_bicycle_codes(A,B,GA) + @test code_n(c) == 180 && code_k(c) == 8 + end +end