Skip to content

Commit

Permalink
enhancements
Browse files Browse the repository at this point in the history
  • Loading branch information
Fe-r-oz committed Dec 5, 2024
1 parent 5fcf353 commit 8ee6d98
Show file tree
Hide file tree
Showing 13 changed files with 435 additions and 4 deletions.
3 changes: 3 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
Hecke = "3e1990a7-5d81-5526-99ce-9ba3ff248f21"
LDPCDecoders = "3c486d74-64b9-4c60-8b1a-13a564e77efb"
Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a"
Oscar = "f1435218-dba5-11e9-1e4d-f1a5fab5fc13"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
PyQDecoders = "17f5de1a-9b79-4409-a58d-4d45812840f7"
Quantikz = "b0d11df0-eea3-4d79-b4a5-421488cbf74b"
Expand All @@ -37,6 +38,7 @@ QuantumCliffordGPUExt = "CUDA"
QuantumCliffordHeckeExt = "Hecke"
QuantumCliffordLDPCDecodersExt = "LDPCDecoders"
QuantumCliffordMakieExt = "Makie"
QuantumCliffordOscarExt = ["Hecke", "Oscar"]
QuantumCliffordPlotsExt = "Plots"
QuantumCliffordPyQDecodersExt = "PyQDecoders"
QuantumCliffordQOpticsExt = "QuantumOpticsBase"
Expand All @@ -57,6 +59,7 @@ LinearAlgebra = "1.9"
MacroTools = "0.5.9"
Makie = "0.20, 0.21"
Nemo = "0.42.1, 0.43, 0.44, 0.45, 0.46, 0.47"
Oscar = "1.1.1"
Plots = "1.38.0"
PrecompileTools = "1.2"
PyQDecoders = "0.2.1"
Expand Down
7 changes: 6 additions & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ import Hecke

const QuantumCliffordHeckeExt = Base.get_extension(QuantumClifford, :QuantumCliffordHeckeExt)

ENV["OSCAR_PRINT_BANNER"] = "false"
import Oscar

const QuantumCliffordOscarExt = Base.get_extension(QuantumClifford, :QuantumCliffordOscarExt)

#DocMeta.setdocmeta!(QuantumClifford, :DocTestSetup, :(using QuantumClifford); recursive=true)

ENV["LINES"] = 80 # for forcing `displaysize(io)` to be big enough
Expand All @@ -25,7 +30,7 @@ doctest = false,
clean = true,
sitename = "QuantumClifford.jl",
format = Documenter.HTML(size_threshold_ignore = ["API.md"]),
modules = [QuantumClifford, QuantumClifford.Experimental.NoisyCircuits, QuantumClifford.ECC, QuantumInterface, QuantumCliffordHeckeExt],
modules = [QuantumClifford, QuantumClifford.Experimental.NoisyCircuits, QuantumClifford.ECC, QuantumInterface, QuantumCliffordHeckeExt, QuantumCliffordOscarExt],
warnonly = [:missing_docs],
linkcheck = true,
authors = "Stefan Krastanov",
Expand Down
7 changes: 7 additions & 0 deletions docs/src/ECC_API.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,11 @@ Private = false
```@autodocs
Modules = [QuantumCliffordHeckeExt]
Private = true
```

## Implemented in an extension requiring `Oscar.jl`

```@autodocs
Modules = [QuantumCliffordOscarExt]
Private = true
```
20 changes: 20 additions & 0 deletions docs/src/references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -561,3 +561,23 @@ @article{haah2011local
pages={042330},
year={2011},
}

@inproceedings{wang2023abelian,
title={Abelian and non-Abelian quantum two-block codes},
author={Wang, Renyu and Lin, Hsiang-Ku and Pryadko, Leonid P},
booktitle={2023 12th International Symposium on Topics in Coding (ISTC)},
pages={1--5},
year={2023},
organization={IEEE}
}

@article{naghipour2015quantum,
title={Quantum stabilizer codes from Abelian and non-Abelian groups association schemes},
author={Naghipour, Avaz and Jafarizadeh, Mohammad Ali and Shahmorad, Sedaghat},
journal={International Journal of Quantum Information},
volume={13},
number={03},
pages={1550021},
year={2015},
publisher={World Scientific}
}
2 changes: 2 additions & 0 deletions docs/src/references.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ For quantum code construction routines:
- [lin2024quantum](@cite)
- [bravyi2024high](@cite)
- [haah2011local](@cite)
- [wang2023abelian](@cite)
- [naghipour2015quantum](@cite)

For classical code construction routines:
- [muller1954application](@cite)
Expand Down
19 changes: 19 additions & 0 deletions ext/QuantumCliffordOscarExt/QuantumCliffordOscarExt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module QuantumCliffordOscarExt

using DocStringExtensions

import Nemo
import Nemo: FqFieldElem
import Hecke: group_algebra, GF, abelian_group, gens, quo, one, GroupAlgebra,
GroupAlgebraElem, direct_product, sub
import Oscar
import Oscar: free_group, small_group_identification, describe, order, FPGroupElem, FPGroup,
BasicGAPGroupElem, DirectProductGroup, cyclic_group

import QuantumClifford.ECC: two_block_group_algebra_codes

include("types.jl")
include("direct_product.jl")
include("group_presentation.jl")

end # module
110 changes: 110 additions & 0 deletions ext/QuantumCliffordOscarExt/direct_product.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
"""
# Direct Product of Groups
The direct product of groups is instrumental in constructing group algebra of two-block
group algebra code. Lin and Pryadko illustrate this method in Appendix C, Table 2 of
[lin2024quantum](@cite), where they utilize the direct product of two cyclic groups,
expressed as `C₂ₘ = Cₘ × C₂`, with an order of `2m`.
`Hecke.jl` contains only abelian groups and a list of all finite groups of order up to 100.
`Oscar.jl` brings in comprehensive functionality for computational group theory, including
support for **arbitrary finitely presented groups** (groups of the form `⟨X | S⟩`. `Oscar.jl`
supports the **direct product** operation between two or more arbitrary **general** groups,
including non-abelian groups such as `alternating_group`, `dihedral_group`, `symmetric_group`,
and even arbitrary finitely presented groups (e.g., `free_group`). This capability is not
available in `Hecke.jl`. The 2BGA codes discovered in [lin2024quantum](@cite) rely on direct
products of two or more *general* groups, which necessitate the use of `Oscar.direct_product`.
The schematic below illustrates the limitations of `Hecke.direct_product` compared to
`Oscar.direct_product`:
```@raw html
<div class="mermaid">
graph TB
root[Direct Product of Groups]
root --> A[Hecke.direct_product]
root --> B[Oscar.direct_product]
%% Hecke Branch
A --> A1[Supports mostly abelian groups and list of finite groups]
A1--> A2[abelian_group symmetric_group small_group]
A2 --> A3[C × C, C × S]
%% Oscar Branch
B --> B1[Supports finite general groups, including non-abelian groups]
B1--> B2[alternating_group <br> dihedral_group <br> free_group <br> cyclic_group <br> permutation_group <br> quaternion_group <br> symmetric_group <br> abelian_group<br> small_group]
B2--> B3[A × C, A × D <br> D × C, D × D <br> F × F, F × A, F × D <br> F × S, F × C <br> C × C, C × S]
</div>
```
# Example
The [[56, 28, 2]] abelian 2BGA code from Appendix C, Table II in [lin2024quantum](@cite)
can be constructed using the direct product of two cyclic groups. Specifically, the group
`C₂₈` of order `l = 28` can be represented as `C₁₄ × C₂`, where the first group has order
`m = 14` and the second group has order `n = 2`.
```jldoctest directprod
julia> import Oscar: cyclic_group, small_group_identification, describe, order; # hide
julia> import Hecke: gens, quo, group_algebra, GF, one, direct_product, sub; # hide
julia> m = 14; n = 2;
julia> C₁₄ = cyclic_group(m);
julia> C₂ = cyclic_group(n);
julia> G = direct_product(C₁₄, C₂);
julia> GA = group_algebra(GF(2), G);
julia> x, s = gens(GA)[1], gens(GA)[3];
julia> a = [one(GA), x^7];
julia> b = [one(GA), x^7, s, x^8, s * x^7, x];
julia> c = twobga_from_direct_product(a, b, GA);
julia> order(G)
28
julia> code_n(c), code_k(c)
(56, 28)
julia> describe(G), small_group_identification(G)
("C14 x C2", (28, 4))
```
!!! note When using the direct product of two cyclic groups, it is essential to verify
the group presentation `Cₘ = ⟨x, s | xᵐ = s² = xsx⁻¹s⁻¹ = 1⟩` is satisfied, where the
order is `2m`. Ensure that the selected generators have the correct orders of `m = 14`
and `n = 2`, respectively. If the group presentation is not satisfied, the resulting
group algebra over `GF(2)` will not represent the intended group, `C₂₈ = C₁₄ × C₂`. In
addition, `Oscar.sub` can be used to determine if `H` is a subgroup of `G` and to
confirm that both `C₁₄` and `C₂` are subgroups of `C₂₈`.
```jldoctest directprod
julia> order(gens(G)[1])
14
julia> order(gens(G)[3])
2
julia> x^14 == s^2 == x * s * x^-1 * s^-1
true
julia> H, _ = sub(G, [gens(G)[1], gens(G)[3]]);
julia> H == G
true
```
"""
function twobga_from_direct_product(a_elts::VectorDirectProductGroupElem, b_elts::VectorDirectProductGroupElem, F2G::DirectProductGroupAlgebra)
a = sum(F2G(x) for x in a_elts)
b = sum(F2G(x) for x in b_elts)
c = two_block_group_algebra_codes(a,b)
return c
end
151 changes: 151 additions & 0 deletions ext/QuantumCliffordOscarExt/group_presentation.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
"""
# Specific Group Presentations
For quantum error-correcting codes like the two-block group algebra (2BGA) code, designing specific
group presentations for both abelian and non-abelian groups is crucial. These presentations are essential
for constructing the group algebra of the 2BGA code for a given finite general group, `G`.
Lin and Pryadko, in their seminal paper titled "Quantum Two-Block Group Algebra Codes" [lin2024quantum](@cite),
employ specific presentations that necessitate the use of `Oscar.free_group`. The diagram below distinguishes
between small groups (`Hecke/Oscar.small_group`) and finitely presented groups (`Oscar.free_group`) by highlighting
the existence of extra relations in their presentations.
```@raw html
<div class="mermaid">
graph TD
A[Group Presentation ⟨S ∣ R⟩] --> B{Are there <br> extra relations?}
B -- No --> C[Small groups <br> Hecke/Oscar.small_group]
C --> D[Independent generators]
C --> E["Example: <br> ⟨r, s ∣ s⁴, r⁹⟩"]
B -- Yes --> F[Finitely presented groups <br> Oscar.free_group]
F --> G[Defined by interactions]
F --> H["Example: <br> ⟨r, s ∣ s⁴, r⁹, s⁻¹rsr⟩"]
</div>
```
# Example
The [[96, 12, 10]] 2BGA code from Table I in [lin2024quantum](@cite) has the group presentation
`⟨r, s | s⁶ = r⁸ = r⁻¹srs = 1⟩` and a group structure of `C₂ × (C₃ ⋉ C₈)`.
```jldoctest finitegrp
julia> import Oscar: free_group, small_group_identification, describe, order; # hide
julia> import Hecke: gens, quo, group_algebra, GF, one; # hide
julia> F = free_group(["r", "s"]);
julia> r, s = gens(F); # generators
julia> G, = quo(F, [s^6, r^8, r^(-1) * s * r * s]); # relations
julia> GA = group_algebra(GF(2), G);
julia> r, s = gens(G);
julia> a = [one(G), r, s^3 * r^2, s^2 * r^3];
julia> b = [one(G), r, s^4 * r^6, s^5 * r^3];
julia> c = twobga_from_fp_group(a, b, GA);
julia> order(G)
48
julia> code_n(c), code_k(c)
(96, 12)
julia> describe(G), small_group_identification(G)
("C2 x (C3 : C8)", (48, 9))
```
# Cyclic Groups
Cyclic groups with specific group presentations, given by `Cₘ = ⟨x, s | xᵐ = s² = xsx⁻¹s⁻¹ = 1⟩`,
where the order is `2m`, are supported.
To construct the group algebra for a cyclic group, specify the group presentation `⟨S | R⟩`, using
its generators `S` and defining relations `R`.
# Example
The [[56, 28, 2]] abelian 2BGA code from Appendix C, Table II in [lin2024quantum](@cite) is constructed using
the cyclic group `C₂₈ = C₁₄ × C₂`.
```jldoctest finitegrp
julia> m = 14;
julia> F = free_group(["x", "s"]);
julia> x, s = gens(F); # generators
julia> G, = quo(F, [x^m, s^2, x * s * x^-1 * s^-1]); # relations
julia> GA = group_algebra(GF(2), G);
julia> x, s = gens(G);
julia> a = [one(G), x^7];
julia> b = [one(G), x^7, s, x^8, s * x^7, x];
julia> c = twobga_from_fp_group(a, b, GA);
julia> order(G)
28
julia> code_n(c), code_k(c)
(56, 28)
julia> describe(G), small_group_identification(G)
("C14 x C2", (28, 4))
```
# Dihedral Groups
Dihedral groups with specific group presentations, given by `Dₘ = ⟨r, s | rᵐ = s² = (rs)² = 1⟩`,
where the order is `2m`, are supported.
To construct the group algebra for a dihedral group, specify the group presentation `⟨S | R⟩`
using its generators `S` and defining relations `R`.
# Example
The [[24, 8, 3]] 2BGA code from Appendix C, Table III in [lin2024quantum](@cite) is constructed
using the dihedral group `D₆ = C₆ ⋉ C₂`.
```jldoctest finitegrp
julia> m = 6;
julia> F = free_group(["r", "s"]);
julia> r, s = gens(F); # generators
julia> G, = quo(F, [r^m, s^2, (r*s)^2]); # relations
julia> GA = group_algebra(GF(2), G);
julia> r, s = gens(G);
julia> a = [one(G), r^4];
julia> b = [one(G), s*r^4, r^3, r^4, s*r^2, r];
julia> c = twobga_from_fp_group(a, b, GA);
julia> order(G)
12
julia> code_n(c), code_k(c)
(24, 8)
julia> describe(G), small_group_identification(G)
("D12", (12, 4))
```
"""
function twobga_from_fp_group(a_elts::VectorFPGroupElem, b_elts::VectorFPGroupElem, F2G::FqFieldFPGroupAlgebra)
a = sum(F2G(x) for x in a_elts)
b = sum(F2G(x) for x in b_elts)
c = two_block_group_algebra_codes(a,b)
return c
end
7 changes: 7 additions & 0 deletions ext/QuantumCliffordOscarExt/types.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const VectorFPGroupElem = Vector{FPGroupElem}

const VectorDirectProductGroupElem = Vector{GroupAlgebraElem{FqFieldElem, GroupAlgebra{FqFieldElem, DirectProductGroup, BasicGAPGroupElem{DirectProductGroup}}}}

const FqFieldFPGroupAlgebra = GroupAlgebra{FqFieldElem, FPGroup, FPGroupElem}

const DirectProductGroupAlgebra = GroupAlgebra{FqFieldElem, DirectProductGroup, BasicGAPGroupElem{DirectProductGroup}}
Loading

0 comments on commit 8ee6d98

Please sign in to comment.