diff --git a/Project.toml b/Project.toml index 4d52366..09723eb 100644 --- a/Project.toml +++ b/Project.toml @@ -13,6 +13,7 @@ Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" Oscar = "f1435218-dba5-11e9-1e4d-f1a5fab5fc13" +Hecke = "3e1990a7-5d81-5526-99ce-9ba3ff248f21" ProgressMeter = "92933f4c-e287-5a05-a399-4b506db050ca" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" diff --git a/docs/src/Quantum/product_codes.md b/docs/src/Quantum/product_codes.md index cf1ae93..a7dbdf1 100644 --- a/docs/src/Quantum/product_codes.md +++ b/docs/src/Quantum/product_codes.md @@ -6,6 +6,8 @@ - [Generealized bicycle](https://errorcorrectionzoo.org/c/generalized_bicycle): [pryadko2013quantum](@cite), [Kovalev_2013](@cite), [panteleev2021degenerate](@cite) - Generalized hypergraph product: [panteleev2021degenerate](@cite) - Bias-tailored lifted product: [roffe2023bias](@cite) +- Bivariate bicycle: [wang2024coprime](@cite) +- Coprime bivarate bicycle: [wang2024coprime](@cite) ```@autodocs diff --git a/docs/src/references.bib b/docs/src/references.bib index 6eeb9ce..e91e3cc 100644 --- a/docs/src/references.bib +++ b/docs/src/references.bib @@ -183,3 +183,21 @@ @inproceedings{yao2024belief year={2024}, organization={IEEE} } + +@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} +} + +@article{wang2024coprime, + title={Coprime Bivariate Bicycle Codes and their Properties}, + author={Wang, Ming and Mueller, Frank}, + journal={arXiv preprint arXiv:2408.10001}, + year={2024} +} diff --git a/src/CodingTheory.jl b/src/CodingTheory.jl index a4940f2..c17b6d3 100644 --- a/src/CodingTheory.jl +++ b/src/CodingTheory.jl @@ -376,7 +376,7 @@ export HypergraphProductCode, GeneralizedShorCode, BaconCasaccinoConstruction, GeneralizedHypergraphProductCode, LiftedProductCode, bias_tailored_lifted_product_matrices, BiasTailoredLiftedProductCode, SPCDFoldProductCode, SingleParityCheckDFoldProductCode, Quintavalle_basis, asymmetric_product, symmetric_product, random_homological_product_code, - homological_product, ⊠, BivariateBicycleCode + homological_product, ⊠, BivariateBicycleCode, CoprimeBivariateBicycleCode ############################# # Quantum/simulation.jl diff --git a/src/Quantum/product_codes.jl b/src/Quantum/product_codes.jl index efd5fa3..187c9f1 100644 --- a/src/Quantum/product_codes.jl +++ b/src/Quantum/product_codes.jl @@ -917,7 +917,7 @@ function BivariateBicycleCode(a::T, b::T) where T <: Union{MPolyQuoRingElem{FqMP l = exps[1][1] end end - + x = matrix(F, [mod1(i + 1, l) == j ? 1 : 0 for i in 1:l, j in 1:l]) ⊗ identity_matrix(F, m) y = identity_matrix(F, l) ⊗ matrix(F, [mod1(i + 1, m) == j ? 1 : 0 for i in 1:m, j in 1:m]) @@ -943,5 +943,56 @@ function BivariateBicycleCode(a::T, b::T) where T <: Union{MPolyQuoRingElem{FqMP end end + + return CSSCode(hcat(A, B), hcat(transpose(B), transpose(A))) +end + +""" + CoPrimeBivariateBicycleCode(a::MPolyQuoRingElem{FqMPolyRingElem}, b::MPolyQuoRingElem{FqMPolyRingElem}) + +Return the coprime bivariate bicycle code defined by the residue ring elements `a` and `b`. + +# Note +- This is defined in https://arxiv.org/pdf/2408.10001v1. +""" +function CoprimeBivariateBicycleCode(a::T, b::T) where T <: Union{MPolyQuoRingElem{FqMPolyRingElem}, MPolyQuoRingElem{fpMPolyRingElem}} + R = parent(a) + R == parent(b) || throw(DomainError("Polynomials must have the same parent.")) + F = base_ring(base_ring(a)) + order(F) == 2 || throw(DomainError("This code family is currently only defined over binary fields.")) + length(symbols(parent(a))) == 1 || throw(DomainError("Polynomials must be over one variable.")) + g = gens(modulus(R)) + + m = -1 + l = -1 + + exps = collect(exponents(g[1]))[1][1] + length(exps) == 1 || throw(ArgumentError("Moduli of the incorrect form.")) + facs = factor(ZZ(exps)).fac + pfacs = collect(keys(facs)) + pexps = collect(values(facs)) + + l = Int(pfacs[1]^pexps[1]) + m = Int(pfacs[2]^pexps[2]) + + length(pfacs) == 2 ? (gcd([l, m]) == 1 ? + nothing : throw(ArgumentError("l and m must be coprime numbers."))) : throw(ArgumentError("Moduli of the incorrect form.")) + + x = matrix(F, [mod1(i + 1, l) == j ? 1 : 0 for i in 1:l, j in 1:l]) ⊗ identity_matrix(F, m) + y = identity_matrix(F, l) ⊗ matrix(F, [mod1(i + 1, m) == j ? 1 : 0 for i in 1:m, j in 1:m]) + + P = x*y + A = zero_matrix(F, exps, exps) + for ex in exponents(lift(a)) + power, _ = findmax(ex) + A += P^power + end + + B = zero_matrix(F, exps, exps) + for ex in exponents(lift(b)) + power, _ = findmax(ex) + B += P^power + end + return CSSCode(hcat(A, B), hcat(transpose(B), transpose(A))) end diff --git a/test/Quantum/product_codes_test.jl b/test/Quantum/product_codes_test.jl index 4f1dca5..0490d8d 100644 --- a/test/Quantum/product_codes_test.jl +++ b/test/Quantum/product_codes_test.jl @@ -606,5 +606,62 @@ @test length(Q) == 196 @test dimension(Q) == 12 @test_broken minimum_distance(S) == 8 - end + + # Coprime Bivariate Bicycle codes + # Table 2 of https://arxiv.org/pdf/2408.10001v1 + # [[30, 4, 6]] + S, (P) = polynomial_ring(Oscar.Nemo.Native.GF(2), [:P]) + l = 3 + m = 5 + R, _ = quo(S, ideal(S, [P[1]^(l*m)])) + a = R(1 + P[1] + P[1]^2) + b = R(P[1] + P[1]^3 + P[1]^8) + Q = CoprimeBivariateBicycleCode(a, b) + @test length(Q) == 30 + @test dimension(Q) == 4 + @test_broken minimum_distance(Q) == 6 + + # [[42, 6, 6]] + l = 3 + m = 7 + R, _ = quo(S, ideal(S, [P[1]^(l*m)])) + a = R(1 + P[1]^2 + P[1]^3) + b = R(P[1] + P[1]^3 + P[1]^11) + Q = CoprimeBivariateBicycleCode(a, b) + @test length(Q) == 42 + @test dimension(Q) == 6 + @test_broken minimum_distance(Q) == 6 + + # [[70, 6, 8]] + l = 5 + m = 7 + R, _ = quo(S, ideal(S, [P[1]^(l*m)])) + a = R(1 + P[1] + P[1]^5) + b = R(1 + P[1] + P[1]^12) + Q = CoprimeBivariateBicycleCode(a, b) + @test length(Q) == 70 + @test dimension(Q) == 6 + @test_broken minimum_distance(Q) == 8 + + # [[108, 12, 6]] + l = 2 + m = 27 + R, _ = quo(S, ideal(S, [P[1]^(l*m)])) + a = R(P[1]^2 + P[1]^5 + P[1]^44) + b = R(P[1]^8 + P[1]^14 + P[1]^47) + Q = CoprimeBivariateBicycleCode(a, b) + @test length(Q) == 108 + @test dimension(Q) == 12 + @test_broken minimum_distance(Q) == 6 + + # [126, 12, 10]] + l = 7 + m = 9 + R, _ = quo(S, ideal(S, [P[1]^(l*m)])) + a = R(1 + P[1] + P[1]^58) + b = R(P[1]^3 + P[1]^16 + P[1]^44) + Q = CoprimeBivariateBicycleCode(a, b) + @test length(Q) == 126 + @test dimension(Q) == 12 + @test_broken minimum_distance(Q) == 10 end