From 6d3e1c483dee6dcd34ab34ee696ed59156a46183 Mon Sep 17 00:00:00 2001 From: Fe-r-oz Date: Thu, 29 Aug 2024 06:04:49 +0500 Subject: [PATCH] quantum tensor product codes --- docs/src/references.bib | 27 ++++++++++++++++++++++++ docs/src/references.md | 3 +++ src/ecc/ECC.jl | 8 +++++-- src/ecc/codes/classical/bch.jl | 2 +- src/ecc/codes/classical/tensorproduct.jl | 20 ++++++++++++++++++ src/ecc/codes/classical_codes.jl | 2 +- src/ecc/codes/quantumtensorproduct.jl | 19 +++++++++++++++++ test/test_ecc_base.jl | 3 ++- test/test_ecc_bch.jl | 4 ++-- test/test_ecc_tensorproduct.jl | 10 +++++++++ test/test_ecc_throws.jl | 1 + 11 files changed, 92 insertions(+), 7 deletions(-) create mode 100644 src/ecc/codes/classical/tensorproduct.jl create mode 100644 src/ecc/codes/quantumtensorproduct.jl create mode 100644 test/test_ecc_tensorproduct.jl diff --git a/docs/src/references.bib b/docs/src/references.bib index 6a50a9194..69c66bb3b 100644 --- a/docs/src/references.bib +++ b/docs/src/references.bib @@ -402,3 +402,30 @@ @inproceedings{brown2013short pages = {346--350}, doi = {10.1109/ISIT.2013.6620245} } + +@article{wolf1965codes, + title={On codes derivable from the tensor product of check matrices}, + author={Wolf, Jack}, + journal={IEEE Transactions on Information Theory}, + volume={11}, + number={2}, + pages={281--284}, + year={1965}, + publisher={IEEE} +} + +@inproceedings{wolf2006introduction, + title={An introduction to tensor product codes and applications to digital storage systems}, + author={Wolf, Jack Keil}, + booktitle={2006 IEEE Information Theory Workshop-ITW'06 Chengdu}, + pages={6--10}, + year={2006}, + organization={IEEE} +} + +@article{fan2016quantum, + title={On quantum tensor product codes}, + author={Fan, Jihao and Li, Yonghui and Hsieh, Min-Hsiu and Chen, Hanwu}, + journal={arXiv preprint arXiv:1605.09598}, + year={2016} +} diff --git a/docs/src/references.md b/docs/src/references.md index b37e94d4e..49dead4f5 100644 --- a/docs/src/references.md +++ b/docs/src/references.md @@ -37,6 +37,7 @@ For quantum code construction routines: - [kitaev2003fault](@cite) - [fowler2012surface](@cite) - [knill1996concatenated](@cite) +- [fan2016quantum](@cite) For classical code construction routines: - [muller1954application](@cite) @@ -48,6 +49,8 @@ For classical code construction routines: - [bose1960class](@cite) - [bose1960further](@cite) - [error2024lin](@cite) +- [wolf1965codes](@cite) +- [wolf2006introduction](@cite) # References diff --git a/src/ecc/ECC.jl b/src/ecc/ECC.jl index ed50dba5b..285846276 100644 --- a/src/ecc/ECC.jl +++ b/src/ecc/ECC.jl @@ -8,7 +8,7 @@ using DocStringExtensions using Combinatorics: combinations using SparseArrays: sparse using Statistics: std -using Nemo: ZZ, residue_ring, matrix, finite_field, GF, minpoly, coeff, lcm, FqPolyRingElem, FqFieldElem, is_zero, degree, defining_polynomial, is_irreducible +using Nemo: ZZ, residue_ring, matrix, finite_field, GF, minpoly, coeff, lcm, FqPolyRingElem, FqFieldElem, is_zero, degree, defining_polynomial, is_irreducible, kronecker_product abstract type AbstractECC end @@ -16,11 +16,12 @@ export parity_checks, parity_checks_x, parity_checks_z, iscss, code_n, code_s, code_k, rate, distance, isdegenerate, faults_matrix, naive_syndrome_circuit, shor_syndrome_circuit, naive_encoding_circuit, - RepCode, + RepCode, BCH, TensorProduct, CSS, Shor9, Steane7, Cleve8, Perfect5, Bitflip3, Toric, Gottesman, Surface, Concat, CircuitCode, random_brickwork_circuit_code, random_all_to_all_circuit_code, + QuantumTensorProduct, evaluate_decoder, CommutationCheckECCSetup, NaiveSyndromeECCSetup, ShorSyndromeECCSetup, TableDecoder, @@ -360,7 +361,10 @@ include("codes/toric.jl") include("codes/gottesman.jl") include("codes/surface.jl") include("codes/concat.jl") +include("codes/quantumtensorproduct.jl") include("codes/random_circuit.jl") include("codes/classical/reedmuller.jl") include("codes/classical/bch.jl") +include("codes/classical/tensorproduct.jl") + end #module diff --git a/src/ecc/codes/classical/bch.jl b/src/ecc/codes/classical/bch.jl index 70580a909..d1ed925a7 100644 --- a/src/ecc/codes/classical/bch.jl +++ b/src/ecc/codes/classical/bch.jl @@ -32,7 +32,7 @@ struct BCH <: AbstractPolynomialCode m::Int t::Int function BCH(m, t) - if m < 3 || t < 0 || t >= 2 ^ (m - 1) + if m < 3 || t < 0 || (3 <= t <= 4 && t >= 2^(m - 1) - 1) || (t > 4 && t >= 2^(m - 1)) throw(ArgumentError("Invalid parameters: `m` and `t` must be positive. Additionally, ensure `m ≥ 3` and `t < 2ᵐ ⁻ ¹` to obtain a valid code.")) end new(m, t) diff --git a/src/ecc/codes/classical/tensorproduct.jl b/src/ecc/codes/classical/tensorproduct.jl new file mode 100644 index 000000000..2f5f56f37 --- /dev/null +++ b/src/ecc/codes/classical/tensorproduct.jl @@ -0,0 +1,20 @@ +""" +The classical Tensor-product code was discovered by Wolf in his 1963 paper [wolf1965codes](@cite). It combines two component linear error correcting codes by taking the tensor product of their parity check matrices. + +The ECC Zoo has an [entry for this family](https://errorcorrectionzoo.org/c/tensor). +""" +struct TensorProduct + A::AbstractMatrix + B::AbstractMatrix + function TensorProduct(A, B) + all(x -> x isa Bool, A) && all(x -> x isa Bool, B) || throw(ArgumentError("All matrices should be defined over the Boolean field, GF(2)")) + new(A, B) + end +end + +function parity_checks(tp::TensorProduct) + A, B = tp.A, tp.B + C = kronecker_product(matrix(ZZ, B), matrix(ZZ, A)) + C = Matrix{Bool}(Matrix{Int}(C)) + return C +end diff --git a/src/ecc/codes/classical_codes.jl b/src/ecc/codes/classical_codes.jl index e0007754b..16c37ee2a 100644 --- a/src/ecc/codes/classical_codes.jl +++ b/src/ecc/codes/classical_codes.jl @@ -9,5 +9,5 @@ function parity_checks(c::RepCode) I = [i for i in 1:n for δ in (0,1)] J = [(i+δ-1)%n+1 for i in 1:n for δ in (0,1)] V = true - sparse(I,J,V,n,n) + Matrix{Bool}(sparse(I,J,V,n,n)) end diff --git a/src/ecc/codes/quantumtensorproduct.jl b/src/ecc/codes/quantumtensorproduct.jl new file mode 100644 index 000000000..4f44492e3 --- /dev/null +++ b/src/ecc/codes/quantumtensorproduct.jl @@ -0,0 +1,19 @@ +""" +The binary quantum Tensor Product Code(TQC) is derived from classical TPCs using the CSS construction. A classical TPC is dual-containing if at least one of its component codes is. + +The ECC Zoo has an [entry for this family](https://errorcorrectionzoo.org/c/quantum_tensor_product). +""" +struct QuantumTensorProduct + A::AbstractMatrix + B::AbstractMatrix + function QuantumTensorProduct(A, B) + all(x -> x isa Bool, A) && all(x -> x isa Bool, B) || throw(ArgumentError("All matrices should be defined over the Boolean field, GF(2).")) + new(A, B) + end +end + +function parity_checks(Tₚ::QuantumTensorProduct) + T = parity_checks(TensorProduct(Tₚ.A, Tₚ.B)) + H = Stabilizer(CSS(T, T)) + return H +end diff --git a/test/test_ecc_base.jl b/test/test_ecc_base.jl index 9b4dac227..498654ff1 100644 --- a/test/test_ecc_base.jl +++ b/test/test_ecc_base.jl @@ -20,7 +20,8 @@ const code_instance_args = Dict( Gottesman => [3, 4, 5], CSS => (c -> (parity_checks_x(c), parity_checks_z(c))).([Shor9(), Steane7(), Toric(4, 4)]), Concat => [(Perfect5(), Perfect5()), (Perfect5(), Steane7()), (Steane7(), Cleve8()), (Toric(2, 2), Shor9())], - CircuitCode => random_circuit_code_args + CircuitCode => random_circuit_code_args, + QuantumTensorProduct => [(RepCode(3),RepCode(4)), (RepCode(5),RepCode(6)), (BCH(3,1),BCH(3,2)), (BCH(3,2),BCH(4,1))] ) function all_testablable_code_instances(;maxn=nothing) diff --git a/test/test_ecc_bch.jl b/test/test_ecc_bch.jl index 10cbece67..3e24efdd1 100644 --- a/test/test_ecc_bch.jl +++ b/test/test_ecc_bch.jl @@ -2,7 +2,7 @@ using LinearAlgebra using QuantumClifford.ECC using QuantumClifford.ECC: AbstractECC, BCH, generator_polynomial - using Nemo: ZZ, residue_ring, matrix, finite_field, GF, minpoly, coeff, lcm, FqPolyRingElem, FqFieldElem, is_zero, degree, defining_polynomial, is_irreducible + using Nemo: ZZ, residue_ring, matrix, finite_field, GF, minpoly, coeff, lcm, FqPolyRingElem, FqFieldElem, is_zero, degree, defining_polynomial, is_irreducible """ - To prove that `t`-bit error correcting BCH code indeed has minimum distance of at least `2 * t + 1`, it is shown that no `2 * t` or fewer columns of its binary parity check matrix `H` sum to zero. A formal mathematical proof can be found on pages 168 and 169 of Ch6 of Error Control Coding by Lin, Shu and Costello, Daniel. @@ -26,7 +26,7 @@ m_cases = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] for m in m_cases n = 2 ^ m - 1 - for t in rand(1:m, 2) + for t in rand(1:m-1, 2) H = parity_checks(BCH(m, t)) @test check_designed_distance(H, t) == true # n - k == degree of generator polynomial, `g(x)` == rank of binary parity check matrix, `H`. diff --git a/test/test_ecc_tensorproduct.jl b/test/test_ecc_tensorproduct.jl new file mode 100644 index 000000000..723bf19fb --- /dev/null +++ b/test/test_ecc_tensorproduct.jl @@ -0,0 +1,10 @@ +@testitem "Tensor Producr codes" begin + using QuantumClifford.ECC + using QuantumClifford.ECC: TensorProduct, parity_checks + A = [1 1 1 1 1] .== 1 + B = [1 1 1 0 1 0 0; 1 1 0 1 0 1 0; 1 0 1 1 0 0 1] .== 1 + # Example 1 of [wolf2006introduction](@cite) + @test parity_checks(TensorProduct(A, B)) == Matrix{Bool}([ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0; + 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0; + 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1]) +end diff --git a/test/test_ecc_throws.jl b/test/test_ecc_throws.jl index bd648327b..87fc0655f 100644 --- a/test/test_ecc_throws.jl +++ b/test/test_ecc_throws.jl @@ -5,5 +5,6 @@ @test_throws ArgumentError ReedMuller(1, 0) @test_throws ArgumentError BCH(2, 2) + @test_throws ArgumentError BCH(3, 3) @test_throws ArgumentError BCH(3, 4) end