Skip to content

Commit

Permalink
Adding classical Bose–Chaudhuri–Hocquenghem code to ECC module
Browse files Browse the repository at this point in the history
  • Loading branch information
Fe-r-oz committed Apr 19, 2024
1 parent 3cdf46b commit dcee70f
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

## v0.9.4 - dev

- Added the classical Bose–Chaudhuri–Hocquenghem (BCH) code to the ECC module
- Gate errors are now conveniently supported by the various ECC benchmark setups in the `ECC` module.
- Remove printing of spurious debug info from the PyBP decoder.

Expand Down
32 changes: 32 additions & 0 deletions docs/src/references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -341,3 +341,35 @@ @book{djordjevic2021quantum
year={2021},
publisher={Academic Press}
}


@article{hocquenghem1959codes,
title={Codes correcteurs d'erreurs},
author={Hocquenghem, Alexis},
journal={Chiffers},
volume={2},
pages={147--156},
year={1959}
}

@article{bose1960class,
title={On a class of error correcting binary group codes},
author={Bose, Raj Chandra and Ray-Chaudhuri, Dwijendra K},
journal={Information and control},
volume={3},
number={1},
pages={68--79},
year={1960},
publisher={Elsevier}
}

@article{bose1960further,
title={Further results on error correcting binary group codes},
author={Bose, Raj Chandra and Ray-Chaudhuri, Dwijendra K},
journal={Information and Control},
volume={3},
number={3},
pages={279--290},
year={1960},
publisher={Elsevier}
}
3 changes: 3 additions & 0 deletions docs/src/references.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ For classical code construction routines:
- [raaphorst2003reed](@cite)
- [abbe2020reed](@cite)
- [djordjevic2021quantum](@cite)
- [hocquenghem1959codes](@cite)
- [bose1960class](@cite)
- [bose1960further](@cite)

# References

Expand Down
15 changes: 15 additions & 0 deletions src/ecc/ECC.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,20 @@ function iscss(c::AbstractECC)
return iscss(typeof(c))
end

"""
Generator Polynomial
In a polynomial code, the generator polynomial `g(x)` is a polynomial of the minimal degree over a finite field F. The set of valid codewords in the code consists of all polynomials that are divisible by `g(x)` without remainder.
Description
- Defines the valid codewords in a polynomial code.
- Has minimal degree among polynomials with this property.
- Coefficients belong to a finite field (e.g., GF(2) for binary codes).
"""
function generator_polynomial end

parity_checks(s::Stabilizer) = s
Stabilizer(c::AbstractECC) = parity_checks(c)
MixedDestabilizer(c::AbstractECC; kwarg...) = MixedDestabilizer(Stabilizer(c); kwarg...)
Expand Down Expand Up @@ -347,4 +361,5 @@ include("codes/toric.jl")
include("codes/gottesman.jl")
include("codes/surface.jl")
include("codes/classical/reedmuller.jl")
include("codes/classical/bch.jl")
end #module
93 changes: 93 additions & 0 deletions src/ecc/codes/classical/bch.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
"""The family of Bose–Chaudhuri–Hocquenghem (BCH) codes, as discovered in 1959 by Alexis Hocquenghem [hocquenghem1959codes](@cite), and independently in 1960 by Raj Chandra Bose and D.K. Ray-Chaudhuri [bose1960class](@cite).
The binary parity check matrix can be obtained from the following matrix over field elements, after each field element is expressed as a binary column vector over GF(2).
1 a^1 a^2 a^3 ... a^(n - 1)
1 (a^3)^1 (a^3)^2 (a^3)^3 ... (a^3)^(n - 1)
1 (a^5)^1 (a^5)^2 (a^5)^3 ... (a^5)^(n - 1)
. . . . .
. . . . .
. . . . .
1 a^(2*t - 1) a^(2*t - 1)^2 a^(2*t - 1)^3 ... a^(2*t - 1)^(n -1)
Note: The entries of matrix over field elements are in GF(2^m). Each element in GF(2^m) can be represented by a m-tuple/binary column of length m over GF(2). If each entry of H is replaced by its corresponding m-tuple/binary column of length m over GF(2) arranged in column form, we obtain a binary parity check matrix for the code.
You might be interested in consulting [bose1960further](@cite) as well.
The ECC Zoo has an [entry for this family](https://errorcorrectionzoo.org/c/q-ary_bch)
"""
struct BCH <: ClassicalCode
n::Int
t::Int #Error correction capability; t bits can be corrected

function BCH(n, t)
if n < 6 || n > 500 || t < 0 || t > 2^(ceil(Int, log2(n + 1)) - 1)
throw(ArgumentError("Invalid parameters: 'n' and 't' must be positive, and 'r' must be >= to 3. Additionally, 'n' is >= to 7 since n = 2ͬ - 1 and 't' < 2^(r - 1), to obtain a valid code and to tractable."))
end
new(n, t)
end
end

"""
Generator Polynomial of BCH Codes
This function calculates the generator polynomial `g(x)` of a t-bit error-correcting BCH code of length `2^m - 1` over the finite Galois field GF(2).
Input Arguments:
- `m` (Integer): The positive integer defining the code length (`2^m - 1`).
- `t` (Integer): The positive integer specifying the number of correctable errors (`t`).
Description:
The generator polynomial `g(x)` is the fundamental polynomial used for encoding and decoding BCH codes. It has the following properties:
1. Roots: It has `α`, `α^2`, `α^3`, ..., `α^(2^t)` as its roots, where `α` is a primitive element of the Galois Field GF(2^m).
2. Error Correction: A BCH code with generator polynomial `g(x)` can correct up to `t` errors in a codeword of length `2^m - 1`.
3. Minimal Polynomials: `g(x)` is the least common multiple (LCM) of the minimal polynomials `φ_i(x)` of `α^i` for `i = 1` to `2^t`.
Minimal Polynomial:
- The minimal polynomial of a field element `α` in GF(2^m) is the polynomial of the lowest degree over GF(2) that has `α` as a root. It represents the simplest polynomial relationship between `α` and the elements of GF(2).
Least Common Multiple (LCM):
- The LCM of two or more polynomials `f_i(x)` is the polynomial with the lowest degree that is a multiple of all `f_i(x)`. It ensures that `g(x)` has all the roots of `φ_i(x)` for `i = 1` to `2^t`.
"""
function generator_polynomial(rs::BCH)
r = ceil(Int, log2(rs.n + 1))
GF2ͬ, a = finite_field(2, r, "a")
GF2x, x = GF(2)["x"]
minimal_poly = FqPolyRingElem[]
for i in 1:(2*rs.t - 1)
if i % 2 != 0
minimal_poly = [minimal_poly; minpoly(GF2x, a^i)]
end
end
gx = lcm(minimal_poly)
return gx
end

function parity_checks(rs::BCH)
r = ceil(Int, log2(rs.n + 1))
GF2ͬ, a = finite_field(2, r, "a")
HField = Matrix{FqFieldElem}(undef, rs.t, rs.n)
for i in 1:rs.t
for j in 1:rs.n
base = 2*i - 1
HField[i, j] = (a^base)^(j - 1)
end
end
H = Matrix{Bool}(undef, r*rs.t, rs.n)
for i in 1:rs.t
row_start = (i - 1) * r + 1
row_end = row_start + r - 1
for j in 1:rs.n
t_tuple = Bool[]
for k in 0:r - 1
t_tuple = [t_tuple; !is_zero(coeff(HField[i, j], k))]
end
H[row_start:row_end, j] .= vec(t_tuple')
end
end
return H
end
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ end
@doset "ecc_encoding"
@doset "ecc_gottesman"
@doset "ecc_reedmuller"
@doset "ecc_bch"
@doset "ecc_syndromes"
@doset "ecc_throws"
@doset "precompile"
Expand Down
25 changes: 25 additions & 0 deletions test/test_ecc_bch.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Test
using Nemo
using QuantumClifford
using QuantumClifford.ECC
using QuantumClifford.ECC: AbstractECC

@testset "Test BCH(n, t) generator polynomial g(x) universal property: mod(x^n - 1, g(x)) == 0" begin
n_cases = [7, 15, 31, 63, 127, 255]
for n in n_cases
#Testing all 1 Bit, 2 Bit, 3 Bit and 4 Bit BCH codes for n_cases
for t in 1:4
r = ceil(Int, log2(n + 1))
GF2ͬ, a = finite_field(2, r, "a")
GF2x, x = GF(2)["x"]
mx = FqPolyRingElem[]
for i in 1:(2*t - 1)
if i % 2 != 0
mx = [mx; minpoly(GF2x, a^i)]
end
end
gx = lcm(mx)
@test mod(x^n - 1, gx) == 0
end
end
end

0 comments on commit dcee70f

Please sign in to comment.