Skip to content
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
4 changes: 2 additions & 2 deletions src/QuantumExpanders.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ using QuantumClifford: Stabilizer, comm
using QuantumClifford.ECC: DistanceMIPAlgorithm
using LinearAlgebra
using Random
using Random: AbstractRNG, GLOBAL_RNG
using Random: AbstractRNG, GLOBAL_RNG, shuffle
using Graphs
using Graphs: add_edge!, nv, ne, neighbors, Graphs, edges, Edge, src, dst, degree, adjacency_matrix, add_vertex!, has_edge,
vertices, induced_subgraph, AbstractGraph, is_bipartite, bipartite_map, has_edge
Expand Down Expand Up @@ -51,6 +51,6 @@ export
parity_matrix, parity_matrix_x, parity_matrix_z, parity_matrix_xz, code_n, code_k,
# tensor codes
uniformly_random_code_checkmatrix, dual_code, good_css,
normal_cayley_subset, GeneralizedQuantumTannerCode
normal_cayley_subset, GeneralizedQuantumTannerCode, find_random_generating_sets

end #module
171 changes: 171 additions & 0 deletions src/quantum_tanner_codes.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,174 @@
"""
Generate a pair of symmetric generating sets for group G of sizes δ_A and δ_B.

Returns a pair of symmetric generating sets (A, B) that generate G and satisfy the non-conjugacy condition.

Both A and B are symmetric (closed under inversion), the union A ∪ B generates G, A and B are disjoint,
and the pair (A, B) satisfies the total non-conjugacy condition: for all a ∈ A, b ∈ B, g ∈ G, a ≠ gbg⁻¹.

```jldoctest examples
julia> using QuantumExpanders; using Oscar; using Random;

julia> G = symmetric_group(4);

julia> rng = MersenneTwister(68);

julia> A, B = find_random_generating_sets(G, 3, 2; rng=deepcopy(rng))
2-element Vector{Vector{PermGroupElem}}:
[(1,3)(2,4), (1,2,4,3), (1,3,4,2)]
[(2,4), (2,3)]

julia> A, B = find_random_generating_sets(G, 3; rng=deepcopy(rng))
2-element Vector{Vector{PermGroupElem}}:
[(1,2,4,3), (1,3,4,2), (1,4)(2,3)]
[(1,4,3), (1,3,4), (1,2)]
```

Here is a new `[[108, 11, 6]]` quantum Tanner code generated using these symmetric generating sets, A and B, as follows:

```jldoctest examples
julia> H_A = [1 0 1; 1 1 0];

julia> G_A = [1 1 1];

julia> H_B = [1 1 1; 1 1 0];

julia> G_B = [1 1 0];

julia> classical_code_pair = ((H_A, G_A), (H_B, G_B));

julia> c = QuantumTannerCode(G, A, B, classical_code_pair);

julia> code_n(c), code_k(c)
[ Info: Left-right Cayley complex Γ(G,A,B) square enumeration complete
[ Info: Group order |G| = 24, |A| = 3, |B| = 3
[ Info: Physical qubits: 108
[ Info: Left-right Cayley complex Γ(G,A,B): enumerated 108 faces placed on 4-cycles {gᵢ, (a·g)ⱼ, (g·b)ⱼ, (a·g·b)ᵢ} where i,j ∈ {0,1}, i≠j [radebold2025explicit](@cite)
[ Info: Squares incident to vertices: 216 at V₀ vertices (Z-type stabilizers) [radebold2025explicit](@cite)
[ Info: Squares incident to vertices: 216 at V₁ vertices (X-type stabilizers) [radebold2025explicit](@cite)
[ Info: Left-right Cayley complex Γ(G,A,B) square enumeration complete
[ Info: Group order |G| = 24, |A| = 3, |B| = 3
[ Info: Physical qubits: 108
[ Info: Left-right Cayley complex Γ(G,A,B): enumerated 108 faces placed on 4-cycles {gᵢ, (a·g)ⱼ, (g·b)ⱼ, (a·g·b)ᵢ} where i,j ∈ {0,1}, i≠j [radebold2025explicit](@cite)
[ Info: Squares incident to vertices: 216 at V₀ vertices (Z-type stabilizers) [radebold2025explicit](@cite)
[ Info: Squares incident to vertices: 216 at V₁ vertices (X-type stabilizers) [radebold2025explicit](@cite)
(108, 11)

julia> import JuMP; import HiGHS;

julia> distance(c, DistanceMIPAlgorithm(solver=HiGHS))
[ Info: Left-right Cayley complex Γ(G,A,B) square enumeration complete
[ Info: Group order |G| = 24, |A| = 3, |B| = 3
[ Info: Physical qubits: 108
[ Info: Left-right Cayley complex Γ(G,A,B): enumerated 108 faces placed on 4-cycles {gᵢ, (a·g)ⱼ, (g·b)ⱼ, (a·g·b)ᵢ} where i,j ∈ {0,1}, i≠j [radebold2025explicit](@cite)
[ Info: Squares incident to vertices: 216 at V₀ vertices (Z-type stabilizers) [radebold2025explicit](@cite)
[ Info: Squares incident to vertices: 216 at V₁ vertices (X-type stabilizers) [radebold2025explicit](@cite)
[ Info: Left-right Cayley complex Γ(G,A,B) square enumeration complete
[ Info: Group order |G| = 24, |A| = 3, |B| = 3
[ Info: Physical qubits: 108
[ Info: Left-right Cayley complex Γ(G,A,B): enumerated 108 faces placed on 4-cycles {gᵢ, (a·g)ⱼ, (g·b)ⱼ, (a·g·b)ᵢ} where i,j ∈ {0,1}, i≠j [radebold2025explicit](@cite)
[ Info: Squares incident to vertices: 216 at V₀ vertices (Z-type stabilizers) [radebold2025explicit](@cite)
[ Info: Squares incident to vertices: 216 at V₁ vertices (X-type stabilizers) [radebold2025explicit](@cite)
[ Info: Left-right Cayley complex Γ(G,A,B) square enumeration complete
[ Info: Group order |G| = 24, |A| = 3, |B| = 3
[ Info: Physical qubits: 108
[ Info: Left-right Cayley complex Γ(G,A,B): enumerated 108 faces placed on 4-cycles {gᵢ, (a·g)ⱼ, (g·b)ⱼ, (a·g·b)ᵢ} where i,j ∈ {0,1}, i≠j [radebold2025explicit](@cite)
[ Info: Squares incident to vertices: 216 at V₀ vertices (Z-type stabilizers) [radebold2025explicit](@cite)
[ Info: Squares incident to vertices: 216 at V₁ vertices (X-type stabilizers) [radebold2025explicit](@cite)
[ Info: Left-right Cayley complex Γ(G,A,B) square enumeration complete
[ Info: Group order |G| = 24, |A| = 3, |B| = 3
[ Info: Physical qubits: 108
[ Info: Left-right Cayley complex Γ(G,A,B): enumerated 108 faces placed on 4-cycles {gᵢ, (a·g)ⱼ, (g·b)ⱼ, (a·g·b)ᵢ} where i,j ∈ {0,1}, i≠j [radebold2025explicit](@cite)
[ Info: Squares incident to vertices: 216 at V₀ vertices (Z-type stabilizers) [radebold2025explicit](@cite)
[ Info: Squares incident to vertices: 216 at V₁ vertices (X-type stabilizers) [radebold2025explicit](@cite)
[ Info: Left-right Cayley complex Γ(G,A,B) square enumeration complete
[ Info: Group order |G| = 24, |A| = 3, |B| = 3
[ Info: Physical qubits: 108
[ Info: Left-right Cayley complex Γ(G,A,B): enumerated 108 faces placed on 4-cycles {gᵢ, (a·g)ⱼ, (g·b)ⱼ, (a·g·b)ᵢ} where i,j ∈ {0,1}, i≠j [radebold2025explicit](@cite)
[ Info: Squares incident to vertices: 216 at V₀ vertices (Z-type stabilizers) [radebold2025explicit](@cite)
[ Info: Squares incident to vertices: 216 at V₁ vertices (X-type stabilizers) [radebold2025explicit](@cite)
[ Info: Left-right Cayley complex Γ(G,A,B) square enumeration complete
[ Info: Group order |G| = 24, |A| = 3, |B| = 3
[ Info: Physical qubits: 108
[ Info: Left-right Cayley complex Γ(G,A,B): enumerated 108 faces placed on 4-cycles {gᵢ, (a·g)ⱼ, (g·b)ⱼ, (a·g·b)ᵢ} where i,j ∈ {0,1}, i≠j [radebold2025explicit](@cite)
[ Info: Squares incident to vertices: 216 at V₀ vertices (Z-type stabilizers) [radebold2025explicit](@cite)
[ Info: Squares incident to vertices: 216 at V₁ vertices (X-type stabilizers) [radebold2025explicit](@cite)
[ Info: Left-right Cayley complex Γ(G,A,B) square enumeration complete
[ Info: Group order |G| = 24, |A| = 3, |B| = 3
[ Info: Physical qubits: 108
[ Info: Left-right Cayley complex Γ(G,A,B): enumerated 108 faces placed on 4-cycles {gᵢ, (a·g)ⱼ, (g·b)ⱼ, (a·g·b)ᵢ} where i,j ∈ {0,1}, i≠j [radebold2025explicit](@cite)
[ Info: Squares incident to vertices: 216 at V₀ vertices (Z-type stabilizers) [radebold2025explicit](@cite)
[ Info: Squares incident to vertices: 216 at V₁ vertices (X-type stabilizers) [radebold2025explicit](@cite)
6
```

### Arguments
- `G`: A finite group
- `δ_A`: The size of the first symmetric generating set
- `δ_B`: The size of the second symmetric generating set (defaults to δ_A)
"""
function find_random_generating_sets(G::Group, δ_A::Int, δ_B::Int=δ_A; rng::AbstractRNG=GLOBAL_RNG)
elems = collect(G)
non_identity = [g for g in elems if g != one(G)]
ord2 = [g for g in non_identity if order(g) == 2]
pairs = []
used = Set{elem_type(G)}()
for g in non_identity
if order(g) > 2 && !(g in used)
inv_g = inv(g)
if g != inv_g
push!(pairs, (g, inv_g))
push!(used, g, inv_g)
end
end
end
total_symmetric_elements = length(ord2)+2*length(pairs)
if δ_A+δ_B > total_symmetric_elements
@info "Requested δ_A=$δ_A and δ_B=$δ_B require $((δ_A + δ_B)) symmetric elements, but only $total_symmetric_elements available"
return false
end
for attempt in 1:10000
A = elem_type(G)[]
B = elem_type(G)[]
shuffled = shuffle(rng, elems)
for elem in shuffled
elem == one(G) && continue
if order(elem) == 2
if !(elem in A) && !(elem in B) && length(A) < δ_A
push!(A, elem)
elseif !(elem in A) && !(elem in B) && length(B) < δ_B
push!(B, elem)
end
else
inv_elem = inv(elem)
if elem != inv_elem
if !(elem in A) && !(elem in B) && !(inv_elem in A) && !(inv_elem in B) &&
length(A) < δ_A-1
push!(A, elem, inv_elem)
elseif !(elem in A) && !(elem in B) && !(inv_elem in A) && !(inv_elem in B) &&
length(B) < δ_B-1
push!(B, elem, inv_elem)
end
end
end
if length(A) == δ_A && length(B) == δ_B
break
end
end
if length(A) == δ_A && length(B) == δ_B
if is_symmetric_gen(A) &&
is_symmetric_gen(B) && isempty(intersect(Set(A), Set(B))) && is_nonconjugate(G, A, B)
all_gens = vcat(A, B)
H, emb = sub(G, all_gens)
if order(H) == order(G)
return [A, B]
end
end
end
end
return false
end

"""
Generate a pair of random classical codes (C_A, C_B) for quantum Tanner code construction [radebold2025explicit](@cite)

Expand Down
17 changes: 17 additions & 0 deletions test/test_quantum_tanner_codes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -697,4 +697,21 @@
@test code_k(c) == 96
@test distance(c, DistanceMIPAlgorithm(solver=HiGHS, time_limit=120)) == 5
end

@testset "Random Symmetric Generating Tests" begin
for seed in 1:50
for o in 4:5
G = symmetric_group(o)
rng = MersenneTwister(seed)
A, B = find_random_generating_sets(G, 3; rng=deepcopy(rng))
H_A = [1 0 1; 1 1 0]
G_A = [1 1 1]
H_B = [1 1 1; 1 1 0]
G_B = [1 1 0]
classical_code_pair = ((H_A, G_A), (H_B, G_B))
c = QuantumTannerCode(G, A, B, classical_code_pair)
@test stab_looks_good(parity_checks(c), remove_redundant_rows=true)
end
end
end
end
Loading