Skip to content
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

bivariate bicycle quantum ldpc code #352

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions docs/src/references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -454,3 +454,21 @@
issn = {2521-327X},
doi = {10.22331/q-2022-07-20-767},
}

@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},

Check warning on line 471 in docs/src/references.bib

View workflow job for this annotation

GitHub Actions / Spell Check with Typos

"Childs" should be "Children".
journal={arXiv preprint arXiv:2404.17676},
year={2024}
}
1 change: 1 addition & 0 deletions docs/src/references.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ For quantum code construction routines:
- [kitaev2003fault](@cite)
- [fowler2012surface](@cite)
- [knill1996concatenated](@cite)
- [bravyi2024high](@cite)

For classical code construction routines:
- [muller1954application](@cite)
Expand Down
4 changes: 2 additions & 2 deletions src/ecc/ECC.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
using Combinatorics: combinations
using SparseArrays: sparse
using Statistics: std
using Nemo: ZZ, residue_ring, matrix, finite_field, GF, minpoly, coeff, lcm, FqPolyRingElem, FqFieldElem, is_zero, degree, defining_polynomial, is_irreducible, echelon_form
using Nemo: ZZ, residue_ring, matrix, finite_field, GF, minpoly, coeff, lcm, FqPolyRingElem, FqFieldElem, is_zero, degree, defining_polynomial, is_irreducible, echelon_form, nullspace, hom, free_module, kernel, domain, map, gens

Check warning on line 12 in src/ecc/ECC.jl

View workflow job for this annotation

GitHub Actions / Spell Check with Typos

"hom" should be "home".

abstract type AbstractECC end

Expand Down Expand Up @@ -376,13 +376,13 @@
include("codes/surface.jl")
include("codes/concat.jl")
include("codes/random_circuit.jl")

include("codes/classical/reedmuller.jl")
include("codes/classical/recursivereedmuller.jl")
include("codes/classical/bch.jl")

# qLDPC
include("codes/classical/lifted.jl")
include("codes/lifted_product.jl")
include("codes/bbqldpc.jl")

end #module
53 changes: 53 additions & 0 deletions src/ecc/codes/bbqldpc.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"""
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).
"""
struct BBQLDPC <: AbstractECC
l::Int
m::Int
A::Vector{Int}
B::Vector{Int}
function BBQLDPC(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")
new(l,m,A,B)
end
end

function iscss(::Type{BBQLDPC})
return true
end

function _AB(c::BBQLDPC)
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)
return A, B
end

function parity_checks(c::BBQLDPC)
A, B = _AB(c)
Hx = hcat(A,B)
Hz = hcat(B',A')
H = CSS(Hx,Hz)
Stabilizer(H)
end

code_n(c::BBQLDPC) = 2*c.l*c.m

code_k(c::BBQLDPC) = 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::BBQLDPC) = hcat(_AB(c)...)

parity_checks_z(c::BBQLDPC) = hcat(_AB(c)[2]', _AB(c)[1]')
41 changes: 41 additions & 0 deletions test/test_ecc_bbqldpc.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
@testitem "Bivariate bicycle (BB) quantum LDPC code" begin
using QuantumClifford: stab_to_gf2
using QuantumClifford.ECC
using Nemo: nullspace, GF, matrix, hom, free_module, kernel, domain, map, gens

Check warning on line 4 in test/test_ecc_bbqldpc.jl

View workflow job for this annotation

GitHub Actions / Spell Check with Typos

"hom" should be "home".
using QuantumClifford.ECC: AbstractECC, BBQLDPC, 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)

Check warning on line 14 in test/test_ecc_bbqldpc.jl

View workflow job for this annotation

GitHub Actions / Spell Check with Typos

"hom" should be "home".
hB = hom(free_module(k, size(B, 1)), free_module(k, size(B, 2)), B)

Check warning on line 15 in test/test_ecc_bbqldpc.jl

View workflow job for this annotation

GitHub Actions / Spell Check with Typos

"hom" should be "home".
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" begin
# Refer to [bravyi2024high](@cite) for code constructions
@test code_k(BBQLDPC(9 , 6 , [3 , 1 , 2] , [3 , 1 , 2])) == 8 == _formula_k(BBQLDPC(9 , 6 , [3 , 1 , 2] , [3 , 1 , 2]))
@test code_k(BBQLDPC(15, 3 , [9 , 1 , 2] , [0 , 2 , 7])) == 8 == _formula_k(BBQLDPC(15, 3 , [9 , 1 , 2] , [0 , 2 , 7]))
@test code_k(BBQLDPC(12, 12, [3 , 2 , 7] , [3 , 1 , 2])) == 12 == _formula_k(BBQLDPC(12, 12, [3 , 2 , 7] , [3 , 1 , 2]))
@test code_k(BBQLDPC(12, 6 , [3 , 1 , 2] , [3 , 1 , 2])) == 12 == _formula_k(BBQLDPC(12, 6 , [3 , 1 , 2] , [3 , 1 , 2]))
@test code_k(BBQLDPC(6 , 6 , [3 , 1 , 2] , [3 , 1 , 2])) == 12 == _formula_k(BBQLDPC(6 , 6 , [3 , 1 , 2] , [3 , 1 , 2]))
@test code_k(BBQLDPC(30, 6 , [9 , 1 , 2] , [3 , 25, 26])) == 12 == _formula_k(BBQLDPC(30, 6 , [9 , 1 , 2] , [3 , 25, 26]))
@test code_k(BBQLDPC(21, 18, [3 , 10, 17], [5 , 3 , 19])) == 16 == _formula_k(BBQLDPC(21, 18, [3 , 10, 17], [5 , 3 , 19]))
@test code_k(BBQLDPC(28, 14, [26, 6 , 8] , [7 , 9 , 20])) == 24 == _formula_k(BBQLDPC(28, 14, [26, 6 , 8] , [7 , 9 , 20]))
end

@testset "Verify number of logical qubits `k` from Table 1" begin
# Refer to [berthusen2024toward](cite for code constructions
@test code_k(BBQLDPC(12, 3 , [9 , 1 , 2] , [0 , 1 , 11])) == 8 == _formula_k(BBQLDPC(12, 3 , [9 , 1 , 2] , [0 , 1 , 11]))
@test code_k(BBQLDPC(9 , 5 , [8 , 4 , 1] , [5 , 8 , 7])) == 8 == _formula_k(BBQLDPC(9 , 5 , [8 , 4 , 1], [5 , 8 , 7]))
@test code_k(BBQLDPC(12, 5 , [10, 4 , 1] , [0 , 1 , 2])) == 8 == _formula_k(BBQLDPC(12, 5 , [10, 4 , 1] , [0 , 1 , 2]))
@test code_k(BBQLDPC(15, 5 , [5 , 2 , 3] , [2 , 7 , 6])) == 8 == _formula_k(BBQLDPC(15, 5 , [5 , 2 , 3] , [2 , 7 , 6]))
@test code_k(BBQLDPC(14, 7 , [6 , 5 , 6] , [0 , 4, 13])) == 12 == _formula_k(BBQLDPC(14, 7 , [6 , 5 , 6] , [0 , 4, 13]))
end
end
Loading