diff --git a/Project.toml b/Project.toml index d8f9e83e4..d78f8bbbc 100644 --- a/Project.toml +++ b/Project.toml @@ -27,6 +27,7 @@ CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" Hecke = "3e1990a7-5d81-5526-99ce-9ba3ff248f21" LDPCDecoders = "3c486d74-64b9-4c60-8b1a-13a564e77efb" Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" +Oscar = "f1435218-dba5-11e9-1e4d-f1a5fab5fc13" Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" PyQDecoders = "17f5de1a-9b79-4409-a58d-4d45812840f7" Quantikz = "b0d11df0-eea3-4d79-b4a5-421488cbf74b" @@ -34,7 +35,7 @@ QuantumOpticsBase = "4f57444f-1401-5e15-980d-4471b28d5678" [extensions] QuantumCliffordGPUExt = "CUDA" -QuantumCliffordHeckeExt = "Hecke" +QuantumCliffordHeckeExt = ["Hecke", "Oscar"] QuantumCliffordLDPCDecodersExt = "LDPCDecoders" QuantumCliffordMakieExt = "Makie" QuantumCliffordPlotsExt = "Plots" @@ -48,7 +49,7 @@ Combinatorics = "1.0" DataStructures = "0.18" DocStringExtensions = "0.9" Graphs = "1.9" -Hecke = "0.28, 0.29, 0.30, 0.31, 0.32, 0.33, 0.34" +Hecke = "0.30, 0.31, 0.32, 0.33, 0.34, 0.34.3, 0.34.4" HostCPUFeatures = "0.1.6" ILog2 = "0.2.3" InteractiveUtils = "1.9" @@ -56,7 +57,8 @@ LDPCDecoders = "0.3.1" LinearAlgebra = "1.9" MacroTools = "0.5.9" Makie = "0.20, 0.21" -Nemo = "0.42.1, 0.43, 0.44, 0.45, 0.46, 0.47" +Nemo = "0.43.1, 0.44, 0.45, 0.46, 0.47" +Oscar = "1.0.0, 1.0.4, 1.1.1" Plots = "1.38.0" PrecompileTools = "1.2" PyQDecoders = "0.2.1" diff --git a/ext/QuantumCliffordHeckeExt/QuantumCliffordHeckeExt.jl b/ext/QuantumCliffordHeckeExt/QuantumCliffordHeckeExt.jl index 29e9de8ce..f5c3d70fd 100644 --- a/ext/QuantumCliffordHeckeExt/QuantumCliffordHeckeExt.jl +++ b/ext/QuantumCliffordHeckeExt/QuantumCliffordHeckeExt.jl @@ -8,10 +8,12 @@ import Hecke: Group, GroupElem, AdditiveGroup, AdditiveGroupElem, multiplication_table, coefficients, abelian_group, group_algebra import Nemo import Nemo: characteristic, matrix_repr, GF, ZZ, lift +import Oscar +import Oscar: cyclic_group, direct_product 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 97e41b044..a4761ed4c 100644 --- a/ext/QuantumCliffordHeckeExt/lifted_product.jl +++ b/ext/QuantumCliffordHeckeExt/lifted_product.jl @@ -120,6 +120,11 @@ function LPCode(shift_array1::Matrix{Int}, shift_array2::Matrix{Int}, l::Int; GA LPCode(LiftedCode(shift_array1, l; GA=GA), LiftedCode(shift_array2, l; GA=GA); GA=GA, repr=representation_matrix) end +# TODO define LiftedProduct code constructor that takes `m` and `GA` as product of cyclic groups as input as well. +function LPCode(shift_array1::Matrix{Int}, shift_array2::Matrix{Int}, l::Int, m::Int; GA::GroupAlgebra=group_algebra(GF(2), direct_product(cyclic_group(l), cyclic_group(m)))) + LPCode(LiftedCode(shift_array1, l, m; GA=GA), LiftedCode(shift_array2, l, m; GA=GA); GA=GA, repr=representation_matrix) +end + iscss(::Type{LPCode}) = true function parity_checks_xz(c::LPCode) @@ -185,3 +190,19 @@ function bicycle_codes(a_shifts::Array{Int}, l::Int) a = sum(GA[n÷l+1] for n in a_shifts) two_block_group_algebra_codes(a, a') end + +""" +Bivariate Bicycle codes belong to a wider class of generalized bicycle (GB) codes, +which are further generalized into of two block group algebra (2GBA) codes. + +BBQLDPC can be viewed as a special case of Lifted Product construction based on +abelian group `ℤₗ x ℤₘ` where `ℤⱼ` cyclic group of order `j`. + +The ECC Zoo has an [entry for this family](https://errorcorrectionzoo.org/c/qcga). +""" +function bivariate_bicycle_codes(a_shifts::Array{Int}, b_shifts::Array{Int}, l::Int, m::Int) + GA = group_algebra(GF(2), direct_product(cyclic_group(l), cyclic_group(m))) + a = sum(GA[(n%l)+l*((n÷l)%m)+1] for n in a_shifts) + b = sum(GA[(n%l)+l*((n÷l)%m)+1] for n in b_shifts) + two_block_group_algebra_codes(a, b) +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/Project.toml b/test/Project.toml index cd15ae310..ab3ef2c96 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -1,28 +1,39 @@ [deps] AbstractAlgebra = "c3fe647b-3220-5bb0-a1ea-a7954cac585d" +AlgebraicSolving = "66b61cbe-0446-4d5d-9090-1ff510639f9d" Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" ArrayInterface = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +DeepDiffs = "ab62b9b5-e342-54a8-a765-a90f495de1a6" +Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b" DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +GAP = "c863536a-3901-11e9-33e7-d5cd0df7b904" Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" Hecke = "3e1990a7-5d81-5526-99ce-9ba3ff248f21" HostCPUFeatures = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" ILog2 = "2cd5bd5f-40a1-5050-9e10-fc8cdb6109f5" InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240" JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b" +JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" LDPCDecoders = "3c486d74-64b9-4c60-8b1a-13a564e77efb" +LazyArtifacts = "4af54fe1-eca0-43a8-85a7-787d91b784e3" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" Nemo = "2edaba10-b0f1-5616-af89-8c11ac63239a" +Oscar = "f1435218-dba5-11e9-1e4d-f1a5fab5fc13" +Polymake = "d720cf60-89b5-51f5-aff5-213f193123e7" PyQDecoders = "17f5de1a-9b79-4409-a58d-4d45812840f7" Quantikz = "b0d11df0-eea3-4d79-b4a5-421488cbf74b" QuantumInterface = "5717a53b-5d69-4fa3-b976-0bf2f97ca1e5" QuantumOpticsBase = "4f57444f-1401-5e15-980d-4471b28d5678" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" SIMD = "fdea26ae-647d-5447-a871-4b548cad5224" +Singular = "bcd08a7b-43d2-5ff7-b6d4-c458787f915c" StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3" Static = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" StridedViews = "4db3bf67-4bd7-4b4e-b153-31dc3fb37143" diff --git a/test/test_ecc_base.jl b/test/test_ecc_base.jl index f087ea627..be11c5f0f 100644 --- a/test/test_ecc_base.jl +++ b/test/test_ecc_base.jl @@ -6,6 +6,7 @@ using InteractiveUtils import Nemo: GF import LinearAlgebra import Hecke: group_algebra, abelian_group, gens +import Oscar: cyclic_group, direct_product # generate instances of all implemented codes to make sure nothing skips being checked @@ -64,7 +65,8 @@ const code_instance_args = Dict( :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)), - :QuantumReedMuller => [3, 4, 5] + :QuantumReedMuller => [3, 4, 5], + :bivariate_bicycle_codes =>[([3,1,2],[3,1,2],6,6),([3,1,2],[3,1,2],9,6)] ) function all_testablable_code_instances(;maxn=nothing) diff --git a/test/test_ecc_decoder_all_setups.jl b/test/test_ecc_decoder_all_setups.jl index c98813a38..71f84191d 100644 --- a/test/test_ecc_decoder_all_setups.jl +++ b/test/test_ecc_decoder_all_setups.jl @@ -35,7 +35,8 @@ ## @testset "belief prop decoders, good for sparse codes" begin - codes = vcat(LP04, LP118, test_gb_codes, other_lifted_product_codes) + codes = [vcat(LP04, LP118, test_gb_codes, other_lifted_product_codes), + bivariate_bicycle_codes([3,1,2],[3,1,2],6,6), bivariate_bicycle_codes([3,1,2],[3,1,2],9,6)] noise = 0.001 diff --git a/test/test_jet.jl b/test/test_jet.jl index 42454e54e..d13e5f992 100644 --- a/test/test_jet.jl +++ b/test/test_jet.jl @@ -9,6 +9,7 @@ using Nemo using AbstractAlgebra using Hecke + using Oscar rep = report_package("QuantumClifford"; ignored_modules=( @@ -21,6 +22,7 @@ AnyFrameModule(Nemo), AnyFrameModule(AbstractAlgebra), AnyFrameModule(Hecke), + AnyFrameModule(Oscar) )) @show rep