Skip to content

Commit 8ea87a5

Browse files
authored
πŸ‘¨β€πŸ’» general and cyclic Q(G₁×Gβ‚‚) quantum Tanner graph product codes (#482)
1 parent 49f6019 commit 8ea87a5

File tree

13 files changed

+392
-10
lines changed

13 files changed

+392
-10
lines changed

β€Ž.typos.tomlβ€Ž

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
ket = "ket"
33
anc = "anc"
44
ba = "ba"
5+
mor = "mor"
56

67
[type.ipynb]
78
# It detects false possitives in the base64 encoded images inside notebooks

β€ŽCHANGELOG.mdβ€Ž

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
## v0.10.1-dev
99

1010
- The lifted product code constructor `LPCode` now supports non-commutative group algebras by appropriate switching left/right representations β€” particularly useful now that there is also an `Oscar` extension, which provides many non-abelian group constructors.
11-
- introduce `metacheck_matrix_x`, `metacheck_matrix_z`, and `metacheck_matrix` for CSS codes built using chain complexes and homology.
11+
- Introduce `metacheck_matrix_x`, `metacheck_matrix_z`, and `metacheck_matrix` for CSS codes built using chain complexes and homology.
1212
- `ReedMuller`, `RecursiveReedMuller`, and `QuantumReedMuller` are moved to `QECCore` from `QuantumClifford.ECC`.
1313
- The phase storage type can now be parameterized, instead of hardcoded to UInt8.
1414
- Drop support for Julia 1.9.
@@ -17,6 +17,7 @@
1717
- Add `Delfosse-Reichardt` codes from classical self-orthogonal `Reed-Muller` seed codes to `QECCore`.
1818
- Add `[[4p, 2(p βˆ’ 2), 4]]` Delfosse-Reichardt repetition `DelfosseReichardtRepCode` code to `QECCore`.
1919
- Add `[[8p, 4p βˆ’ 2, 3]]` Delfosse-Reichardt Generalized `[[8,2,3]]` `DelfosseReichardt823` code to `QECCore`.
20+
- Add Quantum Tanner graph product codes: general and cyclic `Q(G₁×Gβ‚‚)` codes (Tanner graphs `G₁`, `Gβ‚‚`) to `QECCore`.
2021

2122
### Private API
2223

β€Ždocs/src/references.bibβ€Ž

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,3 +754,23 @@ @article{delfosse2020short
754754
journal={arXiv preprint arXiv:2008.05051},
755755
year={2020}
756756
}
757+
758+
@article{tillich2013quantum,
759+
title={Quantum LDPC codes with positive rate and minimum distance proportional to the square root of the blocklength},
760+
author={Tillich, Jean-Pierre and Z{\'e}mor, Gilles},
761+
journal={IEEE Transactions on Information Theory},
762+
volume={60},
763+
number={2},
764+
pages={1193--1202},
765+
year={2013},
766+
publisher={IEEE}
767+
}
768+
769+
@inproceedings{leverrier2015quantum,
770+
title={Quantum expander codes},
771+
author={Leverrier, Anthony and Tillich, Jean-Pierre and Z{\'e}mor, Gilles},
772+
booktitle={2015 IEEE 56th Annual Symposium on Foundations of Computer Science},
773+
pages={810--824},
774+
year={2015},
775+
organization={IEEE}
776+
}

β€Žlib/QECCore/CHANGELOG.mdβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## v0.1.2 - dev
44

5-
- introduce `metacheck_matrix_x`, `metacheck_matrix_z`, and `metacheck_matrix` for CSS codes built using chain complexes and homology.
5+
- Introduce `metacheck_matrix_x`, `metacheck_matrix_z`, and `metacheck_matrix` for CSS codes built using chain complexes and homology.
66
- Move the following codes from `QuantumClifford.ECC` to `QECCore`: `ReedMuller`, `RecursiveReedMuller`, `QuantumReedMuller`, `Hamming`, `Golay`, `Triangular488 `, `Triangular666 `, `Gottesman`.
77
- Add `Delfosse-Reichardt` codes from classical self-orthogonal `Reed-Muller` seed codes to `QECCore`.
88
- Add `[[4p, 2(p βˆ’ 2), 4]]` Delfosse-Reichardt repetition `DelfosseReichardtRepCode` code to `QECCore`.

β€Žlib/QECCore/Project.tomlβ€Ž

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@ version = "0.1.1"
66
[deps]
77
Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"
88
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
9+
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
910
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
1011
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
1112

1213
[compat]
1314
Combinatorics = "1.0"
1415
DocStringExtensions = "0.9"
16+
Graphs = "1.9"
1517
LinearAlgebra = "1.9"
1618
SparseArrays = "1.9"
1719
julia = "1.9"

β€Žlib/QECCore/src/QECCore.jlβ€Ž

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module QECCore
33
using SparseArrays
44
using LinearAlgebra
55
using Combinatorics
6+
using Graphs
67

78
using DocStringExtensions
89

@@ -15,7 +16,7 @@ export Perfect5, Cleve8, Gottesman
1516

1617
# CSS Codes
1718
export Toric, Bitflip3, Phaseflip3, Shor9, Steane7, Surface, CSS, QuantumReedMuller, Triangular488, Triangular666,
18-
DelfosseReichardt, DelfosseReichardtRepCode, DelfosseReichardt823
19+
DelfosseReichardt, DelfosseReichardtRepCode, DelfosseReichardt823, QuantumTannerGraphProduct, CyclicQuantumTannerGraphProduct
1920

2021
# Classical Codes
2122
export RepCode, ReedMuller, RecursiveReedMuller, Golay, Hamming
@@ -42,6 +43,7 @@ include("codes/quantum/surface.jl")
4243
include("codes/quantum/bitflipcode.jl")
4344
include("codes/quantum/gottesman.jl")
4445
include("codes/quantum/color_codes.jl")
46+
include("codes/quantum/quantumtannergraphproduct.jl")
4547

4648
# Reed-Muller Codes
4749
include("codes/classical/reedmuller.jl")
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
"""
2+
Represents a *bipartite* Tanner graph used in classical coding theory. It connects *variable
3+
nodes* (codeword bits or qubits) to *check nodes* (parity constraints) and serves as the
4+
foundation for constructing Tanner graphs in quantum CSS codes.
5+
"""
6+
struct BipartiteGraph
7+
"""The underlying undirected graph (from `Graphs.jl`)."""
8+
g::Graph
9+
"""Indices of variable nodes."""
10+
var_nodes::Vector{Int}
11+
"""Indices of check nodes."""
12+
check_nodes::Vector{Int}
13+
end
14+
15+
"""
16+
Constructs a *Tanner graph* from a given parity-check matrix `H`, where rows correspond to *check nodes*
17+
and columns to *variable nodes*. The resulting *bipartite* graph indexes variable nodes as `1:n` and check
18+
nodes as `n+1:n+m` for an `m Γ— n` matrix `H`."""
19+
function tanner_graph_from_parity_matrix(H::AbstractMatrix)
20+
m, n = size(H)
21+
g = SimpleGraph(n + m)
22+
var_nodes = collect(1:n)
23+
check_nodes = collect(n+1:n+m)
24+
for row in 1:m, col in 1:n
25+
H[row, col] && add_edge!(g, col, n + row)
26+
end
27+
return BipartiteGraph(g, var_nodes, check_nodes)
28+
end
29+
30+
"""Reconstructs the parity-check matrix from a Tanner graph `g`.
31+
32+
!!! note
33+
The first block of vertices corresponds to variable nodes and the remaining to check nodes. It
34+
returns a parity check matrix `H` of size `(number of check nodes) Γ— (number of variable nodes).`
35+
"""
36+
function parity_matrix_from_tanner_graph(bg::BipartiteGraph)
37+
n_vars = length(bg.var_nodes)
38+
n_checks = length(bg.check_nodes)
39+
H = spzeros(Bool, n_checks, n_vars)
40+
for (check_idx, check_node) in enumerate(bg.check_nodes)
41+
for neighbor in neighbors(bg.g, check_node)
42+
neighbor in bg.var_nodes && (H[check_idx, neighbor] = true)
43+
end
44+
end
45+
return H
46+
end
47+
48+
"""
49+
Constructs a bipartite Tanner graph representing the cycle code of length `n`. The graph
50+
consists of `n` variable nodes and `n` check nodes, totaling `2n` nodes. Each check node `i`
51+
(for `i` in `1...n`) connects to variable nodes `i` and (``i+1 \\mod n``). This results in a
52+
parity-check matrix `H`, where each row contains exactly two `1`s, encoding the edges of a
53+
length-`n` cycle.
54+
"""
55+
function cycle_tanner_graph(n::Int)
56+
g = SimpleGraph(2n)
57+
var_nodes = collect(1:n)
58+
check_nodes = collect(n+1:2n)
59+
for i in 1:n
60+
check_node = n + i
61+
add_edge!(g, i, check_node)
62+
add_edge!(g, mod1(i+1, n), check_node)
63+
end
64+
return BipartiteGraph(g, var_nodes, check_nodes)
65+
end
66+
67+
"""
68+
$TYPEDEF
69+
70+
Represents the CSS quantum code `Q(G₁ Γ— Gβ‚‚)` constructed from two binary codes with
71+
parity-check matrices `H₁` and `Hβ‚‚`, using the hypergraph product formulation introduced
72+
by [tillich2013quantum](@cite).
73+
74+
This construction corresponds to a specific product of Tanner graphs:
75+
- Let `G₁ = T(V₁, C₁, E₁)` and `Gβ‚‚ = T(Vβ‚‚, Cβ‚‚, Eβ‚‚)` be the Tanner graphs of `H₁` and `Hβ‚‚`.
76+
- The product graph `G₁ Γ— Gβ‚‚` has vertex set `(V₁ Γ— Vβ‚‚) βˆͺ (C₁ Γ— Cβ‚‚)` and check set `(C₁ Γ— Vβ‚‚) βˆͺ (V₁ Γ— Cβ‚‚)`.
77+
- The Tanner subgraphs `G₁ Γ—β‚“ Gβ‚‚` and `G₁ ×𝓏 Gβ‚‚` define classical codes `Cβ‚“` and `C𝓏` used in the CSS construction.
78+
79+
The `hgp(H₁, Hβ‚‚)` function algebraically realizes this graph-theoretic product using Kronecker operations,
80+
yielding the `X`- and `Z`-type parity-check matrices:
81+
82+
- `H_X = [H₁ βŠ— I | I βŠ— Hβ‚‚α΅—]` corresponds to `G₁ Γ—β‚“ Gβ‚‚`
83+
- `H_Z = [I βŠ— Hβ‚‚ | H₁ᡗ βŠ— I]` corresponds to `G₁ ×𝓏 Gβ‚‚`
84+
85+
These matrices ensure `H_X * H_Zα΅— = 0`, satisfying the CSS condition.
86+
87+
See: [tillich2013quantum](@cite), Section 4.3 β€” β€œThe hypergraph connection, product codes”
88+
89+
# 𝑄(𝐺₁ Γ— 𝐺₂)
90+
91+
The `𝑄(𝐺₁ Γ— 𝐺₂)` quantum LDPC codes represent a broader generalization of **quantum expander codes**
92+
which are derived from the Leverrier-Tillich-ZΓ©mor construction [tillich2013quantum](@cite).
93+
94+
```jldoctest examples
95+
julia> using QuantumClifford; using QuantumClifford.ECC; using QECCore
96+
97+
julia> H1 = [1 0 1 0; 0 1 0 1; 1 1 0 0];
98+
99+
julia> H2 = [1 1 0; 0 1 1];
100+
101+
julia> c = parity_checks(QuantumTannerGraphProduct(H1, H2))
102+
+ X_____X_____X_____
103+
+ _X_____X____XX____
104+
+ __X_____X____X____
105+
+ ___X_____X____X___
106+
+ ____X_____X___XX__
107+
+ _____X_____X___X__
108+
+ X__X____________X_
109+
+ _X__X___________XX
110+
+ __X__X___________X
111+
+ ZZ__________Z___Z_
112+
+ _ZZ__________Z___Z
113+
+ ___ZZ_________Z_Z_
114+
+ ____ZZ_________Z_Z
115+
+ ______ZZ____Z_____
116+
+ _______ZZ____Z____
117+
+ _________ZZ___Z___
118+
+ __________ZZ___Z__
119+
120+
julia> code_n(c), code_k(c)
121+
(18, 1)
122+
```
123+
124+
# Quantum Expander code
125+
126+
The `𝑄(𝐺₁ Γ— 𝐺₂)` code is more general than the **standard quantum expander code**
127+
[leverrier2015quantum](@cite) construction. The quantum expander code construction
128+
corresponds to the specific case where `G = G1 = G2`​.
129+
130+
```jldoctest examples
131+
julia> H = parity_matrix(RepCode(3));
132+
133+
julia> c = parity_checks(QuantumTannerGraphProduct(H, H))
134+
+ X__X_____X_X______
135+
+ _X__X____XX_______
136+
+ __X__X____XX______
137+
+ ___X__X_____X_X___
138+
+ ____X__X____XX____
139+
+ _____X__X____XX___
140+
+ X_____X________X_X
141+
+ _X_____X_______XX_
142+
+ __X_____X_______XX
143+
+ ZZ_______Z_____Z__
144+
+ _ZZ_______Z_____Z_
145+
+ Z_Z________Z_____Z
146+
+ ___ZZ____Z__Z_____
147+
+ ____ZZ____Z__Z____
148+
+ ___Z_Z_____Z__Z___
149+
+ ______ZZ____Z__Z__
150+
+ _______ZZ____Z__Z_
151+
+ ______Z_Z_____Z__Z
152+
153+
julia> code_n(c), code_k(c)
154+
(18, 2)
155+
```
156+
157+
### Fields
158+
$TYPEDFIELDS
159+
"""
160+
struct QuantumTannerGraphProduct <: AbstractCSSCode
161+
"""The first classical seed code for the the quantum tanner graph code."""
162+
H1::AbstractMatrix
163+
"""The second classical seed code for the the quantum tanner graph code."""
164+
H2::AbstractMatrix
165+
end
166+
167+
parity_matrix_xz(c::QuantumTannerGraphProduct) = hgp(c.H1, c.H2)
168+
169+
"""
170+
$TYPEDEF
171+
172+
Constructs a `𝑄(𝐺₁ Γ— 𝐺₂)` quantum Tanner graph product code using cyclic Tanner graphs of length `2m`.
173+
174+
```jldoctest
175+
julia> using QuantumClifford; using QuantumClifford.ECC;
176+
177+
julia> m = 1;
178+
179+
julia> c = parity_checks(CyclicQuantumTannerGraphProduct(m))
180+
+ X_X_XX__
181+
+ _X_XXX__
182+
+ X_X___XX
183+
+ _X_X__XX
184+
+ ZZ__Z_Z_
185+
+ ZZ___Z_Z
186+
+ __ZZZ_Z_
187+
+ __ZZ_Z_Z
188+
189+
julia> code_n(c), code_k(c)
190+
(8, 2)
191+
192+
julia> m = 10;
193+
194+
julia> c = parity_checks(CyclicQuantumTannerGraphProduct(m));
195+
196+
julia> code_n(c), code_k(c)
197+
(800, 2)
198+
```
199+
200+
### Fields
201+
$TYPEDFIELDS
202+
"""
203+
struct CyclicQuantumTannerGraphProduct <: AbstractCSSCode
204+
m::Int
205+
function CyclicQuantumTannerGraphProduct(m::Int)
206+
m > 0 || throw(ArgumentError("m must be positive."))
207+
new(m)
208+
end
209+
end
210+
211+
function parity_matrix_xz(Q::CyclicQuantumTannerGraphProduct)
212+
n = 2*Q.m
213+
G1 = cycle_tanner_graph(n)
214+
G2 = cycle_tanner_graph(n)
215+
H1 = parity_matrix_from_tanner_graph(G1)
216+
H2 = parity_matrix_from_tanner_graph(G2)
217+
return hgp(H1, H2)
218+
end
219+
220+
parity_matrix_x(c::Union{QuantumTannerGraphProduct,CyclicQuantumTannerGraphProduct}) = parity_matrix_xz(c)[1]
221+
222+
parity_matrix_z(c::Union{QuantumTannerGraphProduct,CyclicQuantumTannerGraphProduct}) = parity_matrix_xz(c)[2]

β€Žlib/QECCore/test/Project.tomlβ€Ž

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
[deps]
2+
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
3+
HiGHS = "87dc4568-4c63-4d18-b0c0-bb2238e4078b"
4+
Hecke = "3e1990a7-5d81-5526-99ce-9ba3ff248f21"
5+
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
6+
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
27
Nemo = "2edaba10-b0f1-5616-af89-8c11ac63239a"
8+
QuantumClifford = "0525e862-1e90-11e9-3e4d-1b39d7109de1"
9+
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
10+
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
311
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
412
TestItemRunner = "f8b46487-2199-4994-9208-9a1283c18c0a"
5-
QuantumClifford = "0525e862-1e90-11e9-3e4d-1b39d7109de1"
6-
Hecke = "3e1990a7-5d81-5526-99ce-9ba3ff248f21"
7-
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
8-
HiGHS = "87dc4568-4c63-4d18-b0c0-bb2238e4078b"

0 commit comments

Comments
Β (0)