Skip to content

Commit a1572bf

Browse files
authored
Merge pull request #24 from esabo/fix/hyperbicycle
fixed hyperbicycle constructors, added tests
2 parents b46d3f5 + ecb8580 commit a1572bf

File tree

2 files changed

+73
-57
lines changed

2 files changed

+73
-57
lines changed

src/Quantum/product_codes.jl

Lines changed: 31 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -162,38 +162,20 @@ function HyperBicycleCodeCSS(a::Vector{T}, b::Vector{T}, χ::Int; char_vec::Unio
162162
(k2, n2) == size(b[i]) || throw(ArgumentError("Second set of matrices must all have the same dimensions."))
163163
end
164164

165-
# Julia creates a new scope for every iteration of the for loop,
166-
# so the else doesn't work without declaring these variables outside here
167-
H1::T
168-
H2::T
169-
HT1::T
170-
HT2::T
165+
H1 = zero_matrix(F, c * k1, c * n1)
166+
H2 = zero_matrix(F, c * k2, c * n2)
167+
HT1 = zero_matrix(F, c * n1, c * k1)
168+
HT2 = zero_matrix(F, c * n2, c * k2)
169+
Ic = identity_matrix(F, c)
170+
= Ic[mod1.(1:χ:c * χ, c), :]
171171
for i in 1:c
172-
Sχi = zero_matrix(F, c, c)
173-
Ii = zero_matrix(F, c, c)
174-
for c1 in 1:c
175-
for r in 1:c
176-
if (c1 - r) % c == 1
177-
Ii[r, c1] = F(1)
178-
end
179-
if (c1 - r) % c == (r - 1) *- 1) % c
180-
Sχi[r, c1] = F(1)
181-
end
182-
end
183-
end
184-
Iχi = Sχi * Ii
185-
ITχi = transpose(Sχi) * transpose(Ii)
186-
if i == 1
187-
H1 = Iχi a[i]
188-
H2 = b[i] Iχi
189-
HT1 = ITχi transpose(a[i])
190-
HT2 = transpose(b[i]) ITχi
191-
else
192-
H1 += Iχi a[i]
193-
H2 += b[i] Iχi
194-
HT1 += ITχi transpose(a[i])
195-
HT2 += transpose(b[i]) ITχi
196-
end
172+
Ii = vcat(Ic[i:end, :], Ic[1:i - 1, :])
173+
Iχi =* Ii
174+
ITχi = transpose(Sχ) * transpose(Ii)
175+
H1 += Iχi a[i]
176+
H2 += b[i] Iχi
177+
HT1 += ITχi transpose(a[i])
178+
HT2 += transpose(b[i]) ITχi
197179
end
198180

199181
Ek1 = identity_matrix(F, k1)
@@ -204,22 +186,20 @@ function HyperBicycleCodeCSS(a::Vector{T}, b::Vector{T}, χ::Int; char_vec::Unio
204186
GX = hcat(Ek2 H1, H2 Ek1)
205187
GZ = hcat(HT2 En1, En2 HT1)
206188
return CSSCode(GX, GZ, char_vec = char_vec, logs_alg = logs_alg)
207-
# equations 41 and 42 of the paper give matrices from which the logicals may be chosen
208-
# not really worth it, just use standard technique from StabilizerCode.jl
209189
end
210190

211191
"""
212192
HyperBicycleCode(a::Vector{CTMatrixTypes}, b::Vector{CTMatrixTypes}, χ::Int; char_vec::Union{Vector{nmod}, Missing} = missing, logs_alg::Symbol = :stnd_frm)
213193
214-
Return the hyperbicycle CSS code of `a` and `b` given `χ`.
194+
Return the hyperbicycle non-CSS code of `a` and `b` given `χ`.
215195
216196
# Arguments
217197
- a: A vector of length `c` of binary matrices of the same dimensions.
218198
- b: A vector of length `c` of binary matrices of the same dimensions,
219199
potentially different from those of `a`.
220200
- χ: A strictly positive integer coprime with `c`.
221201
"""
222-
function HyperBicycleCode(a::Vector{T}, b::Vector{T}, χ::Int, char_vec::Union{Vector{nmod},
202+
function HyperBicycleCode(a::Vector{T}, b::Vector{T}, χ::Int; char_vec::Union{Vector{nmod},
223203
Missing} = missing, logs_alg::Symbol = :stnd_frm) where T <: CTMatrixTypes
224204

225205
logs_alg (:stnd_frm, :VS, :sys_eqs) || throw(ArgumentError("Unrecognized logicals algorithm"))
@@ -238,35 +218,29 @@ function HyperBicycleCode(a::Vector{T}, b::Vector{T}, χ::Int, char_vec::Union{V
238218
(k2, n2) == size(b[i]) || throw(ArgumentError("Second set of matrices must all have the same dimensions."))
239219
end
240220

221+
H1 = zero_matrix(F, c * k1, c * n1)
222+
H2 = zero_matrix(F, c * k2, c * n2)
223+
HT1 = zero_matrix(F, c * n1, c * k1)
224+
HT2 = zero_matrix(F, c * n2, c * k2)
225+
Ic = identity_matrix(F, c)
226+
= Ic[mod1.(1:χ:c * χ, c), :]
241227
for i in 1:c
242-
Sχi = zero_matrix(F, c, c)
243-
Ii = zero_matrix(F, c, c)
244-
for c1 in 1:c
245-
for r in 1:c
246-
if (c1 - r) % c == 1
247-
Ii[r, c1] = F(1)
248-
end
249-
if (c1 - r) % c == (r - 1) *- 1) % c
250-
Sχi[r, c1] = F(1)
251-
end
252-
end
253-
end
254-
Iχi = Sχi * Ii
255-
if i == 1
256-
H1 = Iχi a[i]
257-
H2 = b[i] Iχi
258-
else
259-
H1 += Iχi a[i]
260-
H2 += b[i] Iχi
261-
end
228+
Ii = vcat(Ic[i:end, :], Ic[1:i - 1, :])
229+
Iχi =* Ii
230+
ITχi = transpose(Sχ) * transpose(Ii)
231+
H1 += Iχi a[i]
232+
H2 += b[i] Iχi
233+
HT1 += ITχi transpose(a[i])
234+
HT2 += transpose(b[i]) ITχi
262235
end
263236

237+
(H1 == HT1 && H2 == HT2) || throw(ArgumentError("H_i must equal H̃_i for i = 1, 2."))
238+
264239
Ek1 = identity_matrix(F, k1)
265240
Ek2 = identity_matrix(F, k2)
241+
266242
stabs = hcat(Ek2 H1, H2 Ek1)
267243
return StabilizerCode(stabs, char_vec = char_vec, logs_alg = logs_alg)
268-
# equations 41 and 42 of the paper give matrices from which the logicals may be chosen
269-
# not really worth it, just use standard technique from StabilizerCode.jl
270244
end
271245

272246
"""

test/Quantum/product_codes_test.jl

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,48 @@
4747
@test LogicalTrait(typeof(Q)) == HasLogicals()
4848
@test GaugeTrait(typeof(Q)) == HasNoGauges()
4949

50+
# Quantum kronecker sum-product low-density parity-check codes with finite rate
51+
# Fig 2
52+
l = 21
53+
R = residue_ring(S, x^l - 1)
54+
h = R(1 + x + x^3)
55+
A = residue_polynomial_to_circulant_matrix(h)
56+
a1 = A[1:7, 1:7]
57+
a2 = A[1:7, 8:14]
58+
a3 = A[1:7, 15:21]
59+
χ = 1
60+
Q = HyperBicycleCodeCSS([a1, a2, a3], [a1, a2, a3], χ)
61+
@test length(Q) == 294
62+
@test CodingTheory.dimension(Q) == 18
63+
@test LogicalTrait(typeof(Q)) == HasLogicals()
64+
@test GaugeTrait(typeof(Q)) == HasNoGauges()
65+
66+
# Example 6
67+
l = 30
68+
R = residue_ring(S, x^l - 1)
69+
h = R(1 + x + x^3 + x^5)
70+
A = residue_polynomial_to_circulant_matrix(h)
71+
a1 = A[1:15, 1:15]
72+
a2 = A[1:15, 16:30]
73+
χ = 1
74+
Q = HyperBicycleCodeCSS([a1, a2], [a1, a2], χ)
75+
@test length(Q) == 900
76+
@test CodingTheory.dimension(Q) == 50
77+
@test LogicalTrait(typeof(Q)) == HasLogicals()
78+
@test GaugeTrait(typeof(Q)) == HasNoGauges()
79+
80+
# Example 13 (non-CSS example)
81+
l = 17
82+
R = residue_ring(S, x^l - 1)
83+
h = R(x^4 * (1 + x + x^3 + x^6 + x^8 + x^9))
84+
A = residue_polynomial_to_circulant_matrix(h)
85+
χ = 1
86+
Q = HyperBicycleCode([A], [A], χ)
87+
@test length(Q) == 289
88+
@test CodingTheory.dimension(Q) == 81
89+
@test LogicalTrait(typeof(Q)) == HasLogicals()
90+
@test GaugeTrait(typeof(Q)) == HasNoGauges()
91+
5092
# HGP codes are (l, q)-QLDPC code
5193
# l, q = columnrowweights(Sq2)
5294

0 commit comments

Comments
 (0)