Constructing Quantum Codes

A quantum code of length n over GF(q) is defined in terms of a symplectic self-orthogonal stabilizer code, which is given either as a length n additive code over GF(q2) (compact format) or as a length 2n additive code over GF(q) (extended format). If Q is a quantum code with generator matrix G1 in compact format, and generator matrix G2 = (A|B) in extended format, then G1 = A + λ B, where λ is a fixed element returned by the function QuantumBasisElement(GF(q2)). By default Magma assumes the compact format. However, the extended format can be flagged by setting the variable argument ExtendedFormat to true.

An [n, k] symplectic self-orthogonal linear code over GF(q2) will generate an [[n, n/2 - k]] quantum stabilizer code. A (compact format) additive symplectic self-orthogonal code C over GF(q2) will give a quantum code of the same length and "dimension" logq(N), where N is the number of code words in C.

Contents

Construction of General Quantum Codes

QuantumCode(S) : Code -> CodeQuantum
    ExtendedFormat: BoolElt             Default: false
Given an additive code S which is self-orthogonal with respect to the symplectic inner product, return the quantum code defined by S. By default, S is interpreted as being in compact format, that is, a length n additive code over GF(q2). If ExtendedFormat is set true, then S is interpreted as being in extended format, that is, a length 2n additive code over GF(q).

Example QECC_SimpleQuantConstr (H167E1)

A linear code over GF(4) that is even is symplectic self-orthogonal. Note that when a quantum code is printed in Magma, an additive stabilizer matrix over GF(q2) is displayed.

> F<w> := GF(4);
> M := Matrix(F, 2, 6, [1,0,0,1,w,w, 0,1,0,w,w,1]);
> C := LinearCode(M);
> C;
[6, 2, 4] Linear Code over GF(2^2)
Generator matrix:
[  1   0   0   1   w   w]
[  0   1   0   w   w   1]
> IsEven(C);
true
> IsSymplecticSelfOrthogonal(C);
true
> Q := QuantumCode(C);
> Q;
[[6, 2]] Quantum code over GF(2^2), stabilized by:
[  1   0   0   1   w   w]
[  w   0   0   w w^2 w^2]
[  0   1   0   w   w   1]
[  0   w   0 w^2 w^2   w]
> MinimumWeight(Q);
1
> Q;
[[6, 2, 1]] Quantum code over GF(2^2), stabilized by:
[  1   0   0   1   w   w]
[  w   0   0   w w^2 w^2]
[  0   1   0   w   w   1]
[  0   w   0 w^2 w^2   w]

Example QECC_SimpleQuantExtendedConstr (H167E2)

Any stabilizer code used to construct a quantum code, may be expressed in either compact or extended format. The length 6 quaternary additive code S in the previous example (H167E1) is equivalent to a length 12 binary additive code in extended format.

Note that the code will still be displayed in compact format.

> F<w> := GF(4);
> C := LinearCode<GF(2), 12 |
>      [ 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1 ],
>      [ 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0 ],
>      [ 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0 ],
>      [ 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1 ] >;
> C;
[12, 4, 4] Linear Code over GF(2)
Generator matrix:
[1 0 0 0 0 1 1 1 0 0 1 1]
[0 1 0 0 0 1 0 0 0 1 1 0]
[0 0 0 1 0 1 1 1 0 0 0 0]
[0 0 0 0 1 1 1 0 0 1 1 1]
> Q := QuantumCode(C : ExtendedFormat := true);
> Q;
[[6, 2]] Quantum code over GF(2^2), stabilized by:
[  1   0   0   1   w   w]
[  w   0   0   w w^2 w^2]
[  0   1   0   w   w   1]
[  0   w   0 w^2 w^2   w]

Example QECC_SimpleQuantSelfDualConstr (H167E3)

Any self-orthogonal code which has a rate of 1/2 must be self-dual, and gives rise to a dimension zero quantum code (which is also termed self-dual). In this example we construct the hexacode, which is the unique extremal length 6 self-dual quantum code of minimum weight 4.
> F<w> := GF(4);
> M := Matrix(F, 3, 6, [0,0,1,1,1,1, 0,1,0,1,w,w^2, 1,0,0,1,w^2,w]);
> C := LinearCode(M);
> C;
[6, 3, 4] Linear Code over GF(2^2)
Generator matrix:
[  1   0   0   1 w^2   w]
[  0   1   0   1   w w^2]
[  0   0   1   1   1   1]
> IsSymplecticSelfOrthogonal(C);
true
> Q := QuantumCode(C);
> MinimumWeight(Q);
4
> Q;
[[6, 0, 4]] self-dual Quantum code over GF(2^2), stabilized by:
[  1   0   0   1 w^2   w]
[  w   0   0   w   1 w^2]
[  0   1   0   1   w w^2]
[  0   w   0   w w^2   1]
[  0   0   1   1   1   1]
[  0   0   w   w   w   w]

Example QECC_SimpleQuantAdditiveConstr (H167E4)

Stabilizer codes neither have to be linear nor even and indeed any additive code which is symplectic self-orthogonal will generate a quantum code. The following code was randomly generated.
> F<w> := GF(4);
> M := Matrix(F, 3, 7, [1,w,w,w,0,0,1, w,0,1,0,w^2,0,1, 0,w^2,w,w^2,w,0,0]);
> C := AdditiveCode(GF(2),M);
> C;
[7, 1 1/2 : 3, 4] GF(2)-Additive Code over GF(2^2)
Generator matrix:
[  1   w   w   w   0   0   1]
[  w   0   1   0 w^2   0   1]
[  0 w^2   w w^2   w   0   0]
> IsSymplecticSelfOrthogonal(C);
true

The code C can be shown to be neither linear nor even: in fact it has the same number of even and odd codewords.

> IsLinear(C);
false
> {* Weight(v) mod 2 : v in C *};
{* 0^^4, 1^^4 *}
>
> Q := QuantumCode(C);
> MinimumWeight(Q);
1
> Q;
[[7, 4, 1]] Quantum code over GF(2^2), stabilized by:
[  1   w   w   w   0   0   1]
[  w   0   1   0 w^2   0   1]
[  0 w^2   w w^2   w   0   0]
QuantumCode(M) : ModMatRngElt -> CodeQuantum
    ExtendedFormat: BoolElt             Default: false
Given a matrix M over GF(q2) for which the GF(q) additive span of its rows is a self-orthogonal code S with respect to the symplectic inner product, return the quantum code defined by S. By default, M is interpreted as being in compact format, that is, a matrix whose rows are length n vectors over GF(q2). However, if ExtendedFormat is set true, then M will be interpreted as being in extended format, that is, a matrix whose rows are length 2n vectors over GF(q).

Example QECC_SimpleQuantConstrMat (H167E5)

A quantum code can be constructed directly from an additive stabilizer matrix, thereby avoiding creation of the stabilizer code. The quantum code given in example H167E4 could have also been constructed as follows:
> F<w> := GF(4);
> M := Matrix(F, 3, 7, [1,w,w,w,0,0,1, w,0,1,0,w^2,0,1, 0,w^2,w,w^2,w,0,0]);
> Q := QuantumCode(M);
> Q;
[[7, 4]] Quantum code over GF(2^2), stabilized by:
[  1   w   w   w   0   0   1]
[  w   0   1   0 w^2   0   1]
[  0 w^2   w w^2   w   0   0]
QuantumCode(G) : Grph -> CodeQuantum
Given a graph G, return the self-dual (dimension 0) quantum code defined by the adjacency matrix of G.

Example QECC_HexacodeQuant (H167E6)

The unique extremal [[6, 0, 4]] hexacode can be defined in terms of a graph representing a 5--spoked wheel. The graph is specified by listing the edges comprising its circumference, followed by the spokes radiating out from the center.
> G := Graph<6 | {1,2},{2,3},{3,4},{4,5},{5,1}, <6, {1,2,3,4,5}> >;
> Q := QuantumCode(G);
> Q:Minimal;
[[6, 0]] self-dual Quantum code over GF(2^2)
> MinimumWeight(Q);
4
> Q:Minimal;
[[6, 0, 4]] self-dual Quantum code over GF(2^2)

Example QECC_DodecacodeQuant (H167E7)

The unique extremal [[12, 0, 6]] dodecacode can also be described by a graph with a nice mathematical structure. The graph construction is derived from the diagram given by Danielson in [Dan05]. In order to employ modular arithmetic, the graph vertices are numbered from 0 to 11.
> S := {@ i : i in [0 .. 11] @};
> G := Graph<S |
>     { {4*k+i,4*k+i+2} : i in [0..1], k in [0..2] },
>     { {4*k+i,4*k+(i+1) mod 4} : i in [0..3], k in [0..2] },
>     { {4*k+i,4*((k+1) mod 3)+(i+1) mod 4} : i in [0..3], k in [0..2] } >;
> Q := QuantumCode(G);
> MinimumWeight(Q);
6
> Q:Minimal;
[[12, 0, 6]] self-dual Quantum code over GF(2^2)
RandomQuantumCode(F, n, k) : FldFin, RngIntElt, RngIntElt -> CodeQuantum
Let F be a degree 2 extension of a finite field GF(q). Given positive integers n and k such that n ≥k, this function returns a random [[n, k]] quantum stabilizer code over F. The field F is assumed to be given in compact format.

Example QECC_RandomQuantConstr (H167E8)

We construct a random [[10, 6]] quantum code over GF(4).
> F<w> := GF(4);
> Q := RandomQuantumCode(F, 10, 6);
> Q;
[[10, 6]] Quantum code over GF(2^2), stabilized by:
[  w   0   0   w   1   1   w w^2   w w^2]
[  0   1   0   w   1 w^2 w^2   1   w   w]
[  0   w   1   1   1   0 w^2   0   0   0]
[  0   0   w   1   1   0   1 w^2   1   w]
Subcode(Q, k) : CodeQuantum, RngIntElt -> CodeQuantum
Given a quantum code Q of dimension kQ ≥k then return a subcode of Q of dimension k.

Construction of Special Quantum Codes

Hexacode() : -> CodeQuantum
Return the [[6, 0, 4]] self-dual quantum hexacode.
Dodecacode() : -> CodeQuantum
Return the [[12, 0, 6]] self-dual quantum dodecacode.

CSS Codes

CSSCode(C1, C2) : Code, Code -> CodeQuantum
CalderbankShorSteaneCode(C1, C2) : Code, Code -> CodeQuantum
Given two classical linear binary codes C1 and C2 of length n such that C2 is a subcode of C1, form a quantum code using the construction of Calderbank, Shor and Steane [CS96], [Ste96a], [Ste96b].

Example QECC_CSSQuantConstr (H167E9)

Let C1 denote the [7, 4, 3] Hamming code and C2 denote its dual. Observing that C1 contains C2, we may apply the CSS construction using C1 and C2 to obtain a [[7, 1, 3]] code.
> F<w> := GF(4);
> C1 := HammingCode(GF(2), 3);
> C1;
[7, 4, 3] "Hamming code (r = 3)" Linear Code over GF(2)
Generator matrix:
[1 0 0 0 1 1 0]
[0 1 0 0 0 1 1]
[0 0 1 0 1 1 1]
[0 0 0 1 1 0 1]
> C2 := Dual(C1);
> C2;
[7, 3, 4] Cyclic Linear Code over GF(2)
Generator matrix:
[1 0 0 1 0 1 1]
[0 1 0 1 1 1 0]
[0 0 1 0 1 1 1]
> C2 subset C1;
true
> Q := CSSCode(C1, C2);
> MinimumWeight(Q);
3
> Q;
[[7, 1, 3]] CSS Quantum code over GF(2^2), stabilised by:
[  1   0   0   1   0   1   1]
[  w   0   0   w   0   w   w]
[  0   1   0   1   1   1   0]
[  0   w   0   w   w   w   0]
[  0   0   1   0   1   1   1]
[  0   0   w   0   w   w   w]

Cyclic Quantum Codes

Cyclic quantum codes are those having cyclic stabilizer codes. Conditions are listed in [CRSS98] for generating polynomials which give rise to symplectic self-orthogonal stabilizer codes.

QuantumCyclicCode(v) : ModTupFldElt -> CodeAdd
QuantumCyclicCode(Q) : [ModTupFldElt] -> CodeAdd
    LinearSpan: BoolElt                 Default: false
Given either a single vector v or sequence of vectors Q defined over a finite field F, return the quantum code generated by the span of the cyclic shifts of the supplied vectors. The span must be self-orthogonal with respect to the symplectic inner product. By default, the additive span is taken over the prime field, but if the variable argument LinearSpan is set to true, then the linear span will be taken.

Example QECC_CyclicQuantCodesimple (H167E10)

A large number of good cyclic quantum codes exist. For example, the best known binary self-dual quantum code of length 15 is cyclic.
> F<w> := GF(4);
> v := VectorSpace(F, 15) ! [w,1,1,0,1,0,1,0,0,1,0,1,0,1,1];
> Q := QuantumCyclicCode(v);
> MinimumWeight(Q);
6
> Q:Minimal;
[[15, 0, 6]] self-dual Quantum code over GF(2^2)
QuantumCyclicCode(n, f) : RngIntElt, RngUPolElt -> CodeAdd
QuantumCyclicCode(n, Q) : RngIntElt, [RngUPolElt] -> CodeAdd
    LinearSpan: BoolElt                 Default: false
Let n be a positive integer. Given either a single polynomial f or a sequence of polynomials Q over some finite field F, return the quantum code of length n generated by the additive span of their cyclic shifts. The additive span must be symplectic self-orthogonal. By default, the additive span is taken over the prime field, but if the variable argument LinearSpan is set to true, then the linear span will be taken.

Example QECC_CyclicQuantCodePoly (H167E11)

Since classical cyclic codes correspond to factors of cyclotomic polynomials it is frequently convenient to specify a cyclic code in terms of polynomials. Here we construct the best known binary quantum codes with parameters [[23, 12, 4]] and [[25, 0, 8]].
> F<w> := GF(4);
> P<x> := PolynomialRing(F);
> f := x^16 + x^15 + x^13 + w*x^12 + x^11 + w*x^10 + x^9 + x^8 + w^2*x^7 +
>      x^6 + x^5 + w*x^4 + w^2*x^3 + w*x^2 + w^2*x + w^2;
> Q := QuantumCyclicCode(23, f);
> MinimumWeight(Q);
4
> Q:Minimal;
[[23, 12, 4]] Quantum code over GF(2^2)
>
> f := x^12 + x^11 + x^10 + x^8 + w*x^6 + x^4 + x^2 + x + 1;
> Q := QuantumCyclicCode(25, f);
> MinimumWeight(Q);
8
> Q:Minimal;
[[25, 0, 8]] self-dual Quantum code over GF(2^2)
QuantumCyclicCode(v4, v2) : ModTupFldElt, ModTupFldElt -> CodeAdd
In the important case of GF(2)-additive codes over GF(4), any cyclic code can be specified by two generators. Given vectors v4 and v2 both of length n, where v4 is over GF(4) and v2 is over GF(2), this function returns the length n quantum code generated by the additive span of their cyclic shifts. This span must be self-orthogonal with respect to the symplectic inner product.

Example QECC_CyclicQuantCodeGF4GF2 (H167E12)

Any cyclic binary quantum code of length n is determined by a cyclic stabilizer code, which can be defined uniquely in terms of an n-dimensional vector over GF(4) together with an n-dimensional vector over GF(2). We construct the best known [[21, 0, 8]] and [[21, 5, 6]] cyclic binary quantum codes.
> F<w> := GF(4);
> v4 := RSpace(F, 21) ! [w^2,w^2,1,w,0,0,1,1,1,1,0,1,0,1,1,0,1,1,0,0,0];
> v2 := RSpace(GF(2),21) ! [1,0,1,1,1,0,0,1,0,1,1,1,0,0,1,0,1,1,1,0,0];
> Q := QuantumCyclicCode(v4,v2);
> MinimumWeight(Q);
8
> Q:Minimal;
[[21, 0, 8]] self-dual Quantum code over GF(2^2)
>
> v4 := RSpace(F, 21) ! [w,0,w^2,w^2,w,w^2,w^2,0,w,1,0,0,1,0,0,0,0,1,0,0,1];
> v2 := RSpace(GF(2), 21) ! [1,0,1,1,1,0,0,1,0,1,1,1,0,0,1,0,1,1,1,0,0];
> Q := QuantumCyclicCode(v4,v2);
> MinimumWeight(Q);
6
> Q:Minimal;
[[21, 5, 6]] Quantum code over GF(2^2)

Quasi-Cyclic Quantum Codes

Quasi-cyclic quantum codes are those having quasi-cyclic stabilizer codes.

QuantumQuasiCyclicCode(n, Q) : RngIntElt, SeqEnum[RngUPolElt] -> CodeAdd
    LinearSpan: BoolElt                 Default: false
Given an integer n, and a sequence Q of polynomials over some finite field F, let S be the quasi-cyclic classical code generated by the span of the set of vectors formed by concatenating cyclic blocks generated by the polynomials in Q. Assuming that S is self-orthogonal with respect to the symplectic inner product, this function returns the quasi-cyclic quantum code with stabiliser code S. If the span of the vectors is not symplectic self-orthogonal, an error will be flagged.

By default the additive span is taken over the prime field, but if the variable argument LinearSpan is set to true, then the linear span will be taken.

QuantumQuasiCyclicCode(Q) : SeqEnum[ModTupFldElt] -> CodeAdd
    LinearSpan: BoolElt                 Default: false
Given a sequence Q of vectors, return the quantum code whose additive stabilizer matrix is constructed from the length n cyclic blocks generated by the cyclic shifts of the vectors in Q. If the variable argument LinearSpan is set to true, then the linear span of the shifts will be used, else the additive span will be used (default).

Example QECC_QuasiCyclicQuantCode (H167E13)

Most quasi-cyclic quantum codes currently known are linear, since this is where most research on quasi-cyclic codes has been focused. In this example we construct the best known quasi-cyclic binary quantum codes with parameters [[14, 0, 6]] and [[18, 6, 5]].
> F<w> := GF(4);
> V7 := VectorSpace(F, 7);
> v1 := V7 ! [1,0,0,0,0,0,0];
> v2 := V7 ! [w^2,1,w^2,w,0,0,w];
> Q := QuantumQuasiCyclicCode([v1, v2] : LinearSpan := true);
> MinimumWeight(Q);
6
> Q:Minimal;
[[14, 0, 6]] self-dual Quantum code over GF(2^2)
>
> V6 := VectorSpace(F, 6);
> v1 := V6 ! [1,1,0,0,0,0];
> v2 := V6 ! [1,0,1,w^2,0,0];
> v3 := V6 ! [1,1,w,1,w,0];
> Q := QuantumQuasiCyclicCode([v1, v2, v3] : LinearSpan := true);
> MinimumWeight(Q);
5
> Q:Minimal;
[[18, 6, 5]] Quantum code over GF(2^2)
V2.28, 13 July 2023