-
Notifications
You must be signed in to change notification settings - Fork 47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Circulant GF(2) permutation matrix-based construction of Bivariate Bicycle quantum LDPC code #352
base: master
Are you sure you want to change the base?
Changes from all commits
b680589
7eeb82c
8c4d158
e77e1ca
a575cbf
3977d80
d4e8669
f6ff830
2212903
254768e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,15 +48,15 @@ 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.28, 0.29, 0.30, 0.31, 0.32, 0.33, 0.34, 0.34.3" | ||
HostCPUFeatures = "0.1.6" | ||
ILog2 = "0.2.3" | ||
InteractiveUtils = "1.9" | ||
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.42.1, 0.43, 0.44, 0.45, 0.46, 0.47, 0.47.1" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is this needed? |
||
Plots = "1.38.0" | ||
PrecompileTools = "1.2" | ||
PyQDecoders = "0.2.1" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -487,3 +487,28 @@ | |
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} | ||
} | ||
|
||
@article{berthusen2024toward, | ||
title={Toward a 2D local implementation of quantum LDPC codes}, | ||
author={Berthusen, Noah and Devulapalli, Dhruv and Schoute, Eddie and Childs, Andrew M and Gullans, Michael J and Gorshkov, Alexey V and Gottesman, Daniel}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "Childs" needs to be added to the spellchecker (the |
||
journal={arXiv preprint arXiv:2404.17676}, | ||
year={2024} | ||
} | ||
|
||
@article{wang2024coprime, | ||
title={Coprime Bivariate Bicycle Codes and their Properties}, | ||
author={Wang, Ming and Mueller, Frank}, | ||
journal={arXiv preprint arXiv:2408.10001}, | ||
year={2024} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
""" | ||
A bivariate bicycle (BB) quantum LDPC code was introduced by Bravyi et al. in their 2024 paper [bravyi2024high](@cite). This code uses identity and cyclic shift matrices. Define `Iₗ` as the `l × l` identity matrix and `Sₗ` as the cyclic shift matrix of the same size, where each row of `Sₗ` has a single '1' at the column `(i + 1) mod l`. | ||
|
||
The matrices `x = Sₗ ⊗ Iₘ` and `y = Iₗ ⊗ Sₘ` are used. The BB code is represented by matrices `A` and `B`, defined as: `A = A₁ + A₂ + A₃` and `B = B₁ + B₂ + B₃`. The addition and multiplication operations on binary matrices are performed modulo 2. The check matrices are: `Hx = [A|B]` and `Hz = [B'|A']`. Both `Hx` and `Hz` are `(n/2)×n` matrices. | ||
|
||
The ECC Zoo has an [entry for this family](https://errorcorrectionzoo.org/c/qcga). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This also needs:
|
||
""" | ||
struct circulant_bivariate_bicycle <: AbstractECC | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should be named like a struct, not like a function (e.g. |
||
l::Int | ||
m::Int | ||
A::Vector{Int} | ||
B::Vector{Int} | ||
function circulant_bivariate_bicycle(l,m,A,B) | ||
(l >= 0 && m >= 0) || error("l and m must be non-negative") | ||
(length(A) == 3 && length(B) == 3) || error("A and B must each have exactly 3 entries") | ||
(all(x -> x >= 0, A) && all(x -> x >= 0, B)) || error("A and B must contain only non-negative integers") | ||
(all(x -> x in 0:max(l, m), A) && all(x -> x in 0:max(l, m), B)) || error("Each element in A and B must be in the range [0, $(max(l, m))].") | ||
Comment on lines
+14
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could you use an explicit throw of an argument error or domain error instead of a generic |
||
new(l,m,A,B) | ||
end | ||
end | ||
|
||
function iscss(::Type{circulant_bivariate_bicycle}) | ||
return true | ||
end | ||
|
||
function parity_checks(c::circulant_bivariate_bicycle) | ||
a₁,a₂,a₃ = c.A[1],c.A[2],c.A[3] | ||
b₁,b₂,b₃ = c.B[1],c.B[2],c.B[3] | ||
Iₗ = Matrix{Bool}(LinearAlgebra.I,c.l,c.l) | ||
Iₘ = Matrix{Bool}(LinearAlgebra.I,c.m,c.m) | ||
x = Dict{Bool, Matrix{Bool}}() | ||
y = Dict{Bool, Matrix{Bool}}() | ||
x = Dict(i => kron(circshift(Iₗ,(0,i)),Iₘ) for i in 0:(c.l)) | ||
y = Dict(i => kron(Iₗ,circshift(Iₘ,(0,i))) for i in 0:(c.m)) | ||
A = mod.(x[a₁]+y[a₂]+y[a₃],2) | ||
B = mod.(y[b₁]+x[b₂]+x[b₃],2) | ||
Hx = hcat(A,B) | ||
Hz = hcat(B',A') | ||
H = CSS(Hx,Hz) | ||
Stabilizer(H) | ||
end | ||
|
||
code_n(c::circulant_bivariate_bicycle) = 2*c.l*c.m | ||
|
||
code_k(c::circulant_bivariate_bicycle) = code_n(c) - LinearAlgebra.rank(matrix(GF(2), parity_checks_x(c))) - LinearAlgebra.rank(matrix(GF(2), parity_checks_z(c))) | ||
|
||
parity_checks_x(c::circulant_bivariate_bicycle) = stab_to_gf2(parity_checks(circulant_bivariate_bicycle(c.l, c.m, c.A, c.B)))[1:end÷2,:] | ||
|
||
parity_checks_z(c::circulant_bivariate_bicycle) = stab_to_gf2(parity_checks(circulant_bivariate_bicycle(c.l, c.m, c.A, c.B)))[end÷2+1:end,:] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ ArrayInterface = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" | |
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" | ||
Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" | ||
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" | ||
GAP = "c863536a-3901-11e9-33e7-d5cd0df7b904" | ||
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" | ||
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" | ||
Hecke = "3e1990a7-5d81-5526-99ce-9ba3ff248f21" | ||
|
@@ -16,12 +17,15 @@ 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" | ||
Polymake = "d720cf60-89b5-51f5-aff5-213f193123e7" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is polymake needed? |
||
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" | ||
Singular = "bcd08a7b-43d2-5ff7-b6d4-c458787f915c" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is Singular needed? |
||
SIMD = "fdea26ae-647d-5447-a871-4b548cad5224" | ||
StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3" | ||
Static = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
@testitem "ECC circulant_bivariate_bicycle" begin | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these tests probable also need a subset of tests that verify correctness against the other construction method you have already contributed |
||
using Test | ||
using QuantumClifford: stab_to_gf2 | ||
using QuantumClifford.ECC | ||
using Nemo: nullspace, GF, matrix | ||
using Oscar: hom, free_module, kernel, domain, map, gens | ||
using QuantumClifford.ECC: AbstractECC, circulant_bivariate_bicycle, parity_checks_x, parity_checks_z | ||
|
||
# According to Lemma 1 from [bravyi2024high](@cite), k = 2·dim(ker(A)∩ker(B)). | ||
function _formula_k(stab) | ||
Hx = parity_checks_x(stab) | ||
n = size(Hx,2)÷2 | ||
A = matrix(GF(2), Hx[:,1:n]) | ||
B = matrix(GF(2), Hx[:,n+1:end]) | ||
k = GF(2) | ||
hA = hom(free_module(k, size(A, 1)), free_module(k, size(A, 2)), A) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hom needs to be added to the spellchecker (the |
||
hB = hom(free_module(k, size(B, 1)), free_module(k, size(B, 2)), B) | ||
ans = kernel(hA)[1] ∩ kernel(hB)[1] | ||
k = 2*size(map(domain(hA), gens(ans[1])), 1) | ||
return k | ||
end | ||
|
||
@testset "Verify number of logical qubits `k` from Table 3: bravyi2024high" begin | ||
# Refer to [bravyi2024high](@cite) for code constructions | ||
@test code_k(circulant_bivariate_bicycle(9 , 6 , [3 , 1 , 2] , [3 , 1 , 2])) == 8 == _formula_k(circulant_bivariate_bicycle(9 , 6 , [3 , 1 , 2] , [3 , 1 , 2])) | ||
@test code_k(circulant_bivariate_bicycle(15, 3 , [9 , 1 , 2] , [0 , 2 , 7])) == 8 == _formula_k(circulant_bivariate_bicycle(15, 3 , [9 , 1 , 2] , [0 , 2 , 7])) | ||
@test code_k(circulant_bivariate_bicycle(12, 12, [3 , 2 , 7] , [3 , 1 , 2])) == 12 == _formula_k(circulant_bivariate_bicycle(12, 12, [3 , 2 , 7] , [3 , 1 , 2])) | ||
@test code_k(circulant_bivariate_bicycle(12, 6 , [3 , 1 , 2] , [3 , 1 , 2])) == 12 == _formula_k(circulant_bivariate_bicycle(12, 6 , [3 , 1 , 2] , [3 , 1 , 2])) | ||
@test code_k(circulant_bivariate_bicycle(6 , 6 , [3 , 1 , 2] , [3 , 1 , 2])) == 12 == _formula_k(circulant_bivariate_bicycle(6 , 6 , [3 , 1 , 2] , [3 , 1 , 2])) | ||
@test code_k(circulant_bivariate_bicycle(30, 6 , [9 , 1 , 2] , [3 , 25, 26])) == 12 == _formula_k(circulant_bivariate_bicycle(30, 6 , [9 , 1 , 2] , [3 , 25, 26])) | ||
@test code_k(circulant_bivariate_bicycle(21, 18, [3 , 10, 17], [5 , 3 , 19])) == 16 == _formula_k(circulant_bivariate_bicycle(21, 18, [3 , 10, 17], [5 , 3 , 19])) | ||
@test code_k(circulant_bivariate_bicycle(28, 14, [26, 6 , 8] , [7 , 9 , 20])) == 24 == _formula_k(circulant_bivariate_bicycle(28, 14, [26, 6 , 8] , [7 , 9 , 20])) | ||
end | ||
|
||
@testset "Verify number of logical qubits `k` from Table 1: berthusen2024toward" begin | ||
# Refer to [berthusen2024toward](@cite) for code constructions | ||
@test code_k(circulant_bivariate_bicycle(12, 3 , [9 , 1 , 2] , [0 , 1 , 11])) == 8 == _formula_k(circulant_bivariate_bicycle(12, 3 , [9 , 1 , 2] , [0 , 1 ,11])) | ||
@test code_k(circulant_bivariate_bicycle(9 , 5 , [8 , 4 , 1] , [5 , 8 , 7])) == 8 == _formula_k(circulant_bivariate_bicycle(9 , 5 , [8 , 4 , 1], [5 , 8 , 7])) | ||
@test code_k(circulant_bivariate_bicycle(12, 5 , [10, 4 , 1] , [0 , 1 , 2])) == 8 == _formula_k(circulant_bivariate_bicycle(12, 5 , [10, 4 , 1] , [0 , 1 , 2])) | ||
@test code_k(circulant_bivariate_bicycle(15, 5 , [5 , 2 , 3] , [2 , 7 , 6])) == 8 == _formula_k(circulant_bivariate_bicycle(15, 5 , [5 , 2 , 3] , [2 , 7 , 6])) | ||
@test code_k(circulant_bivariate_bicycle(14, 7 , [6 , 5 , 6] , [0 , 4, 13])) == 12 == _formula_k(circulant_bivariate_bicycle(14, 7 , [6 , 5 , 6] , [0 , 4, 13])) | ||
end | ||
|
||
@testset "Verify number of logical qubits `k` from Table 1: wang2024coprime" begin | ||
# # Refer to [wang2024coprime](@cite) for code constructions | ||
@test code_k(circulant_bivariate_bicycle(3, 9 , [0 , 2 , 4] , [3 , 1 , 2])) == 8 == _formula_k(circulant_bivariate_bicycle(3, 9 , [0 , 2 , 4] , [3 , 1 , 2])) | ||
@test code_k(circulant_bivariate_bicycle(7, 7 , [3 , 5 , 6] , [2 , 3 , 5])) == 6 == _formula_k(circulant_bivariate_bicycle(7, 7 , [3 , 5 , 6] , [2 , 3 , 5])) | ||
@test code_k(circulant_bivariate_bicycle(3, 21 , [0 , 2 ,10] , [3 , 1 , 2])) == 8 == _formula_k(circulant_bivariate_bicycle(3, 21 , [0 , 2 ,10] , [3 , 1 , 2])) | ||
@test code_k(circulant_bivariate_bicycle(5, 15 , [0 , 6 , 8] , [5 , 1 , 4])) == 16 == _formula_k(circulant_bivariate_bicycle(5, 15 , [0 , 6 , 8] , [5 , 1 , 4])) | ||
@test code_k(circulant_bivariate_bicycle(3, 27 , [0 , 10,14] , [12, 1 , 2])) == 8 == _formula_k(circulant_bivariate_bicycle(3, 27 , [0 , 10,14] , [12, 1 , 2])) | ||
@test code_k(circulant_bivariate_bicycle(6, 15 , [3 , 1 , 2] , [6 , 4 , 5])) == 8 == _formula_k(circulant_bivariate_bicycle(6, 15 , [3 , 1 , 2] , [6 , 4 , 5])) | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not needed now thanks to Tommy CI Oscar Injection!
This PR was done earlier, why I was trying to add Oscar to test runner, so that's why the weird additions