diff --git a/ext/QuantumCliffordHeckeExt/QuantumCliffordHeckeExt.jl b/ext/QuantumCliffordHeckeExt/QuantumCliffordHeckeExt.jl index 83c3dc036..29e9de8ce 100644 --- a/ext/QuantumCliffordHeckeExt/QuantumCliffordHeckeExt.jl +++ b/ext/QuantumCliffordHeckeExt/QuantumCliffordHeckeExt.jl @@ -5,7 +5,7 @@ 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, small_group, direct_product + multiplication_table, coefficients, abelian_group, group_algebra import Nemo import Nemo: characteristic, matrix_repr, GF, ZZ, lift diff --git a/ext/QuantumCliffordHeckeExt/lifted_product.jl b/ext/QuantumCliffordHeckeExt/lifted_product.jl index d9fa7c280..ef09eddbb 100644 --- a/ext/QuantumCliffordHeckeExt/lifted_product.jl +++ b/ext/QuantumCliffordHeckeExt/lifted_product.jl @@ -161,48 +161,6 @@ function two_block_group_algebra_codes(a::GroupAlgebraElem, b::GroupAlgebraElem) LPCode(A, B) end -""" -[[72, 8, 9]] 2BGA code from Table 1 of [lin2024quantum](@cite) with direct product -of `C₉ x C₄`. - -```jldoctest -julia> c = two_block_group_algebra_codes([0, 28], [0, 9, 18, 12, 29, 14], (36, 2)); - -julia> code_n(c), code_k(c) -(72, 8) -``` -""" -function two_block_group_algebra_codes(a_shifts::Array{Int}, b_shifts::Array{Int}, sg::Tuple{Int,Int}) - m, i = sg - g1 = small_group(m, i) - GA = group_algebra(GF(2), g1) - a = sum(GA[n%dim(GA)+1] for n in a_shifts) - b = sum(GA[n%dim(GA)+1] for n in b_shifts) - two_block_group_algebra_codes(a, b) -end - -""" -[[48, 8, 6]] 2BGA code from Table 3 of [lin2024quantum](@cite) with dihedral group of -order `l = 12`. - -```jldoctest -julia> c = two_block_group_algebra_codes([0, 10], [0, 8, 9, 4, 2, 5], (12, 4), (2, 1)); - -julia> code_n(c), code_k(c) -(48, 8) -``` -""" -function two_block_group_algebra_codes(a_shifts::Array{Int}, b_shifts::Array{Int}, sg1::Tuple{Int,Int}, sg2::Tuple{Int,Int}) - m, i = sg1 - l, i = sg2 - g1 = small_group(m, i) - g2 = small_group(l, i) - GA = group_algebra(GF(2), direct_product(g1, g2)) - a = sum(GA[n%dim(GA)+1] for n in a_shifts) - b = sum(GA[n%dim(GA)+1] for n in b_shifts) - two_block_group_algebra_codes(a, b) -end - """ Generalized bicycle codes, which are a special case of 2GBA codes (and therefore of lifted product codes). Here the group is chosen as the cyclic group of order `l`, diff --git a/test/Project.toml b/test/Project.toml index cd15ae310..c69088264 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -16,6 +16,7 @@ LDPCDecoders = "3c486d74-64b9-4c60-8b1a-13a564e77efb" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" Nemo = "2edaba10-b0f1-5616-af89-8c11ac63239a" +Oscar = "f1435218-dba5-11e9-1e4d-f1a5fab5fc13" PyQDecoders = "17f5de1a-9b79-4409-a58d-4d45812840f7" Quantikz = "b0d11df0-eea3-4d79-b4a5-421488cbf74b" QuantumInterface = "5717a53b-5d69-4fa3-b976-0bf2f97ca1e5" diff --git a/test/test_ecc_nonabelin2bga.jl b/test/test_ecc_nonabelin2bga.jl new file mode 100644 index 000000000..f06f6968e --- /dev/null +++ b/test/test_ecc_nonabelin2bga.jl @@ -0,0 +1,224 @@ +@testitem "ECC 2BGA lin2024quantum" begin + import Hecke: group_algebra, GF, abelian_group, gens, quo, one + using QuantumClifford.ECC + using QuantumClifford.ECC: LPCode, code_k, code_n, two_block_group_algebra_codes + using Oscar: free_group, small_group_identification, describe + + @testset "Reproduce Table 1 Block 1" begin + # [[72, 8, 9]] + F = free_group(["r"]) + r = gens(F)[1] + G, = quo(F, [r^36]) + F2G = group_algebra(GF(2), G) + r = gens(G)[1] + a_elts = [one(G), r^28] + b_elts = [one(G), r, r^18, r^12, r^29, r^14] + a = sum(F2G(x) for x in a_elts) + b = sum(F2G(x) for x in b_elts) + c = two_block_group_algebra_codes(a, b) + @test describe(G) == "C36" + @test small_group_identification(G) == (36, 2) + @test code_n(c) == 72 && code_k(c) == 8 + end + + @testset "Reproduce Table 1 Block 2" begin + # [[72, 8, 9]] + F = free_group(["r", "s"]) + r, s = gens(F) + G, = quo(F, [s^4, r^9, s^(-1)*r*s*r]) + F2G = group_algebra(GF(2), G) + r, s = gens(G) + a_elts = [one(G), r] + b_elts = [one(G), s, r^6, s^3 * r, s * r^7, s^3 * r^5] + a = sum(F2G(x) for x in a_elts) + b = sum(F2G(x) for x in b_elts) + c = two_block_group_algebra_codes(a, b) + @test describe(G) == "C9 : C4" + @test small_group_identification(G) == (36, 1) + @test code_n(c) == 72 && code_k(c) == 8 + + # [[80, 8, 10]] + F = free_group(["r", "s"]) + r, s = gens(F) + G, = quo(F, [s^5, r^8, r^(-1)*s*r*s]) + F2G = group_algebra(GF(2), G) + r, s = gens(G) + a_elts = [one(G), s*r^4] + b_elts = [one(G), r, r^2, s, s^3 * r, s^2 * r^6] + a = sum(F2G(x) for x in a_elts) + b = sum(F2G(x) for x in b_elts) + c = two_block_group_algebra_codes(a, b) + @test describe(G) == "C5 : C8" + @test small_group_identification(G) == (40, 1) + @test code_n(c) == 80 && code_k(c) == 8 + end + + @testset "Reproduce Table 1 Block 3" begin + # [[54, 6, 9]] + F = free_group(["r"]) + r = gens(F)[1] + G, = quo(F, [r^27]) + F2G = group_algebra(GF(2), G) + r = gens(G)[1] + a_elts = [one(G), r, r^3, r^7] + b_elts = [one(G), r, r^12, r^19] + a = sum(F2G(x) for x in a_elts); + b = sum(F2G(x) for x in b_elts) + c = two_block_group_algebra_codes(a, b) + @test describe(G) == "C27" + @test small_group_identification(G) == (27, 1) + @test code_n(c) == 54 && code_k(c) == 6 + + # [[60, 6, 10]] + F = free_group(["r"]) + r = gens(F)[1] + G, = quo(F, [r^30]) + F2G = group_algebra(GF(2), G) + r = gens(G)[1] + a_elts = [one(G), r^10, r^6, r^13] + b_elts = [one(G), r^25, r^16, r^12] + a = sum(F2G(x) for x in a_elts); + b = sum(F2G(x) for x in b_elts) + c = two_block_group_algebra_codes(a, b) + @test describe(G) == "C30" + @test small_group_identification(G) == (30, 4) + @test code_n(c) == 60 && code_k(c) == 6 + + # [[70, 8, 10]] + F = free_group(["r"]) + r = gens(F)[1] + G, = quo(F, [r^35]) + F2G = group_algebra(GF(2), G) + r = gens(G)[1] + a_elts = [one(G), r^15, r^16, r^18] + b_elts = [one(G), r, r^24, r^27] + a = sum(F2G(x) for x in a_elts); + b = sum(F2G(x) for x in b_elts) + c = two_block_group_algebra_codes(a, b) + @test describe(G) == "C35" + @test small_group_identification(G) == (35, 1) + @test code_n(c) == 70 && code_k(c) == 8 + + # [[72, 8, 10]] + F = free_group(["r"]) + r = gens(F)[1] + G, = quo(F, [r^36]) + F2G = group_algebra(GF(2), G) + r = gens(G)[1] + a_elts = [one(G), r^9, r^28, r^31] + b_elts = [one(G), r, r^21, r^34] + a = sum(F2G(x) for x in a_elts); + b = sum(F2G(x) for x in b_elts) + c = two_block_group_algebra_codes(a, b) + @test describe(G) == "C36" + @test small_group_identification(G) == (36, 2) + @test code_n(c) == 72 && code_k(c) == 8 + + # [[72, 10, 9]] + F = free_group(["r"]) + r = gens(F)[1] + G, = quo(F, [r^36]) + F2G = group_algebra(GF(2), G) + r = gens(G)[1] + a_elts = [one(G), r^9, r^28, r^13] + b_elts = [one(G), r, r^3, r^22] + a = sum(F2G(x) for x in a_elts); + b = sum(F2G(x) for x in b_elts) + c = two_block_group_algebra_codes(a, b) + @test describe(G) == "C36" + @test small_group_identification(G) == (36, 2) + @test code_n(c) == 72 && code_k(c) == 10 + end + + @testset "Reproduce Table 1 Block 4" begin + # [[72, 8, 9]] + F = free_group(["r", "s"]) + r, s = gens(F) + G, = quo(F, [s^4, r^9, s^(-1)*r*s*r]) + F2G = group_algebra(GF(2), G) + r, s = gens(G) + a_elts = [one(G), s, r, s*r^6] + b_elts = [one(G), s^2*r, s^2*r^6, r^2] + a = sum(F2G(x) for x in a_elts); + b = sum(F2G(x) for x in b_elts) + c = two_block_group_algebra_codes(a, b) + @test describe(G) == "C9 : C4" + @test small_group_identification(G) == (36, 1) + @test code_n(c) == 72 && code_k(c) == 8 + + # [[80, 8, 10]] + F = free_group(["r", "s"]) + r, s = gens(F) + G, = quo(F, [s^5, r^8, r^(-1)*s*r*s]) + F2G = group_algebra(GF(2), G) + r, s = gens(G) + a_elts = [one(G), r, s, s^3*r^5] + b_elts = [one(G), r^2, s*r^4, s^3*r^2] + a = sum(F2G(x) for x in a_elts) + b = sum(F2G(x) for x in b_elts) + c = two_block_group_algebra_codes(a, b) + @test describe(G) == "C5 : C8" + @test small_group_identification(G) == (40, 1) + @test code_n(c) == 80 && code_k(c) == 8 + + # [[96, 8, 12]] + F = free_group(["r", "s"]) + r, s = gens(F) + G, = quo(F, [s^3, r^16, r^(-1)*s*r*s]) + F2G = group_algebra(GF(2), G) + r, s = gens(G) + a_elts = [one(G), r, s, r^14] + b_elts = [one(G), r^2, s*r^4, r^11] + a = sum(F2G(x) for x in a_elts) + b = sum(F2G(x) for x in b_elts) + c = two_block_group_algebra_codes(a, b) + @test describe(G) == "C3 : C16" + @test small_group_identification(G) == (48, 1) + @test code_n(c) == 96 && code_k(c) == 6 + + # [[84, 10, 9]] + F = free_group(["r", "s"]) + r, s = gens(F) + G, = quo(F, [s^3, r^14, r^(-1)*s*r*s]) + F2G = group_algebra(GF(2), G) + r, s = gens(G) + a_elts = [one(G), r^7, r^8, s*r^10] + b_elts = [one(G), s, r^5, s^2*r^13] + a = sum(F2G(x) for x in a_elts) + b = sum(F2G(x) for x in b_elts) + c = two_block_group_algebra_codes(a, b) + @test describe(G) == "C7 x S3" + @test small_group_identification(G) == (42, 3) + @test code_n(c) == 84 && code_k(c) == 10 + + # [[96, 6, 12]] + F = free_group(["r", "s"]) + r, s = gens(F) + G, = quo(F, [s^4, r^12, s^(-1)*r*s*r]) + F2G = group_algebra(GF(2), G) + r, s = gens(G) + a_elts = [one(G), s, r^9, s * r] + b_elts = [one(G), s^2 * s^9, r^7, r^2] + a = sum(F2G(x) for x in a_elts); + b = sum(F2G(x) for x in b_elts) + c = two_block_group_algebra_codes(a, b) + @test describe(G) == "C12 : C4" + @test small_group_identification(G) == (48, 13) + @test code_n(c) == 96 && code_k(c) == 6 + + # [[96, 12, 10]] + F = free_group(["r", "s"]) + r, s = gens(F) + G, = quo(F, [s^6, r^8, r^(-1)*s*r*s]) + F2G = group_algebra(GF(2), G) + r, s = gens(G) + a_elts = [one(G), r, s^3 * r^2, s^2 * r^3] + b_elts = [one(G), r, s^4 * r^6, s^5 * r^3] + a = sum(F2G(x) for x in a_elts) + b = sum(F2G(x) for x in b_elts) + c = two_block_group_algebra_codes(a, b) + @test describe(G) == "C2 x (C3 : C8)" + @test small_group_identification(G) == (48, 9) + @test code_n(c) == 96 && code_k(c) == 12 + end +end