Skip to content

Commit

Permalink
2D implementation of Bivariate Bicycle codes: Toric Layouts
Browse files Browse the repository at this point in the history
  • Loading branch information
Fe-r-oz committed Oct 10, 2024
1 parent 2b8e81f commit 481f9b8
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 2 deletions.
6 changes: 4 additions & 2 deletions src/ecc/ECC.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ using QuantumClifford: AbstractOperation, AbstractStabilizer, Stabilizer
import QuantumClifford: Stabilizer, MixedDestabilizer, nqubits
using DocStringExtensions
using Combinatorics: combinations
using SparseArrays: sparse
using SparseArrays: SparseMatrixCSC, sparse, spzeros
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

Expand All @@ -27,7 +27,8 @@ export parity_checks, parity_checks_x, parity_checks_z, iscss,
CommutationCheckECCSetup, NaiveSyndromeECCSetup, ShorSyndromeECCSetup,
TableDecoder,
BeliefPropDecoder, BitFlipDecoder,
PyBeliefPropDecoder, PyBeliefPropOSDecoder, PyMatchingDecoder
PyBeliefPropDecoder, PyBeliefPropOSDecoder, PyMatchingDecoder,
bivariate_toric_layout

"""Parity check tableau of a code.
Expand Down Expand Up @@ -361,6 +362,7 @@ end

include("circuits.jl")
include("decoder_pipeline.jl")
include("bivariate_toric_layout.jl")

include("codes/util.jl")

Expand Down
87 changes: 87 additions & 0 deletions src/ecc/bivariate_toric_layout.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using LinearAlgebra
using SparseArrays: SparseMatrixCSC, sparse, spzeros

function cyclic_shift_matrix(l::Int)
arr = spzeros(Int, l, l)
for i in 1:l
arr[i, mod(i,l)+1] = 1
end
return arr
end

pow²(mat::SparseMatrixCSC{Int, Int},exp::Int) = (mat^exp).%2

function order(mat::SparseMatrixCSC{Int}, m::Int, ell::Int)
n = size(mat, 1)
I = sparse(LinearAlgebra.I(n))
p = mat
for i in 1:(m * ell)
if p == I
return i
end
p *= mat
end
return -1
end

function _toric_layout₁(As::Vector{SparseMatrixCSC{Int64, Int64}}, Bs::Vector{SparseMatrixCSC{Int64, Int64}}, m::Int, ell::Int)
A_ord = [order(AA, m, ell) for AA in As]
B_ord = [order(BB, m, ell) for BB in Bs]
valid_orders = []
for (i, Ao) in enumerate(A_ord)
for (j, Bo) in enumerate(B_ord)
if Ao * Bo == m * ell
push!(valid_orders, (Ao, Bo, i, j))
end
end
end
return valid_orders
end

function _toric_layout₂(As::Vector{SparseMatrixCSC{Int64, Int64}}, Bs::Vector{SparseMatrixCSC{Int64, Int64}}, m::Int, ell::Int, codes::NTuple{4,Int64})
em, e_ell, A_idx, B_idx = codes
(A_idx < 1 || A_idx > length(As)) && throw(DimensionMismatch("Invalid index A_idx: $A_idx"))
(B_idx < 1 || B_idx > length(Bs)) && throw(DimensionMismatch("Invalid index B_idx: $B_idx"))
visited = Set{Int}()
ver = sparse(As[A_idx])
hor = sparse(Bs[B_idx])
zero = zeros(Int, m * ell)
zero[1] = 1
for i in 0:(em - 1)
tmp = (ver^i) * zero
for j in 0:(e_ell - 1)
if j == 0
visited = union(visited, Set(findall(tmp .> 0)))
else
visited = union(visited, Set(findall(hor^j * tmp .> 0)))
end
end
end
return length(visited) == ell * m
end

function bivariate_toric_layout(code::Vector{Int})
ell = code[1]
m = code[2]
x = kron(cyclic_shift_matrix(ell), LinearAlgebra.I(m))
y = kron(LinearAlgebra.I(ell), cyclic_shift_matrix(m))
A₁ = pow²(x, code[3])
A₂ = pow²(y, code[4])
A₃ = pow²(y, code[5])
A = (A₁+A₂+A₃).%2
B₁ = pow²(y, code[6])
B₂ = pow²(x, code[7])
B₃ = pow²(x, code[8])
B = (B₁+B₂+B₃).%2
As = [A₁*A₂', A₂'*A₁, A₂*A₃', A₃'*A₂, A₁*A₃', A₃'*A₁]
Bs = [B₁*B₂', B₂'*B₁, B₂*B₃', B₃'*B₂, B₁*B₃', B₃'*B₁]
selected_codes = []
valid_codes = _toric_layout₁(As, Bs, m, ell)
for valid_code in valid_codes
if _toric_layout₂(As, Bs, m, ell, valid_code)
push!(selected_codes, valid_code)
end
end
orig_layout = [(params[1], params[2], params[3]-1, params[4]-1) for params in selected_codes]
return orig_layout
end
20 changes: 20 additions & 0 deletions test/test_ecc_bivariate_toric_layout.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@testitem "ECC Bivaraite Toric Layout" begin
using QuantumClifford.ECC
using QuantumClifford.ECC: AbstractECC, bivariate_toric_layout

codes = [[6 ,6 ,3,1 ,2 ,3,1 ,2 ],
[15,3 ,9,1 ,2 ,0,2 ,7 ],
[6 ,9 ,3,1 ,2 ,3,1 ,2 ],
[12,6 ,3,1 ,2 ,3,1 ,2 ],
[12,12,3,2 ,7 ,3,1 ,2 ],
[30,6 ,9,1 ,2 ,3,25,26],
[21,18,3,10,17,5,3 ,19]]
# cross checks taken from https://arxiv.org/pdf/2404.17676.
@test bivariate_toric_layout(codes[1]) == [(6, 6, 0, 2), (6, 6, 0, 3), (6, 6, 0, 4), (6, 6, 0, 5), (6, 6, 1, 2), (6, 6, 1, 3), (6, 6, 1, 4), (6, 6, 1, 5), (6, 6, 2, 0), (6, 6, 2, 1), (6, 6, 2, 2), (6, 6, 2, 3), (6, 6, 3, 0), (6, 6, 3, 1), (6, 6, 3, 2), (6, 6, 3, 3), (6, 6, 4, 0), (6, 6, 4, 1), (6, 6, 4, 4), (6, 6, 4, 5), (6, 6, 5, 0), (6, 6, 5, 1), (6, 6, 5, 4), (6, 6, 5, 5)]
@test bivariate_toric_layout(codes[2]) == [(15, 3, 0, 2), (15, 3, 0, 3), (15, 3, 1, 2), (15, 3, 1, 3), (3, 15, 2, 0), (3, 15, 2, 1), (3, 15, 2, 4), (3, 15, 2, 5), (3, 15, 3, 0), (3, 15, 3, 1), (3, 15, 3, 4), (3, 15, 3, 5), (15, 3, 4, 2), (15, 3, 4, 3), (15, 3, 5, 2), (15, 3, 5, 3)]
@test bivariate_toric_layout(codes[3]) == [(18, 3, 0, 4), (18, 3, 0, 5), (18, 3, 1, 4), (18, 3, 1, 5), (9, 6, 2, 0), (9, 6, 2, 1), (9, 6, 2, 2), (9, 6, 2, 3), (9, 6, 3, 0), (9, 6, 3, 1), (9, 6, 3, 2), (9, 6, 3, 3), (18, 3, 4, 4), (18, 3, 4, 5), (18, 3, 5, 4), (18, 3, 5, 5)]
@test bivariate_toric_layout(codes[4]) == [(12, 6, 0, 4), (12, 6, 0, 5), (12, 6, 1, 4), (12, 6, 1, 5), (6, 12, 2, 0), (6, 12, 2, 1), (6, 12, 2, 2), (6, 12, 2, 3), (6, 12, 3, 0), (6, 12, 3, 1), (6, 12, 3, 2), (6, 12, 3, 3), (12, 6, 4, 4), (12, 6, 4, 5), (12, 6, 5, 4), (12, 6, 5, 5)]
@test bivariate_toric_layout(codes[5]) == [(12, 12, 0, 0), (12, 12, 0, 1), (12, 12, 0, 4), (12, 12, 0, 5), (12, 12, 1, 0), (12, 12, 1, 1), (12, 12, 1, 4), (12, 12, 1, 5), (12, 12, 2, 0), (12, 12, 2, 1), (12, 12, 2, 2), (12, 12, 2, 3), (12, 12, 3, 0), (12, 12, 3, 1), (12, 12, 3, 2), (12, 12, 3, 3), (12, 12, 4, 2), (12, 12, 4, 3), (12, 12, 4, 4), (12, 12, 4, 5), (12, 12, 5, 2), (12, 12, 5, 3), (12, 12, 5, 4), (12, 12, 5, 5)]
@test bivariate_toric_layout(codes[6]) == [(6, 30, 2, 2), (6, 30, 2, 3), (6, 30, 3, 2), (6, 30, 3, 3), (30, 6, 4, 0), (30, 6, 4, 1), (30, 6, 5, 0), (30, 6, 5, 1)]
@test bivariate_toric_layout(codes[7]) == [(18, 21, 2, 2), (18, 21, 2, 3), (18, 21, 3, 2), (18, 21, 3, 3)]
end

0 comments on commit 481f9b8

Please sign in to comment.