---
title: "Handbook of Magma Functions, Part XXI: Coding Theory"
version: "2.30-1"
canonical: "https://docs.magma-maths.org/CodingTheory/index-coding-theory.html"
---

# Coding Theory

- [Linear Codes over Finite Fields](https://docs.magma-maths.org/CodingTheory/LinearCodes/index-linear-codes.md): Linear code constructors, generator matrices, and parameters.
- [Algebraic-Geometric Codes](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/index-algebraic-geometric-codes.md): Codes constructed from algebraic curves, and their decoding.
- [Low Density Parity Check Codes](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/index-low-density-parity-check-codes.md): LDPC code construction and properties.
- [Linear Codes over Finite Rings](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/index-linear-codes-over-finite-rings.md): Linear codes over finite rings: creation, subcodes, and Boolean operations.
- [Linear Codes over the Integer Residue Ring Z4](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/index-linear-codes-over-z4.md): Linear codes over :math:`\Z_4`, invariants, weight enumerators, and decoding.
- [Additive Codes](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/index-additive-codes.md): Additive code constructors, subcodes, and Boolean operations.
- [Quantum Codes](https://docs.magma-maths.org/CodingTheory/QuantumCodes/index-quantum-codes.md): Quantum error-correcting codes, inner products, and code combination.
- [Pseudo-random Bit Sequences](https://docs.magma-maths.org/CodingTheory/PseudoRandomBitSequences/index-pseudo-random-bit-sequences.md): Linear feedback shift registers, Berlekamp-Massey, correlation, decimation, and the SHA-1 hash.

<a id="error-correcting-linear-code"></a>
<a id="chap-codefld"></a>
## Linear Codes over Finite Fields

- [Introduction](https://docs.magma-maths.org/CodingTheory/LinearCodes/introduction.md)
- [Construction of Codes](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md)
  - [Construction of General Linear Codes](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#construction-of-general-linear-codes)
    - [`LinearCode<R, n | L>: FldFin, RngIntElt, List → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#constructor-constructor-linearcode-fldfin-rngintelt-list-code)
    - [Example: Ternary Golay Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#example-ex-4d7dd8)
    - [`LinearCode(U): ModTupRng → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#function-linearcode-modtuprng)
    - [`LinearCode(A): ModMatRngElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#function-linearcode-modmatrngelt)
    - [Example: Code from a Matrix](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#example-ex-854c75)
    - [`PermutationCode(u, G): ModTupRngElt, GrpPerm → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#function-permutationcode-modtuprngelt-grpperm)
    - [Example: Code from a Permutation Group](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#example-ex-db1b6e)
  - [Some Trivial Linear Codes](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#some-trivial-linear-codes)
    - [`ZeroCode(R, n): FldFin, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#function-zerocode-fldfin-rngintelt)
    - [`RepetitionCode(R, n): FldFin, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#function-repetitioncode-fldfin-rngintelt)
    - [`ZeroSumCode(R, n): FldFin, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#function-zerosumcode-fldfin-rngintelt)
    - [`UniverseCode(R, n): FldFin, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#function-universecode-fldfin-rngintelt)
    - [`EvenWeightCode(n): RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#function-evenweightcode-rngintelt)
    - [`EvenWeightSubcode(C): Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#function-evenweightsubcode-code)
    - [`RandomLinearCode(K, n, k): FldFin, RngIntElt, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#function-randomlinearcode-fldfin-rngintelt-rngintelt)
    - [`CordaroWagnerCode(n): RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#function-cordarowagnercode-rngintelt)
    - [Example: Chain of Trivial Linear Codes](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#example-ex-552322)
  - [Some Basic Families of Codes](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#some-basic-families-of-codes)
    - [`CyclicCode(n, g): RngIntElt, RngUPolElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#function-cycliccode-rngintelt-rngupolelt)
    - [Example: Golay Code as a Cyclic Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#example-ex-667d8b)
    - [`HammingCode(K, r): FldFin, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#function-hammingcode-fldfin-rngintelt)
    - [Example: Hamming Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#example-ex-496ba8)
    - [`SimplexCode(r): RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#function-simplexcode-rngintelt)
    - [`ReedMullerCode(r, m): RngIntElt, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#function-reedmullercode-rngintelt-rngintelt)
    - [Example: Reed-Muller Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/creation.md#example-ex-86fc03)
- [Invariants of a Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md)
  - [Basic Numerical Invariants](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#basic-numerical-invariants)
    - [`Length(C): Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#function-length-code)
    - [`Dimension(C): Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#function-dimension-code)
    - [`NumberOfGenerators(C): Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#function-numberofgenerators-code)
    - [`# C: Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#operation-operation-code-rngintelt)
    - [`InformationRate(C): Code → FldPrElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#function-informationrate-code)
  - [The Ambient Space and Alphabet](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#the-ambient-space-and-alphabet)
    - [`AmbientSpace(C): Code → ModTupRng`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#function-ambientspace-code)
    - [`RSpace(C): Code → ModTupRng`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#function-rspace-code)
    - [`VectorSpace(C): Code → ModTupFld`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#function-vectorspace-code)
    - [`Generic(C): Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#function-generic-code)
    - [`Alphabet(C): Code → Rng`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#function-alphabet-code)
    - [`Field(C): Code → Rng`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#function-field-code)
  - [The Code Space](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#the-code-space)
    - [`GeneratorMatrix(C): Code → ModMatFldElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#function-generatormatrix-code)
    - [`BasisMatrix(C): Code → ModMatRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#function-basismatrix-code)
    - [`Basis(C): Code → [ ModTupRngElt ]`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#function-basis-code)
    - [`Generators(C): Code → { ModTupFldElt }`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#function-generators-code)
    - [`C . i: Code, RngIntElt → ModTupFldElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#operation-operation-code-rngintelt-modtupfldelt)
  - [The Dual Space](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#the-dual-space)
    - [`Dual(C): Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#function-dual-code)
    - [`ParityCheckMatrix(C): Code → ModMatFldElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#function-paritycheckmatrix-code)
    - [Example: Generator and Parity Check Matrices](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#example-ex-7ec540)
    - [`Hull(C): Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#function-hull-code)
  - [The Information Space and Information Sets](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#the-information-space-and-information-sets)
    - [`InformationSpace(C): Code → ModTupFld`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#function-informationspace-code)
    - [`InformationSet(C): Code → [ RngIntElt ]`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#function-informationset-code)
    - [`AllInformationSets(C): Code → [ [ RngIntElt ] ]`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#function-allinformationsets-code)
    - [`StandardForm(C): Code → Code, Map`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#function-standardform-code)
    - [Example: Standard Form of a Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#example-ex-8132b6)
  - [The Syndrome Space](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#the-syndrome-space)
    - [`SyndromeSpace(C): Code → ModTupFld`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#function-syndromespace-code)
  - [The Generator Polynomial](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#the-generator-polynomial)
    - [`GeneratorPolynomial(C): Code → RngUPolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#function-generatorpolynomial-code)
    - [`CheckPolynomial(C): Code → RngUPolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#function-checkpolynomial-code)
    - [`Idempotent(C): Code → RngUPolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#function-idempotent-code)
    - [Example: Generator and Check Polynomials](https://docs.magma-maths.org/CodingTheory/LinearCodes/access.md#example-ex-889cde)
- [Operations on Codewords](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md)
  - [Construction of a Codeword](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#construction-of-a-codeword)
    - [`C ! [a₁, ..., aₙ]: Code, [ RngElt ] → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#operation-op-code-rngelt)
    - [`elt< C | a₁, ..., aₙ>: Code, List → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#constructor-constructor-elt-code-list-modtuprngelt)
    - [`C ! u: Code, ModTupRngElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#operation-op-code-modtuprngelt)
    - [`C ! 0: Code, RngIntElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#operation-op-code-rngintelt)
    - [`Random(C): Code → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#function-random-code)
  - [Arithmetic Operations on Codewords](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#arithmetic-operations-on-codewords)
    - [`u + v: ModTupRngElt, ModTupRngElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#operation-op-plus-modtuprngelt-modtuprngelt)
    - [`- u: ModTupRngElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#operation-operation-modtuprngelt-modtuprngelt)
    - [`u - v: ModTupRngElt, ModTupRngElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#operation-op-minus-modtuprngelt-modtuprngelt)
    - [`a * u: RngElt, ModTupRngElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#operation-op-times-rngelt-modtuprngelt)
    - [`Normalize(u): ModTupRngElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#function-normalize-modtuprngelt)
    - [`Syndrome(w, C): ModTupFldElt, Code → ModTupFldElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#function-syndrome-modtupfldelt-code)
  - [Distance and Weight](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#distance-and-weight)
    - [`Distance(u, v): ModTupRngElt, ModTupRngElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#function-distance-modtuprngelt-modtuprngelt)
    - [`Weight(u): ModTupRngElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#function-weight-modtuprngelt)
    - [`LeeWeight(u): ModTupRngElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#function-leeweight-modtuprngelt)
    - [Example: Distances in the Ternary Golay Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#example-ex-75e920)
  - [Vector Space and Related Operations](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#vector-space-and-related-operations)
    - [`(u, v): ModTupRngElt, ModTupRngElt → RngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#literal-literal-u-v-modtuprngelt-modtuprngelt-rngelt)
    - [`InnerProduct(u, v): ModTupRngElt, ModTupRngElt → RngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#function-innerproduct-modtuprngelt-modtuprngelt)
    - [`Support(w): ModTupRngElt → { RngIntElt }`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#function-support-modtuprngelt)
    - [`Coordinates(C, u): Code, ModTupRngElt → [ RngFinElt ]`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#function-coordinates-code-modtuprngelt)
    - [`Parent(w): ModTupRngElt → ModTupRng`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#function-parent-modtuprngelt)
    - [`Rotate(u, k): ModTupRngElt, RngIntElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#function-rotate-modtuprngelt-rngintelt)
    - [`Rotate(~u, k): ModTupRngElt, RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#procedure-rotate-modtuprngelt-rngintelt-ref)
    - [`Trace(u, S): ModTupFldElt, FldFin → ModTupFldElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#function-trace-modtupfldelt-fldfin)
    - [`Trace(u): ModTupFldElt → ModTupFldElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#function-trace-modtupfldelt)
    - [Example: Coordinates of a Code Word](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#example-ex-fb5172)
  - [Predicates for Codewords](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#predicates-for-codewords)
    - [`u eq v: ModTupRngElt, ModTupRngElt → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#operation-op-eq-modtuprngelt-modtuprngelt)
    - [`u ne v: ModTupRngElt, ModTupRngElt → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#operation-op-ne-modtuprngelt-modtuprngelt)
    - [`IsZero(u): ModTupRngElt → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#function-iszero-modtuprngelt)
  - [Accessing Components of a Codeword](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#accessing-components-of-a-codeword)
    - [`u[i]: ModTupRngElt, RngIntElt → RngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#literal-literal-u-i-modtuprngelt-rngintelt-rngelt)
    - [`u[i] := x;`](https://docs.magma-maths.org/CodingTheory/LinearCodes/element.md#literal-literal-u-i-x)
- [Coset Leaders](https://docs.magma-maths.org/CodingTheory/LinearCodes/coset-leader.md)
  - [`CosetLeaders(C): Code → {@ ModTupFldElt  @}, Map`](https://docs.magma-maths.org/CodingTheory/LinearCodes/coset-leader.md#function-cosetleaders-code)
  - [Example: Decoding with Coset Leaders](https://docs.magma-maths.org/CodingTheory/LinearCodes/coset-leader.md#example-ex-6ef726)
- [Subcodes](https://docs.magma-maths.org/CodingTheory/LinearCodes/subcode.md)
  - [The Subcode Constructor](https://docs.magma-maths.org/CodingTheory/LinearCodes/subcode.md#the-subcode-constructor)
    - [`sub<C | L>: Code, List → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/subcode.md#constructor-constructor-sub-code-list-code)
    - [`Subcode(C, k): Code, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/subcode.md#function-subcode-code-rngintelt)
    - [`Subcode(C, S): Code, { RngIntElt } → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/subcode.md#function-subcode-code-rngintelt-2)
    - [`SubcodeBetweenCode(C1, C2, k): Code, Code, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/subcode.md#function-subcodebetweencode-code-code-rngintelt)
    - [`SubcodeWordsOfWeight(C, S): Code, { RngIntElt } → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/subcode.md#function-subcodewordsofweight-code-rngintelt)
    - [Example: Subcode between Two Codes](https://docs.magma-maths.org/CodingTheory/LinearCodes/subcode.md#example-ex-db10dc)
  - [Sum, Intersection, Duals, and Hulls](https://docs.magma-maths.org/CodingTheory/LinearCodes/subcode.md#sum-intersection-duals-and-hulls)
    - [`C + D: Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/subcode.md#operation-op-plus-code-code)
    - [`C meet D: Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/subcode.md#operation-op-meet-code-code)
    - [`Dual(C): Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/subcode.md#function-dual-code-2)
    - [Example: Sums and Intersections of Subcodes](https://docs.magma-maths.org/CodingTheory/LinearCodes/subcode.md#example-ex-377d6d)
    - [Example: Dual of a Reed-Solomon Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/subcode.md#example-ex-cfd60d)
    - [`HermitianDual(C): CodeLinFld → CodeLinFld`](https://docs.magma-maths.org/CodingTheory/LinearCodes/subcode.md#function-hermitiandual-codelinfld)
    - [`Hull(C): CodeLinFld → CodeLinFld`](https://docs.magma-maths.org/CodingTheory/LinearCodes/subcode.md#function-hull-codelinfld)
    - [`HermitianHull(C): CodeLinFld → CodeLinFld`](https://docs.magma-maths.org/CodingTheory/LinearCodes/subcode.md#function-hermitianhull-codelinfld)
  - [Membership and Equality](https://docs.magma-maths.org/CodingTheory/LinearCodes/subcode.md#membership-and-equality)
    - [`u in C: ModTupRngElt, Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/subcode.md#operation-op-in-modtuprngelt-code)
    - [`u notin C: ModTupRngElt, Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/subcode.md#operation-op-notin-modtuprngelt-code)
    - [`C subset D: Code, Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/subcode.md#operation-op-subset-code-code)
    - [`C notsubset D: Code, Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/subcode.md#operation-operation-notsubset-code-code-boolelt)
    - [`C eq D: Code, Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/subcode.md#operation-op-eq-code-code)
    - [`C ne D: Code, Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/subcode.md#operation-op-ne-code-code)
- [Properties of Codes](https://docs.magma-maths.org/CodingTheory/LinearCodes/Boolean.md)
  - [`IsCyclic(C): Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/Boolean.md#function-iscyclic-code)
  - [`IsSelfDual(C): Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/Boolean.md#function-isselfdual-code)
  - [`IsSelfOrthogonal(C): Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/Boolean.md#function-isselforthogonal-code)
  - [`IsHermitianSelfDual(C): CodeLinFld → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/Boolean.md#function-ishermitianselfdual-codelinfld)
  - [`IsHermitianSelfOrthogonal(C): CodeLinFld → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/Boolean.md#function-ishermitianselforthogonal-codelinfld)
  - [`IsMaximumDistanceSeparable(C): Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/Boolean.md#function-ismaximumdistanceseparable-code)
  - [`IsMDS(C): Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/Boolean.md#function-ismds-code)
  - [`IsEquidistant(C): Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/Boolean.md#function-isequidistant-code)
  - [`IsPerfect(C): Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/Boolean.md#function-isperfect-code)
  - [`IsNearlyPerfect(C): Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/Boolean.md#function-isnearlyperfect-code)
  - [`IsEven(C): Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/Boolean.md#function-iseven-code)
  - [`IsDoublyEven(C): Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/Boolean.md#function-isdoublyeven-code)
  - [`IsProjective(C): Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/Boolean.md#function-isprojective-code)
  - [Example: Self-Dual Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/Boolean.md#example-ex-a18e45)
  - [Example: Self-Orthogonal Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/Boolean.md#example-ex-f19a8e)
- [The Weight Distribution](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md)
  - [The Minimum Weight](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#the-minimum-weight)
    - [`MinimumWeight(C: parameters): Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-codefld-minimumweight)
    - [`MinimumDistance(C: parameters): Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-minimumdistance-code)
    - [`MinimumWeightBounds(C): Code → RngIntElt, RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-minimumweightbounds-code)
    - [`ResetMinimumWeightBounds(C): Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#procedure-resetminimumweightbounds-code)
    - [`VerifyMinimumDistanceLowerBound(C, d): Code, RngIntElt → BoolElt, RngIntElt, BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-verifyminimumdistancelowerbound-code-rngintelt)
    - [`VerifyMinimumDistanceUpperBound(C, d): Code, RngIntElt → BoolElt, RngIntElt, BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-verifyminimumdistanceupperbound-code-rngintelt)
    - [`VerifyMinimumWeightUpperBound(C, d: parameters): Code, RngIntElt → BoolElt, RngIntElt, BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-verifyminimumweightupperbound-code-rngintelt)
    - [`MinimumWord(C): Code → ModTupFldElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-minimumword-code)
    - [`MinimumWords(C): Code → { ModTupFldElt }`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-minimumwords-code)
    - [Example: Verifying a Minimum Weight Lower Bound](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#example-ex-1d8077)
    - [`IncludeAutomorphism(~C, p): Code, GrpPermElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#procedure-includeautomorphism-code-grppermelt-ref)
    - [`IncludeAutomorphism(~C, G): Code, GrpPerm`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#procedure-includeautomorphism-code-grpperm-ref)
    - [`KnownAutomorphismSubgroup(C): Code → GrpPerm`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-knownautomorphismsubgroup-code)
  - [The Weight Distribution](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#id2)
    - [`WeightDistribution(C): Code → [ <RngIntElt, RngIntElt> ]`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-weightdistribution-code)
    - [`WeightDistribution(C, u): Code, ModTupFldElt → [ <RngIntElt, RngIntElt> ]`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-weightdistribution-code-modtupfldelt)
    - [`DualWeightDistribution(C): Code → [ <RngIntElt, RngIntElt> ]`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-dualweightdistribution-code)
    - [Example: Weight Distribution of a Reed-Muller Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#example-ex-004d0f)
    - [`PartialWeightDistribution(C, ub): Code, RngIntElt → [ <RngIntElt, RngIntElt> ]`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-partialweightdistribution-code-rngintelt)
  - [The Weight Enumerator](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#the-weight-enumerator)
    - [`WeightEnumerator(C): Code → RngMPolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-weightenumerator-code)
    - [`WeightEnumerator(C, u): Code, ModTupFldElt → RngMPolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-weightenumerator-code-modtupfldelt)
    - [`CompleteWeightEnumerator(C): Code → RngMPolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-completeweightenumerator-code)
    - [`CompleteWeightEnumerator(C, u): Code, ModTupFldElt → RngMPolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-completeweightenumerator-code-modtupfldelt)
    - [Example: Weight Enumerators of a Ternary Cyclic Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#example-ex-012900)
  - [The MacWilliams Transform](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#the-macwilliams-transform)
    - [`MacWilliamsTransform(n, k, q, W): RngIntElt, RngIntElt, RngIntElt, [ <RngIntElt, RngIntElt> ] → [ <RngIntElt, RngIntElt> ]`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-macwilliamstransform-rngintelt-rngintelt-rngintelt-rngintelt-rngintelt)
    - [`MacWilliamsTransform(n, k, K, W): RngIntElt, RngIntElt, FldFin, RngMPol → RngMPol`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-macwilliamstransform-rngintelt-rngintelt-fldfin-rngmpol)
    - [Example: MacWilliams Transform](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#example-ex-09add6)
  - [Words](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#words)
    - [`Words(C, w: parameters): Code, RngIntElt → { ModTupFldElt }`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-words-code-rngintelt)
    - [`NumberOfWords(C, w): Code, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-numberofwords-code-rngintelt)
    - [`WordsOfBoundedWeight(C, l, u: parameters): Code, RngIntElt, RngIntElt → { ModTupFldElt }`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-wordsofboundedweight-code-rngintelt-rngintelt)
    - [`ConstantWords(C, i): Code, RngIntElt → { ModTupFldElt }`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-constantwords-code-rngintelt)
    - [`NumberOfConstantWords(C, i): Code, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-numberofconstantwords-code-rngintelt)
    - [Example: Words of a Given Weight](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#example-ex-22cd32)
  - [Covering Radius and Diameter](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#covering-radius-and-diameter)
    - [`CosetDistanceDistribution(C): Code → [ <RngIntElt, RngIntElt> ]`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-cosetdistancedistribution-code)
    - [`CoveringRadius(C): Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-coveringradius-code)
    - [`Diameter(C): Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#function-diameter-code)
    - [Example: Covering Radius and Coset Distances](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#example-ex-df764c)
- [Families of Linear Codes](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md)
  - [Cyclic and Quasicyclic Codes](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#cyclic-and-quasicyclic-codes)
    - [`CyclicCode(u): ModTupRngElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-cycliccode-modtuprngelt)
    - [`CyclicCode(n, T, K): RngIntElt, [ FldFinElt ], FldFin → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-cycliccode-rngintelt-fldfinelt-fldfin)
    - [`CyclicCode(n, T, K): RngIntElt, { FldFinElt }, FldFin → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-cycliccode-rngintelt-fldfinelt-fldfin-2)
    - [`QuasiCyclicCode(n, Gen): RngIntElt, [ RngUPolElt ] → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-quasicycliccode-rngintelt-rngupolelt)
    - [`QuasiCyclicCode(Gen): [ ModTupRngElt ] → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-quasicycliccode-modtuprngelt)
    - [`QuasiCyclicCode(n, Gen, h): RngIntElt, [ RngUPolElt ], RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-quasicycliccode-rngintelt-rngupolelt-rngintelt)
    - [`QuasiCyclicCode(Gen, h): [ModTupRngElt], RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-quasicycliccode-modtuprngelt-rngintelt)
    - [`ConstaCyclicCode(n, f, alpha): RngIntElt, RngUPolElt, FldFinElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-constacycliccode-rngintelt-rngupolelt-fldfinelt)
    - [`QuasiTwistedCyclicCode(n, Gen, alpha): RngIntElt, [RngUPolElt], FldFinElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-quasitwistedcycliccode-rngintelt-rngupolelt-fldfinelt)
    - [`QuasiTwistedCyclicCode(Gen, alpha): [ModTupRngElt], FldFinElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-quasitwistedcycliccode-modtuprngelt-fldfinelt)
    - [`QuasiTwistedCyclicCode(n, Gen, alpha, h): RngIntElt, [RngUPolElt], FldFinElt, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-quasitwistedcycliccode-rngintelt-rngupolelt-fldfinelt-rngintelt)
    - [`QuasiTwistedCyclicCode(Gen, alpha, h): [ModTupRngElt], FldFinElt, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-quasitwistedcycliccode-modtuprngelt-fldfinelt-rngintelt)
    - [Example: Chain of Cyclic Codes](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#example-ex-03b862)
    - [Example: Constacyclic Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#example-ex-975a7d)
  - [BCH Codes and their Generalizations](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#bch-codes-and-their-generalizations)
    - [`BCHCode(K, n, d, b): FldFin, RngIntElt, RngIntElt, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-bchcode-fldfin-rngintelt-rngintelt-rngintelt)
    - [`BCHCode(K, n, d): FldFin, RngIntElt, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-bchcode-fldfin-rngintelt-rngintelt)
    - [Example: BCH Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#example-ex-4d1633)
    - [`GoppaCode(L, G): [ FldFinElt ], RngUPolElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-goppacode-fldfinelt-rngupolelt)
    - [Example: Goppa Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#example-ex-150eaa)
    - [`ChienChoyCode(P, G, n, S): RngUPolElt, RngUPolElt, RngIntElt, FldFin → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-chienchoycode-rngupolelt-rngupolelt-rngintelt-fldfin)
    - [`AlternantCode(A, Y, r, S): [ FldFinElt ], [ FldFinElt ], RngIntElt, FldFin → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-alternantcode-fldfinelt-fldfinelt-rngintelt-fldfin)
    - [`AlternantCode(A, Y, r): [ FldFinElt ], [ FldFinElt ], RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-alternantcode-fldfinelt-fldfinelt-rngintelt)
    - [Example: Alternant Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#example-ex-c9dd03)
    - [`NonPrimitiveAlternantCode(n, m, r): RngIntElt, RngIntElt, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-nonprimitivealternantcode-rngintelt-rngintelt-rngintelt)
    - [`FireCode(h, s, n): RngUPolElt, RngIntElt, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-firecode-rngupolelt-rngintelt-rngintelt)
    - [`GabidulinCode(A, W, Z, t): [ FldFinElt ], [ FldFinElt ], [ FldFinElt ], RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-gabidulincode-fldfinelt-fldfinelt-fldfinelt-rngintelt)
    - [`SrivastavaCode(A, W, mu, S): [ FldFinElt ], [ FldFinElt ], RngIntElt, FldFin → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-srivastavacode-fldfinelt-fldfinelt-rngintelt-fldfin)
    - [`GeneralizedSrivastavaCode(A, W, Z, t, S): [ FldFinElt ], [ FldFinElt ], [ FldFinElt ], RngIntElt, FldFin → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-generalizedsrivastavacode-fldfinelt-fldfinelt-fldfinelt-rngintelt-fldfin)
  - [Quadratic Residue Codes and their Generalizations](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#quadratic-residue-codes-and-their-generalizations)
    - [`QRCode(K, n): FldFin, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-qrcode-fldfin-rngintelt)
    - [`GolayCode(K, ext): FldFin, BoolElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-golaycode-fldfin-boolelt)
    - [`DoublyCirculantQRCode(p): RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-doublycirculantqrcode-rngintelt)
    - [`DoublyCirculantQRCodeGF4(m, a): RngIntElt, RngElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-doublycirculantqrcodegf4-rngintelt-rngelt)
    - [`BorderedDoublyCirculantQRCode(p, a, b): RngIntElt, RngElt, RngElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-bordereddoublycirculantqrcode-rngintelt-rngelt-rngelt)
    - [`TwistedQRCode(l, m): RngIntElt, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-twistedqrcode-rngintelt-rngintelt)
    - [`PowerResidueCode(K, n, p): FldFin, RngIntElt, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-powerresiduecode-fldfin-rngintelt-rngintelt)
    - [Example: Quadratic Residue Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#example-ex-6c6e7c)
  - [Reed–Solomon and Justesen Codes](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#reed-solomon-and-justesen-codes)
    - [`ReedSolomonCode(K, d, b): FldFin, RngIntElt, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-reedsolomoncode-fldfin-rngintelt-rngintelt)
    - [`ReedSolomonCode(K, d): FldFin, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-reedsolomoncode-fldfin-rngintelt)
    - [`ReedSolomonCode(n, d): RngIntElt, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-reedsolomoncode-rngintelt-rngintelt)
    - [`ReedSolomonCode(n, d, b): RngIntElt, RngIntElt, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-reedsolomoncode-rngintelt-rngintelt-rngintelt)
    - [`GRSCode(A, V, k): [ FldFinElt ], [ FldFinElt ], RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-grscode-fldfinelt-fldfinelt-rngintelt)
    - [`JustesenCode(N, K): Code, FldFinElt, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-justesencode-code-fldfinelt-rngintelt)
    - [Example: Generalized Reed-Solomon Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#example-ex-6976f5)
  - [Maximum Distance Separable Codes](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#maximum-distance-separable-codes)
    - [`MDSCode(K, k): FldFin, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/families.md#function-mdscode-fldfin-rngintelt)
- [New Codes from Existing](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md)
  - [Standard Constructions](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#standard-constructions)
    - [`AugmentCode(C): Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-augmentcode-code)
    - [`CodeComplement(C, C1): Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-codecomplement-code-code)
    - [`DirectSum(C, D): Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-directsum-code-code)
    - [`DirectSum(Q): [Code] → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-directsum-code)
    - [`DirectProduct(C, D): Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-directproduct-code-code)
    - [`ProductCode(C, D): Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-productcode-code-code)
    - [`ExtendCode(C): Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-extendcode-code)
    - [`ExtendCode(C, n): Code, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-extendcode-code-rngintelt)
    - [`PadCode(C, n): Code, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-padcode-code-rngintelt)
    - [`ExpurgateCode(C): Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-expurgatecode-code)
    - [`ExpurgateCode(C, L): Code, [ModTupFldElt] → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-expurgatecode-code-modtupfldelt)
    - [`ExpurgateWeightCode(C, w): Code, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-expurgateweightcode-code-rngintelt)
    - [`LengthenCode(C): Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-lengthencode-code)
    - [`PlotkinSum(C1, C2): Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-plotkinsum-code-code)
    - [`PlotkinSum(C1, C2, C3: parameters): Code, Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-plotkinsum-code-code-code)
    - [`PunctureCode(C, i): Code, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-puncturecode-code-rngintelt)
    - [`PunctureCode(C, S): Code, { RngIntElt } → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-puncturecode-code-rngintelt-2)
    - [`ShortenCode(C, i): Code, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-shortencode-code-rngintelt)
    - [`ShortenCode(C, S): Code, { RngIntElt } → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-shortencode-code-rngintelt-2)
    - [Example: Constructing a \[12,4,6\] Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#example-ex-7b4c39)
  - [Changing the Alphabet of a Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#changing-the-alphabet-of-a-code)
    - [`ExtendField(C, L): Code, FldFin → Code, Map`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-extendfield-code-fldfin)
    - [`LinearCode(C, S): Code, FldFin → Code, Map`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-linearcode-code-fldfin)
    - [`SubfieldRepresentationCode(C, K): Code, FldFin → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-subfieldrepresentationcode-code-fldfin)
    - [`SubfieldRepresentationParityCode(C, K): Code, FldFin → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-subfieldrepresentationparitycode-code-fldfin)
    - [`SubfieldSubcode(C, S): Code, FldFin → Code, Map`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-subfieldsubcode-code-fldfin)
    - [`RestrictField(C, S): Code, FldFin → Code, Map`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-restrictfield-code-fldfin)
    - [`SubfieldSubcode(C): Code → Code, Map`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-subfieldsubcode-code)
    - [`RestrictField(C): Code → Code, Map`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-restrictfield-code)
    - [`SubfieldCode(C, S): Code, FldFin → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-subfieldcode-code-fldfin)
    - [`Trace(C, F): Code, FldFin → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-trace-code-fldfin)
    - [`Trace(C): Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-trace-code)
  - [Combining Codes](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#combining-codes)
    - [`C1 cat C2: Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#operation-operation-cat-code-code-code)
    - [`Juxtaposition(C1, C2): Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-juxtaposition-code-code)
    - [`ConcatenatedCode(O, I): Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-concatenatedcode-code-code)
    - [Example: Concatenated Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#example-ex-b27a80)
    - [`ConstructionX(C1, C2, C3): Code, Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-constructionx-code-code-code)
    - [`ConstructionXChain(S, C): [Code], Code → [Code]`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-constructionxchain-code-code)
    - [Example: Construction X](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#example-ex-78f34f)
    - [`ConstructionX3(C1, C2, C3, D1, D2): Code, Code, Code, Code, Code → Code, Map`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-constructionx3-code-code-code-code-code)
    - [`ConstructionX3u(C1, C2, C3, D1, D2): Code, Code, Code, Code, Code → Code, Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-constructionx3u-code-code-code-code-code)
    - [Example: Construction X3](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#example-ex-3a19a8)
    - [`ConstructionXX(C1, C2, C3, D2, D3): Code, Code, Code, Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-constructionxx-code-code-code-code-code)
    - [Example: Construction XX](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#example-ex-db315b)
    - [`ZinovievCode(I, O): [Code], [Code] → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-zinovievcode-code-code)
    - [Example: Zinoviev Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#example-ex-cc2def)
    - [`ConstructionY1(C): Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-constructiony1-code)
    - [`ConstructionY1(C, w): Code, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/operation.md#function-constructiony1-code-rngintelt)
- [Bounds](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md)
  - [Best Known Bounds for Linear Codes](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#best-known-bounds-for-linear-codes)
    - [`BKLCLowerBound(F, n, k): FldFin, RngIntElt, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#function-bklclowerbound-fldfin-rngintelt-rngintelt)
    - [`BKLCUpperBound(F, n, k): FldFin, RngIntElt, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#function-bklcupperbound-fldfin-rngintelt-rngintelt)
    - [`BLLCLowerBound(F, k, d): FldFin, RngIntElt, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#function-bllclowerbound-fldfin-rngintelt-rngintelt)
    - [`BLLCUpperBound(F, k, d): FldFin, RngIntElt, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#function-bllcupperbound-fldfin-rngintelt-rngintelt)
    - [`BDLCLowerBound(F, n, d): FldFin, RngIntElt, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#function-bdlclowerbound-fldfin-rngintelt-rngintelt)
    - [`BDLCUpperBound(F, n, d): FldFin, RngIntElt, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#function-bdlcupperbound-fldfin-rngintelt-rngintelt)
  - [Bounds on the Cardinality of a Largest Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#bounds-on-the-cardinality-of-a-largest-code)
    - [`EliasBound(K, n, d): FldFin, RngIntElt, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#function-eliasbound-fldfin-rngintelt-rngintelt)
    - [`GriesmerBound(K, n, d): FldFin, RngIntElt, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#function-griesmerbound-fldfin-rngintelt-rngintelt)
    - [`JohnsonBound(n, d): RngIntElt, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#function-johnsonbound-rngintelt-rngintelt)
    - [`LevenshteinBound(K, n, d): FldFin, RngIntElt, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#function-levenshteinbound-fldfin-rngintelt-rngintelt)
    - [`PlotkinBound(K, n, d): FldFin, RngIntElt, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#function-plotkinbound-fldfin-rngintelt-rngintelt)
    - [`SingletonBound(K, n, d): FldFin, RngIntElt, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#function-singletonbound-fldfin-rngintelt-rngintelt)
    - [`SpherePackingBound(K, n, d): FldFin, RngIntElt, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#function-spherepackingbound-fldfin-rngintelt-rngintelt)
    - [`GilbertVarshamovBound(K, n, d): FldFin, RngIntElt, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#function-gilbertvarshamovbound-fldfin-rngintelt-rngintelt)
    - [`GilbertVarshamovLinearBound(K, n, d): FldFin, RngIntElt, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#function-gilbertvarshamovlinearbound-fldfin-rngintelt-rngintelt)
    - [`VanLintBound(K, n, d): FldFin, RngIntElt, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#function-vanlintbound-fldfin-rngintelt-rngintelt)
    - [Example: Computed and Stored Cardinality Bounds](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#example-ex-89ddc1)
  - [Bounds on the Minimum Distance](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#bounds-on-the-minimum-distance)
    - [`BCHBound(C): Code → RngIntElt, RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#function-bchbound-code)
    - [`GriesmerMinimumWeightBound(K, n, k): FldFin, RngIntElt, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#function-griesmerminimumweightbound-fldfin-rngintelt-rngintelt)
  - [Asymptotic Bounds on the Information Rate](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#asymptotic-bounds-on-the-information-rate)
    - [`EliasAsymptoticBound(K, delta): FldFin, FldPrElt → FldPrElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#function-eliasasymptoticbound-fldfin-fldprelt)
    - [`McElieceEtAlAsymptoticBound(delta): FldPrElt → FldPrElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#function-mcelieceetalasymptoticbound-fldprelt)
    - [`PlotkinAsymptoticBound(K, delta): FldFin, FldPrElt → FldPrElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#function-plotkinasymptoticbound-fldfin-fldprelt)
    - [`SingletonAsymptoticBound(delta): FldPrElt → FldPrElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#function-singletonasymptoticbound-fldprelt)
    - [`HammingAsymptoticBound(K, delta): FldFin, FldPrElt → FldPrElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#function-hammingasymptoticbound-fldfin-fldprelt)
    - [`GilbertVarshamovAsymptoticBound(K, delta): FldFin, FldPrElt → FldPrElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#function-gilbertvarshamovasymptoticbound-fldfin-fldprelt)
  - [Other Bounds](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#other-bounds)
    - [`GriesmerLengthBound(K, k, d): FldFin, RngIntElt, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#function-griesmerlengthbound-fldfin-rngintelt-rngintelt)
- [Best Known Linear Codes](https://docs.magma-maths.org/CodingTheory/LinearCodes/best-codes.md)
  - [`BKLC(K, n, k): FldFin, RngIntElt, RngIntElt → Code, BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/best-codes.md#function-bklc-fldfin-rngintelt-rngintelt)
  - [`BestKnownLinearCode(K, n, k): FldFin, RngIntElt, RngIntElt → Code, BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/best-codes.md#function-bestknownlinearcode-fldfin-rngintelt-rngintelt)
  - [`BLLC(K, k, d): FldFin, RngIntElt, RngIntElt → Code, BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/best-codes.md#function-bllc-fldfin-rngintelt-rngintelt)
  - [`BestLengthLinearCode(K, k, d): FldFin, RngIntElt, RngIntElt → Code, BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/best-codes.md#function-bestlengthlinearcode-fldfin-rngintelt-rngintelt)
  - [`BDLC(K, n, d): FldFin, RngIntElt, RngIntElt → Code, BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/best-codes.md#function-bdlc-fldfin-rngintelt-rngintelt)
  - [`BestDimensionLinearCode(K, n, d): FldFin, RngIntElt, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/best-codes.md#function-bestdimensionlinearcode-fldfin-rngintelt-rngintelt)
  - [Example: Best Known Binary Codes](https://docs.magma-maths.org/CodingTheory/LinearCodes/best-codes.md#example-ex-49ec3e)
  - [Example: Best Known Quaternary Codes](https://docs.magma-maths.org/CodingTheory/LinearCodes/best-codes.md#example-ex-018bf4)
  - [Example: Best Known Lengths of Binary Codes](https://docs.magma-maths.org/CodingTheory/LinearCodes/best-codes.md#example-ex-508dda)
  - [Example: Best Known Dimensions of Quaternary Codes](https://docs.magma-maths.org/CodingTheory/LinearCodes/best-codes.md#example-ex-2cda79)
  - [Example: Reconstructing a Best Known Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/best-codes.md#example-ex-026c31)
- [Decoding](https://docs.magma-maths.org/CodingTheory/LinearCodes/decoding.md)
  - [Syndrome Decoding](https://docs.magma-maths.org/CodingTheory/LinearCodes/decoding.md#syndrome-decoding)
    - [`SyndromeDecoding(C, v): CodeLinFld, ModTupRngElt → BoolElt, ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/decoding.md#function-syndromedecoding-codelinfld-modtuprngelt)
    - [`SyndromeDecoding(C, Q): CodeLinFld, [ ModTupRngElt ] → [ BoolElt ], [ ModTupRngElt ]`](https://docs.magma-maths.org/CodingTheory/LinearCodes/decoding.md#function-syndromedecoding-codelinfld-modtuprngelt-2)
    - [Example: Syndrome Decoding](https://docs.magma-maths.org/CodingTheory/LinearCodes/decoding.md#example-ex-8f7190)
  - [Euclidean Decoding](https://docs.magma-maths.org/CodingTheory/LinearCodes/decoding.md#euclidean-decoding)
    - [`EuclideanDecoding(C, v): CodeLinFld, ModTupRngElt → BoolElt, ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/decoding.md#function-euclideandecoding-codelinfld-modtuprngelt)
    - [`EuclideanDecoding(C, Q): CodeLinFld, [ ModTupRngElt ] → [ BoolElt ], [ ModTupRngElt ]`](https://docs.magma-maths.org/CodingTheory/LinearCodes/decoding.md#function-euclideandecoding-codelinfld-modtuprngelt-2)
    - [Example: Euclidean Decoding of a Reed-Solomon Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/decoding.md#example-ex-72e926)
  - [Permutation Decoding](https://docs.magma-maths.org/CodingTheory/LinearCodes/decoding.md#permutation-decoding)
    - [`IsPermutationDecodeSet(C, I, S, s): CodeLinFld, [RngIntElt], [AlgMatElt], RngIntElt → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/decoding.md#function-ispermutationdecodeset-codelinfld-rngintelt-algmatelt-rngintelt)
    - [`IsPermutationDecodeSet(C, I, S, s): CodeLinFld, [RngIntElt], [GrpPermElt], RngIntElt → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/decoding.md#function-ispermutationdecodeset-codelinfld-rngintelt-grppermelt-rngintelt)
    - [`PermutationDecode(C, I, S, s, u): CodeLinFld, [RngIntElt], [AlgMatElt], RngIntElt, ModTupFldElt → BoolElt, ModTupFldElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/decoding.md#function-permutationdecode-codelinfld-rngintelt-algmatelt-rngintelt-modtupfldelt)
    - [`PermutationDecode(C, I, S, s, u): CodeLinFld, [RngIntElt], [GrpPermElt], RngIntElt, ModTupFldElt → BoolElt, ModTupFldElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/decoding.md#function-permutationdecode-codelinfld-rngintelt-grppermelt-rngintelt-modtupfldelt)
    - [`PermutationDecode(C, I, S, s, Q): CodeLinFld, [RngIntElt], [AlgMatElt], RngIntElt, [ModTupFldElt] → [BoolElt], [ModTupFldElt]`](https://docs.magma-maths.org/CodingTheory/LinearCodes/decoding.md#function-permutationdecode-codelinfld-rngintelt-algmatelt-rngintelt-modtupfldelt-2)
    - [`PermutationDecode(C, I, S, s, Q): CodeLinFld, [RngIntElt], [GrpPermElt], RngIntElt, [ModTupFldElt] → [BoolElt], [ModTupFldElt]`](https://docs.magma-maths.org/CodingTheory/LinearCodes/decoding.md#function-permutationdecode-codelinfld-rngintelt-grppermelt-rngintelt-modtupfldelt-2)
    - [`PDSetSimplexCode(K, m): FldFin, RngIntElt → SeqEnum, SeqEnum, SeqEnum`](https://docs.magma-maths.org/CodingTheory/LinearCodes/decoding.md#function-pdsetsimplexcode-fldfin-rngintelt)
    - [`PDSetHadamardCode(m): RngIntElt → SeqEnum, SeqEnum, SeqEnum`](https://docs.magma-maths.org/CodingTheory/LinearCodes/decoding.md#function-pdsethadamardcode-rngintelt)
    - [Example: Permutation Decoding of a Binary Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/decoding.md#example-ex-7bde55)
    - [Example: Permutation Decoding of a Quaternary Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/decoding.md#example-ex-982ee0)
- [Transforms](https://docs.magma-maths.org/CodingTheory/LinearCodes/transforms.md)
  - [Mattson–Solomon Transforms](https://docs.magma-maths.org/CodingTheory/LinearCodes/transforms.md#mattson-solomon-transforms)
    - [`MattsonSolomonTransform(f, n): RngUPolElt, RngIntElt → RngUPolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/transforms.md#function-mattsonsolomontransform-rngupolelt-rngintelt)
    - [`InverseMattsonSolomonTransform(A, n): RngUPolElt, RngIntElt → RngUPolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/transforms.md#function-inversemattsonsolomontransform-rngupolelt-rngintelt)
    - [Example: Mattson-Solomon Transform](https://docs.magma-maths.org/CodingTheory/LinearCodes/transforms.md#example-ex-15eadc)
  - [Krawchouk Polynomials](https://docs.magma-maths.org/CodingTheory/LinearCodes/transforms.md#krawchouk-polynomials)
    - [`KrawchoukPolynomial(K, n, k): FldFin, RngIntElt, RngIntElt → RngUPolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/transforms.md#function-krawchoukpolynomial-fldfin-rngintelt-rngintelt)
    - [`KrawchoukTransform(f, K, n): RngUPolElt, FldFin, RngIntElt → RngUPolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/transforms.md#function-krawchouktransform-rngupolelt-fldfin-rngintelt)
    - [`InverseKrawchouk(A, K, n): RngUPolElt, FldFin, RngIntElt → RngUPolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/transforms.md#function-inversekrawchouk-rngupolelt-fldfin-rngintelt)
- [Automorphism Groups](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md)
  - [Introduction](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#introduction)
  - [Group Actions](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#group-actions)
    - [`v ^ x: ModTupFldElt, GrpPermElt → ModTupFldElt`](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#operation-op-pow-modtupfldelt-grppermelt)
    - [`v ^ G: ModTupFldElt, GrpPerm → GSet{ ModTupFldElt }`](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#operation-op-pow-modtupfldelt-grpperm)
    - [`C ^ x: Code, GrpPermElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#operation-op-pow-code-grppermelt)
    - [`C ^ G: Code, GrpPerm → GSet{ Code }`](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#operation-op-pow-code-grpperm)
    - [`S ^ x: [ModTupFldElt], GrpPermElt → [ModTupFldElt]`](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#operation-op-pow-modtupfldelt-grppermelt-2)
    - [`S ^ x: { ModTupFldElt }, GrpPermElt → { ModTupFldElt }`](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#operation-op-pow-modtupfldelt-grppermelt-3)
    - [`S ^ x: [Code], GrpPermElt → [Code]`](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#operation-op-pow-code-grppermelt-2)
    - [`S ^ x: { Code }, GrpPermElt → { Code }`](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#operation-op-pow-code-grppermelt-3)
    - [`Fix(C, G): Code, GrpPerm → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#function-fix-code-grpperm)
  - [Automorphism Group](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#automorphism-group)
    - [`AutomorphismGroup(C: parameters): Code → GrpPerm, PowMap, Map`](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#function-automorphismgroup-code)
    - [`MonomialGroup(C: parameters): Code → GrpPerm, PowMap, Map`](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#function-monomialgroup-code)
    - [`PermutationGroup(C): Code → GrpPerm, PowMap, Map`](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#function-permutationgroup-code)
    - [`AutomorphismSubgroup(C): Code → GrpPerm, PowMap, Map`](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#function-automorphismsubgroup-code)
    - [`MonomialSubgroup(C): Code → GrpPerm, PowMap, Map`](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#function-monomialsubgroup-code)
    - [`AutomorphismGroupStabilizer(C, k): Code, RngIntElt → GrpPerm, PowMap, Map`](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#function-automorphismgroupstabilizer-code-rngintelt)
    - [`MonomialGroupStabilizer(C, k): Code, RngIntElt → GrpPerm, PowMap, Map`](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#function-monomialgroupstabilizer-code-rngintelt)
    - [`Aut(C): Code → Pow, Map`](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#function-aut-code)
    - [`Aut(C, T): Code, MonStgElt → Pow, Map`](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#function-aut-code-monstgelt)
    - [Example: Automorphism Group of a Reed-Muller Code](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#example-ex-d651f4)
    - [Example: Automorphism Group via Minimum Weight Words](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#example-ex-374f40)
  - [Equivalence and Isomorphism of Codes](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#equivalence-and-isomorphism-of-codes)
    - [`IsIsomorphic(C, D: parameters): Code, Code → BoolElt, Map`](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#function-isisomorphic-code-code)
    - [`IsEquivalent(C, D: parameters): Code, Code → BoolElt, Map`](https://docs.magma-maths.org/CodingTheory/LinearCodes/group-action.md#function-isequivalent-code-code)
- [Bibliography](https://docs.magma-maths.org/CodingTheory/LinearCodes/bibliography.md)

### Introduction

Let $K$ be a finite field and let $V$ be the vector space of $n$-tuples over $K$. The *Hamming-distance* between elements $x$ and $y$ of $V$, denoted $d(x, y)$, is defined by

$$
d(x, y) := \#\{\ 1 \leq i \leq n\ |\ x_i \neq y_i\ \}.
$$

The *minimum distance d* for a subset $C$ of $V$ is then

$$
d = \min\{\ d(x, y)\ |\ x \in C, y \in C, x \neq y\ \}.
$$

The subset $C$ of $V$ is called an $(n, M, d)$ *code* if the minimum distance for the subset $C$ is $d$ and $|C| = M$. Then $V$ is referred to as the *ambient space* of $C$.

The code $C$ is called a $[n, k, d]$ *linear code* if $C$ is a $k$-dimensional subspace of $V$. Currently Magma supports not only linear codes, but also codes over finite fields which are only linear over some subfield. These are known as *additive codes* and can be found in Chapter [Additive Codes](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/index-additive-codes.md#chap-codeadd). This chapter deals only with linear codes.

In this chapter, the term “code” will refer to a linear code. Magma provides machinery for studying linear codes over finite fields $F_q=GF(q)$, over the integer residue classes ${\mathbb{Z}}_m = {\mathbb{Z}}/m{\mathbb{Z}}$, and over galois rings $GR(p^n,k)$.

This chapter describes those functions which are applicable to codes over $F_q$. The highlights of the facilities provided for such codes include:

- The construction of codes in terms of generator matrices, parity check matrices, and generating polynomials (cyclic codes).
- A large number of constructions for particular families of codes, e.g., quadratic residue codes.
- Highly optimized algorithms for the calculation of the minimum weight.
- Various forms of weight enumerator including the MacWilliams transform.
- A database that gives the user access to best known linear codes $GF(q)$ for $q=2,3,4,5,7,8,9$.
- Machinery that allows the user to construct algebraic-geometric codes from a curve defined over $F_q$.
- The computation of automorphism groups for codes over small fields.

The reader is referred to [[MS78](https://docs.magma-maths.org/references.md#cite-sloane)] as a general reference on coding theory.

### Construction of Codes

#### Construction of General Linear Codes

<a id="constructor-constructor-linearcode-fldfin-rngintelt-list-code"></a>
##### `LinearCode<R, n | L>: FldFin, RngIntElt, List -> Code`

Create a code as a subspace of $V = R^{(n)}$ which is generated by the elements specified by the list $L$, where $L$ is a list of one or more items of the following types:

**(a)**
An element of $V$.

**(b)**
A set or sequence of elements of $V$.

**(c)**
A sequence of $n$ elements of $K$, defining an element of $V$.

**(d)**
A set or sequence of sequences of type (c).

**(e)**
A subspace of $V$.

**(f)**
A set or sequence of subspaces of $V$.

<a id="example-ex-4d7dd8"></a>
##### `Example: Ternary Golay Code (ex-4d7dd8)`

We define the ternary Golay code as a six-dimensional subspace of the vector space $K^{(11)}$, where $K$ is ${\bf F}_{3}$. The ternary Golay code could be defined in a single statement as follows:

```magma
> K := FiniteField(3);
> C := LinearCode<K, 11 |
>    [1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1], [0, 1, 0, 0, 0, 0, 0, 1, 2, 2, 1],
>    [0, 0, 1, 0, 0, 0, 1, 0, 1, 2, 2], [0, 0, 0, 1, 0, 0, 2, 1, 0, 1, 2],
>    [0, 0, 0, 0, 1, 0, 2, 2, 1, 0, 1], [0, 0, 0, 0, 0, 1, 1, 2, 2, 1, 0]>;
```

Alternatively, if we want to see the code as a subspace of $K^{(11)}$, we would proceed as follows:

```magma
> K := FiniteField(3);
> K11 := VectorSpace(K, 11);
> C := LinearCode(sub<K11 |
>    [1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1], [0, 1, 0, 0, 0, 0, 0, 1, 2, 2, 1],
>    [0, 0, 1, 0, 0, 0, 1, 0, 1, 2, 2], [0, 0, 0, 1, 0, 0, 2, 1, 0, 1, 2],
>    [0, 0, 0, 0, 1, 0, 2, 2, 1, 0, 1], [0, 0, 0, 0, 0, 1, 1, 2, 2, 1, 0]>);
```

<a id="function-linearcode-modtuprng"></a>
##### `LinearCode(U): ModTupRng -> Code`

Let $V$ be the $R$-space $R^{(n)}$ and suppose that $U$ is a subspace of $V$. The effect of this function is to define the linear code $C$ corresponding to the subspace $U$. Suppose the code $C$ being constructed has dimension $k$. The evaluation of this constructor results in the creation of the following objects:

**(a)**
The generator matrix $G$ for $C$, created as a $k\ \times\ n$ matrix belonging to the $R$-matrix space, $R^{(k\ \times\ n)}$.

**(b)**
The parity check matrix $H$ for $C$, created as an $(n-k)\ \times\ n$ matrix belonging to the $R$-matrix space, $R^{(n-k)\ \times\ n)}$.

<a id="function-linearcode-modmatrngelt"></a>
##### `LinearCode(A): ModMatRngElt -> Code`

Given a $k\ \times\ n$ matrix $A$ over the ring $R$, construct the linear code generated by the rows of $A$. Note that it is not assumed that the rank of $A$ is $k$. The effect of this constructor is otherwise identical to that described above.

<a id="example-ex-854c75"></a>
##### `Example: Code from a Matrix (ex-854c75)`

We define a code by constructing a matrix in a $K$-matrix space and using its row space to generate the code:

```magma
> M := KMatrixSpace(FiniteField(5), 2, 4);
> G := M ! [1,1,1,2, 3,2,1,4];
> G;
[1 1 1 2]
[3 2 1 4]
> C := LinearCode(G);
> C;
[4, 2, 2] Linear Code over GF(5)
Generator matrix:
[1 0 4 0]
[0 1 2 2]
```

<a id="function-permutationcode-modtuprngelt-grpperm"></a>
##### `PermutationCode(u, G): ModTupRngElt, GrpPerm -> Code`

Given a finite permutation group $G$ of degree $n$, and a vector $u$ belonging to the $n$-dimensional vector space $V$ over the ring $R$, construct the code $C$ corresponding to the subspace of $V$ spanned by the set of vectors obtained by applying the permutations of $G$ to the vector $u$.

<a id="example-ex-db1b6e"></a>
##### `Example: Code from a Permutation Group (ex-db1b6e)`

We define $G$ to be a permutation group of degree 7 and construct the code $C$ as the $F_2$-code generated by applying the permutations of $G$ to a certain vector:

```magma
> G := PSL(3, 2);
> G;
Permutation group G of degree 7
    (1, 4)(6, 7)
    (1, 3, 2)(4, 7, 5)
> V := VectorSpace(GF(2), 7);
> u := V ! [1, 0, 0, 1, 0, 1, 1];
> C := PermutationCode(u, G);
> C;
[7, 3, 4] 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]
```

#### Some Trivial Linear Codes

<a id="function-zerocode-fldfin-rngintelt"></a>
##### `ZeroCode(R, n): FldFin, RngIntElt -> Code`

Given a ring $R$ and positive integer $n$, return the $[n,0,n]$ code consisting of only the zero code word, (where the minimum weight is by convention equal to $n$).

<a id="function-repetitioncode-fldfin-rngintelt"></a>
##### `RepetitionCode(R, n): FldFin, RngIntElt -> Code`

Given a ring $R$ and positive integer $n$, return the $[n,1,n]$ code over $K$ generated by the all-ones vector.

<a id="function-zerosumcode-fldfin-rngintelt"></a>
##### `ZeroSumCode(R, n): FldFin, RngIntElt -> Code`

Given a ring $R$ and positive integer $n$, return the $[n,n-1,2]$ code over $R$ such that for all codewords $(c_1,c_2,\ldots ,c_n)$ we have $\sum_{i} c_i =0$.

<a id="function-universecode-fldfin-rngintelt"></a>
##### `UniverseCode(R, n): FldFin, RngIntElt -> Code`

Given a ring $R$ and positive integer $n$, return the $[n,n,1]$ code consisting of all possible codewords.

<a id="function-evenweightcode-rngintelt"></a>
##### `EvenWeightCode(n): RngIntElt -> Code`

Given a positive integer $n$, return the $[n,n-1,2]$ code over ${\bf F}_{2}$ such that all vectors have even weight. This is equivalent to the zero sum code over ${\bf F}_{2}$.

<a id="function-evenweightsubcode-code"></a>
##### `EvenWeightSubcode(C): Code -> Code`

Given a linear code $C$ over ${\bf F}_{2}$, return the subcode of $C$ containing the vectors of even weight.

<a id="function-randomlinearcode-fldfin-rngintelt-rngintelt"></a>
##### `RandomLinearCode(K, n, k): FldFin, RngIntElt, RngIntElt -> Code`

Given a finite field $K$ and positive integers $n$ and $k$, such that $0 < k \le n$, the function returns a random linear code of length $n$ and dimension $k$ over the field $K$. The method employed is to successively choose random vectors from $K^{(n)}$ until generators for a $k$-dimensional subspace have been found.

<a id="function-cordarowagnercode-rngintelt"></a>
##### `CordaroWagnerCode(n): RngIntElt -> Code`

Construct the Cordaro–Wagner code of length $n$, This is the $2$-dimensional repetition code over ${\bf F}_{2}$ of length $n$ and having the largest possible minimum weight.

<a id="example-ex-552322"></a>
##### `Example: Chain of Trivial Linear Codes (ex-552322)`

Over any specific finite field $K$, the zero code of length $n$ is contained in every code of length $n$, and similarly every code of length $n$ is contained in the universe code of length $n$. This is illustrated over $GF(2)$ for length $6$ codes with an arbitrary code of length $6$ dimension $3$.

```magma
> K := GF(2);
> U := UniverseCode(K, 6);
> U;
[6, 6, 1] Linear Code over GF(2)
> Z := ZeroCode(K, 6);
> Z;
[6, 0, 6] Linear Code over GF(2)
> R := RandomLinearCode(K, 6, 3);
> (Z subset R) and (R subset U);
true
```

#### Some Basic Families of Codes

In this section we describe how to construct three very important families of codes: cyclic codes, Hamming codes, and Reed-Muller codes. We choose to present these very important families at this stage since they are easily understood and they give us a nice collection of codes for use in examples.

Many more constructions will be described in subsequent sections. In particular, variations and generalizations of the cyclic code construction presented here will be given.

<a id="function-cycliccode-rngintelt-rngupolelt"></a>
##### `CyclicCode(n, g): RngIntElt, RngUPolElt -> Code`

Let $K$ be a finite field. Given a positive integer $n$ and a univariate polynomial $g(x) \in K[x]$ of degree $n-k$ such that $g(x) \mid x^n - 1$, construct the $[n, k]$ cyclic code generated by $g(x)$.

<a id="example-ex-667d8b"></a>
##### `Example: Golay Code as a Cyclic Code (ex-667d8b)`

We construct the length $23$ Golay code over $GF(2)$ as a cyclic code by factorizing the polynomial $x^{23} - 1$ over $GF(2)$ and constructing the cyclic code generated by one of the factors of degree $11$.

```magma
> P<x> := PolynomialRing(FiniteField(2));
> F := Factorization(x^23 - 1);
> F;
[
    <x + 1, 1>,
    <x^11 + x^9 + x^7 + x^6 + x^5 + x + 1, 1>,
    <x^11 + x^10 + x^6 + x^5 + x^4 + x^2 + 1, 1>
]
> CyclicCode(23, F[2][1]);
[23, 12, 7] Cyclic Code over GF(2)
Generator matrix:
[1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 1 0 1 0]
[0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 1 0 1]
[0 0 1 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 0 1 0 0]
[0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 0 1 0]
[0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 0 1]
[0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 1 1 0 0 1 1 0 0]
[0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 1 1 0 0 1 1 0]
[0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 1 1 0 0 1 1]
[0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 1 1 1 0 0 0 1 1]
[0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 1 0 0 1 0 1 1]
[0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 1 1 1 1 1]
[0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 1 0 1 0 1]
```

<a id="function-hammingcode-fldfin-rngintelt"></a>
##### `HammingCode(K, r): FldFin, RngIntElt -> Code`

Given a positive integer $r$, and a finite field $K$ of cardinality $q$, construct the $r$-th order Hamming code over $K$ of cardinality $q$. This code has length

$$
n = (q^r - 1)/(q - 1).
$$

<a id="example-ex-496ba8"></a>
##### `Example: Hamming Code (ex-496ba8)`

We construct the third order Hamming code over GF(2) together with its parity check matrix.

```magma
> H := HammingCode(FiniteField(2), 3);
> H;
[7, 4, 3] Hamming code (r = 3) over GF(2)
Generator matrix:
[1 0 0 0 0 1 1]
[0 1 0 0 1 1 0]
[0 0 1 0 1 0 1]
[0 0 0 1 1 1 1]
> ParityCheckMatrix(H);
[1 0 1 0 1 1 0]
[0 1 1 0 0 1 1]
[0 0 0 1 1 1 1]
```

<a id="function-simplexcode-rngintelt"></a>
##### `SimplexCode(r): RngIntElt -> Code`

Given a positive integer $r$, construct the $[2^r-1,r,2^{r-1}]$ binary simplex code, which is the dual of a Hamming code.

<a id="function-reedmullercode-rngintelt-rngintelt"></a>
##### `ReedMullerCode(r, m): RngIntElt, RngIntElt -> Code`

Given positive integers $r$ and $m$, where $0 \leq r \leq m$, construct the $r$-th order binary Reed–Muller code of length $n = 2^m$.

<a id="example-ex-86fc03"></a>
##### `Example: Reed-Muller Code (ex-86fc03)`

We construct the first order Reed–Muller code of length 16 and count the number of pairs of vectors whose components are orthogonal.

```magma
> R := ReedMullerCode(1, 4);
> R;
[16, 5, 8] Reed-Muller Code (r = 1, m = 4) over GF(2)
Generator matrix:
[1 0 0 1 0 1 1 0 0 1 1 0 1 0 0 1]
[0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1]
[0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1]
[0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1]
[0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1]
> #{<v, w>: v, w in R | IsZero(InnerProduct(v, w))};
1024
```

### Invariants of a Code

#### Basic Numerical Invariants

<a id="function-length-code"></a>
##### `Length(C): Code -> RngIntElt`

Given an $[n, k]$ code $C$, return the block length $n$ of $C$.

<a id="function-dimension-code"></a>
##### `Dimension(C): Code -> RngIntElt`

<a id="function-numberofgenerators-code"></a>
##### `NumberOfGenerators(C): Code -> RngIntElt`

The dimension $k$ of the $[n, k]$ linear code $C$.

<a id="operation-operation-code-rngintelt"></a>
##### `# C: Code -> RngIntElt`

Given a code $C$, return the number of codewords belonging to $C$.

<a id="function-informationrate-code"></a>
##### `InformationRate(C): Code -> FldPrElt`

The information rate of the $[n, k]$ code $C$. This is the ratio $k/n$.

#### The Ambient Space and Alphabet

<a id="function-ambientspace-code"></a>
##### `AmbientSpace(C): Code -> ModTupRng`

The ambient space of the code $C$, i.e. the generic $R$-space $V$ in which $C$ is contained.

<a id="function-rspace-code"></a>
##### `RSpace(C): Code -> ModTupRng`

<a id="function-vectorspace-code"></a>
##### `VectorSpace(C): Code -> ModTupFld`

Given an $[n, k]$ linear code $C$, defined as a subspace $U$ of the $n$-dimensional space $V$, return $U$ as a subspace of $V$ with basis corresponding to the rows of the generator matrix for $C$.

<a id="function-generic-code"></a>
##### `Generic(C): Code -> Code`

Given an $[n, k]$ code $C$, return the generic $[n, n, 1]$ code in which $C$ is contained.

<a id="function-alphabet-code"></a>
##### `Alphabet(C): Code -> Rng`

<a id="function-field-code"></a>
##### `Field(C): Code -> Rng`

The underlying ring (or alphabet) $R$ of the code $C$.

#### The Code Space

<a id="function-generatormatrix-code"></a>
##### `GeneratorMatrix(C): Code -> ModMatFldElt`

<a id="function-basismatrix-code"></a>
##### `BasisMatrix(C): Code -> ModMatRngElt`

The generator matrix for the linear code $C$, returned as an element of ${\operatorname{Hom}}(U, V)$ where $U$ is the information space of $C$ and $V$ is the ambient space of $C$.

<a id="function-basis-code"></a>
##### `Basis(C): Code -> [ ModTupRngElt ]`

The current vector space basis for the linear code $C$, returned as a sequence of elements of $C$.

<a id="function-generators-code"></a>
##### `Generators(C): Code -> { ModTupFldElt }`

The current vector space basis for the linear code $C$, returned as a set of elements of $C$.

<a id="operation-operation-code-rngintelt-modtupfldelt"></a>
##### `C . i: Code, RngIntElt -> ModTupFldElt`

Given an $[n, k]$ code $C$ and a positive integer $i$, $1 \le i \le k$, return the $i$-th element of the current basis of $C$.

#### The Dual Space

<a id="function-dual-code"></a>
##### `Dual(C): Code -> Code`

The code that is dual to the code $C$.

<a id="function-paritycheckmatrix-code"></a>
##### `ParityCheckMatrix(C): Code -> ModMatFldElt`

The parity check matrix for the code $C$, returned as an element of ${\operatorname{Hom}}(V, U)$.

<a id="example-ex-7ec540"></a>
##### `Example: Generator and Parity Check Matrices (ex-7ec540)`

We create a Reed–Muller code and demonstrate some simple relations.

```magma
> R := ReedMullerCode(1, 3);
> R;
[8, 4, 4] Reed-Muller Code (r = 1, m = 3) over GF(2)
Generator matrix:
[1 0 0 1 0 1 1 0]
[0 1 0 1 0 1 0 1]
[0 0 1 1 0 0 1 1]
[0 0 0 0 1 1 1 1]
> G := GeneratorMatrix(R);
> P := ParityCheckMatrix(R);
> P;
[1 0 0 1 0 1 1 0]
[0 1 0 1 0 1 0 1]
[0 0 1 1 0 0 1 1]
[0 0 0 0 1 1 1 1]
> G * Transpose(P);
[0 0 0 0]
[0 0 0 0]
[0 0 0 0]
[0 0 0 0]
> D := LinearCode(P);
> Dual(R) eq D;
true
```

<a id="function-hull-code"></a>
##### `Hull(C): Code -> Code`

The Hull of a code is the intersection between itself and its dual.

#### The Information Space and Information Sets

<a id="function-informationspace-code"></a>
##### `InformationSpace(C): Code -> ModTupFld`

Given an $[n, k]$ linear code $C$, return the $k$-dimensional $R$-space $U$ which is the space of information vectors for the code $C$.

<a id="function-informationset-code"></a>
##### `InformationSet(C): Code -> [ RngIntElt ]`

Given an $[n, k]$ linear code $C$ over a finite field, return the current information set for $C$. The information set for $C$ is an ordered set of $k$ linearly independent columns of the generator matrix, such that the generator matrix is the identity matrix when restricted to these columns. The information set is returned as a sequence of $k$ integers, giving the numbers of the columns that correspond to the information set.

<a id="function-allinformationsets-code"></a>
##### `AllInformationSets(C): Code -> [ [ RngIntElt ] ]`

Given an $[n, k]$ linear code $C$ over a finite field, return all the possible information sets of $C$ as a (sorted) sequence of sequences of column indices. Each inner sequence contains a maximal set of indices of linearly independent columns in the generator matrix of $C$.

<a id="function-standardform-code"></a>
##### `StandardForm(C): Code -> Code, Map`

Given an $[n, k]$ linear code $C$ over a finite field, return the standard form $D$ of $C$. A code is in *standard form* if the first $k$ components of the code words correspond to the information set. Magma returns one of the many codes in standard form which is isomorphic to $C$. (The same code is returned each time.) Thus, the effect of this function is to return a code $D$ whose generators come from the generator matrix of $C$ with its columns permuted, so that the submatrix consisting of the first $k$ columns of the generator matrix for $D$ is the identity matrix. Two values are returned: The standard form code $D$;

**(b)**
An isomorphism from $C$ to $D$.

<a id="example-ex-8132b6"></a>
##### `Example: Standard Form of a Code (ex-8132b6)`

We construct a Reed–Muller code $C$ and its standard form $S$ and then map a codeword of $C$ into $S$.

```magma
> C := ReedMullerCode(1, 4);
> C;
[16, 5, 8] Reed-Muller Code (r = 1, m = 4) over GF(2)
Generator matrix:
[1 0 0 1 0 1 1 0 0 1 1 0 1 0 0 1]
[0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1]
[0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1]
[0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1]
[0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1]
> InformationSet(C);
[ 1, 2, 3, 5, 9 ]
> #AllInformationSets(C);
2688
> S, f := StandardForm(C);
> S;
[16, 5, 8] Linear Code over GF(2)
Generator matrix:
[1 0 0 0 0 1 1 1 0 1 1 0 1 0 0 1]
[0 1 0 0 0 1 1 0 1 1 0 1 0 1 0 1]
[0 0 1 0 0 1 0 1 1 0 1 1 0 0 1 1]
[0 0 0 1 0 0 1 1 1 0 0 0 1 1 1 1]
[0 0 0 0 1 0 0 0 0 1 1 1 1 1 1 1]
> u := C.1;
> u;
(1 0 0 1 0 1 1 0 0 1 1 0 1 0 0 1)
> f(u);
(1 0 0 0 0 1 1 1 0 1 1 0 1 0 0 1)
```

#### The Syndrome Space

<a id="function-syndromespace-code"></a>
##### `SyndromeSpace(C): Code -> ModTupFld`

Given an $[n, k]$ linear code $C$, return the $(n-k)$-dimensional vector space $W$, which is the space of syndrome vectors for the code $C$.

#### The Generator Polynomial

The operations in this section are restricted to cyclic codes.

<a id="function-generatorpolynomial-code"></a>
##### `GeneratorPolynomial(C): Code -> RngUPolElt`

Given a cyclic code $C$ over a finite field, return the generator polynomial of $C$. The generator polynomial of $C$ is a divisor of $x^n - 1$, where $n$ is the length of $C$.

<a id="function-checkpolynomial-code"></a>
##### `CheckPolynomial(C): Code -> RngUPolElt`

Given a cyclic code $C$ over a finite field, return the check polynomial of $C$ as an element of $K[x]$. If $g(x)$ is the generator polynomial of $C$ and $h(x)$ is the check polynomial of $C$, then $g(x)h(x) = 0$ (mod $x^n - 1$), where $n$ is the length of $C$.

<a id="function-idempotent-code"></a>
##### `Idempotent(C): Code -> RngUPolElt`

Given a cyclic code $C$, return the (polynomial) idempotent of $C$. If $c(x)$ is the idempotent of $C$, then $c(x)^{2} = c(x)$ (mod $x^n - 1$), where $n$ is the length of $C$.

<a id="example-ex-889cde"></a>
##### `Example: Generator and Check Polynomials (ex-889cde)`

We find the generator and check polynomials for the third order Hamming code over GF(2).

```magma
> K<w> := GF(2);
> P<x> := PolynomialRing(K);
> H := HammingCode(K, 3);
> g := GeneratorPolynomial(H);
> g;
x^3 + x + 1
> h := CheckPolynomial(H);
> h;
x^4 + x^2 + x + 1
> g*h mod (x^7 - 1);
0
> forall{ c : c in H | h * P!Eltseq(c) mod (x^7-1) eq 0 };
true
> e := Idempotent(H);
> e;
x^4 + x^2 + x
> e^2;
x^8 + x^4 + x^2
```

### Operations on Codewords

#### Construction of a Codeword

<a id="operation-op-code-rngelt"></a>
##### `C ! [a₁, ..., aₙ]: Code, [ RngElt ] -> ModTupRngElt`

<a id="constructor-constructor-elt-code-list-modtuprngelt"></a>
##### `elt< C | a₁, ..., aₙ>: Code, List -> ModTupRngElt`

Given a code $C$ which is defined as a subset of the $R$-space $R^{(n)}$, and elements $a_1, \ldots, a_n$ belonging to $R$, construct the codeword $(a_1, \ldots, a_n)$ of $C$. It is checked that the vector ($a_1, \ldots, a_n$) is an element of $C$.

<a id="operation-op-code-modtuprngelt"></a>
##### `C ! u: Code, ModTupRngElt -> ModTupRngElt`

Given a code $C$ which is defined as a subset of the $R$-space $V = R^{(n)}$, and an element $u$ belonging to $V$, create the codeword of $C$ corresponding to $u$. The function will fail if $u$ does not belong to $C$.

<a id="operation-op-code-rngintelt"></a>
##### `C ! 0: Code, RngIntElt -> ModTupRngElt`

The zero word of the code $C$.

<a id="function-random-code"></a>
##### `Random(C): Code -> ModTupRngElt`

A random codeword of $C$.

#### Arithmetic Operations on Codewords

<a id="operation-op-plus-modtuprngelt-modtuprngelt"></a>
##### `u + v: ModTupRngElt, ModTupRngElt -> ModTupRngElt`

Sum of the codewords $u$ and $v$, where $u$ and $v$ belong to the same linear code $C$.

<a id="operation-operation-modtuprngelt-modtuprngelt"></a>
##### `- u: ModTupRngElt -> ModTupRngElt`

Additive inverse of the codeword $u$ belonging to the linear code $C$.

<a id="operation-op-minus-modtuprngelt-modtuprngelt"></a>
##### `u - v: ModTupRngElt, ModTupRngElt -> ModTupRngElt`

Difference of the codewords $u$ and $v$, where $u$ and $v$ belong to the same linear code $C$.

<a id="operation-op-times-rngelt-modtuprngelt"></a>
##### `a * u: RngElt, ModTupRngElt -> ModTupRngElt`

Given an element $a$ belonging to the field $K$, and a codeword $u$ belonging to the linear code $C$, return the codeword $a*u$.

<a id="function-normalize-modtuprngelt"></a>
##### `Normalize(u): ModTupRngElt -> ModTupRngElt`

Given an element $u$ over a field, not the zero element, belonging to the linear code $C$, return ${1\over a}*u$, where $a$ is the first non-zero component of $u$. If $u$ is the zero vector, it is returned as the value of this function. The net effect is that `Normalize(u)` always returns a vector $v$ in the subspace generated by $u$, such that the first non-zero component of $v$ is the unit of $K$.

<a id="function-syndrome-modtupfldelt-code"></a>
##### `Syndrome(w, C): ModTupFldElt, Code -> ModTupFldElt`

Given an $[n, k]$ linear code $C$ over a finite field with parent vector space $V$, and a vector $w$ belonging to $V$, construct the syndrome of $w$ relative to the code $C$. This will be an element of the *syndrome space* of $C$.

#### Distance and Weight

<a id="function-distance-modtuprngelt-modtuprngelt"></a>
##### `Distance(u, v): ModTupRngElt, ModTupRngElt -> RngIntElt`

The Hamming distance between the codewords $u$ and $v$, where $u$ and $v$ belong to the same code $C$.

<a id="function-weight-modtuprngelt"></a>
##### `Weight(u): ModTupRngElt -> RngIntElt`

The Hamming weight of the codeword $u$, i.e., the number of non-zero components of $u$.

<a id="function-leeweight-modtuprngelt"></a>
##### `LeeWeight(u): ModTupRngElt -> RngIntElt`

The Lee weight of the codeword $u$.

<a id="example-ex-75e920"></a>
##### `Example: Distances in the Ternary Golay Code (ex-75e920)`

We calculate all possible distances between code words of the non-extended Golay code over GF(3), and show the correspondence with all possible code word weights.

```magma
> C := GolayCode(GF(3),false);
> {Distance(v,w):v,w in C};
{ 0, 5, 6, 8, 9, 11 }
> {Weight(v):v in C};
{ 0, 5, 6, 8, 9, 11 }
```

#### Vector Space and Related Operations

<a id="literal-literal-u-v-modtuprngelt-modtuprngelt-rngelt"></a>
##### `(u, v): ModTupRngElt, ModTupRngElt -> RngElt`

<a id="function-innerproduct-modtuprngelt-modtuprngelt"></a>
##### `InnerProduct(u, v): ModTupRngElt, ModTupRngElt -> RngElt`

Inner product of the vectors $u$ and $v$ with respect to the Euclidean norm, where $u$ and $v$ belong to the parent vector space of the code $C$.

<a id="function-support-modtuprngelt"></a>
##### `Support(w): ModTupRngElt -> { RngIntElt }`

Given a word $w$ belonging to the $[n, k]$ code $C$, return its support as a subset of the integer set $\{ 1 .. n \}$. The support of $w$ consists of the coordinates at which $w$ has non-zero entries.

<a id="function-coordinates-code-modtuprngelt"></a>
##### `Coordinates(C, u): Code, ModTupRngElt -> [ RngFinElt ]`

Given an $[n, k]$ linear code $C$ and a codeword $u$ of $C$ return the coordinates of $u$ with respect to $C$. The coordinates of $u$ are returned as a sequence $Q = [a_1, \ldots, a_k]$ of elements from the alphabet of $C$ so that $u = a_1 * C.1 + \ldots + a_k * C.k$.

<a id="function-parent-modtuprngelt"></a>
##### `Parent(w): ModTupRngElt -> ModTupRng`

Given a word $w$ belonging to the code $C$, return the ambient space $V$ of $C$.

<a id="function-rotate-modtuprngelt-rngintelt"></a>
##### `Rotate(u, k): ModTupRngElt, RngIntElt -> ModTupRngElt`

Given a vector $u$, return the vector obtained from $u$ by cyclically shifting its components to the right by $k$ coordinate positions.

<a id="procedure-rotate-modtuprngelt-rngintelt-ref"></a>
##### `Rotate(~u, k): ModTupRngElt, RngIntElt`

Given a vector $u$, destructively rotate $u$ by $k$ coordinate positions.

<a id="function-trace-modtupfldelt-fldfin"></a>
##### `Trace(u, S): ModTupFldElt, FldFin -> ModTupFldElt`

<a id="function-trace-modtupfldelt"></a>
##### `Trace(u): ModTupFldElt -> ModTupFldElt`

Given a vector $u$ with components in $K$, and a subfield $S$ of $K$, construct the vector with components in $S$ obtained from $u$ by taking the trace of each component with respect to $S$. If $S$ is omitted, it is taken to be the prime field of $K$.

<a id="example-ex-fb5172"></a>
##### `Example: Coordinates of a Code Word (ex-fb5172)`

We create a specific code word in the length $5$ even weight code, after a failed attempt to create a code word of odd weight. We then display its support, find its coordinates with respect to the basis and then confirm it by way of re-construction.

```magma
> C := EvenWeightCode(5);
> C![1,1,0,1,0];

>> C![1,1,0,1,0];
    ^
Runtime error in '!': Result is not in the given structure
> c := C![1,1,0,1,1];
> c;
(1 1 0 1 1)
> Support(c);
{ 1, 2, 4, 5 }
> Coordinates(C,c);
[ 1, 1, 0, 1 ]
> C.1 + C.2 + C.4;
(1 1 0 1 1)
```

#### Predicates for Codewords

<a id="operation-op-eq-modtuprngelt-modtuprngelt"></a>
##### `u eq v: ModTupRngElt, ModTupRngElt -> BoolElt`

The function returns `true` if and only if the codewords $u$ and $v$ are equal.

<a id="operation-op-ne-modtuprngelt-modtuprngelt"></a>
##### `u ne v: ModTupRngElt, ModTupRngElt -> BoolElt`

The function returns `true` if and only if the codewords $u$ and $v$ are not equal.

<a id="function-iszero-modtuprngelt"></a>
##### `IsZero(u): ModTupRngElt -> BoolElt`

The function returns `true` if and only if the codeword $u$ is the zero vector.

#### Accessing Components of a Codeword

<a id="literal-literal-u-i-modtuprngelt-rngintelt-rngelt"></a>
##### `u[i]: ModTupRngElt, RngIntElt -> RngElt`

Given a codeword $u$ belonging to the code $C$ defined over the ring $R$, return the $i$-th component of $u$ (as an element of $R$).

<a id="literal-literal-u-i-x"></a>
##### `u[i] := x;`

Given an element $u$ belonging to a subcode $C$ of the full $R$-space $V = R^n$, a positive integer $i$, $1 \leq i\leq n$, and an element $x$ of $R$, this function returns a vector in $V$ which is $u$ with its $i$-th component redefined to be $x$.

### Coset Leaders

<a id="function-cosetleaders-code"></a>
#### `CosetLeaders(C): Code -> {@ ModTupFldElt @}, Map`

Given a code $C$ with ambient space $V$ over a finite field, return a set of coset leaders (vectors of minimal weight in their cosets) for $C$ in $V$ as an indexed set of vectors from $V$. Note that this function is only applicable when $V$ and $C$ are small. This function also returns a map from the syndrome space of $C$ into the coset leaders (mapping a syndrome into its corresponding coset leader).

<a id="example-ex-6ef726"></a>
#### `Example: Decoding with Coset Leaders (ex-6ef726)`

We construct a Hamming code $C$, encode an information word using $C$, introduce one error, and then decode by calculating the syndrome of the “received” vector and applying the CosetLeaders map to the syndrome to recover the original vector.

First we set $C$ to be the third order Hamming Code over the finite field with two elements.

```magma
> C := HammingCode(GF(2), 3);
> C;
[7, 4, 3] Hamming code (r = 3) over GF(2)
Generator matrix:
[1 0 0 0 0 1 1]
[0 1 0 0 1 0 1]
[0 0 1 0 1 1 0]
[0 0 0 1 1 1 1]
```

Then we set $L$ to be the set of coset leaders of $C$ in its ambient space $V$ and $f$ to be the map which maps the syndrome of a vector in $V$ to its coset leader in $L$.

```magma
> L, f := CosetLeaders(C);
> L;
{@
    (0 0 0 0 0 0 0),
    (1 0 0 0 0 0 0),
    (0 1 0 0 0 0 0),
    (0 0 1 0 0 0 0),
    (0 0 0 1 0 0 0),
    (0 0 0 0 1 0 0),
    (0 0 0 0 0 1 0),
    (0 0 0 0 0 0 1)
@}
```

Since $C$ has dimension 4, the degree of the information space $I$ of $C$ is 4. We set $i$ to be an “information vector” of length 4 in $I$, and then encode $i$ using $C$ by setting $w$ to be the product of $i$ by the generator matrix of $C$.

```magma
> I := InformationSpace(C);
> I;
Full Vector space of degree 4 over GF(2)
> i := I ! [1, 0, 1, 1];
> w := i * GeneratorMatrix(C);
> w;
(1 0 1 1 0 1 0)
```

Now we set $r$ to be the same as $w$ but with an error in the $7$-th coordinate (so $r$ is the “received vector”).

```magma
> r := w;
> r[7] := 1;
> r;
(1 0 1 1 0 1 1)
```

Finally we let $s$ be the syndrome of $r$ with respect to $C$, apply $f$ to $s$ to get the coset leader $l$, and subtract $l$ from $r$ to get the corrected vector $v$. Finding the coordinates of $v$ with respect to the basis of $C$ (the rows of the generator matrix of $C$) gives the original information vector.

```magma
> s := Syndrome(r, C);
> s;
(1 1 1)
> l := f(s);
> l;
(0 0 0 0 0 0 1)
> v := r - l;
> v;
(1 0 1 1 0 1 0)
> res := I ! Coordinates(C, v);
> res;
(1 0 1 1)
```

### Subcodes

#### The Subcode Constructor

<a id="constructor-constructor-sub-code-list-code"></a>
##### `sub<C | L>: Code, List -> Code`

Given an $[n, k]$ linear code $C$ over $R$, construct the subcode of $C$, generated by the elements specified by the list $L$, where $L$ is a list of one or more items of the following types:

**(a)**
An element of $C$;

**(b)**
A set or sequence of elements of $C$;

**(c)**
A sequence of $n$ elements of $R$, defining an element of $C$;

**(d)**
A set or sequence of sequences of type (c);

**(e)**
A subcode of $C$;

<a id="function-subcode-code-rngintelt"></a>
##### `Subcode(C, k): Code, RngIntElt -> Code`

Given an $[n, k]$ linear code $C$ and an integer $t$, $1 \le t < n$, return a subcode of $C$ of dimension $t$.

<a id="function-subcode-code-rngintelt-2"></a>
##### `Subcode(C, S): Code, { RngIntElt } -> Code`

Given an $[n, k]$ linear code $C$ and a set $S$ of integers, each of which lies in the range $[1,k]$, return the subcode of $C$ generated by the basis elements whose positions appear in $S$.

<a id="function-subcodebetweencode-code-code-rngintelt"></a>
##### `SubcodeBetweenCode(C1, C2, k): Code, Code, RngIntElt -> Code`

Given a linear code $C_1$ and a subcode $C_2$ of $C_1$, return a subcode of $C_1$ of dimension $k$ containing $C_2$.

<a id="function-subcodewordsofweight-code-rngintelt"></a>
##### `SubcodeWordsOfWeight(C, S): Code, { RngIntElt } -> Code`

Given an $[n, k]$ linear code $C$ and a set $S$ of integers, each of which lies in the range $[1,n]$, return the subcode of $C$ generated by those words of $C$ whose weights lie in $S$.

<a id="example-ex-db10dc"></a>
##### `Example: Subcode between Two Codes (ex-db10dc)`

We give an example of how `SubcodeBetweenCode` may be used to create a code nested in between a subcode pair.

```magma
> C1 := RepetitionCode(GF(2),6);
> C1;
[6, 1, 6] Cyclic Code over GF(2)
Generator matrix:
[1 1 1 1 1 1]
> C3 := EvenWeightCode(6);
> C3;
[6, 5, 2] Linear Code over GF(2)
Generator matrix:
[1 0 0 0 0 1]
[0 1 0 0 0 1]
[0 0 1 0 0 1]
[0 0 0 1 0 1]
[0 0 0 0 1 1]
> C1 subset C3;
true
> C2 := SubcodeBetweenCode(C3, C1, 4);
> C2;
[6, 4, 2] Linear Code over GF(2)
Generator matrix:
[1 0 0 0 1 0]
[0 1 0 0 0 1]
[0 0 1 0 0 1]
[0 0 0 1 0 1]
> (C1 subset C2) and (C2 subset C3);
true
```

#### Sum, Intersection, Duals, and Hulls

For the following operators, $C$ and $D$ are codes defined as subsets (or subspaces) of the same $R$-space $V$.

<a id="operation-op-plus-code-code"></a>
##### `C + D: Code, Code -> Code`

The (vector space) sum of the linear codes $C$ and $D$, where $C$ and $D$ are contained in the same $K$-space $V$.

<a id="operation-op-meet-code-code"></a>
##### `C meet D: Code, Code -> Code`

The intersection of the linear codes $C$ and $D$, where $C$ and $D$ are contained in the same $K$-space $V$.

<a id="function-dual-code-2"></a>
##### `Dual(C): Code -> Code`

The dual $D$ of the linear code $C$. The dual consists of all codewords in the $K$-space $V$ which are orthogonal to all codewords of $C$.

<a id="example-ex-377d6d"></a>
##### `Example: Sums and Intersections of Subcodes (ex-377d6d)`

Verify some simple results from the sum and intersection of subcodes with known basis.

```magma
> C := EvenWeightCode(5);
> C;
[5, 4, 2] Linear Code over GF(2)
Generator matrix:
[1 0 0 0 1]
[0 1 0 0 1]
[0 0 1 0 1]
[0 0 0 1 1]
> C1 := sub< C | C.1 >;
> C2 := sub< C | C.4 >;
> C3 := sub< C | { C.1 , C.4} >;
> (C1 + C2) eq C3;
true
> (C1 meet C3) eq C1;
true
```

<a id="example-ex-cfd60d"></a>
##### `Example: Dual of a Reed-Solomon Code (ex-cfd60d)`

Verify the orthogonality of codewords in the dual for a `ReedSolomonCode`.

```magma
> K<w> := GF(8);
> R := ReedSolomonCode(K, 3);
> R;
[7, 5, 3] BCH code (d = 3, b = 1) over GF(2^3)
Generator matrix:
[  1   0   0   0   0 w^3 w^4]
[  0   1   0   0   0   1   1]
[  0   0   1   0   0 w^3 w^5]
[  0   0   0   1   0   w w^5]
[  0   0   0   0   1   w w^4]
> D := Dual(R);
> D;
[7, 2, 6] Cyclic Code over GF(2^3)
Generator matrix:
[  1   0 w^3   1 w^3   w   w]
[  0   1 w^4   1 w^5 w^5 w^4]
> {<u,v> : u in R, v in D | InnerProduct(u,v) ne 0};
{}
```

<a id="function-hermitiandual-codelinfld"></a>
##### `HermitianDual(C): CodeLinFld -> CodeLinFld`

The Hermitian dual $D$ of the linear code $C$. The Hermitian dual consists of all codewords in the $K$-space $V$ which are orthogonal to all codewords of $C$ with respect to the Hermitian inner product for quadratic extensions.

<a id="function-hull-codelinfld"></a>
##### `Hull(C): CodeLinFld -> CodeLinFld`

The (Euclidean) hull of the linear code $C$ is the intersection of the code with its dual.

<a id="function-hermitianhull-codelinfld"></a>
##### `HermitianHull(C): CodeLinFld -> CodeLinFld`

The Hermitian hull of the linear code $C$ is the intersection of the code with its Hermitian dual.

#### Membership and Equality

For the following operators, $C$ and $D$ are codes defined as a subset (or subspace) of the $R$-space $V$.

<a id="operation-op-in-modtuprngelt-code"></a>
##### `u in C: ModTupRngElt, Code -> BoolElt`

Return `true` if and only if the vector $u$ of $V$ belongs to the code $C$.

<a id="operation-op-notin-modtuprngelt-code"></a>
##### `u notin C: ModTupRngElt, Code -> BoolElt`

Return `true` if and only if the vector $u$ of $V$ does not belong to the code $C$.

<a id="operation-op-subset-code-code"></a>
##### `C subset D: Code, Code -> BoolElt`

Return `true` if and only if the code $C$ is a subcode of the code $D$.

<a id="operation-operation-notsubset-code-code-boolelt"></a>
##### `C notsubset D: Code, Code -> BoolElt`

Return `true` if and only if the code $C$ is not a subcode of the code $D$.

<a id="operation-op-eq-code-code"></a>
##### `C eq D: Code, Code -> BoolElt`

Return `true` if and only if the codes $C$ and $D$ are equal.

<a id="operation-op-ne-code-code"></a>
##### `C ne D: Code, Code -> BoolElt`

Return `true` if and only if the codes $C$ and $D$ are not equal.

### Properties of Codes

For the following operators, $C$ and $D$ are codes defined as a subset (or subspace) of the vector space $V$.

<a id="function-iscyclic-code"></a>
#### `IsCyclic(C): Code -> BoolElt`

Return `true` if and only if the linear code $C$ is a cyclic code.

<a id="function-isselfdual-code"></a>
#### `IsSelfDual(C): Code -> BoolElt`

Return `true` if and only if the linear code $C$ is self-dual. (i.e. $C$ equals the dual of $C$).

<a id="function-isselforthogonal-code"></a>
#### `IsSelfOrthogonal(C): Code -> BoolElt`

Return `true` if and only if the linear code $C$ is self-orthogonal (i.e., $C$ is contained in the dual of $C$).

<a id="function-ishermitianselfdual-codelinfld"></a>
#### `IsHermitianSelfDual(C): CodeLinFld -> BoolElt`

Return `true` if and only if the linear code $C$ equals the Hermitian dual of $C$.

<a id="function-ishermitianselforthogonal-codelinfld"></a>
#### `IsHermitianSelfOrthogonal(C): CodeLinFld -> BoolElt`

Return `true` if and only if the linear code $C$ is contained in the Hermitian dual of $C$.

<a id="function-ismaximumdistanceseparable-code"></a>
#### `IsMaximumDistanceSeparable(C): Code -> BoolElt`

<a id="function-ismds-code"></a>
#### `IsMDS(C): Code -> BoolElt`

Returns `true` if and only if the linear code $C$ is maximum-distance separable; that is, has parameters $[n, k, n - k + 1]$.

<a id="function-isequidistant-code"></a>
#### `IsEquidistant(C): Code -> BoolElt`

Returns `true` if and only if the linear code $C$ is equidistant.

<a id="function-isperfect-code"></a>
#### `IsPerfect(C): Code -> BoolElt`

Returns `true` if and only if the linear code $C$ is perfect; that is, if and only if the cardinality of $C$ is equal to the size of the sphere packing bound of $C$.

<a id="function-isnearlyperfect-code"></a>
#### `IsNearlyPerfect(C): Code -> BoolElt`

Returns `true` if and only if the binary linear code $C$ is nearly perfect.

<a id="function-iseven-code"></a>
#### `IsEven(C): Code -> BoolElt`

Returns `true` if and only if $C$ is an even linear binary code, (i.e., all codewords have even weight). If `true`, then Magma will adjust the upper and lower minimum weight bounds of $C$ if possible.

<a id="function-isdoublyeven-code"></a>
#### `IsDoublyEven(C): Code -> BoolElt`

Returns `true` if and only if $C$ is a doubly even linear binary code, (i.e., all codewords have weight divisible by $4$). If `true`, then Magma will adjust the upper and lower minimum weight bounds of $C$ if possible.

<a id="function-isprojective-code"></a>
#### `IsProjective(C): Code -> BoolElt`

Returns `true` if and only if the (non-quantum) code $C$ is projective.

<a id="example-ex-a18e45"></a>
#### `Example: Self-Dual Code (ex-a18e45)`

We look at an extended quadratic residue code over $GF(2)$ which is self-dual, and then confirm it manually.

```magma
> C := ExtendCode( QRCode(GF(2),23) );
> C:Minimal;
[24, 12, 8] Linear Code over GF(2)
> IsSelfDual(C);
true
> D := Dual(C);
> D: Minimal;
[24, 12, 8] Linear Code over GF(2)
> C eq D;
true
```

<a id="example-ex-f19a8e"></a>
#### `Example: Self-Orthogonal Code (ex-f19a8e)`

We look at the `CordaroWagnerCode` of length $6$, which is self-orthogonal, and then confirm it manually.

```magma
> C := CordaroWagnerCode(6);
> C;
[6, 2, 4] Linear Code over GF(2)
Generator matrix:
[1 1 0 0 1 1]
[0 0 1 1 1 1]
> IsSelfOrthogonal(C);
true
> D := Dual(C);
> D;
[6, 4, 2] Linear Code over GF(2)
Generator matrix:
[1 0 0 1 0 1]
[0 1 0 1 0 1]
[0 0 1 1 0 0]
[0 0 0 0 1 1]
> C subset D;
true
```

### The Weight Distribution

<a id="minimum-weight"></a>
<a id="code-lin-minweight"></a>
#### The Minimum Weight

In the case of a linear code, the minimum weight and distance are equivalent. It is clear that is substantially easier to determine the minimum weight of a (possibly non-linear) code than its minimum distance. The general principle underlying the minimum weight algorithm in Magma is the embedding of low-weight information vectors into the code space, in the hope that they will map onto low weight codewords.

Let $C$ be a $[n,k]$ linear code over a finite field and $G$ be its generator matrix. The minimum weight algorithm proceeds as follows: Starting with $r = 1$, all linear combinations of $r$ rows of $G$ are enumerated. By taking the minimum weight of each such combination, an upper bound, $d_{upper}$, on the minimum weight of $C$ is obtained. A strictly increasing function, $d_{lower}(r)$, finds a lower bound on the minimum weight of the non-enumerated vectors for each computational step (the precise form of this function depends upon the algorithm being used). The algorithm terminates when $d_{lower}(r) \ge d_{upper}$, at which point the actual minimum weight is equal to $d_{upper}$.

The algorithm is used for non-cyclic codes, and is due to A.E. Brouwer and K.H. Zimmermann [[BFK+98](https://docs.magma-maths.org/references.md#cite-zimm1)]. The key idea is to construct as many different generator matrices for the same code as possible, each having a different information set and such that the information sets are as disjoint as possible. By maximizing the number of information sets, $d_{lower}(r)$ can be made increasingly accurate. Each information set will provide a different embedding of information vectors into the code, and thus the probability of a low-weight information vector mapping onto a low-weight codeword is increased.

A well known improvement attributed to Brouwer exists for cyclic codes, requiring the enumeration fo only one information set. A generalisation of this improvement has been made by G. White to quasicyclic codes, and any codes whose known automorphisms have large cycles. Functionality is included in this section for inputting partial knowledge of the automorphism group to take advantage of this improvement.

Information sets are discarded if their ranks are too low to contribute to the lower bound calculation. The user may also specify a lower bound, `RankLowerBound`, on the rank of information sets initially created.

<a id="function-codefld-minimumweight"></a>
##### `MinimumWeight(C: parameters): Code -> RngIntElt`

<a id="function-minimumdistance-code"></a>
##### `MinimumDistance(C: parameters): Code -> RngIntElt`

```magma
Method        : MonStgElt                      Default: "Auto"
RankLowerBound: RngIntElt                      Default: 0
MaximumTime   : RngReSubElt                    Default: Infinity()
Nthreads      : RngIntElt                      Default: 1
```

Determine the minimum weight of the words belonging to the code $C$, which is also the minimum distance between any two codewords. The parameter `RankLowerBound` sets a minimum rank on the information sets used in the calculation, while the parameter `MaximumTime` sets a time limit (in seconds of “user time”) after which the calculation is aborted.

If the parameter `Nthreads` is set to a positive integer $n$, then $n$ threads will be used in the computation, if POSIX threads are enabled. One can alternatively use the procedure [`SetNthreads`](https://docs.magma-maths.org/MagmaLanguage/Parallelism/kernel-distributed-parallelism.md#procedure-par-setnthreads) to set the global number of threads to a value $n$ so that $n$ threads are always used by default in this algorithm unless overridden by the `Nthreads` parameter.

Sometimes a brute force calculation of the entire weight distribution can be a faster way to get the minimum weight for small codes. When the parameter `Method` is set to the default `"Auto"` then the method is internally chosen. The user can specify which method they want using setting it to either `"Distribution"` or `"Zimmermann"`.

By setting the verbose flag `"Code"`, information about the progress of the computation can be printed. An example to demonstrate the interpretation of the verbose output follows:

```magma
> SetVerbose("Code", true);
> SetSeed(1);
> MinimumWeight(RandomLinearCode(GF(2),85,26));
Linear Code over GF(2) of length 85 with 26 generators. Is not cyclic
Lower Bound: 1, Upper Bound: 60
Constructed 4 distinct generator matrices
Relative Ranks:  26  26  26   7
Starting search for low weight codewords...
Enumerating using 1 generator at a time:
     New codeword identified of weight 32, time 0.000
     New codeword identified of weight 28, time 0.000
     New codeword identified of weight 27, time 0.000
     New codeword identified of weight 25, time 0.000
     Discarding non-contributing rank 7 matrix
     New Relative Ranks:  26  26  26
   Completed Matrix  1:  lower =  4, upper = 25. Time so far: 0.000
     New codeword identified of weight 23, time 0.000
   Completed Matrix  2:  lower =  5, upper = 23. Time so far: 0.000
   Completed Matrix  3:  lower =  6, upper = 23. Time so far: 0.000
Enumerating using 2 generators at a time:
     New codeword identified of weight 20, time 0.000
   Completed Matrix  1:  lower =  7, upper = 20. Time so far: 0.000
   Completed Matrix  2:  lower =  8, upper = 20. Time so far: 0.000
   Completed Matrix  3:  lower =  9, upper = 20. Time so far: 0.000
Enumerating using 3 generators at a time:
     New codeword identified of weight 19, time 0.000
   Completed Matrix  1:  lower = 10, upper = 19. Time so far: 0.000
   Completed Matrix  2:  lower = 11, upper = 19. Time so far: 0.000
   Completed Matrix  3:  lower = 12, upper = 19. Time so far: 0.000
Enumerating using 4 generators at a time:
     New codeword identified of weight 18, time 0.000
   Completed Matrix  1:  lower = 13, upper = 18. Time so far: 0.000
     New codeword identified of weight 17, time 0.000
   Completed Matrix  2:  lower = 14, upper = 17. Time so far: 0.010
   Completed Matrix  3:  lower = 15, upper = 17. Time so far: 0.010
Termination predicted with 5 generators at matrix 2
Enumerating using 5 generators at a time:
   Completed Matrix  1:  lower = 16, upper = 17. Time so far: 0.020
   Completed Matrix  2:  lower = 17, upper = 17. Time so far: 0.030
Final Results: lower = 17, upper = 17, Total time: 0.030
17
```

Verbose output can be invaluable on long minimum weight calculations.

The algorithm constructs different (equivalent) generator matrices, each of which have pivots in different column positions of the code, called its *information set*. A generator matrix’s *relative rank* is the size of its information set independent from the previously constructed matrices.

The algorithm proceeds by enumerating all combinations derived from $r$ generators, for each successive $r$. Once $r$ exceeds the difference between the actual rank of a matrix (i.e., the dimension), and its relative rank, then the lower bound on the minimum weight will increment by $1$ for that step.

The upper bound on the minimum weight is determined by the minimum weight of codewords that are enumerated. Once these bounds meet the computation is complete.

<a id="function-minimumweightbounds-code"></a>
##### `MinimumWeightBounds(C): Code -> RngIntElt, RngIntElt`

Return the currently known lower and upper bounds on the minimum weight of code $C$.

<a id="procedure-resetminimumweightbounds-code"></a>
##### `ResetMinimumWeightBounds(C): Code`

Undefine the minimum weight of the code $C$ if it is known, and reset any known bounds on its value.

<a id="function-verifyminimumdistancelowerbound-code-rngintelt"></a>
##### `VerifyMinimumDistanceLowerBound(C, d): Code, RngIntElt -> BoolElt, RngIntElt, BoolElt`

```magma
RankLowerBound: RngIntElt                    Default: 0
MaximumTime   : RngIntElt                    Default: Infinity()
```

The minimum weight algorithm is executed until it determines whether or not $d$ is a lower bound for the minimum weight of the code $C$. (See the description of the function `MinimumWeight` for information on the parameters `RankLowerBound` and `MaximumTime` and on the verbose output). Three values are returned. The first of these is a boolean value, taking the value `true` if and only if $d$ is verified to be a lower bound for the minimum weight of $C$, (`false` if the calculation is aborted due to time restrictions). The second return value is the best available lower bound for the minimum weight of $C$, and the third is a boolean which is `true` if this value is the actual minimum weight of $C$.

<a id="function-verifyminimumdistanceupperbound-code-rngintelt"></a>
##### `VerifyMinimumDistanceUpperBound(C, d): Code, RngIntElt -> BoolElt, RngIntElt, BoolElt`

<a id="function-verifyminimumweightupperbound-code-rngintelt"></a>
##### `VerifyMinimumWeightUpperBound(C, d: parameters): Code, RngIntElt -> BoolElt, RngIntElt, BoolElt`

```magma
RankLowerBound: RngIntElt                    Default: 0
MaximumTime   : RngIntElt                    Default: Infinity()
```

The minimum weight algorithm is executed until it determines whether or not $d$ is an upper bound for the minimum weight of the code $C$. (See the description of the function `MinimumWeight` for information on the parameters `RankLowerBound` and `MaximumTime` and on the verbose output). Three values are returned. The first of these is a boolean value, taking the value `true` if and only if $d$ is verified to be an upper bound for the minimum weight of $C$, (`false` if the calculation is aborted due to time restrictions). The second return value is the best available upper bound for the minimum weight of $C$, and the third is a boolean which is `true` if this value is the actual minimum weight of $C$.

<a id="function-minimumword-code"></a>
##### `MinimumWord(C): Code -> ModTupFldElt`

Return one word of the code $C$ having minimum weight.

<a id="function-minimumwords-code"></a>
##### `MinimumWords(C): Code -> { ModTupFldElt }`

```magma
NumWords      : RngIntElt                      Default: 
Method        : MonStgElt                      Default: "Auto"
RankLowerBound: RngIntElt                      Default: Infinity()
MaximumTime   : RngReSubElt                    Default: Infinity()
```

Given a linear code $C$, return the set of all words of $C$ having minimum weight. If `NumWords` is set to a non-negative integer, then the algorithm will terminate after that total of words have been found. Similarly, if `MaximumTime` then the algorithm will abort if the specified time limit expires.

A variation of the Zimmermann minimum weight algorithm is generally used to collect the minimum words, although in some cases (such as small codes) a brute force enumeration may be used. When the parameter `Method` is set to the default `"Auto"` then the method is internally chosen. The user can specify which method they want using setting it to either `"Distribution"` or `"Zimmermann"`.

By setting the verbose flag `"Code"`, information about the progress of the computation can be printed.

<a id="example-ex-1d8077"></a>
##### `Example: Verifying a Minimum Weight Lower Bound (ex-1d8077)`

The function `BKLC(K, n, k)` returns the best known linear $[n, k]$-code over the field $K$. We use this function to construct the $[77,34,16]$ best known linear code and confirm a lower bound on its minimum weight (which is not as good as its actual minimum weight). We check to see whether the minimum weight of this code is at least $11$ and in doing so we will actually get a slightly better bound, though it will be still less than the true minimum weight. Since the function `BLKC` will set the true minimum weight, it is first necessary to reset the bounds so that the minimum weight data is lost.

```magma
> a := BKLC(GF(2),77,34);
> a:Minimal;
[77, 34, 16] Linear Code over GF(2)
> ResetMinimumWeightBounds(a);
> MinimumWeightBounds(a);
1 44
> a:Minimal;
[77, 34] Linear Code over GF(2)
> SetVerbose("Code",true);
> IsLB, d_lower, IsMinWeight := VerifyMinimumWeightLowerBound(a, 11);
Linear Code over GF(2) of length 77 with 34 generators. Is not cyclic
Lower Bound: 1, Upper Bound: 44
Using congruence d mod 4 = 0
Constructed 3 distinct generator matrices
Relative Ranks:  34  34   6
Starting search for low weight codewords...
     Discarding non-contributing rank 6 matrix
Enumerating using 1 generator at a time:
     New codeword identified of weight 20, time 0.000
     New codeword identified of weight 16, time 0.000
   Completed Matrix  1:  lower =  4, upper = 16. Time so far: 0.000
   Completed Matrix  2:  lower =  4, upper = 16. Time so far: 0.000
Enumerating using 2 generators at a time:
   Completed Matrix  1:  lower =  8, upper = 16. Time so far: 0.000
   Completed Matrix  2:  lower =  8, upper = 16. Time so far: 0.000
Enumerating using 3 generators at a time:
   Completed Matrix  1:  lower =  8, upper = 16. Time so far: 0.000
   Completed Matrix  2:  lower =  8, upper = 16. Time so far: 0.000
Enumerating using 4 generators at a time:
   Completed Matrix  1:  lower = 12, upper = 16. Time so far: 0.010
Final Results: lower = 12, upper = 16, Total time: 0.010
> IsLB;
true
> d_lower, IsMinWeight;
12 false
```

<a id="procedure-includeautomorphism-code-grppermelt-ref"></a>
##### `IncludeAutomorphism(~C, p): Code, GrpPermElt`

<a id="procedure-includeautomorphism-code-grpperm-ref"></a>
##### `IncludeAutomorphism(~C, G): Code, GrpPerm`

Given some automorphism $p$ or group of automorphisms $G$ of the code $C$, which can either be a permutation of the columns or a full monomial permutation of the code. Then include these automorphism in the known automorphisms subgroup. Automorphisms with long cycles that can aid the minimum weight calculation should be added in this way.

<a id="function-knownautomorphismsubgroup-code"></a>
##### `KnownAutomorphismSubgroup(C): Code -> GrpPerm`

Return the maximally known subgroup of the full group of automorphisms of the code $C$.

<a id="id2"></a>
#### The Weight Distribution

<a id="function-weightdistribution-code"></a>
##### `WeightDistribution(C): Code -> [ <RngIntElt, RngIntElt> ]`

```magma
Nthreads: RngIntElt                    Default: 1
```

Determine the weight distribution for the code $C$. The distribution is returned in the form of a sequence of tuples, where the $i$-th tuple contains the $i$-th weight, $w_i$ say, and the number of codewords having weight $w_i$.

If the parameter `Nthreads` is set to a positive integer $n$, then $n$ threads will be used in the computation, if POSIX threads are enabled. One can alternatively use the procedure [`SetNthreads`](https://docs.magma-maths.org/MagmaLanguage/Parallelism/kernel-distributed-parallelism.md#procedure-par-setnthreads) to set the global number of threads to a value $n$ so that $n$ threads are always used by default in this algorithm unless overridden by the `Nthreads` parameter.

<a id="function-weightdistribution-code-modtupfldelt"></a>
##### `WeightDistribution(C, u): Code, ModTupFldElt -> [ <RngIntElt, RngIntElt> ]`

Determine the weight distribution of the coset $C + u$ of the linear code $C$. The distribution is returned in the form of a sequence of tuples, where the $i$-th tuple contains the $i$-th weight, $w_i$ say, and the number of codewords having weight $w_i$.

<a id="function-dualweightdistribution-code"></a>
##### `DualWeightDistribution(C): Code -> [ <RngIntElt, RngIntElt> ]`

The weight distribution of the dual code of $C$ (see `WeightDistribution`).

<a id="example-ex-004d0f"></a>
##### `Example: Weight Distribution of a Reed-Muller Code (ex-004d0f)`

We construct the second order Reed–Muller code of length 64, and calculate the its weight distribution and that of its dual code.

```magma
> R := ReedMullerCode(2, 6);
> #R;
4194304
> WeightDistribution(R);
[ <0, 1>, <16, 2604>, <24, 291648>, <28, 888832>, <32, 1828134>, <36, 888832>,
<40, 291648>, <48, 2604>, <64, 1> ]
> D := Dual(R);
> #D;
4398046511104
> time WeightDistribution(D);
[ <0, 1>, <8, 11160>, <12, 1749888>, <14, 22855680>, <16, 232081500>, <18,
1717223424>, <20, 9366150528>, <22, 38269550592>, <24, 119637587496>, <26,
286573658112>, <28, 533982211840>, <30, 771854598144>, <32, 874731154374>,
<34, 771854598144>, <36, 533982211840>, <38, 286573658112>, <40,
119637587496>, <42, 38269550592>, <44, 9366150528>, <46, 1717223424>,
<48, 232081500>, <50, 22855680>, <52, 1749888>, <56, 11160>, <64, 1> ]
```

<a id="function-partialweightdistribution-code-rngintelt"></a>
##### `PartialWeightDistribution(C, ub): Code, RngIntElt -> [ <RngIntElt, RngIntElt> ]`

Return the weight distribution of the code $C$ up to the specified upper bound. This function uses the minimum weight collection to collect word sets.

#### The Weight Enumerator

<a id="function-weightenumerator-code"></a>
##### `WeightEnumerator(C): Code -> RngMPolElt`

The (Hamming) weight enumerator $W_C(x, y)$ for the linear code $C$. The weight enumerator is defined by

$$
W_C(x, y) = \sum_{u \in C}{x^{n-wt(u)}y^{wt(u)}}.
$$

<a id="function-weightenumerator-code-modtupfldelt"></a>
##### `WeightEnumerator(C, u): Code, ModTupFldElt -> RngMPolElt`

The (Hamming) weight enumerator $W_{C+u}(x, y)$ for the coset $C + u$.

<a id="function-completeweightenumerator-code"></a>
##### `CompleteWeightEnumerator(C): Code -> RngMPolElt`

The complete weight enumerator ${\cal W}_C(z_0, \ldots, z_{q-1})$ for the linear code $C$ where $q$ is the size of the alphabet $K$ of $C$. Let the $q$ elements of $K$ be denoted by $\omega_0, \ldots, \omega_{q-1}$. If $K$ is a prime field, we let $\omega_i$ be $i$ (i.e. take the natural representation of each number). If $K$ is a non-prime field, we let $\omega_0$ be the zero element of $K$ and let $\omega_i$ be $\alpha^{i-1}$ for $i = 1 \ldots q - 1$ where $\alpha$ is the primitive element of $K$. Now for a codeword $u$ of $C$, let $s_i(u)$ be the number of components of $u$ equal to $\omega_i$. The complete weight enumerator is defined by

$$
{\cal W}_C(z_0, \ldots, z_{q-1}) =
   \sum_{u \in C}{{z_0}^{s_0(u)}\ldots{z_{q-1}}^{s_{q-1}(u)}}.
$$

<a id="function-completeweightenumerator-code-modtupfldelt"></a>
##### `CompleteWeightEnumerator(C, u): Code, ModTupFldElt -> RngMPolElt`

The complete weight enumerator ${\cal W}_{C+u}(z_0, \ldots, z_{q-1})$ for the coset $C+u$.

<a id="example-ex-012900"></a>
##### `Example: Weight Enumerators of a Ternary Cyclic Code (ex-012900)`

We construct the cyclic ternary code of length $11$ with generator polynomial $t^5 + t^4 + 2t^3 + t^2 + 2$ and calculate both its weight enumerator and its complete weight enumerator. To ensure the polynomials print out nicely, we assign names to the polynomial ring indeterminates in each case. These names will persist if further calls to `WeightEnumerator` and `CompleteWeightEnumerator` over the same alphabet are made.

```magma
> R<t> := PolynomialRing(GF(3));
> C := CyclicCode(11, t^5 + t^4 + 2*t^3 + t^2 + 2);
> W<x, y> := WeightEnumerator(C);
> W;
x^11 + 132*x^6*y^5 + 132*x^5*y^6 + 330*x^3*y^8 + 110*x^2*y^9 + 24*y^11
> CW<u, v, w> := CompleteWeightEnumerator(C);
> CW;
u^11 + 11*u^6*v^5 + 55*u^6*v^3*w^2 + 55*u^6*v^2*w^3 + 11*u^6*w^5 +
      11*u^5*v^6 + 110*u^5*v^3*w^3 + 11*u^5*w^6 + 55*u^3*v^6*w^2 +
      110*u^3*v^5*w^3 + 110*u^3*v^3*w^5 + 55*u^3*v^2*w^6 + 55*u^2*v^6*w^3 +
      55*u^2*v^3*w^6 + v^11 + 11*v^6*w^5 + 11*v^5*w^6 + w^11
```

The vector $u = (0,0,0,0,0,0,0,0,0,0,1)$ does not lie in the code $C$ and can be taken as a coset leader. We determine the weight enumerator of the coset containing $u$.

```magma
> u := AmbientSpace(C)![0,0,0,0,0,0,0,0,0,0,1];
> Wu := WeightEnumerator(C, u);
> Wu;
x^10*y + 30*x^7*y^4 + 66*x^6*y^5 + 108*x^5*y^6 + 180*x^4*y^7 + 165*x^3*y^8 +
    135*x^2*y^9 + 32*x*y^10 + 12*y^11
```

#### The MacWilliams Transform

<a id="function-macwilliamstransform-rngintelt-rngintelt-rngintelt-rngintelt-rngintelt"></a>
##### `MacWilliamsTransform(n, k, q, W): RngIntElt, RngIntElt, RngIntElt, [ <RngIntElt, RngIntElt> ] -> [ <RngIntElt, RngIntElt> ]`

Let $C$ be a hypothetical $[n, k]$ linear code over a finite field of cardinality $q$. Let $W$ be the weight distribution of $C$ (in the form as returned by the function `WeightDistribution`). This function applies the MacWilliams transform to $W$ to obtain the weight distribution $W'$ of the dual code of $C$. The transform is a combinatorial algorithm based on $n$, $k$, $q$, and $W$ alone. Thus $C$ itself need not exist—the function simply works with the sequence of integer pairs supplied by the user. Furthermore, if $W$ is not the weight distribution of an actual code, the result $W'$ will be meaningless and even negative weights may be returned.

<a id="function-macwilliamstransform-rngintelt-rngintelt-fldfin-rngmpol"></a>
##### `MacWilliamsTransform(n, k, K, W): RngIntElt, RngIntElt, FldFin, RngMPol -> RngMPol`

Let $C$ be a hypothetical $[n, k]$ linear code over a finite field $K$. Let $W$ be the complete weight enumerator of $C$ (in the form as returned by the function `CompleteWeightEnumerator`). This function applies the MacWilliams transform to $W$ to obtain the complete weight enumerator $W'$ of the dual code of $C$. The transform is a combinatorial algorithm based on $K$, $n$, $k$, and $W$ alone. Thus $C$ itself need not exist—the function simply manipulates the given polynomial. Furthermore, if $W$ is not the weight distribution of an actual code, the weight enumerator $W'$ will be meaningless.

<a id="example-ex-09add6"></a>
##### `Example: MacWilliams Transform (ex-09add6)`

Let us suppose there exists a $[31, 11]$ code $C$ over $F_2$ that has complete weight enumerator

$$
u^{31} + 186u^{20}v^{11} + 310u^{19}v^{12} + 527u^{16}v^{15} + 527u^{15}v^{16} +
       310u^{12}v^{19} + 186u^{11}v^{20} + v^{31}
$$

We compute the weight distribution and the complete weight enumerator of the dual of the hypothetical code $C$.

```magma
> W := [ <0, 1>, <11, 186>, <12, 310>, <15, 527>, <16, 527>,
>        <19, 310>, <20, 186>, <31, 1> ];
>  MacWilliamsTransform(31, 11, 2, W);
[ <0, 1>, <6, 806>, <8, 7905>, <10, 41602>, <12, 142600>, <14,
251100>, <16, 301971>, <18, 195300>, <20, 85560>, <22, 18910>, <24,
2635>, <26, 186> ]
> R<u, v> := PolynomialRing(Integers(), 2);
> CWE := u^31 + 186*u^20*v^11 + 310*u^19*v^12 + 527*u^16*v^15 + 527*u^15*v^16 +
>          310*u^12*v^19 + 186*u^11*v^20 + v^31;
> MacWilliamsTransform(31, 11, GF(2), CWE);
u^31 + 806*u^25*v^6 + 7905*u^23*v^8 + 41602*u^21*v^10 + 142600*u^19*v^12 +
      251100*u^17*v^14 + 301971*u^15*v^16 + 195300*u^13*v^18 + 85560*u^11*v^20 +
      18910*u^9*v^22 + 2635*u^7*v^24 + 186*u^5*v^26
```

#### Words

The functions in this section only apply to codes over finite fields.

<a id="function-words-code-rngintelt"></a>
##### `Words(C, w: parameters): Code, RngIntElt -> { ModTupFldElt }`

```magma
NumWords      : RngIntElt                      Default: 
Method        : MonStgElt                      Default: "Auto"
RankLowerBound: RngIntElt                      Default: Infinity()
MaximumTime   : RngReSubElt                    Default: Infinity()
```

Given a linear code $C$, return the set of all words of $C$ having weight $w$. If `NumWords` is set to a non-negative integer $c$, then the algorithm will terminate after that total of words have been found. Similarly, if `MaximumTime` then the algorithm will abort if the specified time limit expires.

There are two methods for collecting words, one based on the Zimmermann minimum weight algorithm, and a brute force type calculation. When the parameter `Method` is set to the default `"Auto"` then the method is internally chosen. The user can specify which method they want using setting it to either `"Distribution"` or `"Zimmermann"`.

By setting the verbose flag `"Code"`, information about the progress of the computation can be printed.

<a id="function-numberofwords-code-rngintelt"></a>
##### `NumberOfWords(C, w): Code, RngIntElt -> RngIntElt`

Given a linear code $C$, return the number of words of $C$ having weight $w$.

<a id="function-wordsofboundedweight-code-rngintelt-rngintelt"></a>
##### `WordsOfBoundedWeight(C, l, u: parameters): Code, RngIntElt, RngIntElt -> { ModTupFldElt }`

```magma
Cutoff    : RngIntElt                    Default: Infinity()
StoreWords: BoolElt                      Default: true
```

Given a linear code $C$, return the set of all words of $C$ having weight between $l$ and $u$, inclusive. If `Cutoff` is set to a non-negative integer $c$, then the algorithm will terminate after a total of $c$ words have been found.

If `StoreWords` is true then any words of a *single weight* generated will be stored internally.

<a id="function-constantwords-code-rngintelt"></a>
##### `ConstantWords(C, i): Code, RngIntElt -> { ModTupFldElt }`

Given a linear code $C$, return the set of all words of $C$ which have weight $i$ and which consist of zeros and ones alone.

<a id="function-numberofconstantwords-code-rngintelt"></a>
##### `NumberOfConstantWords(C, i): Code, RngIntElt -> RngIntElt`

Given a linear code $C$, return the number of words of $C$ which have weight $i$ and which consist of zeros and ones alone.

<a id="example-ex-22cd32"></a>
##### `Example: Words of a Given Weight (ex-22cd32)`

We construct the words of weight 11 and also the constant (zero-one) words of weight 11 in the length 23 cyclic code over ${\bf F}_{3}$ that is defined by the generator polynomial $x^{11} + x^{10} + x^9 + 2x^8 + 2x^7 + x^5 + x^3 + 2$.

```magma
> R<x> := PolynomialRing(GF(3));
> f := x^11 + x^10 + x^9 + 2*x^8 + 2*x^7 + x^5 + x^3 + 2;
> C := CyclicCode(23, f);
> C;
[23, 12, 8] BCH code (d = 5, b = 1) over GF(3)
Generator matrix:
[1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 1 0 1 0 2 2 1 1]
[0 1 0 0 0 0 0 0 0 0 0 0 1 2 0 2 1 2 1 1 0 1 0]
[0 0 1 0 0 0 0 0 0 0 0 0 0 1 2 0 2 1 2 1 1 0 1]
[0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 1 0 1 1 0 2 0 2]
[0 0 0 0 1 0 0 0 0 0 0 0 2 1 0 2 1 1 1 0 2 0 1]
[0 0 0 0 0 1 0 0 0 0 0 0 1 2 1 2 2 0 1 2 1 1 2]
[0 0 0 0 0 0 1 0 0 0 0 0 2 1 2 2 2 0 0 0 1 2 2]
[0 0 0 0 0 0 0 1 0 0 0 0 2 2 1 0 2 0 0 2 2 2 0]
[0 0 0 0 0 0 0 0 1 0 0 0 0 2 2 1 0 2 0 0 2 2 2]
[0 0 0 0 0 0 0 0 0 1 0 0 2 0 2 0 1 1 2 2 2 0 0]
[0 0 0 0 0 0 0 0 0 0 1 0 0 2 0 2 0 1 1 2 2 2 0]
[0 0 0 0 0 0 0 0 0 0 0 1 0 0 2 0 2 0 1 1 2 2 2]
> time WeightDistribution(C);
[ <0, 1>, <8, 1518>, <9, 2530>, <11, 30912>, <12, 30912>, <14, 151800>, <15,
91080>, <17, 148764>, <18, 49588>, <20, 21252>, <21, 3036>, <23, 48> ]
Time: 0.030
```

Note that the minimum distance is $8$. We calculate all words of weight $11$ and the constant words of weight $11$.

```magma
1518
> time W11 := Words(C, 11);
Time: 0.350
> #W11;
30912
> ZOW11 := ConstantWords(C, 11);
> #ZOW11;
23
> ZOW11 subset W11;
true
```

#### Covering Radius and Diameter

<a id="function-cosetdistancedistribution-code"></a>
##### `CosetDistanceDistribution(C): Code -> [ <RngIntElt, RngIntElt> ]`

Given a linear code $C$, determine the coset distance distribution of $C$, relative to $C$. The distance between $C$ and a coset $D$ of $C$ is the Hamming weight of a vector of minimum weight in $D$. The distribution is returned as a sequence of pairs comprising a distance $d$ and the number of cosets that are distance $d$ from $C$.

<a id="function-coveringradius-code"></a>
##### `CoveringRadius(C): Code -> RngIntElt`

The covering radius of the linear code $C$.

<a id="function-diameter-code"></a>
##### `Diameter(C): Code -> RngIntElt`

The diameter of the code $C$ (the largest weight of the codewords of $C$).

<a id="example-ex-df764c"></a>
##### `Example: Covering Radius and Coset Distances (ex-df764c)`

We construct the second order Reed–Muller code of length 32, and calculate its coset distance distribution.

```magma
> R := ReedMullerCode(2, 5);
> R:Minimal;
[32, 16, 8] Reed-Muller Code (r = 2, m = 5) over GF(2)
> CD := CosetDistanceDistribution(R);
> CD;
[ <0, 1>, <1, 32>, <2, 496>, <3, 4960>, <4, 17515>, <5, 27776>, <6, 14756> ]
```

From the dimension of the code we know $C$ has $2^{16}$ cosets. The coset distance distribution tells us that there are $32$ cosets at distance $1$ from $C$, $496$ cosets are distance $2$, etc. We confirm that all cosets are represented in the distribution.

```magma
> &+ [ t[2] : t in CD ];
65536
> CoveringRadius(R);
6
> Diameter(R);
32
> WeightDistribution(R);
[ <0, 1>, <8, 620>, <12, 13888>, <16, 36518>, <20, 13888>, <24, 620>, <32, 1> ]
```

The covering radius gives the maximum distance of any coset from the code, and, from the coset distance distribution, we see that this maximum distance is indeed $6$. We can confirm the value (32) for the diameter by examining the weight distribution and seeing that $32$ is the largest weight of a codeword.

### Families of Linear Codes

#### Cyclic and Quasicyclic Codes

<a id="function-cycliccode-modtuprngelt"></a>
##### `CyclicCode(u): ModTupRngElt -> Code`

Given a vector $u$ belonging to the $R$-space $R^{(n)}$, construct the $[n, k]$ cyclic code generated by the right cyclic shifts of the vector $u$.

<a id="function-cycliccode-rngintelt-fldfinelt-fldfin"></a>
##### `CyclicCode(n, T, K): RngIntElt, [ FldFinElt ], FldFin -> Code`

<a id="function-cycliccode-rngintelt-fldfinelt-fldfin-2"></a>
##### `CyclicCode(n, T, K): RngIntElt, { FldFinElt }, FldFin -> Code`

Given a positive integer $n$ and a set or sequence $T$ of primitive $n$-th roots of unity from a finite field $L$, together with a subfield $K$ of L, construct the cyclic code $C$ over $K$ of length $n$, such that the generator polynomial for $C$ is the polynomial of least degree having the elements of $T$ as roots.

<a id="function-quasicycliccode-rngintelt-rngupolelt"></a>
##### `QuasiCyclicCode(n, Gen): RngIntElt, [ RngUPolElt ] -> Code`

Constructs the quasi-cyclic code of length $n$ with generator polynomials given by the sequence of polynomials in $Gen$. Created by `HorizontalJoin` of each `GeneratorMatrix` from the `CyclicCode`’s generated by the polynomials in $Gen$. Requires that $|Gen| \mid n$.

<a id="function-quasicycliccode-modtuprngelt"></a>
##### `QuasiCyclicCode(Gen): [ ModTupRngElt ] -> Code`

Constructs the quasi-cyclic code of length $n$ generated by simultaneous cyclic shifts of the vectors in $Gen$.

<a id="function-quasicycliccode-rngintelt-rngupolelt-rngintelt"></a>
##### `QuasiCyclicCode(n, Gen, h): RngIntElt, [ RngUPolElt ], RngIntElt -> Code`

Constructs the quasi-cyclic code of length $n$ with generator polynomials given by the sequence of polynomials in $Gen$. The `GeneratorMatrix`’s are joined $2$ dimensionally, with height $h$. Requires that $h \mid (|Gen|)$ and $(|Gen|/h) \mid n$.

<a id="function-quasicycliccode-modtuprngelt-rngintelt"></a>
##### `QuasiCyclicCode(Gen, h): [ModTupRngElt], RngIntElt -> Code`

Constructs the quasi-cyclic code generated by simultaneous cyclic shifts of the vectors in $Gen$, arranging them two dimensionally with height $h$.

<a id="function-constacycliccode-rngintelt-rngupolelt-fldfinelt"></a>
##### `ConstaCyclicCode(n, f, alpha): RngIntElt, RngUPolElt, FldFinElt -> Code`

Let $k$ be a finite field and $\alpha$ a non-zero element of $K$. A linear code $C$ of length $n$ is called a *constacyclic code* with shift constant $\alpha$ if for each word $( x_1, x_2, \ldots, x_n)$ in $C$, the vector $(\alpha x_n, x_1, \ldots, x_{n-1})$ is also in $C$. Such a code is generated by a factor $f$ of the polynomial $x^n - \alpha$, where $f$ is monic polynomial. This intrinsic returns the length $n$ code generated by constacyclic shifts by $\alpha$ of the coefficients of polynomial $f$.

<a id="function-quasitwistedcycliccode-rngintelt-rngupolelt-fldfinelt"></a>
##### `QuasiTwistedCyclicCode(n, Gen, alpha): RngIntElt, [RngUPolElt], FldFinElt -> Code`

Construct the quasi-twisted cyclic code of length $n$ pasting together the constacyclic codes with parameter $\alpha$ generated by the polynomials in $Gen$.

<a id="function-quasitwistedcycliccode-modtuprngelt-fldfinelt"></a>
##### `QuasiTwistedCyclicCode(Gen, alpha): [ModTupRngElt], FldFinElt -> Code`

Construct the quasi-twisted cyclic code generated by simultaneous constacyclic shifts w.r.t. $\alpha$ of the codewords in $Gen$.

<a id="function-quasitwistedcycliccode-rngintelt-rngupolelt-fldfinelt-rngintelt"></a>
##### `QuasiTwistedCyclicCode(n, Gen, alpha, h): RngIntElt, [RngUPolElt], FldFinElt, RngIntElt -> Code`

Constructs the quasi-twisted cyclic code of length $n$ with generator polynomials given by $Gen$. Attaches the Generator matrices of the consta-cyclic codes with parameter $\alpha$ generated by $Gen$ 2-dimensionally, stacking with height $h$. Requires that $\#Gen$ be a multiple of $h$, and that $n$ be a multiple of $\#Gen/h$.

<a id="function-quasitwistedcycliccode-modtuprngelt-fldfinelt-rngintelt"></a>
##### `QuasiTwistedCyclicCode(Gen, alpha, h): [ModTupRngElt], FldFinElt, RngIntElt -> Code`

Construct the quasi-twisted cyclic code generated by simultaneous constacyclic shifts w.r.t. $\alpha$ of the vectors in $Gen$. Attaches the Generator matrices of the consta-cyclic codes with parameter $\alpha$ generated by $Gen$ 2-dimensionally, stacking with height $h$. Requires that $\#Gen$ be a multiple of $h$, and that $n$ be a multiple of $\#Gen/h$.

<a id="example-ex-03b862"></a>
##### `Example: Chain of Cyclic Codes (ex-03b862)`

Let the $m$ factors of $x^n-1$ be $f_i(x)$,$i=0, \ldots, m$ in any particular order. Then we can construct a chain of polynomials $g_k(x) = \prod_{i=0}^{k}f_i(x)$ such that $g_k(x) \mid g_{k+1}(x)$. This chain of polynomials will generate a nested chain of cyclic codes of length $n$, which is illustrated here for $n=7$.

```magma
> P<x> := PolynomialRing(GF(2));
> n := 7;
> F := Factorization(x^n-1);
> F;
[
    <x + 1, 1>,
    <x^3 + x + 1, 1>,
    <x^3 + x^2 + 1, 1>
]
> Gens := [ &*[F[i][1]:i in [1..k]] : k in [1..#F] ];
> Gens;
[
    x + 1,
    x^4 + x^3 + x^2 + 1,
    x^7 + 1
]
> Codes := [ CyclicCode(n, Gens[k]) : k in [1..#Gens] ];
> Codes;
[
    [7, 6, 2] Cyclic Code over GF(2)
    Generator matrix:
    [1 0 0 0 0 0 1]
    [0 1 0 0 0 0 1]
    [0 0 1 0 0 0 1]
    [0 0 0 1 0 0 1]
    [0 0 0 0 1 0 1]
    [0 0 0 0 0 1 1],

    [7, 3, 4] Cyclic 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],
    [7, 0, 7] Cyclic Code over GF(2)
]
> { Codes[k+1] subset Codes[k] : k in [1..#Codes-1] };
{ true }
```

<a id="example-ex-975a7d"></a>
##### `Example: Constacyclic Code (ex-975a7d)`

We construct a constacyclic code $C_1$ of length $11$ over $GF(5)$ with shift constant $a = 3$. In order to find a suitable generator polynomial $f$ we first find the factors of the polynomial $x^n -a$.

```magma
> n := 11;
> k := GF(5);
> _<x> := PolynomialRing(k);
> a := k!3;
>
> f := Factorisation( x^n - a );
> f;
[
    <x + 3, 1>,
    <x^5 + 3*x^4 + x^3 + 3*x^2 + 3*x + 3, 1>,
    <x^5 + 4*x^4 + x^3 + 3*x^2 + x + 3, 1>
]
```

The two polynomials of degree $5$ will give us non-trivial codes.

```magma
> f1 := f[2][1];
> C1 := ConstaCyclicCode(n, f1, a);

    [11, 6, 5] Constacyclic by 3 Linear Code over GF(5)
    [Generator matrix:
    [1 0 0 0 0 0 1 1 1 2 1]
    [0 1 0 0 0 0 2 3 3 0 4]
    [0 0 1 0 0 0 3 0 1 4 3]
    [0 0 0 1 0 0 1 4 1 3 0]
    [0 0 0 0 1 0 0 1 4 1 3]
    [0 0 0 0 0 1 1 1 2 1 2]

> E<p, q> :=  WeightEnumerator(C1);
p^11 + 220*p^6*q^5 + 528*p^5*q^6 + 1980*p^4*q^7 + 2860*p^3*q^8 +
    5280*p^2*q^9 + 3344*p*q^10 + 1412*q^11
```

We now take the second polynomial of degree $5$ and construct the constacyclic code it defines.

```magma
> f2 := f[3][1];
> C2 := ConstaCyclicCode(n, f2, a);
> iseq := IsEquivalent( C1, C2); iseq;

{true}
```

Not unexpectably they define equivalent codes!

#### BCH Codes and their Generalizations

<a id="function-bchcode-fldfin-rngintelt-rngintelt-rngintelt"></a>
##### `BCHCode(K, n, d, b): FldFin, RngIntElt, RngIntElt, RngIntElt -> Code`

<a id="function-bchcode-fldfin-rngintelt-rngintelt"></a>
##### `BCHCode(K, n, d): FldFin, RngIntElt, RngIntElt -> Code`

Given a finite field $K=F_q$ and positive integers $n$, $d$, and $b$ such that $\gcd(n, q) = 1$, we define $m$ to be the smallest integer such that $n \mid (q^m-1)$, and $\alpha$ to be a primitive $n$-th root of unity in the degree $m$ extension of $K$, $GF(q^m)$. This function constructs the BCH code of designated distance $d$ as the cyclic code with generator polynomial

$$
g(x) = {\operatorname{lcm}}\{ m_1(x), \cdots, m_{d-1}(x)\}
$$

where $m_i(x)$ is the minimum polynomial of $\alpha^{b+i-1}$. The BCH code is an $[n,\geq (n - m(d - 1)),\geq d]$ code over $K$. If $b$ is omitted its value is taken to be $1$, in which case the corresponding code is a *narrow sense* BCH code.

<a id="example-ex-4d1633"></a>
##### `Example: BCH Code (ex-4d1633)`

We construct a BCH code of length 13 over GF(3) and designated minimum distance 3

```magma
> C := BCHCode(GF(3), 13, 3);
> C;
[13, 7, 4] BCH code (d = 3, b = 1) over GF(3)
Generator matrix:
[1 0 0 0 0 0 0 1 2 1 2 2 2]
[0 1 0 0 0 0 0 1 0 0 0 1 1]
[0 0 1 0 0 0 0 2 2 2 1 1 2]
[0 0 0 1 0 0 0 1 1 0 1 0 0]
[0 0 0 0 1 0 0 0 1 1 0 1 0]
[0 0 0 0 0 1 0 0 0 1 1 0 1]
[0 0 0 0 0 0 1 2 1 2 2 2 1]
```

<a id="function-goppacode-fldfinelt-rngupolelt"></a>
##### `GoppaCode(L, G): [ FldFinElt ], RngUPolElt -> Code`

Let $K$ be the field $GF(q)$, let $G(z) = G$ be a polynomial defined over the degree $m$ extension field $F$ of $K$ (i.e. the field $GF(q^m)$) and let $L = [\alpha_1, \ldots, \alpha_n]$ be a sequence of elements of $F$ such that $G(\alpha_i) \neq 0$ for all $\alpha_i \in L$. This function constructs the Goppa code $\Gamma(L, G)$ over $K$. If the degree of $G(z)$ is $r$, this is an $[n, k \geq n - mr, d \geq r + 1]$ code.

<a id="example-ex-150eaa"></a>
##### `Example: Goppa Code (ex-150eaa)`

We construct a Goppa code of length 31 over GF(2) with generator polynomial $G(z) = z^3 + z + 1$.

```magma
> q := 2^5;
> K<w> := FiniteField(q);
> P<z> := PolynomialRing(K);
> G := z^3 + z + 1;
> L := [w^i : i in [0 .. q - 2]];
> C := GoppaCode(L, G);
> C:Minimal;
[31, 16, 7] Goppa code (r = 3) over GF(2)
> WeightDistribution(C);
[ <0, 1>, <7, 105>, <8, 295>, <9, 570>, <10, 1333>, <11, 2626>,
 <12, 4250>, <13, 6270>, <14, 8150>, <15, 9188>, <16, 9193>,
 <17, 8090>, <18, 6240>, <19, 4270>, <20, 2590>, <21, 1418>,
 <22, 650>, <23, 195>, <24, 55>, <25, 36>, <26, 11> ]
```

<a id="function-chienchoycode-rngupolelt-rngupolelt-rngintelt-fldfin"></a>
##### `ChienChoyCode(P, G, n, S): RngUPolElt, RngUPolElt, RngIntElt, FldFin -> Code`

Let $P$ and $G$ be polynomials over a finite field $F$, let $n$ be an integer greater than one, and let $S$ be a subfield of $F$. Suppose also that $n$ is coprime to the cardinality of $S$, $F$ is the splitting field of $x^n - 1$ over $S$, $P$ and $G$ are both coprime to $x^n - 1$ and both have degree less than $n$. This function constructs the Chien-Choy generalised BCH code with parameters $P$, $G$, $n$ over $S$.

<a id="function-alternantcode-fldfinelt-fldfinelt-rngintelt-fldfin"></a>
##### `AlternantCode(A, Y, r, S): [ FldFinElt ], [ FldFinElt ], RngIntElt, FldFin -> Code`

<a id="function-alternantcode-fldfinelt-fldfinelt-rngintelt"></a>
##### `AlternantCode(A, Y, r): [ FldFinElt ], [ FldFinElt ], RngIntElt -> Code`

Let $A = [\alpha_1, \ldots, \alpha_n]$ be a sequence of $n$ distinct elements taken from the degree $m$ extension $K$ of the finite field $S$, and let $Y = [y_1, \ldots, y_n]$ be a sequence of $n$ non-zero elements from $K$. Let $r$ be a positive integer. Given such $A$, $Y$, $r$, and $S$, this function constructs the alternant code $A(A, Y)$ over $S$. This is an $[n, k \geq n - mr, d \geq r + 1]$ code. If $S$ is omitted, $S$ is taken to be the prime subfield of $K$.

<a id="example-ex-c9dd03"></a>
##### `Example: Alternant Code (ex-c9dd03)`

We construct an alternant code over GF(2) based on sequences of elements in the extension field GF($2^4$) of GF(2). The parameter $r$ is taken to be 4, so the minimum weight 6 is greater than $r + 1$.

```magma
> q := 2^4;
> K<w> := GF(q);
> A := [w ^ i : i in [0 .. q - 2]];
> Y := [K ! 1 : i in [0 .. q - 2]];
> r := 4;
> C := AlternantCode(A, Y, r);
> C;
[15, 6, 6] Alternant code over GF(2)
Generator matrix:
[1 0 0 0 0 0 1 1 0 0 1 1 1 0 0]
[0 1 0 0 0 0 0 1 1 0 0 1 1 1 0]
[0 0 1 0 0 0 0 0 1 1 0 0 1 1 1]
[0 0 0 1 0 0 1 1 0 1 0 1 1 1 1]
[0 0 0 0 1 0 1 0 1 0 0 1 0 1 1]
[0 0 0 0 0 1 1 0 0 1 1 1 0 0 1]
```

<a id="function-nonprimitivealternantcode-rngintelt-rngintelt-rngintelt"></a>
##### `NonPrimitiveAlternantCode(n, m, r): RngIntElt, RngIntElt, RngIntElt -> Code`

Returns the $[n,k,d]$ non-primitive alternant code over ${\bf F}_{2}$, where $n-mr \le k \le n-r$ and $d \ge r+1$.

<a id="function-firecode-rngupolelt-rngintelt-rngintelt"></a>
##### `FireCode(h, s, n): RngUPolElt, RngIntElt, RngIntElt -> Code`

Let $K$ be the field $GF(q)$. Given a polynomial $h$ in $K$[X], a nonnegative integer $s$, and a positive integer $n$, this function constructs a Fire code of length $n$ with generator polynomial $h(X^s - 1)$.

<a id="function-gabidulincode-fldfinelt-fldfinelt-fldfinelt-rngintelt"></a>
##### `GabidulinCode(A, W, Z, t): [ FldFinElt ], [ FldFinElt ], [ FldFinElt ], RngIntElt -> Code`

Given sequences $A = [a_1,...a_n]$, $W = [w_1,...w_s]$, and $Z=[z_1, ... z_k]$, such that the $n + s$ elements of $A$ and $W$ are distinct and the elements of $Z$ are non-zero, together with a positive integer $t$, construct the Gabidulin MDS code with parameters $A, W, Z, t$.

<a id="function-srivastavacode-fldfinelt-fldfinelt-rngintelt-fldfin"></a>
##### `SrivastavaCode(A, W, mu, S): [ FldFinElt ], [ FldFinElt ], RngIntElt, FldFin -> Code`

Given sequences $A = [\alpha_1, ..., \alpha_n]$, $W = [w_1, ..., w_s]$ of elements from the extension field $K$ of the finite field $S$, such that the elements of $A$ are non-zero and the $n + s$ elements of $A$ and $W$ are distinct, together with an integer $\mu$, construct the Srivastava code of parameters $A$, $W$, $mu$, over $S$.

<a id="function-generalizedsrivastavacode-fldfinelt-fldfinelt-fldfinelt-rngintelt-fldfin"></a>
##### `GeneralizedSrivastavaCode(A, W, Z, t, S): [ FldFinElt ], [ FldFinElt ], [ FldFinElt ], RngIntElt, FldFin -> Code`

Given sequences $A = [\alpha_1, ..., \alpha_n]$, $W = [w_1, ..., w_s]$, and $Z = [z_1, ... z_k]$ of elements from the extension field $K$ of the finite field $S$, such that the elements of $A$ and $Z$ are non-zero and the $n + s$ elements of $A$ and $W$ are distinct, together with a positive integer $t$, construct the generalized Srivastava code with parameters $A$, $W$, $Z$, $t$, over $S$.

#### Quadratic Residue Codes and their Generalizations

If $p$ is an odd prime, the *quadratic residues modulo* $p$ consist of the set of non-zero squares modulo $p$ while the set of non-squares modulo $p$ are termed the *quadratic nonresidues modulo* $p$.

<a id="function-qrcode-fldfin-rngintelt"></a>
##### `QRCode(K, n): FldFin, RngIntElt -> Code`

Given a finite field $K = F_q$ and an odd prime $n$ such that $q$ is a quadratic residue modulo $n$, this function returns the quadratic residue code of length $n$ over $K$. This corresponds to the cyclic code with generator polynomial $g_0(x) = \prod (x - \alpha^r)$, where $\alpha$ is a primitive $n$-th root of unity in some extension field of $K$, and the product is taken over all quadratic residues modulo $p$.

<a id="function-golaycode-fldfin-boolelt"></a>
##### `GolayCode(K, ext): FldFin, BoolElt -> Code`

If the field $K$ is $GF(2)$, construct the binary Golay code. If the field $K$ is $GF(3)$, construct the ternary Golay code. If the boolean argument $ext$ is `true`, construct the extended code in each case.

<a id="function-doublycirculantqrcode-rngintelt"></a>
##### `DoublyCirculantQRCode(p): RngIntElt -> Code`

Given an odd prime $p$, this function returns the doubly circulant binary $[2p, p]$ code based on quadratic residues modulo $p$. A doubly circulant code has generator matrix of the form $[I \mid A]$, where $A$ is a circulant matrix.

<a id="function-doublycirculantqrcodegf4-rngintelt-rngelt"></a>
##### `DoublyCirculantQRCodeGF4(m, a): RngIntElt, RngElt -> Code`

Given a prime power $m$ that is greater than $2$ and an integer $a$ that is either $0$ or $1$, return a $[2m, m]$ doubly circulant linear code over GF(4). For details see [[Gab02](https://docs.magma-maths.org/references.md#cite-gaborit02)].

<a id="function-bordereddoublycirculantqrcode-rngintelt-rngelt-rngelt"></a>
##### `BorderedDoublyCirculantQRCode(p, a, b): RngIntElt, RngElt, RngElt -> Code`

Given an odd prime $p$ and integers $a$ and $b$, this function returns the bordered doubly circulant binary $[2p+1, p+1]$ code based on quadratic residues modulo $p$. The construction is similar to that of a doubly circulant code except that the first $p$ rows are extended by $a$ mod $2$ while the $p+1$-th row is extended by $b$ mod $2$.

<a id="function-twistedqrcode-rngintelt-rngintelt"></a>
##### `TwistedQRCode(l, m): RngIntElt, RngIntElt -> Code`

Given positive integers $l$ and $m$, both coprime to $2$, return a binary “twisted QR” code of length $l*m$.

<a id="function-powerresiduecode-fldfin-rngintelt-rngintelt"></a>
##### `PowerResidueCode(K, n, p): FldFin, RngIntElt, RngIntElt -> Code`

Given a finite field $K=F_q$, a positive integer $n$, and a prime $p$ such that $q$ is a $p$-th power residue modulo $n$, construct the $p$-th power residue code of length $n$.

<a id="example-ex-6c6e7c"></a>
##### `Example: Quadratic Residue Code (ex-6c6e7c)`

We construct a quadratic residue code of length 23 over GF(3).

```magma
> QRCode(GF(3), 23);
[23, 12, 8] Quadratic Residue code over GF(3)
Generator matrix:
[1 0 0 0 0 0 0 0 0 0 0 0 2 2 2 1 1 0 2 0 2 0 0]
[0 1 0 0 0 0 0 0 0 0 0 0 0 2 2 2 1 1 0 2 0 2 0]
[0 0 1 0 0 0 0 0 0 0 0 0 0 0 2 2 2 1 1 0 2 0 2]
[0 0 0 1 0 0 0 0 0 0 0 0 2 2 2 0 0 2 0 1 2 2 0]
[0 0 0 0 1 0 0 0 0 0 0 0 0 2 2 2 0 0 2 0 1 2 2]
[0 0 0 0 0 1 0 0 0 0 0 0 2 2 1 0 0 0 2 2 2 1 2]
[0 0 0 0 0 0 1 0 0 0 0 0 2 1 1 2 1 0 2 2 1 2 1]
[0 0 0 0 0 0 0 1 0 0 0 0 1 0 2 0 1 1 1 2 0 1 2]
[0 0 0 0 0 0 0 0 1 0 0 0 2 0 2 0 1 1 0 1 1 0 1]
[0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 2 1 2 0 2 1 0]
[0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 2 1 2 0 2 1]
[0 0 0 0 0 0 0 0 0 0 0 1 1 1 2 2 0 1 0 1 0 0 2]
```

<a id="reed-solomon-and-justesen-codes"></a>
#### Reed–Solomon and Justesen Codes

<a id="function-reedsolomoncode-fldfin-rngintelt-rngintelt"></a>
##### `ReedSolomonCode(K, d, b): FldFin, RngIntElt, RngIntElt -> Code`

<a id="function-reedsolomoncode-fldfin-rngintelt"></a>
##### `ReedSolomonCode(K, d): FldFin, RngIntElt -> Code`

Given a finite field $K=F_q$ and a positive integer $d$, return the Reed–Solomon code of length $n=q-1$ with design distance $d$. This corresponds to `BCHCode(K, q-1, d)`. For details see [[MS78](https://docs.magma-maths.org/references.md#cite-sloane), p.294].

If $b$ is given as a non-negative integer then the primitive element is first raised to the $b$-th power.

<a id="function-reedsolomoncode-rngintelt-rngintelt"></a>
##### `ReedSolomonCode(n, d): RngIntElt, RngIntElt -> Code`

<a id="function-reedsolomoncode-rngintelt-rngintelt-rngintelt"></a>
##### `ReedSolomonCode(n, d, b): RngIntElt, RngIntElt, RngIntElt -> Code`

Given an integer $n$ such that $q=n+1$ is a prime power, and a positive integer $d$, return the Reed–Solomon code over $F_q$ of length $n$ and designed minimum distance $d$.

If $b$ is given as a non-negative integer then the primitive element is first raised to the $b$-th power.

<a id="function-grscode-fldfinelt-fldfinelt-rngintelt"></a>
##### `GRSCode(A, V, k): [ FldFinElt ], [ FldFinElt ], RngIntElt -> Code`

Let $A = [\alpha_1, \ldots, \alpha_n]$ be a sequence of $n$ distinct elements taken from the finite field $K$, and let $V = [v_1, \ldots, v_n]$ be a sequence of $n$ non-zero elements from $K$. Let $k$ be a non-negative integer. Given such $A$, $V$, and $k$, this function constructs the generalized Reed–Solomon code $GRS_k(A, V)$ over $K$. This is an $[n, k' \leq k]$ code. For details see [[MS78](https://docs.magma-maths.org/references.md#cite-sloane), p.303].

<a id="function-justesencode-code-fldfinelt-rngintelt"></a>
##### `JustesenCode(N, K): Code, FldFinElt, RngIntElt -> Code`

Given an integer $N$ such that $N=2^m-1$ and a positive integer $K$, construct the binary linear Justesen code of length $2mN$ and dimension mK. For details see [[MS78](https://docs.magma-maths.org/references.md#cite-sloane), p.307].

<a id="example-ex-6976f5"></a>
##### `Example: Generalized Reed-Solomon Code (ex-6976f5)`

We construct a generalized Reed–Solomon code over GF(2) based on sequences of elements in the extension field GF($2^3$) of GF(2). The parameter $k$ is taken to be 3, so the dimension 3 is at most $k$.

```magma
> q := 2^3;
> K<w> := GF(q);
> A := [w ^ i : i in [0 .. q - 2]];
> V := [K ! 1 : i in [0 .. q - 2]];
> k := 3;
> C := GRSCode(A, V, k);
[7, 3, 5] GRS code over GF(2^3)
Generator matrix:
[  1   0   0 w^3   w   1 w^3]
[  0   1   0 w^6 w^6   1 w^2]
[  0   0   1 w^5 w^4   1 w^4]
```

#### Maximum Distance Separable Codes

<a id="function-mdscode-fldfin-rngintelt"></a>
##### `MDSCode(K, k): FldFin, RngIntElt -> Code`

Given a finite field $GF(q = 2^m)$, this function constructs the $[q + 1,k,q - k + 2]$ maximum distance separable code.

### New Codes from Existing

The operations described here produce a new code by modifying in some way the codewords of a given code.

#### Standard Constructions

<a id="function-augmentcode-code"></a>
##### `AugmentCode(C): Code -> Code`

Given an $[n, k]$ binary code $C$, construct a new code $C'$ by including the all-ones vector with the words of $C$ (provided that it is not already in $C$).

<a id="function-codecomplement-code-code"></a>
##### `CodeComplement(C, C1): Code, Code -> Code`

Given a subcode $C_1$ of $C$, return a code $C_2$ such that $C=C_1 +  C_2$.

<a id="function-directsum-code-code"></a>
##### `DirectSum(C, D): Code, Code -> Code`

Given an $[n_1, k_1]$ code $C$ and an $[n_2, k_2]$ code $D$, both over the same field $F$, construct the direct sum of $C$ and $D$. The direct sum consists of all vectors $u|v$, where $u \in C$ and $v \in D$.

<a id="function-directsum-code"></a>
##### `DirectSum(Q): [Code] -> Code`

Given a sequence of codes $Q = [C_1, \dots, C_r]$, all defined over the same field $F$, construct the direct sum of the $C_i$.

<a id="function-directproduct-code-code"></a>
##### `DirectProduct(C, D): Code, Code -> Code`

<a id="function-productcode-code-code"></a>
##### `ProductCode(C, D): Code, Code -> Code`

Given an $[n_1, k_1]$ code $C$ and an $[n_2, k_2]$ code $D$, both over the same ring $R$, construct the direct product of $C$ and $D$. The direct product has length $n_1\cdot n_2$, dimension $k_1\cdot k_2$, and its generator matrix is the Kronecker product of the basis matrices of $C$ and $D$.

<a id="function-extendcode-code"></a>
##### `ExtendCode(C): Code -> Code`

Given an $[n, k, d]$ code $C$ form a new code $C'$ from $C$ by adding the appropriate extra coordinate to each vector of $C$ such that the sum of the coordinates of the extended vector is zero. (Thus if $C$ is a binary code, the construction will add a $0$ at the end of every codeword having even weight, and a $1$ at the end of every codeword having odd weight.)

<a id="function-extendcode-code-rngintelt"></a>
##### `ExtendCode(C, n): Code, RngIntElt -> Code`

Return the code $C$ extended $n$ times.

<a id="function-padcode-code-rngintelt"></a>
##### `PadCode(C, n): Code, RngIntElt -> Code`

Add $n$ zeros to the end of each codeword of $C$.

<a id="function-expurgatecode-code"></a>
##### `ExpurgateCode(C): Code -> Code`

Construct a new code by deleting all the code words of $C$ having odd weight.

<a id="function-expurgatecode-code-modtupfldelt"></a>
##### `ExpurgateCode(C, L): Code, [ModTupFldElt] -> Code`

The sequence $L$ consists of codewords from $C$. The result is obtained by deleting the words in $L$ from $C$.

<a id="function-expurgateweightcode-code-rngintelt"></a>
##### `ExpurgateWeightCode(C, w): Code, RngIntElt -> Code`

Delete a subspace generated by a word of weight $w$.

<a id="function-lengthencode-code"></a>
##### `LengthenCode(C): Code -> Code`

Given an $[n, k]$ binary code $C$, construct a new code by first adding the all-ones codeword, and then extending it by adding an overall parity check.

<a id="function-plotkinsum-code-code"></a>
##### `PlotkinSum(C1, C2): Code, Code -> Code`

Given two codes over the same alphabet, return the code consisting of all vectors of the form $u|u+v$, where $u \in C_1$ and $v \in C_2$. Zeros are appended where needed to make up any length differences in the two codes. The result is a $[n_1 + \max\{n_1,n_2\},k_1 + k_2, \min\{2*d_1,d_2\}]$ code.

<a id="function-plotkinsum-code-code-code"></a>
##### `PlotkinSum(C1, C2, C3: parameters): Code, Code, Code -> Code`

```magma
a: FldFinElt                    Default: -1
```

Given three codes over the same alphabet, return the code consisting of all vectors of the form $u|u+a*v|u+v+w$, where $u \in C_1$, $v \in C_2$, and $w \in C_3$. Zeros are appended where needed to make up any length differences in the three codes. The result for the default case of `a := -1` is a $[n_1 + \max\{n_1,n_2\} + \max\{n_1,n_2,n_3\},k_1 + k_2+k_3, \min\{3*d_1,2*d_2,d_3\}]$ code.

<a id="function-puncturecode-code-rngintelt"></a>
##### `PunctureCode(C, i): Code, RngIntElt -> Code`

Given an $[n, k]$ code $C$, and an integer $i$, $1 \leq i \leq n$, construct a new code $C'$ by deleting the $i$-th coordinate from each code word of $C$.

<a id="function-puncturecode-code-rngintelt-2"></a>
##### `PunctureCode(C, S): Code, { RngIntElt } -> Code`

Given an $[n, k]$ code $C$ and a set $S$ of distinct integers $\{ i_1, \cdots, {\mathrm{i}}_r \}$ each of which lies in the range $[1, n]$, construct a new code $C'$ by deleting the components $i_1, \cdots, i_r$ from each code word of $C$.

<a id="function-shortencode-code-rngintelt"></a>
##### `ShortenCode(C, i): Code, RngIntElt -> Code`

Given an $[n, k]$ code $C$ and an integer $i$, $1 \leq i \leq n$, construct a new code from $C$ by selecting only those codewords of $C$ having a zero as their $i$-th component and deleting the $i$-th component from these codewords. Thus, the resulting code will have length $n-1$.

<a id="function-shortencode-code-rngintelt-2"></a>
##### `ShortenCode(C, S): Code, { RngIntElt } -> Code`

Given an $[n, k]$ code $C$ and a set $S$ of distinct integers $\{ i_1, \cdots, {\mathrm{i}}_r\}$, each of which lies in the range $[1, n]$, construct a new code from $C$ by selecting only those codewords of $C$ having zeros in each of the coordinate positions $i_1, \cdots, i_r$, and deleting these components. Thus, the resulting code will have length $n-r$.

<a id="example-ex-7b4c39"></a>
##### `Example: Constructing a [12,4,6] Code (ex-7b4c39)`

Using only two simple `RepetitionCode`’s and several standard constructions, we create a $[12,4,6]$ code. This is the best possible minimum weight for a code of this length and dimension, as is the minimum weight for all codes produced in this example.

Instead of printing each individual code out, the codes are named by convention as c_n_k_d, where $n,k,d$ represent the `Length`,`Dimension` and `MinimumWeight` respectively.

```magma
> c_4_1_4 := RepetitionCode(GF(2),4);
> c_6_1_6 := RepetitionCode(GF(2),6);
> c_4_3_2 := Dual( c_4_1_4 );
> c_8_4_4 := PlotkinSum( c_4_3_2 , c_4_1_4 );
> c_7_4_3 := PunctureCode( c_8_4_4 , 8 );
> c_6_3_3 := ShortenCode(  c_7_4_3 , 7 );
> c_12_4_6 := PlotkinSum( c_6_3_3 , c_6_1_6 );
> c_12_4_6;
[12, 4, 6] Linear Code over GF(2)
Generator matrix:
[1 0 0 1 1 0 0 1 1 0 0 1]
[0 1 0 1 0 1 0 1 0 1 0 1]
[0 0 1 1 1 1 0 0 1 1 1 1]
[0 0 0 0 0 0 1 1 1 1 1 1]
```

#### Changing the Alphabet of a Code

<a id="function-extendfield-code-fldfin"></a>
##### `ExtendField(C, L): Code, FldFin -> Code, Map`

Given an $[n, k, d]$ code $C$ defined over the finite field $K$, and an extension field $L$ of $K$, construct the code $C'$ over $L$ corresponding to $C$. The function also returns the embedding map from $C$ into $C'$.

<a id="function-linearcode-code-fldfin"></a>
##### `LinearCode(C, S): Code, FldFin -> Code, Map`

Given an $[n, k, d]$ code $C$ defined over the finite field $K$, and a subfield $S$ of $K$ such that the degree of $K$ over $S$ is $m$, construct a new $[N = mn, k, D \geq d]$ code $C'$ over $S$ by replacing each component of each codeword of $C$ by its representation as a vector over $S$. The function also returns the isomorphism from $C$ onto $C'$.

<a id="function-subfieldrepresentationcode-code-fldfin"></a>
##### `SubfieldRepresentationCode(C, K): Code, FldFin -> Code`

Given a linear code over $GF(q^m)$, return a code whose codewords are obtained from those of $C$ by expanding each coordinate in $GF(q^m)$ as a vector of dimension $m$ over $K = GF(q)$.

<a id="function-subfieldrepresentationparitycode-code-fldfin"></a>
##### `SubfieldRepresentationParityCode(C, K): Code, FldFin -> Code`

Given a linear code over $GF(q^m)$, return a code whose codewords are obtained from those of $C$ by expanding each coordinate in $GF(q^m)$ as a vector of dimension $m+1$ over $K = GF(q)$, including a parity check bit.

<a id="function-subfieldsubcode-code-fldfin"></a>
##### `SubfieldSubcode(C, S): Code, FldFin -> Code, Map`

<a id="function-restrictfield-code-fldfin"></a>
##### `RestrictField(C, S): Code, FldFin -> Code, Map`

<a id="function-subfieldsubcode-code"></a>
##### `SubfieldSubcode(C): Code -> Code, Map`

<a id="function-restrictfield-code"></a>
##### `RestrictField(C): Code -> Code, Map`

Given an $[n, k, d]$ code $C$ defined over the field $K$, and a subfield $S$ of $K$, construct a new $[n, K \leq k, D \geq d]$ code $C'$ over $S$ consisting of the codewords of $C$ which have all their components in $S$. If $S$ is omitted, it is taken to be the prime subfield of $K$. The function also returns the restriction map from $C$ to the subfield subcode $C'$.

<a id="function-subfieldcode-code-fldfin"></a>
##### `SubfieldCode(C, S): Code, FldFin -> Code`

Given an $[n, k]$ code $C$ defined over the field $K$, and a subfield $S$ of $K$, such that $K$ is a degree $m$ extension of $S$, construct a new $[n, k']$ code over $S$ by expanding each element of $K$ as a column vector over $S$. The new code will have $k'\le km$.

<a id="function-trace-code-fldfin"></a>
##### `Trace(C, F): Code, FldFin -> Code`

<a id="function-trace-code"></a>
##### `Trace(C): Code -> Code`

Given a code $C$ defined over the field $K$, and a subfield $F$ of $K$, construct a new code $C'$ over $F$ consisting of the traces with respect to $F$ of each of the codewords of $L$. If $F$ is omitted, it is taken to be the prime subfield of $K$.

#### Combining Codes

<a id="operation-operation-cat-code-code-code"></a>
##### `C1 cat C2: Code, Code -> Code`

Given codes $C_1$ and $C_2$, both defined over the same field $K$, return the concatenation $C$ of $C_1$ and $C_2$. If $A$ and $B$ are the generator matrices of $C_1$ and $C_2$, respectively, the concatenation of $C_1$ and $C_2$ is the code with generator matrix whose rows consist of each row of $A$ concatenated with each row of $B$.

<a id="function-juxtaposition-code-code"></a>
##### `Juxtaposition(C1, C2): Code, Code -> Code`

Given an $[n_1,k,d_1]$ code $C_1$ and an $[n_2,k,d_2]$ code $C_2$ of the same dimension, where both codes are defined over the same field $K$, the function returns a $[n_1+n_2,k,\geq  d_1+d_2]$ code whose generator matrix is `HorizontalJoin(A, B)`, where $A$ and $B$ are the generator matrices for codes $C_1$ and $C_2$, respectively.

<a id="function-concatenatedcode-code-code"></a>
##### `ConcatenatedCode(O, I): Code, Code -> Code`

Given a $[N,K,D]$-code $O$ defined over $GF(q^k)$ and a $[n,k,d]$-code $I$ defined over $GF(q)$, construct the $[Nn,Kk,\delta \ge dD]$ concatenated code by taking $O$ as outer code and $I$ as inner code.

<a id="example-ex-b27a80"></a>
##### `Example: Concatenated Code (ex-b27a80)`

We use the function `ConcatenatedCode` to construct a $[69,19,22]$ code over $GF(2)$, this being the best known code for this length and dimension. While it is theoretically possible for a code of minimum weight up to $24$ to exist, the best binary $[69, 19]$ code at the time of writing (July 2001) has minimum weight $22$.

```magma
> C1 := ShortenCode( QRCode(GF(4),29) , {24..29} );
> C1:Minimal;
[23, 9] Linear Code over GF(2^2)
> C2 := ConcatenatedCode( C1 , CordaroWagnerCode(3) );
> C2:Minimal;
[69, 18] Linear Code over GF(2)
> res := C2 + RepetitionCode(GF(2),69);
> res:Minimal;
[69, 19] Linear Code over GF(2)
> MinimumWeight(res);
22
> res:Minimal;
[69, 19, 22] Linear Code over GF(2)
```

<a id="function-constructionx-code-code-code"></a>
##### `ConstructionX(C1, C2, C3): Code, Code, Code -> Code`

Let $C_1,C_2$ and $C_3$ be codes with parameters $[n_1, k_1, d_1]$, $[n_2, k_2, d_2]$, and $[n_3, k_3, d_3]$, respectively, where $C_1$ is a union of $b=2^{k_3}$ cosets of $C_2$, (so $n_1=n_2$ and $k_2 \leq k_1$) and $k_1 = k_2+k_3$. The construction divides $C_1$ into a union of cosets of $C_2$ and attaches a different codeword of $C_3$ to each coset. The new code has parameters $[n_1+n_3,k_1,\ge\min\{\ d_2,d_1+d_3  \} ]$. For further details see [[MS78](https://docs.magma-maths.org/references.md#cite-sloane), p.581].

<a id="function-constructionxchain-code-code"></a>
##### `ConstructionXChain(S, C): [Code], Code -> [Code]`

Given a sequence of codes $S$ where all codes are subcodes of the first one, apply `ConstructionX` to $S[1],S[2]$ and $C$. Then compute the resulting subcodes from the other codes in $S$.

<a id="example-ex-78f34f"></a>
##### `Example: Construction X (ex-78f34f)`

We create a $[161, 29, 53]$ code by applying construction X to two BCH codes of length $127$. To maximise the resulting minimum weight we take the best known $[34, 14]$ code as $C_3$. The construction sets a lower bound on the minimum weight, making the calculation of the true minimum weight much faster.

```magma
> SetPrintLevel("Minimal");
>
> C1 := BCHCode(GF(2), 127, 43);
> C2 := BCHCode(GF(2), 127, 55);
> C3 := BKLC(GF(2), 34, 14);
> C1; C2; C3;
[127, 29, 43] BCH code (d = 43, b = 1) over GF(2)
[127, 15, 55] BCH code (d = 55, b = 1) over GF(2)
[34, 14, 10] Linear Code over GF(2)
> CX := ConstructionX(C1, C2, C3);
> CX;
[161, 29] Linear Code over GF(2)
> time MinimumWeight(CX);
53
Time: 0.010
```

<a id="function-constructionx3-code-code-code-code-code"></a>
##### `ConstructionX3(C1, C2, C3, D1, D2): Code, Code, Code, Code, Code -> Code, Map`

Given a chain of codes $C_1=[n,k_1,d_1]$, $C_2=[n,k_2,d_2]$, and $C_3=[n,k_3,d_3]$ with $k_3 < k_2 < k_1$, and suffix codes $D_1=[n_1,k_1-k_2,e_1]$ and $D_2=[n_2,k_3-k_2,e_2]$, construct a code $C=[n+n_1+n_2,k_1,\ge min\{d_3,d_1+e_1,d_2+e_2\}$. For further details see [[MS78](https://docs.magma-maths.org/references.md#cite-sloane), p.583].

<a id="function-constructionx3u-code-code-code-code-code"></a>
##### `ConstructionX3u(C1, C2, C3, D1, D2): Code, Code, Code, Code, Code -> Code, Code`

Given two chains of codes $C_1=[n,k_1] \subset C_2=[n,k_2] \subset C_3=[n,k_3]$ and $D_1=[n',k_1-k_3] \subset D_2=[n',k_2-k_3]$, return the codes $C=[n+n',k_1] \subset C'=[n+n',k_2]$ using Construction X with $C_1, C_3$ and $D_1$ resp. $C_2, C_3$ and $D_2$.

<a id="example-ex-3a19a8"></a>
##### `Example: Construction X3 (ex-3a19a8)`

We construct a best known $[74,43,11]$ code using construction X3. From a chain of BCH subcodes, we take an subcode to get the appropriate length, then use construction X3 with the best possible codes $D_1,D_2$. Because the construction algorithm sets a lower bound on the minimum weight, then it is quick to calculate afterwards.

```magma
> SetPrintLevel("Minimal");
> C1 := ExtendCode( BCHCode(GF(2), 63, 7) );
> C2 := ExtendCode( BCHCode(GF(2), 63, 9) );
> C3 := ExtendCode( BCHCode(GF(2), 63, 11) );
> C1; C2; C3;
[64, 45, 8] Linear Code over GF(2)
[64, 39, 10] Linear Code over GF(2)
[64, 36, 12] Linear Code over GF(2)
> CC := SubcodeBetweenCode(C1, C2, 43);
> CC;
[64, 43] Linear Code over GF(2)
> MinimumWeight(CC);
8
> CX3 := ConstructionX3(CC, C2, C3,
>                 BKLC(GF(2), 7, 4), BKLC(GF(2), 3, 3));
> CX3;
[74, 43] Linear Code over GF(2)
> time MinimumWeight(CX3);
11
Time: 0.000
```

<a id="function-constructionxx-code-code-code-code-code"></a>
##### `ConstructionXX(C1, C2, C3, D2, D3): Code, Code, Code, Code, Code -> Code`

Let the parameters of codes $C_1,C_2,C_3$ be $[n_1,k,d_1],[n_1,k-l_2,d_2]$ and $[n_1,k-l_3,d_3]$ respectively, where $C_2$ and $C_3$ are subcodes of $C_1$. Codes $D_2,D_3$ must have dimensions $l_2,l_3$, with parameters $[n_2,l_2,\delta_2],[n_3,l_3,\delta_3]$ say. The construction breaks $C_1$ up into cosets of $C_2$ and $C_3$ with the relevant tails added from $D_2$ and $D_3$. If the intersection of $C_1$ and $C_2$ has minimum distance $d_0$ then the newly constructed code will have parameters $[n_1+n_2+n_3,k,\min\{d_0,d_2+\delta_2,d_3+\delta_3,d_1+\delta_2+\delta_3\}]$. For further details see [[All84](https://docs.magma-maths.org/references.md#cite-alltopxx)].

<a id="example-ex-db315b"></a>
##### `Example: Construction XX (ex-db315b)`

We construct a best known $[73,38,13]$ code $C$ using construction XX. For $C_1$, $C_2$, $C_3$ we take three cyclic (or BCH) codes of length $63$, while for $D_1$, $D_2$ we use two Best Known Codes.

```magma
> SetPrintLevel("Minimal");
> C1 := BCHCode(GF(2),63,10,57);
> P<x> := PolynomialRing(GF(2));
> p := x^28 + x^25 + x^22 + x^21 + x^20 + x^17 + x^16
>      + x^15 + x^9 + x^8 + x^6 + x^5 + x + 1;
> C2 := CyclicCode(63, p);
> C3 := BCHCode(GF(2), 63, 10, 58);
> C1; C2; C3;
[63, 38] BCH code (d = 10, b = 57) over GF(2)
[63, 35] Cyclic Code over GF(2)
[63, 32] BCH code (d = 10, b = 58) over GF(2)
> MinimumDistance(C1 meet C2);
12
```

So the minimum distance of the code produced by Construction XX must be at least $12$.

```magma
> C := ConstructionXX(C1, C2, C3, BKLC(GF(2),3,3), BKLC(GF(2),7,6) );
> C;
[73, 38] Linear Code over GF(2)
> MinimumDistance(C);
13
```

Thus the actual minimum distance is one greater than the lower bound guaranteed by Construction XX.

<a id="function-zinovievcode-code-code"></a>
##### `ZinovievCode(I, O): [Code], [Code] -> Code`

The arguments are as follows: The first argument must be a sequence $I$ containing an increasing chain of $r$ codes with parameters,

$$
[n,k_1,d_1]_q \subset [n,k_2,d_2]_q \subset \ldots \subset [n,k_r,d_r]_q
$$

where $0=k_0<k_1<k_2< \ldots < k_r$, (the *inner codes*). The second argument must be a sequence $O$ of $r$ codes with parameters $[N,K_i,D_i]_{Q_i}$, where $Q_i = q^{e_i}$ and $e_i = k_i - k_{i-1}$ for $i = 1 \ldots r$ (the *outer codes*). The function constructs a generalised concatenated $[n*N,K,D]_q$ code is constructed, where $K=e_1K_1+ \ldots +e_rK_r$ and $D = min(d_1D_1,\ldots ,d_rD_r)$. For further details see [[MS78](https://docs.magma-maths.org/references.md#cite-sloane), p.590].

<a id="example-ex-cc2def"></a>
##### `Example: Zinoviev Code (ex-cc2def)`

We create a $[72,41,12]$ code over $GF(2)$ using the `ZinovievCode` function, which is the best known code for this length and dimension. While it is theoretically possible for a $[72, 41]$ code to have minimum weight up to $14$, at the time of writing (July 2001) the best known code has minimum weight $12$. The minimum weight is not calculated since it is a lengthy calculation.

```magma
> I1 := RepetitionCode(GF(2),8);
> I2 := I1 + LinearCode( KMatrixSpace(GF(2),3,8) !
>                 [0,1,0,0,0,1,1,1,0,0,1,0,1,0,1,1,0,0,0,1,1,1,0,1]
>                      );
> I3 := Dual(I1);
> Inner := [I1, I2, I3];
> Inner:Minimal;
[
    [8, 1, 8] Cyclic Code over GF(2),
    [8, 4, 4] Linear Code over GF(2),
    [8, 7, 2] Cyclic Code over GF(2)
]
>
> O1 := Dual(RepetitionCode(GF(2),9));
> O2 := BCHCode(GF(8),9,3,4);
> O3 := BCHCode(GF(8),9,6,7);
> Outer := [O1, O2, O3];
> Outer:Minimal;
[
    [9, 8, 2] Cyclic Code over GF(2),
    [9, 7, 3] BCH code (d = 3, b = 4) over GF(2^3),
    [9, 4, 6] BCH code (d = 6, b = 7) over GF(2^3)
]
>
> C := ZinovievCode(Inner, Outer);
> C:Minimal;
[72, 41] Linear Code over GF(2)
```

<a id="function-constructiony1-code"></a>
##### `ConstructionY1(C): Code -> Code`

Apply construction $Y1$ to the code $C$. This construction applies the shortening operation at the positions in the support of a word of minimal weight in the dual of $C$. If $C$ is a $[n,k,d]$ code, whose dual code has minimum weight $d'$, then the returned code has parameters $[n-d',k-d'+1,\geq d]$. For further details see [[MS78](https://docs.magma-maths.org/references.md#cite-sloane), p.592].

<a id="function-constructiony1-code-rngintelt"></a>
##### `ConstructionY1(C, w): Code, RngIntElt -> Code`

Apply construction $Y1$ to the code $C$. This construction applies the shortening operation at the positions in the support of a word of weight $w$ in the dual of $C$. If $C$ is a $[n,k,d]$ code, then the returned code has parameters $[n-w,k-w+1,\geq d]$.

### Bounds

Magma supplies various functions for computing lower and upper bounds for parameters associated with codes. It also contains tables of best known bounds for linear codes. The functions in this section only apply to codes over finite fields.

<a id="best-bounds"></a>
<a id="code-bound-best"></a>
#### Best Known Bounds for Linear Codes

A Magma database allows the user access to tables giving the best known upper and lower bounds of the `Length`, `Dimension`, and `MinimumWeight` of linear codes. Tables are currently available relating to codes over $GF(2)$ and $GF(4)$ with $1 \le$ `Length` $\le 256$, over $GF(3)$ with $1 \le$ `Length` $\le 243$, over $GF(5), GF(8)$, and $GF(9)$ with $1 \le$ `Length` $\le 130$, and over $GF(7)$ with $1 \le$ `Length` $\le 100$.

<a id="function-bklclowerbound-fldfin-rngintelt-rngintelt"></a>
##### `BKLCLowerBound(F, n, k): FldFin, RngIntElt, RngIntElt -> RngIntElt`

Returns the best known lower bound on the maximum possible minimum weight of a linear code over finite field $F$ having length $n$ and dimension $k$.

<a id="function-bklcupperbound-fldfin-rngintelt-rngintelt"></a>
##### `BKLCUpperBound(F, n, k): FldFin, RngIntElt, RngIntElt -> RngIntElt`

Returns the best known upper bound on the minimum weight of a linear code over finite field $F$ of length $n$ and dimension $k$.

<a id="function-bllclowerbound-fldfin-rngintelt-rngintelt"></a>
##### `BLLCLowerBound(F, k, d): FldFin, RngIntElt, RngIntElt -> RngIntElt`

Returns the best known lower bound on the minimum possible length of a linear code over finite field $F$ having dimension $k$ and minimum weight at least $d$. If the required length is out of the range of the database then no bound is available and -1 is returned.

<a id="function-bllcupperbound-fldfin-rngintelt-rngintelt"></a>
##### `BLLCUpperBound(F, k, d): FldFin, RngIntElt, RngIntElt -> RngIntElt`

Returns the best known upper bound on the minimum possible length of a linear code over finite field $F$ of dimension $k$ and minimum weight at least $d$. If the required length is out of the range of the database then no bound is available and -1 is returned.

<a id="function-bdlclowerbound-fldfin-rngintelt-rngintelt"></a>
##### `BDLCLowerBound(F, n, d): FldFin, RngIntElt, RngIntElt -> RngIntElt`

Returns the best known lower bound on the maximum possible dimension of a linear code over finite field $F$ having length $n$ and minimum weight at least $d$.

<a id="function-bdlcupperbound-fldfin-rngintelt-rngintelt"></a>
##### `BDLCUpperBound(F, n, d): FldFin, RngIntElt, RngIntElt -> RngIntElt`

Returns the best known upper bound on the dimension of a linear code over finite field $F$ having length $n$ and minimum weight at least $d$.

#### Bounds on the Cardinality of a Largest Code

<a id="function-eliasbound-fldfin-rngintelt-rngintelt"></a>
##### `EliasBound(K, n, d): FldFin, RngIntElt, RngIntElt -> RngIntElt`

Return the Elias upper bound of the cardinality of a largest code of length $n$ and minimum distance $d$ over the field $K$.

<a id="function-griesmerbound-fldfin-rngintelt-rngintelt"></a>
##### `GriesmerBound(K, n, d): FldFin, RngIntElt, RngIntElt -> RngIntElt`

Return the Griesmer upper bound of the cardinality of a largest code of length $n$ and minimum distance $d$ over the field $K$.

<a id="function-johnsonbound-rngintelt-rngintelt"></a>
##### `JohnsonBound(n, d): RngIntElt, RngIntElt -> RngIntElt`

Return the Johnson upper bound of the cardinality of a largest binary code of length $n$ and minimum distance $d$.

<a id="function-levenshteinbound-fldfin-rngintelt-rngintelt"></a>
##### `LevenshteinBound(K, n, d): FldFin, RngIntElt, RngIntElt -> RngIntElt`

Return the Levenshtein upper bound of the cardinality of a largest code of length $n$ and minimum distance $d$ over the field $K$.

<a id="function-plotkinbound-fldfin-rngintelt-rngintelt"></a>
##### `PlotkinBound(K, n, d): FldFin, RngIntElt, RngIntElt -> RngIntElt`

Return the Plotkin upper bound on the cardinality of a (possibly non-linear) code of length $n$ and minimum distance $d$ over the field $K$. The bound is formed by calculating the maximal possible average distance between codewords.

For binary codes the bound exists for $n \le 2d$, ($d$ even), or $n \le 2d + 1$ ($d$ odd). For codes over general fields the bound exists for $d > (1-1/\#K)*n$.

<a id="function-singletonbound-fldfin-rngintelt-rngintelt"></a>
##### `SingletonBound(K, n, d): FldFin, RngIntElt, RngIntElt -> RngIntElt`

Return the Singleton upper bound of the cardinality of a largest code of length $n$ and minimum distance $d$ over the field $K$.

<a id="function-spherepackingbound-fldfin-rngintelt-rngintelt"></a>
##### `SpherePackingBound(K, n, d): FldFin, RngIntElt, RngIntElt -> RngIntElt`

Return the Hamming sphere packing upper bound on the cardinality of a largest codes of length $n$ and minimum distance $d$ over the field $K$.

<a id="function-gilbertvarshamovbound-fldfin-rngintelt-rngintelt"></a>
##### `GilbertVarshamovBound(K, n, d): FldFin, RngIntElt, RngIntElt -> RngIntElt`

Return the Gilbert–Varshamov lower bound of the cardinality of a largest code (possibly non-linear) of length $n$ and minimum distance $d$ over the field $K$.

<a id="function-gilbertvarshamovlinearbound-fldfin-rngintelt-rngintelt"></a>
##### `GilbertVarshamovLinearBound(K, n, d): FldFin, RngIntElt, RngIntElt -> RngIntElt`

Return the Gilbert–Varshamov lower bound of the cardinality of a largest linear code of length $n$ and minimum distance $d$ over the field $K$.

<a id="function-vanlintbound-fldfin-rngintelt-rngintelt"></a>
##### `VanLintBound(K, n, d): FldFin, RngIntElt, RngIntElt -> RngIntElt`

Return the van Lint lower bound of the cardinality of a largest code of length $n$ and minimum distance $d$ over the field $K$.

<a id="example-ex-89ddc1"></a>
##### `Example: Computed and Stored Cardinality Bounds (ex-89ddc1)`

We compare computed and stored values of best known upper bounds of the dimension of binary linear codes of length $20$. The cardinality of a linear code of dimension $k$ over ${\bf F}_{q}$ is $q^k$, and so the computed bounds on cardinality are compared with the stored bounds on dimension by taking logs.

```magma
> n:=20;
> K := GF(2);
> [ Ilog(#K, Minimum({GriesmerBound(K, n, d), EliasBound(K, n, d),
>                       JohnsonBound(n, d) , LevenshteinBound(K, n, d),
>                       SpherePackingBound(K, n, d)})) : d in [1..n] ];
[ 20, 19, 15, 14, 12, 11, 9, 8, 5, 4, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1 ]
> [ BDLCUpperBound(K, n, d) : d in [1..n] ];
[ 20, 19, 15, 14, 11, 10, 9, 8, 5, 4, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1 ]
```

#### Bounds on the Minimum Distance

<a id="function-bchbound-code"></a>
##### `BCHBound(C): Code -> RngIntElt, RngIntElt`

Given a cyclic code $C$, return the BCH bound for $C$. This a lower bound on the minimum weight of $C$.

<a id="function-griesmerminimumweightbound-fldfin-rngintelt-rngintelt"></a>
##### `GriesmerMinimumWeightBound(K, n, k): FldFin, RngIntElt, RngIntElt -> RngIntElt`

Return the Griesmer upper bound of the minimum weight of a linear code of length $n$ and dimension $k$ over the field $K$.

#### Asymptotic Bounds on the Information Rate

<a id="function-eliasasymptoticbound-fldfin-fldprelt"></a>
##### `EliasAsymptoticBound(K, delta): FldFin, FldPrElt -> FldPrElt`

Return the Elias asymptotic upper bound of the information rate for $\delta$ in $[0, 1]$ over the field $K$.

<a id="function-mcelieceetalasymptoticbound-fldprelt"></a>
##### `McElieceEtAlAsymptoticBound(delta): FldPrElt -> FldPrElt`

Return the McEliece–Rodemich–Rumsey–Welch asymptotic upper bound of the binary information rate for $\delta$ in $[0, 1]$.

<a id="function-plotkinasymptoticbound-fldfin-fldprelt"></a>
##### `PlotkinAsymptoticBound(K, delta): FldFin, FldPrElt -> FldPrElt`

Return the Plotkin asymptotic upper bound of the information rate for $\delta$ in $[0, 1]$ over the field $K$.

<a id="function-singletonasymptoticbound-fldprelt"></a>
##### `SingletonAsymptoticBound(delta): FldPrElt -> FldPrElt`

Return the Singleton asymptotic upper bound of the information rate for $\delta$ in $[0, 1]$ over any finite field.

<a id="function-hammingasymptoticbound-fldfin-fldprelt"></a>
##### `HammingAsymptoticBound(K, delta): FldFin, FldPrElt -> FldPrElt`

Return the Hamming asymptotic upper bound of the information rate for $\delta$ in $[0, 1]$ over the field $K$.

<a id="function-gilbertvarshamovasymptoticbound-fldfin-fldprelt"></a>
##### `GilbertVarshamovAsymptoticBound(K, delta): FldFin, FldPrElt -> FldPrElt`

Return the Gilbert–Varshamov asymptotic lower bound of the information rate for $\delta$ in $[0, 1]$ over the field $K$.

#### Other Bounds

<a id="function-griesmerlengthbound-fldfin-rngintelt-rngintelt"></a>
##### `GriesmerLengthBound(K, k, d): FldFin, RngIntElt, RngIntElt -> RngIntElt`

Return the Griesmer lower bound of the length of a linear code of dimension $k$ and minimum distance $d$ over $K$.

### Best Known Linear Codes

An $[n,k]$ linear code $C$ is said to be a *best known linear* $[n,k]$ *code* (BKLC) if $C$ has the highest minimum weight among all known $[n,k]$ linear codes.

An $[n,k]$ linear code $C$ is said to be an *optimal linear* $[n,k]$ *code* if the minimum weight of $C$ achieves the theoretical upper bound on the minimum weight of $[n,k]$ linear codes.

Magma currently has databases for best known linear codes over $GF(q)$ for $q=2,3,4,5,7,8,9$. There is also a database of best known quantum codes that can be found in Chapter [Quantum Codes](https://docs.magma-maths.org/CodingTheory/QuantumCodes/index-quantum-codes.md#chap-codequantum). The database for codes over $GF(2)$ contains constructions of best codes of length up to $n_{\max}=256$. The codes of length up to $n_{\rm  opt}=31$ are optimal. The database is complete in the sense that it contains a construction for every set of parameters. Thus the user has access to $33\,152$ best-known binary codes.

The database for codes over $GF(3)$ contains constructions of best codes of up to length $n_{\max}=243$. The codes of length up to $n_{\rm opt}=21$ are optimal. The database is complete up to length $n_{\rm complete}=120$. Many of the codes constructed in this database are vast improvements on the previously known bounds for best codes over $GF(3)$. The database of codes over $GF(3)$ is a contribution of Markus Grassl, Karlsruhe then Gdansk.

The database for codes over $GF(4)$ contains constructions of best codes of up to length $n_{\max}=256$. The codes of length up to $n_{\rm opt}=18$ are optimal. The database is over $67\%$ complete with the first missing code coming at length 99. Many of the codes constructed in this database are vast improvements on the previously known bounds for best codes over $GF(4)$.

Similar databases for other small fields were added in V2.14 and extended in V2.23. They are contributions of Markus Grassl, Karlsruhe then Gdansk. The statistics of all databases are summarised in the following table.

Compared to previous released versions of the Magma BKLC database, 1201 missing codes have been added, and the lower bound on the minimum distance has been improved for 5155 codes.

Best known upper and lower bounds on the minimum weight for $[n, k]$ linear codes are also available (see section [Best Known Bounds for Linear Codes](https://docs.magma-maths.org/CodingTheory/LinearCodes/bound.md#code-bound-best)).

The Magma BKLC database makes use of the tables of bounds compiled by A. E. Brouwer [[Bro98](https://docs.magma-maths.org/references.md#cite-brouwer)]. The online version of these tables [[Bro](https://docs.magma-maths.org/references.md#cite-brouwerweb)] has been discontinued. Similar tables are now maintained by Markus Grassl [[Graa](https://docs.magma-maths.org/references.md#cite-grasslweblin)]. Any improvements, errors, or problems with the Magma BKLC database should be reported to `codes@codetables.de`.

It should be noted that the Magma BKLC database is unrelated to the similar (but rather incomplete) BKLC database forming part of GUAVA, a share package in GAP3. A significant number of entries in the Magma BKLC database provide better codes than the corresponding ones listed in Brouwer’s tables.

The construction of the Magma BKLC database has been undertaken by John Cannon (Sydney), Markus Grassl (Karlsruhe) and Greg White (Sydney). The authors wish to express their appreciation to the following people who generously supplied codes, constructions, or other assistance: Nuh Aydin, Anton Betten, Michael Braun, Iliya Bouyukliev, Andries Brouwer, Tat Chan, Zhi Chen, Rumen Daskalov, Scott Duplichan, Iwan Duursma, Yves Edel, Sebastian Egner, Peter Farkas, Damien Fisher, Philippe Gaborit, Willi Geiselmann, Stephan Grosse, Aaron Gulliver, Masaaki Harada, Ray Hill, Plamen Hristov, David Jaffe, Axel Kohnert, San Ling, Simon Litsyn, Pawel Lizak, Tatsuya Maruta, Masami Mohri, Masakatu Morii, Harald Niederreiter, Ayoub Otmani, Fernanda Pambianco, James B. Shearer, Neil Sloane, Roberta Sabin, Cen Tjhai, Ludo Tolhuizen, Martin Tomlinson, Gerard van der Geer, Henk van Tilborg, Chaoping Xing, Karl-Heinz Zimmermann, Johannes Zwanzger.

Given any two of the parameters: length, dimension, and minimum weight, then Magma will return the code with the best possible value of the omitted parameter. Given a specified length and minimum weight, for example, will result in a corresponding code of maximal possible dimension.

The user can display the method used to construct a particular BKLC code through use of a verbose mode, triggered by the verbose flag `BestCode`. When it is set to `true`, all of the functions in this section will output the steps involved in each code they construct. While some codes are defined by stored generator matrices, and some use constructions which are not general enough, or safe enough, to be available to the user, most codes are constructed using standard Magma functions. Note that having the verbose flag `Code` set to `true` at the same time can produce mixed and confusing output, since the database uses functions which have verbose outputs dependent on this flag.

<a id="function-bklc-fldfin-rngintelt-rngintelt"></a>
#### `BKLC(K, n, k): FldFin, RngIntElt, RngIntElt -> Code, BoolElt`

<a id="function-bestknownlinearcode-fldfin-rngintelt-rngintelt"></a>
#### `BestKnownLinearCode(K, n, k): FldFin, RngIntElt, RngIntElt -> Code, BoolElt`

Given a finite field $K$, a positive integer $n$, and a non-negative integer $k$ such that $k\le n$, return an $[n,k]$ linear code over $K$ which has the largest minimum weight among all known $[n,k]$ linear codes. A second boolean return value signals whether or not the desired code exists in the database.

The databases currently available are over $GF(q)$ for $q=2,3,4,5,7,8,9$ of length up to $n_{\max}$ as given in the table above.

If the verbose flag `BestCode` is set to true then the method used to construct the code will be printed.

<a id="function-bllc-fldfin-rngintelt-rngintelt"></a>
#### `BLLC(K, k, d): FldFin, RngIntElt, RngIntElt -> Code, BoolElt`

<a id="function-bestlengthlinearcode-fldfin-rngintelt-rngintelt"></a>
#### `BestLengthLinearCode(K, k, d): FldFin, RngIntElt, RngIntElt -> Code, BoolElt`

Given a finite field $K$, and positive integers $k$ and $d$, return a linear code over $K$ with dimension $k$ and minimum weight at least $d$ which has the shortest length among known codes. A second boolean return value signals whether or not the desired code exists in the database.

The databases currently available are over $GF(q)$ for $q=2,3,4,5,7,8,9$ of length up to $n_{\max}$ as given in the table above.

If the verbose flag `BestCode` is set to true then the method used to construct the code will be printed.

<a id="function-bdlc-fldfin-rngintelt-rngintelt"></a>
#### `BDLC(K, n, d): FldFin, RngIntElt, RngIntElt -> Code, BoolElt`

<a id="function-bestdimensionlinearcode-fldfin-rngintelt-rngintelt"></a>
#### `BestDimensionLinearCode(K, n, d): FldFin, RngIntElt, RngIntElt -> Code`

Given a finite field $K$, a positive integer $n$, and a positive integer $d$ such that $d\le n$, return a linear code over $K$ with length $n$ and minimum weight $\ge d$ which has the largest dimension among known codes. A second boolean return value signals whether or not the desired code exists in the database.

The databases currently available are over $GF(q)$ for $q=2,3,4,5,7,8,9$ of length up to $n_{\max}$ as given in the table above.

If the verbose flag `BestCode` is set to true then the method used to construct the code will be printed.

<a id="example-ex-49ec3e"></a>
#### `Example: Best Known Binary Codes (ex-49ec3e)`

We look at some best known linear codes over $GF(2)$. Since the database over $GF(2)$ is completely filled, we can ignore the second boolean return value.

```magma
> C := BKLC(GF(2),23,12);
> C;
[23, 12, 7] Cyclic Linear Code over GF(2)
Generator matrix:
[1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 1 0 1 0]
[0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 1 0 1]
[0 0 1 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 0 1 0 0]
[0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 0 1 0]
[0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 0 1]
[0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 1 1 0 0 1 1 0 0]
[0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 1 1 0 0 1 1 0]
[0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 1 1 0 0 1 1]
[0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 1 1 1 0 0 0 1 1]
[0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 1 0 0 1 0 1 1]
[0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 1 1 1 1 1]
[0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 1 0 1 0 1]
> WeightDistribution(C);
[ <0, 1>, <7, 253>, <8, 506>, <11, 1288>, <12, 1288>, <15, 506>,
<16, 253>, <23, 1> ]
> BKLCLowerBound(GF(2),23,12), BKLCUpperBound(GF(2),23,12);
7 7
```

So we see that this code is optimal, in the sense that it meets the best known upper bound on its minimum weight. (All best known binary codes of length up to $31$ are optimal).

However larger best known codes are not optimal, making it theoretically possible that better codes exist.

```magma
> C := BKLC(GF(2),145,36);
> C:Minimal;
[145, 36, 42] Linear Code over GF(2)
> BKLCLowerBound(GF(2),145,36), BKLCUpperBound(GF(2),145,36);
42 52
```

<a id="example-ex-018bf4"></a>
#### `Example: Best Known Quaternary Codes (ex-018bf4)`

We look at some best known codes over $GF(4)$. Since this database is only approximately $66\%$ complete, it is necessary to check the second boolean return value to know if the database contains the desired code.

```magma
> F<w> := GF(4);
> C, has_code := BKLC(F, 14, 9);
> has_code;
true
> C;
[14, 9, 4] Linear Code over GF(2^2)
Generator matrix:
[  1   0   0   0   0   0   0   0   0   0   0 w^2   w   1]
[  0   1   0   0   0   0   0   0   0   0   1   1   1 w^2]
[  0   0   1   0   0   0   0   0   0   0 w^2   w   0   w]
[  0   0   0   1   0   0   0   0   0   0   w   1   1   w]
[  0   0   0   0   1   0   0   0   0   0   w   0   w w^2]
[  0   0   0   0   0   1   0   0   0   0 w^2   1   1   1]
[  0   0   0   0   0   0   1   0   0   0   1   w w^2   0]
[  0   0   0   0   0   0   0   1   0   0   0   1   w w^2]
[  0   0   0   0   0   0   0   0   1   0 w^2 w^2   0   1]
> BKLCLowerBound(F, 14, 9), BKLCUpperBound(F, 14, 9);
4 4
```

Since the database over $GF(4)$ is completely filled up to length $97$ the boolean value was in fact unnecessary in this case. We see that the minimum weight of this code reaches the theoretical upper bound, as do all best known codes over $GF(4)$ up to length $18$.

<a id="example-ex-508dda"></a>
#### `Example: Best Known Lengths of Binary Codes (ex-508dda)`

We search for best known codes using dimension and minimum weight, looking at codes over $GF(2)$ of dimension $85$. Even though the database over $GF(2)$ is $100\%$ filled up to length $256$, the code required may be longer than that so we have to check the second boolean return value.

```magma
> C, has_code := BestLengthLinearCode(GF(2),85,23);
> has_code;
true
> C:Minimal;
[166, 85, 23] Linear Code over GF(2)
>
> C, has_code := BestLengthLinearCode(GF(2),85,45);
> has_code;
true
> C:Minimal;
[233, 85, 45] Linear Code over GF(2)
>
> C, has_code := BestLengthLinearCode(GF(2),85,58);
> has_code;
false
```

<a id="example-ex-2cda79"></a>
#### `Example: Best Known Dimensions of Quaternary Codes (ex-2cda79)`

For a given minimum weight, we find the maximal known possible dimensions for a variety of code lengths over $GF(4)$.

For lengths $<98$ we know the database is filled so we do not need to check the second boolean return value.

```magma
> F<w> := GF(4);
> C := BDLC(F, 12, 8);
> C;
[12, 3, 8] Linear Code over GF(2^2)
Generator matrix:
[  1   0   0   w w^2   w w^2   w   w   1   w   w]
[  0   1   0   w w^2   1   0 w^2   w   0 w^2 w^2]
[  0   0   1   0   1 w^2 w^2 w^2   0 w^2   w   w]
>
> C := BDLC(F, 27, 8);
> C:Minimal;
[27, 15, 9] Linear Code over GF(2^2)
> C := BDLC(F, 67, 8);
> C:Minimal;
[67, 52, 8] Linear Code over GF(2^2)
```

But for lengths $\ge 98$ there may be gaps in the database so to be safe we check the second value.

```magma
> C, has_code := BDLC(F, 99, 8);
> has_code;
true
> C:Minimal;
[99, 81, 8] Linear Code over GF(2^2)
> C, has_code := BDLC(F, 195, 8);
> has_code;
true
> C:Minimal;
[195, 174, 8] Linear Code over GF(2^2)
```

<a id="example-ex-026c31"></a>
#### `Example: Reconstructing a Best Known Code (ex-026c31)`

We find the best known code of length $54$ and dimension $36$, then using the output of the verbose mode we re-create this code manually.

```magma
> SetPrintLevel("Minimal");
> SetVerbose("BestCode",true);
> P<x> := PolynomialRing(GF(2));
> a := BKLC(GF(2), 54, 36);
Construction of a [ 54 , 36 , 8 ] Code:
[1]:  [63, 46, 7] Cyclic Code over GF(2)
       CyclicCode of length 63 with generating polynomial x^17 +
       x^16 + x^15 + x^13 + x^12 + x^8 + x^6 + x^4 + x^3 + x^2 +
       1
[2]:  [64, 46, 8] Linear Code over GF(2)
       ExtendCode [1] by 1
[3]:  [54, 36, 8] Linear Code over GF(2)
       Shortening of [2] at { 55 .. 64 }
> a;
[54, 36, 8] Linear Code over GF(2)
>
> p := x^17 + x^16 + x^15 + x^13 + x^12 + x^8 + x^6 + x^4 +
>                                               x^3 + x^2 + 1;
> C1 := CyclicCode(63, p);
> C1;
[63, 46] Cyclic Code over GF(2)
> C2 := ExtendCode(C1);
> C2;
[64, 46] Linear Code over GF(2)
> C3 := ShortenCode(C2, {55 .. 64});
> C3;
[54, 36, 8] Linear Code over GF(2)
>
> C3 eq a;
true
```

### Decoding

Magma supplies functions for decoding vectors from the ambient space of a linear code $C$. The functions in this section only apply to codes over finite fields.

#### Syndrome Decoding

While syndrome decoding applies to any linear code it is restricted to codes having small codimension since it needs to calculate the coset leaders.

<a id="function-syndromedecoding-codelinfld-modtuprngelt"></a>
##### `SyndromeDecoding(C, v): CodeLinFld, ModTupRngElt -> BoolElt, ModTupRngElt`

Given a linear code $C$ and a vector $v$ from the ambient space $V$ of $C$, attempt to decode $v$ with respect to $C$.

If the decoding algorithm succeeds in computing a vector $v'$ as the decoded version of $v$, then the function returns `true` and $v'$. If the decoding algorithm does not succeed in decoding $v$, then the function returns `false` and the zero vector.

<a id="function-syndromedecoding-codelinfld-modtuprngelt-2"></a>
##### `SyndromeDecoding(C, Q): CodeLinFld, [ ModTupRngElt ] -> [ BoolElt ], [ ModTupRngElt ]`

Given a linear code $C$ and a sequence $Q$ of vectors from the ambient space $V$ of $C$, attempt to decode the vectors of $Q$ with respect to $C$. This function is similar to the function `SyndromeDecoding(C, v)` except that rather than decoding a single vector, it decodes a sequence of vectors and returns a sequence of booleans and a sequence of decoded vectors corresponding to the given sequence.

<a id="example-ex-8f7190"></a>
##### `Example: Syndrome Decoding (ex-8f7190)`

We create a code $C$ and a vector $v$ of $C$ and then perturb $v$ to a new vector $w$. We then decode $w$ to find $v$ again.

```magma
> C := GolayCode(GF(2), false);
> v := C ! [1,1,1,1,0,0,0,1,0,0,1,1,0,0,0,1,0,0,0,1,1,1,1];
> w := v;
> w[5] := 1 - w[5];
> w[20] := 1 - w[20];
> v;
(1 1 1 1 0 0 0 1 0 0 1 1 0 0 0 1 0 0 0 1 1 1 1)
> w;
(1 1 1 1 1 0 0 1 0 0 1 1 0 0 0 1 0 0 0 0 1 1 1)
> v - w;
(0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0)
> b, d := SyndromeDecoding(C, w);
> b;
true
> d;
(1 1 1 1 0 0 0 1 0 0 1 1 0 0 0 1 0 0 0 1 1 1 1)
> d eq v;
true
> SyndromeDecoding(C, [w]);
[ true ]
[
    (1 1 1 1 0 0 0 1 0 0 1 1 0 0 0 1 0 0 0 1 1 1 1)
]
```

#### Euclidean Decoding

The Euclidean decoding algorithm applies to alternant codes which include BCH, Goppa, and Reed–Solomon codes. While the Euclidean algorithm cannot correct as many errors as can the syndrome algorithm, in general it is much faster and so can be applied to much larger codes. This is because the syndrome algorithm needs to determine the coset leaders of the code and so becomes inapplicable as soon as the codimension of the code is moderately large.

<a id="function-euclideandecoding-codelinfld-modtuprngelt"></a>
##### `EuclideanDecoding(C, v): CodeLinFld, ModTupRngElt -> BoolElt, ModTupRngElt`

Given a linear alternant code $C$ and a vector $v$ from the ambient space $V$ of $C$, attempt to decode $v$ with respect to $C$.

If the decoding algorithm succeeds in computing a vector $v'$ as the decoded version of $v$, then the function returns `true` and $v'$. It may even happen that $v'$ is not in $C$ because there are too many errors in $v$ to correct. If the decoding algorithm does not succeed in decoding $v$, then the function returns `false` and the zero vector.

<a id="function-euclideandecoding-codelinfld-modtuprngelt-2"></a>
##### `EuclideanDecoding(C, Q): CodeLinFld, [ ModTupRngElt ] -> [ BoolElt ], [ ModTupRngElt ]`

Given a linear alternant code $C$ and a sequence $Q$ of vectors from the ambient space $V$ of $C$, attempt to decode the vectors of $Q$ with respect to $C$. This function is similar to the function `EuclideanDecoding(C, v)` except that rather than decoding a single vector, it decodes a sequence of vectors and returns a sequence of booleans and a sequence of decoded vectors corresponding to the given sequence.

<a id="example-ex-72e926"></a>
##### `Example: Euclidean Decoding of a Reed-Solomon Code (ex-72e926)`

We create a Reed-Solomon code $C$ over $GF(2^8)$ with designated minimum distance $12$.

```magma
> K := GF(2^8);
> C := ReedSolomonCode(K, 12);
> C:Minimal;
[255, 244, 12] "BCH code (d = 12, b = 1)" Linear Code over GF(2^8)
```

So our code has length $255$ and dimension $244$. With minimum distance $12$ it will correct $5$ or fewer errors. We demonstrate this by introducing $5$ errors into a random codeword $c$.

```magma
> c := Random(C);
> V := VectorSpace(C);
> e := V![ 0 :i in [1..255]];
> for i := 1 to 5 do
> j := Random(1, 255);
> k := Random(K);
> e[j] := k;
> end for;
> d := c + e;
> _, cc := EuclideanDecoding(C, d);
> c eq cc;
true;
```

If we introduce $6$ or more errors the decoding will usually fail:-

```magma
> e := V![ 0 :i in [1..255]];
> for i := 1 to 6 do
> j := Random(1, 255);
> k := Random(K);
> e[j] := k;
> end for;
> d := c + e;
> _, cc := EuclideanDecoding(C, d);
> c eq cc;
false
```

#### Permutation Decoding

<a id="function-ispermutationdecodeset-codelinfld-rngintelt-algmatelt-rngintelt"></a>
##### `IsPermutationDecodeSet(C, I, S, s): CodeLinFld, [RngIntElt], [AlgMatElt], RngIntElt -> BoolElt`

<a id="function-ispermutationdecodeset-codelinfld-rngintelt-grppermelt-rngintelt"></a>
##### `IsPermutationDecodeSet(C, I, S, s): CodeLinFld, [RngIntElt], [GrpPermElt], RngIntElt -> BoolElt`

Given

**–**
an $[n,k]$ linear code $C$ over a finite field $K$;

**–**
an information set $I \subseteq \{1,\ldots,n \}$ for $C$ as a sequence of coordinate positions;

**–**
a sequence $S$ of elements in the group of monomial matrices of degree $n$ over $K$, OR if $C$ is a binary code, a sequence of elements in the symmetric group ${\operatorname{Sym}}(n)$ acting on the set $\{1,\ldots,n\}$. In either case $S$ must be an $s$-PD-set for $C$ with respect to $I$;

**–**
and an integer $s \in \{1,\ldots,t\}$, where $t$ is the error-correcting capability of $C$;

this intrinsic returns `true` if and only if $S$ is an $s$-PD-set for $C$ with respect to the information set $I$.

Depending on the length of the code $C$, its dimension $k$, and the integer $s$, this function could take some time to compute whether $S$ is an $s$-PD-set for $C$ with respect to $I$. Specifically, if the function returns `true`, it is necessary to check $\sum_{i=1}^s {{k}\choose{i}} \cdot {{n-k}\choose{s-i}}$ $s$-sets.

The verbose flag `IsPDSetFlag` is set to level 0 by default. If it is set to level 1, the total time used to check the condition is shown. Moreover, the reason the function returns `false` is also shown, that is, whether $I$ is not an information set, $S$ is not a subset of the monomial automorphism group of $C$ or $S$ is not an $s$-PD-set. If it is set to level 2, the percentage of the computation process performed is also printed.

<a id="function-permutationdecode-codelinfld-rngintelt-algmatelt-rngintelt-modtupfldelt"></a>
##### `PermutationDecode(C, I, S, s, u): CodeLinFld, [RngIntElt], [AlgMatElt], RngIntElt, ModTupFldElt -> BoolElt, ModTupFldElt`

<a id="function-permutationdecode-codelinfld-rngintelt-grppermelt-rngintelt-modtupfldelt"></a>
##### `PermutationDecode(C, I, S, s, u): CodeLinFld, [RngIntElt], [GrpPermElt], RngIntElt, ModTupFldElt -> BoolElt, ModTupFldElt`

Given

**–**
an $[n,k]$ linear code $C$ over a finite field $K$;

**–**
an information set $I \subseteq \{1,\ldots,n \}$ for $C$ as a sequence of coordinate positions;

**–**
a sequence $S$ of elements in the group of monomial matrices of degree $n$ over $K$, OR if $C$ is a binary code, a sequence of elements in the symmetric group ${\operatorname{Sym}}(n)$ acting on the set $\{1,\ldots,n\}$. In either case $S$ must be an $s$-PD-set for $C$ with respect to $I$;

**–**
an integer $s \in \{1,\ldots,t\}$, where $t$ is the error-correcting capability of $C$;

**–**
and a vector $u$ from the ambient space $V$ of $C$,

the intrinsic attempts to decode $u$ with respect to $C$. If the decoding algorithm succeeds in computing a vector $u'\in C$ as the decoded version of $u \in V$, then the function returns `true` and the codeword $u'$. If the decoding algorithm does not succeed in decoding $u$, then the function returns `false` and the zero vector in $V$.

The decoding algorithm works by moving all errors in the received vector $u=c+e$, where $c \in C$ and $e \in V$ is the error vector with at most $t$ errors, out of the information positions, that is, moving the nonzero coordinates of $e$ out of the information set $I$ for $C$, by using an automorphism of $C$. Note that the function does not check any of the conditions that $I$ is an information set for $C$, $S$ is an $s$-PD-set for $C$ with respect to $I$, or $s\leq t$.

<a id="function-permutationdecode-codelinfld-rngintelt-algmatelt-rngintelt-modtupfldelt-2"></a>
##### `PermutationDecode(C, I, S, s, Q): CodeLinFld, [RngIntElt], [AlgMatElt], RngIntElt, [ModTupFldElt] -> [BoolElt], [ModTupFldElt]`

<a id="function-permutationdecode-codelinfld-rngintelt-grppermelt-rngintelt-modtupfldelt-2"></a>
##### `PermutationDecode(C, I, S, s, Q): CodeLinFld, [RngIntElt], [GrpPermElt], RngIntElt, [ModTupFldElt] -> [BoolElt], [ModTupFldElt]`

Given

**–**
an $[n,k]$ linear code $C$ over a finite field $K$;

**–**
an information set $I \subseteq \{1,\ldots,n \}$ for $C$ as a sequence of coordinate positions;

**–**
a sequence $S$ of elements in the group of monomial matrices of degree $n$ over $K$, OR if $C$ is a binary code, a sequence of elements in the symmetric group ${\operatorname{Sym}}(n)$ acting on the set $\{1,\ldots,n\}$. In either case $S$ must be an $s$-PD-set for $C$ with respect to $I$;

**–**
an integer $s \in \{1,\ldots,t\}$, where $t$ is the error-correcting capability of $C$;

**–**
a sequence $Q$ of vectors from the ambient space $V$ of $C$,

the intrinsic attempts to decode the vectors of $Q$ with respect to $C$. This function is similar to the function `PermutationDecode(C, I, S, s, u)` except that rather than decoding a single vector, it decodes a sequence of vectors and returns a sequence of booleans and a sequence of decoded vectors corresponding to the given sequence. The algorithm used is as for the function `PermutationDecode(C, I, S, s, u)`.

<a id="function-pdsetsimplexcode-fldfin-rngintelt"></a>
##### `PDSetSimplexCode(K, m): FldFin, RngIntElt -> SeqEnum, SeqEnum, SeqEnum`

Given a finite field $K$ of cardinality $q$, and a positive integer $m$, the intrinsic constructs the $[n=(q^m-1)/(q-1), m, q^{m-1}]$ linear simplex code $C$ over $K$, as `Dual(HammingCode(K, m))`, and then searches for an $s$-PD-set for $C$. The function returns an information set $I$ for $C$ together with a subset $S$ of the monomial automorphism group of $C$ such that $S$ is an $s$-PD-set for $C$ with respect to $I$, where $s=\left \lfloor{(q^{m}-1)/(m(q-1))} \right \rfloor -1$.

The information set $I$ is returned as a sequence of $m$ integers, giving the coordinate positions that correspond to the information set for $C$. The set $S$ is also returned as a sequence, which contains the $s+1$ elements in the group of monomial matrices of degree $n$ over $K$ described in [[FKM12](https://docs.magma-maths.org/references.md#cite-key)]. When $K$ is $GF(2)$, the function also returns the elements of $S$ represented as elements in the symmetric group $Sym(n)$ of permutations on the set $\{1,\ldots,n \}$.

<a id="function-pdsethadamardcode-rngintelt"></a>
##### `PDSetHadamardCode(m): RngIntElt -> SeqEnum, SeqEnum, SeqEnum`

Given a positive integer $m$, the intrinsic constructs the $[2^m, m+1, 2^{m-1}]$ binary linear Hadamard code $C$, as `Dual(ExtendCode(HammingCode(GF(2), m)))`, and then searches for an $s$-PD-set for $C$. The function returns an information set $I \subseteq \{1,\ldots, 2^m \}$ for $C$ together with a subset $S$ of the permutation automorphism group of $C$ such that $S$ is an $s$-PD-set for $C$ with respect to $I$, where $s= \left \lfloor {2^{m}/(m+1)} \right \rfloor -1$.

The information set $I$ is returned as a sequence of $m+1$ integers, giving the coordinate positions that correspond to the information set for $C$. The set $S$ is also returned as a sequence, which contains the $s+1$ elements in the group of permutation matrices of degree $2^m$ over $GF(2)$ described in [[BV16b](https://docs.magma-maths.org/references.md#cite-bv2015a)]. The function also returns the elements of $S$ represented as elements in the symmetric group ${\operatorname{Sym}}(2^m)$ of permutations on the set $\{1,\ldots,2^m \}$.

<a id="example-ex-7bde55"></a>
##### `Example: Permutation Decoding of a Binary Code (ex-7bde55)`

```magma
> C := Dual(ExtendCode(HammingCode(GF(2), 5)));
> C;
[32, 6, 16] Linear Code over GF(2)
Generator matrix:
[1 0 0 0 0 0 1 1 1 0 0 1 0 0 0 1 0 1 0 1 1 1 1 0 1 1 0 1 0 0 1 1]
[0 1 0 0 0 0 1 0 0 1 0 1 1 0 0 1 1 1 1 1 0 0 0 1 1 0 1 1 1 0 1 0]
[0 0 1 0 0 0 1 0 1 0 1 1 1 1 0 1 1 0 1 0 0 1 1 0 0 0 0 0 1 1 1 1]
[0 0 0 1 0 0 1 0 1 1 0 0 1 1 1 1 1 0 0 0 1 1 0 1 1 1 0 1 0 1 0 0]
[0 0 0 0 1 0 0 1 0 1 1 0 0 1 1 1 1 1 0 0 0 1 1 0 1 1 1 0 1 0 1 0]
[0 0 0 0 0 1 1 1 0 0 1 0 0 0 1 0 1 0 1 1 1 1 0 1 1 0 1 0 0 1 1 1]

> I, SMAut, SPAut := PDSetHadamardCode(5);
> I in AllInformationSets(C);
true
> s := #SMAut-1;  s;
4
> [ LinearCode(GeneratorMatrix(C)*SMAut[i]) eq C : i in [1..s+1] ];
[true, true, true, true, true];
> [ LinearCode(GeneratorMatrix(C)^SPAut[i]) eq C : i in [1..s+1] ];
[true, true, true, true, true];
> IsPermutationDecodeSet(C, I, SMAut, s);
true
> IsPermutationDecodeSet(C, I, SPAut, s);
true

> c := C ! [1^^32];
> c in C;
true
> u := c;
> u[1] := c[1] + 1;
> u[2] := c[2] + 1;
> u[4] := c[4] + 1;
> u[32] := c[32] + 1;
> u in C;
false
> isDecoded, uDecoded := PermutationDecode(C, I, SMAut, s, u);
> isDecoded;
true
> uDecoded eq c;
true
> isDecoded, uDecoded := PermutationDecode(C, I, SPAut, s, u);
> isDecoded;
true
> uDecoded eq c;
true
```

<a id="example-ex-982ee0"></a>
##### `Example: Permutation Decoding of a Quaternary Code (ex-982ee0)`

```magma
> K<a> := GF(4);
> C := Dual(HammingCode(K, 3));
> C;
[21, 3, 16] Linear Code over GF(2^2)
Generator matrix:
[1 0 a^2 a 1 0 a^2 a 1 a^2 0 1 a a 1 0 a^2 1 a a^2 0]
[0 1 1 1 1 0 0 0 0 a^2 a^2 a^2 a^2 a a a a 1 1 1 1]
[0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]

> I, SMAut := PDSetSimplexCode(K, 3);
> I in AllInformationSets(C);
true
> s := #SMAut-1;  s;
6
> [ LinearCode(GeneratorMatrix(C)*SMAut[i]) eq C : i in [1..s+1] ];
[true, true, true, true, true, true, true];
> IsPermutationDecodeSet(C, I, SMAut, s);
true

> c := C ! [0,1,1,1,1,0,0,0,0,a^2,a^2,a^2,a^2,a,a,a,a,1,1,1,1];
> c in C;
true
> u := c;
> u[1] := c[1] + a;
> u[2] := c[2] + a^2;
> u[3] := c[3] + a;
> u[4] := c[4] + a^2;
> u[5] := c[5] + a;
> u[6] := c[6] + a^2;
> u in C;
false
> isDecoded, uDecoded := PermutationDecode(C, I, SMAut, s, u);
> isDecoded;
true
> uDecoded eq c;
true
```

### Transforms

<a id="mattson-solomon-transforms"></a>
#### Mattson–Solomon Transforms

<a id="function-mattsonsolomontransform-rngupolelt-rngintelt"></a>
##### `MattsonSolomonTransform(f, n): RngUPolElt, RngIntElt -> RngUPolElt`

Given $f$, a polynomial over a finite field containing a primitive $n$-th root of unity, return the Mattson–Solomon transform of parameter $n$.

<a id="function-inversemattsonsolomontransform-rngupolelt-rngintelt"></a>
##### `InverseMattsonSolomonTransform(A, n): RngUPolElt, RngIntElt -> RngUPolElt`

Given $A$, a polynomial over a finite field containing a primitive $n$-th root of unity, return the inverse Mattson–Solomon transform of parameter $n$.

<a id="example-ex-15eadc"></a>
##### `Example: Mattson-Solomon Transform (ex-15eadc)`

We compute the Mattson–Solomon transform of parameter $n=7$ of the polynomial $x^4 + x^2 + x + 1$ over ${\bf F}_{2^{12}}$.

```magma
> n := 7;
> K := GF(2, 12);
> FP<x> := PolynomialRing(K);
> f := x^4 + x^2 + x + 1;
> A := MattsonSolomonTransform(f, n);
> A;
x^6 + x^5 + x^3
```

#### Krawchouk Polynomials

<a id="function-krawchoukpolynomial-fldfin-rngintelt-rngintelt"></a>
##### `KrawchoukPolynomial(K, n, k): FldFin, RngIntElt, RngIntElt -> RngUPolElt`

Return the Krawchouk polynomial of parameters $k$ and $n$ in $K$ over the rational field.

<a id="function-krawchouktransform-rngupolelt-fldfin-rngintelt"></a>
##### `KrawchoukTransform(f, K, n): RngUPolElt, FldFin, RngIntElt -> RngUPolElt`

Return the Krawchouk transform of the polynomial $f$ over the rational field with respect to the vector space $K^n$.

<a id="function-inversekrawchouk-rngupolelt-fldfin-rngintelt"></a>
##### `InverseKrawchouk(A, K, n): RngUPolElt, FldFin, RngIntElt -> RngUPolElt`

Return the inverse Krawchouk transform of the polynomial $A$ over the rational field with respect to the vector space $K^n$.

### Automorphism Groups

#### Introduction

Let $C$ be an $[n, k]$ linear code and $G$ a permutation group of degree $n$. Then $G$ acts on $C$ in the following way: for a codeword $v$ of $C$ and a permutation $x$ of $G$, the image of $v$ under $x$ is obtained from $v$ by permuting the coordinate positions of $v$ according to $x$. We call this the *permutation* action of $G$ on $C$. If $C$ is a non-binary code over a finite field, there is also a *monomial* action on $C$. Let $K$ be the alphabet of $C$. A monomial permutation of monomial degree $n$ is equivalent to a permutation $s$ on $K^{*} \times \lbrace 1, \ldots, n \rbrace$ which satisfies the following property:

$$
(\alpha, i)^s = (\beta, j) \hbox{ implies }
(\gamma\alpha, i)^s = (\gamma\beta, j)
$$

for all $\alpha, \beta, \gamma \in K^{*}$ and $i,j \in \lbrace 1, \ldots, n \rbrace$. The actual degree of $s$ is $(q - 1)n$. Note that $s$ is completely determined by its action on the points $(1, i)$ for each $i$, and the matrix representation of $s$ is also determined by its action on the elements $(1,i)$, for $1 \le i \le n$. To represent a monomial permutation of monomial degree $n$, we number the pair $(\alpha, i)$ by $(q - 1)(i - 1) + \alpha$ and then use a permutation $s$ of degree $(q - 1)n$. The functions in this section allow one to investigate such actions. The algorithms in Magma to compute with such actions are backtrack searches due to Jeff Leon [[Leo82](https://docs.magma-maths.org/references.md#cite-leon1)][[Leo97](https://docs.magma-maths.org/references.md#cite-leon2)]. There are 4 algorithms which are provided for codes of length $n$ over a field of cardinality $q$:

**(a)**
*Automorphism group* or *Monomial group*. Computes the group of monomials which map a code into itself, where monomials are represented as permutations of degree $(q - 1)n$ (so the group has degree $(q-1)n$). For this function $q$ may be any small prime or 4.

**(b)**
*Permutation group*. Computes the group of permutations which map a code into itself (so the group has degree n). For this function $q$ may be any small prime or 4.

**(c)**
*Equivalence test*. Computes whether there is a monomial permutation which maps a code to another code and, if so, returns the monomial as a permutation of degree $(q - 1)n$. For this function, $q$ may be any small prime or 4.

**(d)**
*Isomorphism test*. Computes whether there is a permutation which maps a code to another code and returns the permutation (of degree $n$) if so. For this function $q$ may only be 2.

For more information on permutation group actions and orbits, see Chapter [Permutation Groups](https://docs.magma-maths.org/FiniteGroups/PermutationGroups/index-permutation-groups.md#chapgrpperm).

#### Group Actions

<a id="operation-op-pow-modtupfldelt-grppermelt"></a>
##### `v ^ x: ModTupFldElt, GrpPermElt -> ModTupFldElt`

Given a codeword $v$ belonging to the $[n, k]$ code $C$ and an element $x$ belonging to a permutation group $G$, construct the vector $w$ obtained from $v$ by the action of $x$. If $G$ has degree $n$, the permutation action is used; otherwise $G$ should have degree $n(q - 1)$ and the monomial action is used.

<a id="operation-op-pow-modtupfldelt-grpperm"></a>
##### `v ^ G: ModTupFldElt, GrpPerm -> GSet{ ModTupFldElt }`

Given a codeword $v$ belonging to the $[n, k]$ code $C$ and a permutation group $G$ (with permutation or monomial action on $C$), construct the vector orbit $Y$ of $v$ under the action of $G$. The orbit $Y$ is a $G$-set for the group $G$.

<a id="operation-op-pow-code-grppermelt"></a>
##### `C ^ x: Code, GrpPermElt -> Code`

Given an $[n, k]$ code $C$ and an element $x$ belonging to a permutation group $G$ (with permutation or monomial action on $C$), construct the code consisting of all the images of the codewords of $C$ under the action of $x$.

<a id="operation-op-pow-code-grpperm"></a>
##### `C ^ G: Code, GrpPerm -> GSet{ Code }`

Given an $[n, k]$ code $C$ and a permutation group $G$ (with permutation or monomial action on $C$), construct the orbit $Y$ of $C$ under the action of $G$. The orbit $Y$ is a $G$-set for the group $G$.

<a id="operation-op-pow-modtupfldelt-grppermelt-2"></a>
##### `S ^ x: [ModTupFldElt], GrpPermElt -> [ModTupFldElt]`

<a id="operation-op-pow-modtupfldelt-grppermelt-3"></a>
##### `S ^ x: { ModTupFldElt }, GrpPermElt -> { ModTupFldElt }`

Given a set or sequence $S$ of codewords belonging to the $[n, k]$ code $C$ and an element $x$ belonging to a permutation group (with permutation or monomial action on the codewords), construct the set or sequence of the vectors obtained by permuting the coordinate positions of $v$, for each $v$ in $S$, according to the permutation $x$.

<a id="operation-op-pow-code-grppermelt-2"></a>
##### `S ^ x: [Code], GrpPermElt -> [Code]`

<a id="operation-op-pow-code-grppermelt-3"></a>
##### `S ^ x: { Code }, GrpPermElt -> { Code }`

Given a set or sequence $S$ of codes of length $n$ and an element $x$ belonging to a permutation group (with permutation or monomial action on the codes) construct the set or sequence of the codes consisting of all the images of the codewords of $C$ under the action of $x$.

<a id="function-fix-code-grpperm"></a>
##### `Fix(C, G): Code, GrpPerm -> Code`

Given an $[n, k]$ code $C$ and a permutation group $G$ of degree $n$, find the subcode of $C$ which consists of those vectors of $C$ which are fixed by the elements of $G$. That is, the subcode consists of those codewords that are fixed by the group $G$.

#### Automorphism Group

<a id="function-automorphismgroup-code"></a>
##### `AutomorphismGroup(C: parameters): Code -> GrpPerm, PowMap, Map`

<a id="function-monomialgroup-code"></a>
##### `MonomialGroup(C: parameters): Code -> GrpPerm, PowMap, Map`

```magma
Al    : MonStgElt                    Default: "Leon"
Weight: RngIntElt                    Default: 0
```

The automorphism group $A$ of the $[n, k]$ linear code $C$ over the field $K$, where $A$ is the group of all monomial-action permutations which preserve the code. Thus both permutation of coordinates and multiplication of components by non-zero elements from $K$ is allowed, and the degree of $A$ is $n(q - 1)$ where $q$ is the cardinality of $K$. A power structure $P$ and transfer map $t$ are also returned, so that, given a permutation $g$ from $A$, one can create a map $f = t(g)$ which represents the automorphism $g$ as a mapping $P: C \rightarrow C$.

If the code is known to have very few words of low weight, then it may take some time to compute the *support* of the code (a set of low weight words). The optional parameter `Weight` can be used to specify the set of vectors of the specified weight to be used as the support in the algorithm. This set should be of a reasonable size, (possibly hundreds for a large code), while also keeping the weight as small as possible.

Warning: If `Weight` specifies a set that is too small, then the algorithm risks getting stuck.

For a code over $GF(2)$ two backtrack searches are available, and the parameter `Al`, with valid string values `"Leon"` and `"Unger"`, selects between them. The default is `"Leon"`, which is usually the faster of the two by a considerable margin. The value `"Unger"` selects a partition backtrack search on the set of words used as the support; this is generally slower, but it does not have the limit on the size of that set which the `"Leon"` method has, so it can be used for a code where the `"Leon"` method reports that the set of minimum-weight words is too large. Over a larger field the parameter is ignored.

<a id="function-permutationgroup-code"></a>
##### `PermutationGroup(C): Code -> GrpPerm, PowMap, Map`

The permutation group $G$ of the $[n, k]$ linear code $C$ over the field $K$, where $G$ is the group of all permutation-action permutations which preserve the code. Thus only permutation of coordinates is allowed, and the degree of $G$ is always $n$. A power structure $P$ and transfer map $t$ are also returned, so that, given a permutation $g$ from $G$, one can create a map $f = t(g)$ which represents the automorphism $g$ as a mapping $P: C \rightarrow C$.

<a id="function-automorphismsubgroup-code"></a>
##### `AutomorphismSubgroup(C): Code -> GrpPerm, PowMap, Map`

<a id="function-monomialsubgroup-code"></a>
##### `MonomialSubgroup(C): Code -> GrpPerm, PowMap, Map`

A subgroup of the (monomial) automorphism group $A$ of the code $C$. If the automorphism group of $C$ is already known then the group returned is the full automorphism group, otherwise it will be a subgroup generated by one element. This allows one to find just one automorphism of $C$ if desired. A power structure $P$ and transfer map $t$ are also returned, so that, given a permutation $g$ from $A$, one can create a map $f = t(g)$ which represents the automorphism $g$ as a mapping $P: C \rightarrow C$.

<a id="function-automorphismgroupstabilizer-code-rngintelt"></a>
##### `AutomorphismGroupStabilizer(C, k): Code, RngIntElt -> GrpPerm, PowMap, Map`

<a id="function-monomialgroupstabilizer-code-rngintelt"></a>
##### `MonomialGroupStabilizer(C, k): Code, RngIntElt -> GrpPerm, PowMap, Map`

The subgroup of the (monomial) automorphism group $A$ of the code $C$, which stabilizes the first $k$ base points as chosen by the backtrack search. These base points may be different to those of the returned group. A power structure $P$ and transfer map $t$ are also returned, so that, given a permutation $g$ from $A$, one can create a map $f = t(g)$ which represents the automorphism $g$ as a mapping $P: C \rightarrow C$.

<a id="function-aut-code"></a>
##### `Aut(C): Code -> Pow, Map`

The power structure $A$ of all automorphisms of the code $C$ (with monomial action), together with the transfer map $t$ into $A$ from the generic symmetric group associated with the automorphism group of $C$.

<a id="function-aut-code-monstgelt"></a>
##### `Aut(C, T): Code, MonStgElt -> Pow, Map`

The power structure $A$ of all automorphisms of the code $C$, together with the transfer map $t$ into $A$ from the generic symmetric group associated with the automorphism group of $C$; the string $T$ determines which action type should be used: `"Monomial"` or `"Permutation"`.

<a id="example-ex-d651f4"></a>
##### `Example: Automorphism Group of a Reed-Muller Code (ex-d651f4)`

We compute the automorphism group of the second order Reed–Muller code of length 64.

```magma
> C := ReedMullerCode(2, 6);
> aut := AutomorphismGroup(C);
> FactoredOrder(aut);
[ <2, 21>, [3, 4>, <5, 1>, <7, 2>, <31, 1> ]
> CompositionFactors(aut);
    G
    |  A(5, 2)                = L(6, 2)
    *
    |  Cyclic(2)
    *
    |  Cyclic(2)
    *
    |  Cyclic(2)
    *
    |  Cyclic(2)
    *
    |  Cyclic(2)
    *
    |  Cyclic(2)
    1
```

<a id="example-ex-374f40"></a>
##### `Example: Automorphism Group via Minimum Weight Words (ex-374f40)`

We compute the automorphism group of a BCH code using the set of vectors of minimal weight as the invariant set. We look first at its weight distribution to confirm that there is sufficient vectors.

```magma
> C := BCHCode(GF(2),23,2);
> C;
[23, 12, 7] BCH code (d = 2, b = 1) over GF(2)
Generator matrix:
[1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 1 0 1 0]
[0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 1 0 1]
[0 0 1 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 0 1 0 0]
[0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 0 1 0]
[0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 0 1]
[0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 1 1 0 0 1 1 0 0]
[0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 1 1 0 0 1 1 0]
[0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 1 1 0 0 1 1]
[0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 1 1 1 0 0 0 1 1]
[0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 1 0 0 1 0 1 1]
[0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 1 1 1 1 1]
[0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 1 0 1 0 1]
> WeightDistribution(C);
[ <0, 1>, <7, 253>, <8, 506>, <11, 1288>, <12, 1288>, <15, 506>,
<16, 253>, <23, 1> ]
> AutomorphismGroup(C : Weight := MinimumWeight(C) );
Permutation group acting on a set of cardinality 23
Order = 10200960 = 2^7 * 3^2 * 5 * 7 * 11 * 23
    (6, 15, 12)(7, 20, 19)(8, 9, 17)(10, 13, 22)(11, 14, 23)(16,
        18, 21)
    (5, 17, 9)(6, 21, 20)(7, 16, 23)(10, 13, 22)(11, 12, 19)(14,
        18, 15)
    (5, 16, 21)(6, 23, 19)(7, 17, 12)(8, 14, 15)(9, 20, 11)(10,
        13, 22)
    (1, 2)(4, 12)(5, 7)(6, 17)(9, 10)(13, 21)(15, 18)(22, 23)
    (2, 3)(4, 21, 6, 20)(5, 10, 12, 17)(7, 13, 9, 11)(15, 18)(16,
        19, 22, 23)
    (3, 8)(4, 5, 20, 22)(6, 16, 21, 12)(7, 11, 13, 9)(10, 17, 19,
        23)(15, 18)
    (4, 8, 6, 21, 20)(5, 10, 14, 17, 12)(7, 22, 18, 16, 9)(11,
        23, 19, 13, 15)
```

#### Equivalence and Isomorphism of Codes

<a id="function-isisomorphic-code-code"></a>
##### `IsIsomorphic(C, D: parameters): Code, Code -> BoolElt, Map`

<a id="function-isequivalent-code-code"></a>
##### `IsEquivalent(C, D: parameters): Code, Code -> BoolElt, Map`

```magma
Al                : MonStgElt                    Default: "Leon"
AutomorphismGroups: MonStgElt                    Default: "Right"
Weight            : RngIntElt                    Default: 0
```

Given $[n, k]$ codes $C$ and $D$, this function returns `true` if and only if $C$ is equivalent to $D$. If $C$ is equivalent to $D$, an equivalence map $f$ is also returned from $C$ onto $D$. The equivalence is with respect to the monomial action. The function first computes none, one, or both of the automorphism groups of the left and right codes. This may assist the isomorphism testing.

The parameter `AutomorphismGroups`, with valid string values `Both`, `Left`, `Right`, `None`, may be used to specify which of the automorphism groups should be constructed first if not already known. The default is `Right`.

In rare cases this algorithm can get stuck, due to an insufficient set of invariant vectors. In this case, the optional parameter `Weight` can be used to specify this set to be the vectors of the specified weight. This set should be of a reasonable size, (possibly hundreds for large codes), while also keeping the weight as small as possible.

Warning: If `Weight` specifies a set that is too small, then the algorithm risks getting stuck.

For codes over $GF(2)$ the parameter `Al`, with valid string values `"Leon"` and `"Unger"`, selects the backtrack search to be used, exactly as for `AutomorphismGroup` above. The default is `"Leon"`.

<a id="error-correcting-linear-code"></a>
<a id="chap-codealg"></a>
## Algebraic-Geometric Codes

- [Introduction](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/introduction.md)
- [Creation of an Algebraic Geometric Code](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/creation.md)
  - [`AlgebraicGeometricCode(S, D): [PlcCrvElt], DivCrvElt → Code`](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/creation.md#function-algebraicgeometriccode-plccrvelt-divcrvelt)
  - [`AGCode(S, D): [PlcCrvElt], DivCrvElt → Code`](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/creation.md#function-agcode-plccrvelt-divcrvelt)
  - [`AlgebraicGeometricDualCode(S, D): [PlcCrvElt], DivCrvElt → Code`](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/creation.md#function-algebraicgeometricdualcode-plccrvelt-divcrvelt)
  - [`AGDualCode(S, D): [PlcCrvElt], DivCrvElt → Code`](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/creation.md#function-agdualcode-plccrvelt-divcrvelt)
  - [`HermitianCode(q, r): RngIntElt, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/creation.md#function-hermitiancode-rngintelt-rngintelt)
  - [Example: Algebraic Geometric Code from a Genus 1 Curve](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/creation.md#example-ex-239058)
  - [Example: Algebraic Geometric Code from a Genus 4 Curve](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/creation.md#example-ex-24ba2f)
- [Properties of AG–Codes](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/properties.md)
  - [`IsWeaklyAG(C): Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/properties.md#function-isweaklyag-code)
  - [`IsWeaklyAGDual(C): Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/properties.md#function-isweaklyagdual-code)
  - [`IsAlgebraicGeometric(C): Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/properties.md#function-isalgebraicgeometric-code)
  - [`IsStronglyAG(C): Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/properties.md#function-isstronglyag-code)
- [Access Functions](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/access.md)
  - [`Curve(C): Code → Crv`](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/access.md#function-curve-code)
  - [`GeometricSupport(C): Code → DivCrvElt`](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/access.md#function-geometricsupport-code)
  - [`Divisor(C): Code → DivCrvElt`](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/access.md#function-divisor-code)
  - [`GoppaDesignedDistance(C): Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/access.md#function-goppadesigneddistance-code)
- [Decoding AG Codes](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/decode.md)
  - [`AGDecode(C, v, Fd): CodeLinFld, ModTupFldElt, DivCrvElt → ModTupFldElt`](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/decode.md#function-agdecode-codelinfld-modtupfldelt-divcrvelt)
  - [Example: Decoding an Algebraic Geometric Code](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/decode.md#example-ex-a1eda2)
- [Toric Codes](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/decode-2.md)
  - [`ToricCode(P, q): TorPol, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/decode-2.md#function-toriccode-torpol-rngintelt)
  - [`ToricCode(S, q): SeqEnum[TorLatElt], RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/decode-2.md#function-toriccode-seqenum-torlatelt-rngintelt)
  - [`ToricCode(S, q): SetEnum[TorLatElt], RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/decode-2.md#function-toriccode-setenum-torlatelt-rngintelt)
  - [Example: Toric Code from a Polygon](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/decode-2.md#example-ex-deddf3)
- [Bibliography](https://docs.magma-maths.org/CodingTheory/AlgebraicGeometricCodes/bibliography.md)

### Introduction

Algebraic–Geometric Codes (AG–codes) are a family of linear codes described by Goppa in [[Gop81a](https://docs.magma-maths.org/references.md#cite-goppa1), [Gop81b](https://docs.magma-maths.org/references.md#cite-goppa1english)]. Let ${\cal X}$ be an irreducible projective plane curve of genus $g$, defined by a (absolutely irreducible) homogeneous polynomial $H(X,Y,Z)$ over a finite field $K=\hbox{\bf F}_q$. A *place* of ${\cal X}$ is the maximal ideal of a discrete valuation subring of $\overline{K}({\cal X})$. We denote by $v_P$ the valuation at place $P$. Its *degree* is the degree of its residue class field over $K$. A *divisor* is an element $D$ of the free abelian group over the set of places of ${\cal X}$. Namely, such an element can be written additively:

$$
D = \sum_{P\in{\rm Pl}({\cal X})}n_P\cdot P\;,
$$

where all but finitely many $n_P\in{\mathbb{Z}}$ are zero. The set of places with nonzero multiplicity is the *support* of $D$, denoted by ${\rm Supp}D$. The set of divisors can be equipped with a natural partial order $\le$ defined by:

$$
D = \sum_{P \in {\rm Pl}({\cal X})} n_P \cdot P \le
D' = \sum_{P \in {\rm Pl}({\cal X})} n'_P \cdot P \quad
     \iff \quad n_P \le n'_P \hbox{ for all } P.
$$

If $f\in K({\cal X})$, then one can define the *principal divisor*:

$$
(f) = \sum_{P\in{\rm Pl}({\cal X})}v_P(f)\cdot P\;.
$$

A divisor $D$ is said to be *defined* over $K$ if it is stable under the natural action of ${\operatorname{Gal}}(\overline{K}/K)$.

If $(P_1,\ldots,P_n)$ is a tuple of places of degree 1, then for a function $f\in K({\cal X})$, $f(P_i)$ can be seen as an element of K. If $D$ is a divisor defined over $K$, then the *Riemann–Roch* space ${\cal L}(D)$ of $D$ is the $K$-vector space of dimension $k$:

$$
{\cal L}(D) = \{ f \in K({\cal X})^*\ |\ (f) + D \ge 0 \} \cup \{ 0 \}.
$$

Now provided $D$ has support disjoint from $S = \{ P_1,\dots,P_n\}$, we can define the *algebraic geometric code* to be the $[n,k]_q$-code:

$$
C = C(S,D) = \{ (f(P_1),\dots,f(P_n))\;, f \in {\cal L}(D) \}.
$$

If $\langle f_1,\ldots,f_k\rangle$ is a base of ${\cal L}_K(D)$ as a $K$-vector space, then a generator matrix for $C$ is:

$$
G = \begin{pmatrix}f_1(P_1) & \cdots & f_1(P_n)\\
\vdots & \ddots & \vdots\\
f_k(P_1) & \cdots & f_k(P_n)\end{pmatrix}\;.
$$

Standard references are [[Sti93](https://docs.magma-maths.org/references.md#cite-stichtenoth)] and [[TV91](https://docs.magma-maths.org/references.md#cite-tsfasman)].

There are two different implementations of the construction of AG–Codes in Magma. The first was implemented by Lancelot Pecquet and is based on the work of Hache [[Hac96](https://docs.magma-maths.org/references.md#cite-hache-phd), [HLB95](https://docs.magma-maths.org/references.md#cite-hache)]. The second approach exploits the divisor machinery for function fields implemented by Florian Hess. In Magma V2.8, only the second implementation is exported. It is intended to rework the Pecquet version to take advantage of the new curve machinery before releasing it.

### Creation of an Algebraic Geometric Code

<a id="function-algebraicgeometriccode-plccrvelt-divcrvelt"></a>
#### `AlgebraicGeometricCode(S, D): [PlcCrvElt], DivCrvElt -> Code`

<a id="function-agcode-plccrvelt-divcrvelt"></a>
#### `AGCode(S, D): [PlcCrvElt], DivCrvElt -> Code`

Suppose $X$ is an irreducible plane curve. Let $S$ be a sequence of places of $X$ having degree $1$ and let $D$ be a divisor of $X$ whose support is disjoint from the support of $S$. The function returns the (weakly) algebraic–geometric code obtained by evaluating functions of the Riemann–Roch space of $D$ at the points of $S$. The degree of $D$ need not be bounded by the cardinality of $S$.

<a id="function-algebraicgeometricdualcode-plccrvelt-divcrvelt"></a>
#### `AlgebraicGeometricDualCode(S, D): [PlcCrvElt], DivCrvElt -> Code`

<a id="function-agdualcode-plccrvelt-divcrvelt"></a>
#### `AGDualCode(S, D): [PlcCrvElt], DivCrvElt -> Code`

Construct the dual of the algebraic geometric code constructed from the sequence of places $S$ and the divisor $D$, which corresponds to a differential code. In order to take advantage of the algebraic geometric structure, the dual must be constructed in this way, and not by directly calling the function `Dual`.

<a id="function-hermitiancode-rngintelt-rngintelt"></a>
#### `HermitianCode(q, r): RngIntElt, RngIntElt -> Code`

Given the prime power $q$ and a positive integer $r$, construct a Hermitian code $C$ with respect to the Hermitian curve $X = x^{(q+1)} + y^{(q+1)} + z^{(q+1)}$ defined over ${\bf F}_{q^2}$. The support of $C$ consists of all places of degree one of $X$ over ${\bf F}_{q^2}$, with the exception of the place over $P = (1:1:0)$. The divisor used to define a Riemann–Roch space is $r*P$.

<a id="example-ex-239058"></a>
#### `Example: Algebraic Geometric Code from a Genus 1 Curve (ex-239058)`

We construct a $[25,9,16]$ code over $F_{16}$ using the genus $1$ curve $x^3+x^2z+y^3+y^2z+z^3$.

```magma
> F<w> := GF(16);
> P2<x,y,z> := ProjectiveSpace(F, 2);
> f := x^3+x^2*z+y^3+y^2*z+z^3;
> X := Curve(P2, f);
> g := Genus(X);
> g;
1
> places1 := Places(X, 1);
> #places1;
25
```

We now need to find an appropriate divisor $D$. Since we require a code of dimension $k=9$ we take the divisor corresponding to a place of degree $k+g-1 = 9$ ($g$ is the genus of the curve).

```magma
> found, place_k := HasPlace(X, 9+g-1);
> D := DivisorGroup(X) ! place_k;
> C := AlgebraicGeometricCode(places1, D);
> C;
[25, 9] Linear Code over GF(2^4)
Generator matrix:
[1 0 0 0 0 0 0 0 0 w^9 w w^8 0 w^5 1 1 w^5 w^7 w^8 w^10 w^4 w^11 w^5
   w^10 w^8]
[0 1 0 0 0 0 0 0 0 w^4 w^5 1 w^10 w^4 w^11 w^12 0 1 w^2 w^4 w^6 w^4 w^5
   w^14 w^4]
[0 0 1 0 0 0 0 0 0 w^5 w^13 w^7 w^10 w^7 w^5 w^14 w^14 w 1 w^10 w^9 1 0
   w^5 w]
[0 0 0 1 0 0 0 0 0 w^8 w^3 w^3 w^12 w^7 w^10 w w^6 0 w^7 w^10 w^4 w^9
   w^14 w^8 w^12]
[0 0 0 0 1 0 0 0 0 w^8 1 w^4 w^7 w^5 w w^8 w w^5 w w^13 0 w^14 w^14 w^14
   w^6]
[0 0 0 0 0 1 0 0 0 1 1 w^12 w^14 w^9 w^10 w^6 w^6 w^7 w^10 w^4 w^3 w^13
   w^13 w^3 w^4]
[0 0 0 0 0 0 1 0 0 w w w^10 w^4 w^12 w w^13 w^4 w w^2 w^3 w^3 w^12 w^10
   w^5 w^13]
[0 0 0 0 0 0 0 1 0 w^13 w^6 w^12 w^2 w^3 w^7 w^3 w^4 w^14 w^4 w^11 w^4 w
   w^6 w^4 w^14]
[0 0 0 0 0 0 0 0 1 0 w^11 w w^7 w^12 w^4 w^3 w^6 w^12 w^3 w^13 w^2 w^11
   w^10 w^3 1]
> MinimumDistance(C);
16
```

<a id="example-ex-24ba2f"></a>
#### `Example: Algebraic Geometric Code from a Genus 4 Curve (ex-24ba2f)`

We construct a $[44,12,29]$ code over $F_{16}$ using the genus $4$ curve $(y^2+xy+x^2)z^3+y^3z^2+(xy^3+x^2y^2+x^3y+x^4)z+x^3y^2+x^4y+x^5$ and taking as the divisor a multiple of a degree $1$ place.

```magma
> k<w> := GF(16);
> P2<x,y,z> := ProjectiveSpace(k, 2);
> f := (y^2+x*y+x^2)*z^3+y^3*z^2+(x*y^3+x^2*y^2+x^3*y+x^4)*z+x^3*y^2+x^4*y+x^5;
> X := Curve(P2, f);
> g := Genus(X);
> g;
4
```

We find all the places of degree $1$.

```magma
> places1 := Places(X, 1);
> #places1;
45
```

We choose as our divisor $15*P1$, where $P1$ is a place of degree $1$. Before applying the AG-Code construction we must remove $P1$ from the set of places of degree $1$.

```magma
> P1 := Random(places1);
> Exclude(~places1, P1);
> #places1;
44
> D := 15 * (DivisorGroup(X) ! P1);
> C := AlgebraicGeometricCode(places1, D);
> C:Minimal;
[44, 12] Linear Code over GF(2^4)
> MinimumWeight(C);
29
```

<a id="properties-of-ag-codes"></a>
### Properties of AG–Codes

<a id="function-isweaklyag-code"></a>
#### `IsWeaklyAG(C): Code -> BoolElt`

Return `true` if and only if the code $C$ is a weakly algebraic–geometric code, i.e. $C$ has been constructed as an algebraic–geometric code with respect to a divisor of any degree.

<a id="function-isweaklyagdual-code"></a>
#### `IsWeaklyAGDual(C): Code -> BoolElt`

Return `true` if and only if the code $C$ was constructed as the dual of a weakly algebraic–geometric code.

<a id="function-isalgebraicgeometric-code"></a>
#### `IsAlgebraicGeometric(C): Code -> BoolElt`

Return `true` if and only if the code $C$ is of algebraic–geometric construction of length $n$, built from a divisor $D$ with $deg(D) < n$.

<a id="function-isstronglyag-code"></a>
#### `IsStronglyAG(C): Code -> BoolElt`

Return `true` if and only if $C$ is an algebraic–geometric code of length $n$ constructed from a divisor $D$ satisfying $2g-2 < deg(D) < n$, where $g$ is the genus of the curve.

### Access Functions

At the time an AG–Code is constructed a number of attributes describing its construction are stored along with the code. The functions in this section give the user access to these attributes.

<a id="function-curve-code"></a>
#### `Curve(C): Code -> Crv`

Given an algebraic–geometric code $C$, returns the curve from which $C$ was defined.

<a id="function-geometricsupport-code"></a>
#### `GeometricSupport(C): Code -> DivCrvElt`

Given an algebraic–geometric code $C$, return the sequence of places which forms the support for $C$.

<a id="function-divisor-code"></a>
#### `Divisor(C): Code -> DivCrvElt`

Given an algebraic–geometric code $C$, return the divisor from which $C$ was constructed.

<a id="function-goppadesigneddistance-code"></a>
#### `GoppaDesignedDistance(C): Code -> RngIntElt`

Given an algebraic–geometric code $C$ constructed from a divisor $D$, return the Goppa designed distance $n - deg(D)$.

### Decoding AG Codes

Specialized decoding algorithms exist for differential code, those which are the duals of the standard algebraic-geometric codes. These algorithms generally require as input another divisor on the curve whose support is disjoint from the divisor defining the code.

<a id="function-agdecode-codelinfld-modtupfldelt-divcrvelt"></a>
#### `AGDecode(C, v, Fd): CodeLinFld, ModTupFldElt, DivCrvElt -> ModTupFldElt`

Decode the received vector $v$ of the dual algebraic geometric code $C$ using the divisor $Fd$.

<a id="example-ex-a1eda2"></a>
#### `Example: Decoding an Algebraic Geometric Code (ex-a1eda2)`

An algebraic-geometric code with Goppa designated distance of $3$ is used to correct one error.

```magma
> q := 8;
> F<a> := GF(q);
> PS<x,y,z> := ProjectiveSpace(F, 2);
> W := x^3*y + y^3*z + x*z^3;
> Cv := Curve(PS, W);
> FF<X,Y> := FunctionField(Cv);
> Pl := Places(Cv, 1);
> plc := Place(Cv ! [0,1,0]);
> P := [ Pl[i] : i in [1..#Pl] | Pl[i] ne plc ];
> G := 11*plc;
> C := AGDualCode(P, G);
>
> v := Random(C);
> rec_vec := v;
> rec_vec[Random(1,Length(C))] +:= Random(F);
> res := AGDecode(C, v, 4*plc);
> res eq v;
true
```

### Toric Codes

<a id="function-toriccode-torpol-rngintelt"></a>
#### `ToricCode(P, q): TorPol, RngIntElt -> Code`

The linear code $C$ over the finite field ${\bf F}_{q}$ associated with the lattice points of the polygon $P$.

To achieve this, after a translation so that the lattice points of $P$ lie in the first quadrant, as close to the origin as possible, these points must lie in the box $[0,q-2] \times [0,q-2]$. Then the code is the monomial evaluation code where each point $(a,b)$ corresponds to the monomial $x^ay^b$, and these monomials are evaluated at the points of the torus $({\bf F}_{q}^*)^2$.

<a id="function-toriccode-seqenum-torlatelt-rngintelt"></a>
#### `ToricCode(S, q): SeqEnum[TorLatElt], RngIntElt -> Code`

<a id="function-toriccode-setenum-torlatelt-rngintelt"></a>
#### `ToricCode(S, q): SetEnum[TorLatElt], RngIntElt -> Code`

The linear code $C$ over the finite field ${\bf F}_{q}$ associated with the lattice points in $S$. (Note that the points will be translated to lie within a box at the origin of the first quadrant, as is usual.)

<a id="example-ex-deddf3"></a>
#### `Example: Toric Code from a Polygon (ex-deddf3)`

We construct the toric code based on the lattice points in the polygon with vertices $(3,0)$, $(5,0)$, $(3,3)$, $(1,5)$, $(0,3)$, $(0,1)$.

```magma
> P := Polytope( [[3,0], [5,0], [3,3], [1,5], [0,3], [0,1]] );
> C := ToricCode(P, 7);
> [ Length(C), Dimension(C), MinimumDistance(C) ];
[ 36, 19, 12 ]
```

We can compare this with the current database of best known linear codes.

```magma
> BKLCLowerBound(Field(C), Length(C), Dimension(C));
12
```

<a id="error-correcting-linear-code"></a>
<a id="chap-codeldpc"></a>
## Low Density Parity Check Codes

- [Introduction](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md)
  - [Constructing LDPC Codes](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#constructing-ldpc-codes)
    - [`LDPCCode(H): MtrxSprs → Code`](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#function-ldpccode-mtrxsprs)
    - [`GallagerCode(n, a, b): RngIntElt, RngIntElt, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#function-gallagercode-rngintelt-rngintelt-rngintelt)
    - [`RegularLDPCEnsemble(n, a, b): RngIntElt, RngIntElt, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#function-regularldpcensemble-rngintelt-rngintelt-rngintelt)
    - [`IrregularLDPCEnsemble(n, Sc, Sv): RngIntElt, SeqEnum, SeqEnum → Code`](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#function-irregularldpcensemble-rngintelt-seqenum-seqenum)
    - [`MargulisCode(p): RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#function-marguliscode-rngintelt)
    - [Example: Saving and Reusing an LDPC Code](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#example-ex-f1c0a4)
  - [Access Functions](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#access-functions)
    - [`IsLDPC(C): Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#function-isldpc-code)
    - [`AssignLDPCMatrix(~C, H): Code, MtrxSprs`](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#procedure-assignldpcmatrix-code-mtrxsprs-ref)
    - [`LDPCMatrix(C): Code → MtrxSprs`](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#function-ldpcmatrix-code)
    - [`LDPCDensity(C): Code → FldReElt`](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#function-ldpcdensity-code)
    - [`IsRegularLDPC(C): Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#function-isregularldpc-code)
    - [`TannerGraph(C): Code → Grph`](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#function-tannergraph-code)
    - [`LDPCGirth(C): Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#function-ldpcgirth-code)
    - [`LDPCEnsembleRate(v, c): RngIntElt, RngIntElt → FldReElt`](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#function-ldpcensemblerate-rngintelt-rngintelt)
    - [`LDPCEnsembleRate(Sv, Sc): [FldReElt], [FldReElt] → FldReElt`](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#function-ldpcensemblerate-fldreelt-fldreelt)
    - [Example: Assigning an LDPC Matrix to Any Code](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#example-ex-69eb66)
  - [LDPC Decoding and Simulation](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#ldpc-decoding-and-simulation)
    - [`LDPCDecode(C, v): Code, ModTupRngElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#function-ldpcdecode-code-modtuprngelt)
    - [Example: LDPC Decoding on a Binary Symmetric Channel](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#example-ex-ece197)
    - [Example: LDPC Decoding on a Gaussian Channel](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#example-ex-557473)
    - [`LDPCSimulate(C, N): Code, RngIntElt → FldReElt, FldReElt`](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#function-ldpcsimulate-code-rngintelt)
    - [Example: Simulating LDPC Error Rates](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#example-ex-103564)
  - [Density Evolution](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#density-evolution)
    - [`LDPCBinarySymmetricThreshold(v, c): RngIntElt, RngIntElt → FldReElt`](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#function-ldpcbinarysymmetricthreshold-rngintelt-rngintelt)
    - [`LDPCBinarySymmetricThreshold(Sv, Sc): [FldReElt], [FldReElt] → FldReElt`](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#function-ldpcbinarysymmetricthreshold-fldreelt-fldreelt)
    - [`DensityEvolutionBinarySymmetric(v, c, p): RngIntElt, RngIntElt, FldReElt → BoolElt`](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#function-densityevolutionbinarysymmetric-rngintelt-rngintelt-fldreelt)
    - [`DensityEvolutionBinarySymmetric(Sv, Sc, p): [FldReElt], [FldReElt], FldReElt → BoolElt`](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#function-densityevolutionbinarysymmetric-fldreelt-fldreelt-fldreelt)
    - [Example: Density Evolution on a Binary Symmetric Channel](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#example-ex-b0bbfa)
    - [`LDPCGaussianThreshold(v, c): RngIntElt, RngIntElt → FldReElt`](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#function-ldpcgaussianthreshold-rngintelt-rngintelt)
    - [`LDPCGaussianThreshold(Sv, Sc): [FldReElt], [FldReElt] → FldReElt`](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#function-ldpcgaussianthreshold-fldreelt-fldreelt)
    - [`DensityEvolutionGaussian(v, c, σ): RngIntElt, RngIntElt, FldReElt → BoolElt`](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#function-densityevolutiongaussian-rngintelt-rngintelt-fldreelt)
    - [`DensityEvolutionGaussian(Sv, Sc, σ): [FldReElt], [FldReElt], FldReElt → BoolElt`](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#function-densityevolutiongaussian-fldreelt-fldreelt-fldreelt)
    - [`GoodLDPCEnsemble(i): RngIntElt → FldReElt, [FldReElt], [FldReElt]`](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#function-goodldpcensemble-rngintelt)
    - [Example: Density Evolution on a Gaussian Channel](https://docs.magma-maths.org/CodingTheory/LowDensityParityCheckCodes/introduction.md#example-ex-4cd36e)

### Introduction

Low density parity check (LDPC) codes are among the best performing codes in practice, being capable of correcting errors close to the Shannon limit. Magma provides facilities for the construction, decoding, simulation, and analysis of LDPC codes.

#### Constructing LDPC Codes

LDPC codes come in two main varieties, *regular* and *irregular*, defined by the row and column weights of the sparse parity check matrix. If all columns in the parity check matrix have some constant weight $a$, and all rows have some constant weight $b$, then the LDPC code is said to be $(a,b)$-regular. When either the columns or the rows have a distribution of weights, the LDPC code is said to be irregular.

Currently, there do not exist many techniques for the explicit construction of LDPC codes. More commonly, these codes are selected at random from an ensemble, and their properties determined through simulation.

<a id="function-ldpccode-mtrxsprs"></a>
##### `LDPCCode(H): MtrxSprs -> Code`

Given a sparse binary matrix $H$, return the LDPC code which has $H$ as its parity check matrix.

<a id="function-gallagercode-rngintelt-rngintelt-rngintelt"></a>
##### `GallagerCode(n, a, b): RngIntElt, RngIntElt, RngIntElt -> Code`

Return a random $(a,b)$-regular LDPC code of length $n$, using Gallager’s original method of construction. The row weight $a$ must divide the length $n$.

<a id="function-regularldpcensemble-rngintelt-rngintelt-rngintelt"></a>
##### `RegularLDPCEnsemble(n, a, b): RngIntElt, RngIntElt, RngIntElt -> Code`

Return a random code from the ensemble of $(a,b)$-regular binary LDPC codes.

<a id="function-irregularldpcensemble-rngintelt-seqenum-seqenum"></a>
##### `IrregularLDPCEnsemble(n, Sc, Sv): RngIntElt, SeqEnum, SeqEnum -> Code`

Given (unnormalized) distributions for the variable and check weights, return length $n$ irregular LDPC codes whose degree distributions match the given distribution. The arguments $Sv$ and $Sc$ are sequences of real numbers, where the $i$-th entry indicates what percentage of the variable (resp. check) nodes should have weight $i$.

Note that the distributions will not be matched perfectly unless everything is in complete balance.

<a id="function-marguliscode-rngintelt"></a>
##### `MargulisCode(p): RngIntElt -> Code`

Return the (3,6)-regular binary LDPC code of length $2(p^3-p)$ using the group-based construction of Margulis.

<a id="example-ex-f1c0a4"></a>
##### `Example: Saving and Reusing an LDPC Code (ex-f1c0a4)`

Most LDPC constructions are generated pseudo-randomly from an ensemble, so the same function will return a different code each time. To be able to re-use an LDPC code, the sparse parity check matrix must be saved.

```magma
> C1 := RegularLDPCEnsemble(10, 2, 4);
> C2 := RegularLDPCEnsemble(10, 2, 4);
> C1 eq C2;
false
> LDPCMatrix(C1):Magma;
SparseMatrix(GF(2), 5, 10, [
    4, 2,1, 3,1, 4,1, 6,1,
    4, 1,1, 7,1, 9,1, 10,1,
    4, 1,1, 2,1, 3,1, 7,1,
    4, 5,1, 6,1, 8,1, 9,1,
    4, 4,1, 5,1, 8,1, 10,1
])
> H := LDPCMatrix(C1);
> C3 := LDPCCode(H);
> C3 eq C1;
true
```

#### Access Functions

Since a code can have many different parity check matrices, the matrix which defines a code as being LDPC must be assigned specifically. Any parity check matrix can be assigned for this purpose, and once a code is assigned an LDPC matrix it is considered by Magma to be an LDPC code (regardless of the density or other properties of the matrix). The matrix must be of sparse type (`MtrxSprs`).

<a id="function-isldpc-code"></a>
##### `IsLDPC(C): Code -> BoolElt`

Return true if $C$ is an LDPC code (which is true if it has been assigned an LDPC matrix).

<a id="procedure-assignldpcmatrix-code-mtrxsprs-ref"></a>
##### `AssignLDPCMatrix(~C, H): Code, MtrxSprs`

Given a sparse matrix $H$ which is a parity check matrix of the code $C$, assign $H$ as the LDPC matrix of $C$.

<a id="function-ldpcmatrix-code"></a>
##### `LDPCMatrix(C): Code -> MtrxSprs`

Given an LDPC code $C$, return the sparse matrix which has been assigned as its low density parity check matrix.

<a id="function-ldpcdensity-code"></a>
##### `LDPCDensity(C): Code -> FldReElt`

Given an LDPC code $C$, return the density of the sparse matrix which has been assigned as its low density parity check matrix.

<a id="function-isregularldpc-code"></a>
##### `IsRegularLDPC(C): Code -> BoolElt`

Returns `true` if $C$ is an LDPC code and has regular column and row weights. If true, the row and column weights are also returned.

<a id="function-tannergraph-code"></a>
##### `TannerGraph(C): Code -> Grph`

For an LDPC code $C$, return its Tanner graph. If there are $n$ variables and $m$ checks, then the graph has $n+m$ nodes, the first $n$ of which are the variable nodes.

<a id="function-ldpcgirth-code"></a>
##### `LDPCGirth(C): Code -> RngIntElt`

For an LDPC code $C$, return the girth of its Tanner graph.

<a id="function-ldpcensemblerate-rngintelt-rngintelt"></a>
##### `LDPCEnsembleRate(v, c): RngIntElt, RngIntElt -> FldReElt`

<a id="function-ldpcensemblerate-fldreelt-fldreelt"></a>
##### `LDPCEnsembleRate(Sv, Sc): [FldReElt], [FldReElt] -> FldReElt`

Return the theoretical rate of LDPC codes from the ensemble described by the given inputs.

<a id="example-ex-69eb66"></a>
##### `Example: Assigning an LDPC Matrix to Any Code (ex-69eb66)`

In Magma, whether or not a code is considered LDPC is based solely on whether or not an LDPC matrix has been assigned. This example shows that any code can be made to be considered LDPC, although a random parity check matrix without low density will perform very badly using LDPC decoding.

```magma
> C := RandomLinearCode(GF(2),100,50);
> IsLDPC(C);
false
> H := SparseMatrix(ParityCheckMatrix(C));
> H;
Sparse matrix with 50 rows and 100 columns over GF(2)
> AssignLDPCMatrix(~C, H);
> IsLDPC(C);
true
> LDPCDensity(C);
0.253400000000000014122036873232
```

The density of the parity check matrices of LDPC codes is much lower than that of randomly generated codes.

```magma
> C1 := RegularLDPCEnsemble(100,3,6);
> C1:Minimal;
[100, 50] Linear Code over GF(2)
> LDPCDensity(C1);
0.0599999999999999977795539507497
```

#### LDPC Decoding and Simulation

The impressive performance of LDPC codes lies in their iterative decoding algorithm. Magma provides facilities to decode using LDPC codes, as well as simulating transmission over a binary symmetric or white Gaussian noise channels.

The binary symmetric channel transmits binary values and is defined by $p < 0.5$. Each individual bit independently sustains a “bit-flip” error with probability $p$.

The Gaussian channel is analog, transmitting real-values, and is defined by a standard deviation $\sigma$. Binary values are mapped to $-1$ and $1$ before being transmitted. Each value independently sustains an errors which are normally distributed about $0$ with standard deviation $\sigma$.

<a id="function-ldpcdecode-code-modtuprngelt"></a>
##### `LDPCDecode(C, v): Code, ModTupRngElt -> ModTupRngElt`

```magma
Channel   : MonStgElt                      Default: "BinarySymmetric"
p         : RngReSubElt                    Default: 0.1
StdDev    : RngReSubElt                    Default: 0.25
Iterations: RngIntElt                      Default: Dimension(C)
```

For an LDPC code $C$ and a received vector $v$, decode $v$ to a codeword of $C$ using the LDPC iterative decoding algorithm.

The nature of the channel from which $v$ is received is described by the variable argument `Channel`, which can either be the `BinarySymmetric` channel or the `Gaussian` channel. Errors on the binary symmetric channel is described by the argument `p`, while on the Gaussian channel they are described by `StdDev`.

The vector $v$ must be over a ring corresponding to the channel which is selected. For the binary symmetric channel $v$ must be a binary vector over $F_2$, while for the Gaussian channel it must be real-valued.

Since the decoding algorithm is iterative and does not necessarily terminate on its own, a maximum number of iterations needs to be specified using the argument `Iterations`. The default value is much larger than would normally be used in practice, giving maximum error-correcting performance (at possibly some cost to efficiency).

<a id="example-ex-ece197"></a>
##### `Example: LDPC Decoding on a Binary Symmetric Channel (ex-ece197)`

Errors in the binary symmetric channel are just bit flips.

```magma
> n := 500;
> C := RegularLDPCEnsemble(n, 4, 8);
> e := 5;
> Errs := {};
> repeat Include(~Errs, Random(1,n)); until #Errs eq e;
> v := Random(C);
> ev := AmbientSpace(C)![ (i in Errs) select 1 else 0 : i in [1..n]];
> rec_vec := v + ev;
> time res := LDPCDecode(C, rec_vec : Channel:="BinarySymmetric", p:=0.2);
Time: 0.000
> res eq v;
true
```

<a id="example-ex-557473"></a>
##### `Example: LDPC Decoding on a Gaussian Channel (ex-557473)`

For the Gaussian channel binary vectors are considered to be transmitted as sequences of the values $1$ and $-1$. Errors are normally distributed with a standard deviation defined by the channel.

To simulate a Gaussian channel requires obtaining normally distributed errors. This can be done (discretely) by generating a multiset of possible errors.

```magma
> sigma := 0.5;
> MaxE := 3.0;
> N := 100;
> V := [ MaxE*(i/N)     : i in [-N div 2..N div 2]];
> E := [ 0.5*(1+Erf(x/(sigma*Sqrt(2)))) : x in V ];
> Dist := {* V[i]^^Round(1000*(E[i]-E[i-1])) : i in [2..#V]*};
```

A codeword of an LDPC code needs to be mapped into the real domain.

```magma
> n := 500;
> C := RegularLDPCEnsemble(n, 4, 8);
> v := Random(C);
> R := RealField();
> RS := RSpace(R, n);
> vR := RS ! [ IsOne(v[i]) select 1 else -1 : i in [1..n]];
```

Normally distributed errors are then introduced, and the received vector decoded.

```magma
> for i in [1..n] do
>    vR[i] +:= Random(Dist);
> end for;
> time res := LDPCDecode(C, vR : Channel:="Gaussian", StdDev:=sigma);
Time: 0.000
> res eq v;
true
```

<a id="function-ldpcsimulate-code-rngintelt"></a>
##### `LDPCSimulate(C, N): Code, RngIntElt -> FldReElt, FldReElt`

```magma
Channel   : MonStgElt                      Default: "BinarySymmetric"
p         : RngReSubElt                    Default: 0.1
StdDev    : RngReSubElt                    Default: 0.25
Iterations: RngIntElt                      Default: Dimension(C)
```

For an LDPC code $C$, simulate $N$ transmissions across the given channel and return the accumulated bit error rate and word error rate.

The variable arguments are as described for the function `LDPCDecode`. The channel which is described controls not only the way the decoding algorithm functions, but also the nature of the errors introduced during the simulation.

<a id="example-ex-103564"></a>
##### `Example: Simulating LDPC Error Rates (ex-103564)`

The more noise that is introduced into the channel the error rate increases. Note that the bit error rate (the first return value) is always lower than the word error rate (the second return value).

```magma
> C := RegularLDPCEnsemble(200, 3, 6);
> LDPCSimulate(C, 10000 : Channel := "Gaussian", StdDev := 0.7);
0.00118249999999999995739519143001 0.00619999999999999978211873141731
> LDPCSimulate(C, 10000 : Channel := "Gaussian", StdDev := 0.75);
0.00749499999999999992617016886243 0.0410000000000000017208456881690
> LDPCSimulate(C, 10000 : Channel := "Gaussian", StdDev := 0.8);
0.0337220000000000019735324485737 0.159700000000000008615330671091
> LDPCSimulate(C, 10000 : Channel := "Gaussian", StdDev := 0.85);
0.0856174999999999991606713933834 0.370800000000000018474111129763
> LDPCSimulate(C, 10000 : Channel := "Gaussian", StdDev := 0.9);
0.162790999999999991265653420669 0.640499999999999958255614274094
> LDPCSimulate(C, 10000 : Channel := "Gaussian", StdDev := 0.95);
0.237657499999999993756105709508 0.840099999999999957900342906214
> LDPCSimulate(C, 10000 : Channel := "Gaussian", StdDev := 1.0);
0.296526500000000026169288958044 0.944799999999999973177011725056
```

#### Density Evolution

The asymptotic performance of ensembles of LDPC codes can be determined using *density evolution*. An ensemble of LDPC codes (either regular or irregular) is defined by a pair of degree distributions, corresponding to the degrees at the variable and check nodes of the Tanner graph.

Over a specific channel, the critical parameter which defines the asymptotic performance of a given ensemble is its *threshold*, which is a value of the channel parameter (i.e., the probability of error $p$ for the binary symmetric channel, and the standard deviation $\sigma$ for the Gaussian channel). When the channel parameter is less than the threshold, asymptotically a code from the ensemble will decode with an error probability tending to zero. However, at any channel parameter above the threshold there will be a non-vanishing finite error probability.

Determining the threshold of an ensemble over the binary symmetric channel is relatively trivial, however over the real-valued Gaussian channel it can involve extensive computations. The speed depends heavily on the granularity of the discretization which is used, though this also affects the accuracy of the result.

The default settings of the Magma implementation use a reasonably coarse discretization, emphasizing speed over accuracy. These (still quite accurate) approximate results can then be used to help reduce the workload of calculations over finer discretizations if more accuracy is required.

<a id="function-ldpcbinarysymmetricthreshold-rngintelt-rngintelt"></a>
##### `LDPCBinarySymmetricThreshold(v, c): RngIntElt, RngIntElt -> FldReElt`

<a id="function-ldpcbinarysymmetricthreshold-fldreelt-fldreelt"></a>
##### `LDPCBinarySymmetricThreshold(Sv, Sc): [FldReElt], [FldReElt] -> FldReElt`

```magma
Precision: RngReSubElt                    Default: 0.00005
```

Determines the threshold of the described ensemble of LDPC codes over the binary symmetric channel, which is the critical value of the channel parameter above which there is a non-vanishing error probability (asymptotically). The ensemble can either be defined by two integers for $(v,c)$-regular LDPC codes, or by two density distributions $Sv$ and $Sc$, which are sequences of non-negative real numbers. The density distributions do not need to be normalized, though the first entry (corresponding to weight $1$ nodes in the Tanner graph) should always be zero.

The computation proceeds by establishing lower and upper bounds on the threshold, then narrowing this range by repeatedly performing density evolution on the midpoint. The argument `Precision` controls the precision to which the threshold is desired.

<a id="function-densityevolutionbinarysymmetric-rngintelt-rngintelt-fldreelt"></a>
##### `DensityEvolutionBinarySymmetric(v, c, p): RngIntElt, RngIntElt, FldReElt -> BoolElt`

<a id="function-densityevolutionbinarysymmetric-fldreelt-fldreelt-fldreelt"></a>
##### `DensityEvolutionBinarySymmetric(Sv, Sc, p): [FldReElt], [FldReElt], FldReElt -> BoolElt`

Perform density evolution on the binary symmetric channel using channel parameter $p$ and determine the asymptotic behaviour for the given LDPC ensemble. The return value is boolean, where `true` indicates that $p$ is below the threshold and the ensemble has error probability asymptotically tending to zero.

<a id="example-ex-b0bbfa"></a>
##### `Example: Density Evolution on a Binary Symmetric Channel (ex-b0bbfa)`

Density evolution on the binary symmetric channel is not computationally intensive.

```magma
> time LDPCBinarySymmetricThreshold(3, 6);
0.0394140625000000000000000000000
Time: 0.010
> time LDPCBinarySymmetricThreshold(4, 8);
0.0473925781250000000000000000001
Time: 0.110
> time LDPCBinarySymmetricThreshold(4, 10);
0.0368359375000000000000000000000
Time: 0.090
```

<a id="function-ldpcgaussianthreshold-rngintelt-rngintelt"></a>
##### `LDPCGaussianThreshold(v, c): RngIntElt, RngIntElt -> FldReElt`

<a id="function-ldpcgaussianthreshold-fldreelt-fldreelt"></a>
##### `LDPCGaussianThreshold(Sv, Sc): [FldReElt], [FldReElt] -> FldReElt`

```magma
Lower        : RngReSubElt                    Default: 0
Upper        : RngReSubElt                    Default: Infinity()
Points       : RngIntElt                      Default: 500
MaxLLR       : RngReSubElt                    Default: 25
MaxIterations: RngIntElt                      Default: Infinity()
QuickCheck   : BoolElt                        Default: true
Precision    : RngReSubElt                    Default: 0.00005
```

Determines the threshold of the described ensemble of LDPC codes over the Gaussian channel, which is the critical value of the standard deviation above which there is a non-vanishing error probability (asymptotically). The ensemble can either be defined by two integers for $(v,c)$-regular LDPC codes, or by two density distributions $Sv$ and $Sc$, which are sequences of non-negative real numbers. The density distributions do not need to be normalized, though the first entry (corresponding to weight $1$ nodes in the Tanner graph) should always be zero.

The computation proceeds by establishing lower and upper bounds on the threshold, then narrowing this range by repeatedly performing density evolution on the midpoint. If the threshold is approximately known then manually setting tight `Lower` and `Upper` bounds can reduce the length of the calculation.

The speed with which these evolutions are computed depends on how fine the discretization is, controlled by the variable argument `Points`. If the threshold is needed to high levels of accuracy then an initial computation with fewer points is recommended to get a reduced searched range. The specific meaning of each variable argument is described below.

`Lower` and `Upper` are real-valued bounds on the threshold, which (if tight) can help to reduce the search range and speed up the threshold determination. The validity of an input bound is verified before the search begins, and an error is returned if it is incorrect.

`Points` and `MaxLLR` define the discretized basis of log likelihood ratios on which density evolution is performed, and have integer and real values resp. Specifically, the probability mass function is defined on the range $[-$`MaxLLR`$, \ldots,$`MaxLLR`$]$ on $2*Points+1$ discretized points.

`MaxIterations` allows the user to set a finite limit of iterations that a density evolution should perform in determining the asymptotic behaviour at each channel parameter. Although this may help reduce the time of a computation, it should be kept in mind that the result may not be valid.

`QuickCheck` defines the method by which the asymptotic behaviour at each channel parameter is identified. If set to `false`, then the probability density must evolve all the way to within an infinitesimal value of unity. When set to `true`, if the rate of change of the probability density is seen to be successively increasing then the asymptotic behaviour is assumed to go to unity. Empirically this method seems to give accurate results and so the default behaviour is `true`, however it has no theoretical justification.

`Precision` is a real-valued parameter defining the precision to which the threshold should be determined.

Setting the verbose mode `Code` prints out the bounds on the threshold as subsequent density evolutions narrow the search range.

<a id="function-densityevolutiongaussian-rngintelt-rngintelt-fldreelt"></a>
##### `DensityEvolutionGaussian(v, c, σ): RngIntElt, RngIntElt, FldReElt -> BoolElt`

<a id="function-densityevolutiongaussian-fldreelt-fldreelt-fldreelt"></a>
##### `DensityEvolutionGaussian(Sv, Sc, σ): [FldReElt], [FldReElt], FldReElt -> BoolElt`

```magma
Points       : RngIntElt                      Default: 500
MaxLLR       : RngReSubElt                    Default: 25
MaxIterations: RngIntElt                      Default: Infinity()
QuickCheck   : BoolElt                        Default: true
```

Perform density evolution on the Gaussian channel using standard deviation $\sigma$ and determine the asymptotic behaviour for the given LDPC ensemble. The return value is boolean, where `true` indicates that $\sigma$ is below the threshold and the ensemble has error probability asymptotically tending to zero.

See the description of `LDPCGaussianThreshold` for a description of the variable arguments.

<a id="function-goodldpcensemble-rngintelt"></a>
##### `GoodLDPCEnsemble(i): RngIntElt -> FldReElt, [FldReElt], [FldReElt]`

Access a small database of density distributions defining good irregular LDPC ensembles. Returned is the published threshold of the ensemble over the Gaussian channel, along with the variable and check degree distributions. The input $i$ is a non-negative integer, which indexes the database (in no particular order).

<a id="example-ex-4cd36e"></a>
##### `Example: Density Evolution on a Gaussian Channel (ex-4cd36e)`

Since performing density evolution on a large number of discrete points is time consuming, it is normally better to first get an estimate with an easier computation.

In this example a published value of the threshold of an ensemble (obtained using a different implementation) can be compared to the outputs from different levels of discretization.

```magma
> thresh, Sv, Sc := GoodLDPCEnsemble(5);
> R4 := RealField(4);
> [R4| x : x in Sv];
[ 0.0000, 0.3001, 0.2839, 0.0000, 0.0000, 0.0000, 0.0000, 0.4159 ]
> [R4| x : x in Sc];
[ 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.2292, 0.7708 ]
> thresh;
0.949700000000000000000000000000
> time approx1 := LDPCGaussianThreshold(Sv, Sc:
>         Points := 500, Precision := 0.001);
Time: 19.400
> approx1;
0.960976562499999964472863211995
> time approx2 := LDPCGaussianThreshold(Sv, Sc:
>       Points := 3000,
>       Lower := approx1-0.02, Upper := approx1+0.02);
Time: 873.560
> approx2;
0.951210937499999964472863211995
```

This estimate can now be used to narrow the search range of accurate density evolution. For the very long calculation the verbose mode is used to keep track of the progress of the calculation.

```magma
> SetVerbose("Code", true);
> time approx3 := LDPCGaussianThreshold(Sv, Sc:
>        Points := 5000,
>        Lower := approx2-0.005, Upper := approx2+0.0005);
Determining the mapping matrix...
                        ...mapping matrix obtained  19.10s
Threshold Determination for LDPC code ensemble:
c:  (6):0.229190 (7):0.770810
v:  (2):0.300130 (3):0.283950 (8):0.415920
will be found to precision 0.000050
Max LLR is 25.000000 distributed across 5000 points
Asymptotic behaviour determination is: fast
Beginning search with lb = 0.946211, ub = 0.951711
New Bounds: lb = 0.948961, ub = 0.951711  114.41s
New Bounds: lb = 0.950336, ub = 0.951711  367.19s
New Bounds: lb = 0.950336, ub = 0.951023  553.95s
New Bounds: lb = 0.950336, ub = 0.950680  814.35s
New Bounds: lb = 0.950508, ub = 0.950680  1261.46s
New Bounds: lb = 0.950508, ub = 0.950594  1557.46s
New Bounds: lb = 0.950508, ub = 0.950551  1891.52s
Time: 2136.150
```

The thresholds given in the database are published values taken from other implementations, and so are not guaranteed to match up exactly with the values obtained using Magma.

<a id="error-correcting-linear-code"></a>
<a id="chap-coderng"></a>
## Linear Codes over Finite Rings

- [Introduction](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/introduction.md)
- [Constructions](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/creation.md)
  - [General Linear Codes](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/creation.md#general-linear-codes)
    - [`LinearCode<R, n | L>: Rng, RngIntElt, List → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/creation.md#constructor-constructor-linearcode-rng-rngintelt-list-code)
    - [`LinearCode(U): ModTupRng → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/creation.md#function-linearcode-modtuprng)
    - [`LinearCode(A): ModMatRngElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/creation.md#function-linearcode-modmatrngelt)
    - [`PermutationCode(u, G): ModTupRngElt, GrpPerm → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/creation.md#function-permutationcode-modtuprngelt-grpperm)
    - [Example: Octacode over Z4](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/creation.md#example-ex-adca47)
    - [Example: Code from a Matrix over a Galois Ring](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/creation.md#example-ex-11a0fe)
    - [Example: Permutation Code over Z4](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/creation.md#example-ex-215ff7)
  - [Simple Linear Codes](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/creation.md#simple-linear-codes)
    - [`ZeroCode(R, n): Rng, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/creation.md#function-zerocode-rng-rngintelt)
    - [`RepetitionCode(R, n): Rng, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/creation.md#function-repetitioncode-rng-rngintelt)
    - [`ZeroSumCode(R, n): Rng, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/creation.md#function-zerosumcode-rng-rngintelt)
    - [`UniverseCode(R, n): Rng, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/creation.md#function-universecode-rng-rngintelt)
    - [`RandomLinearCode(R, n, k): Rng, RngIntElt, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/creation.md#function-randomlinearcode-rng-rngintelt-rngintelt)
    - [Example: Repetition and Zero Sum Codes](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/creation.md#example-ex-3c3cdf)
  - [General Cyclic Codes](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/creation.md#general-cyclic-codes)
    - [`CyclicCode(u): ModTupRngElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/creation.md#function-cycliccode-modtuprngelt)
    - [`CyclicCode(n, g): RngIntElt, RngUPolElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/creation.md#function-cycliccode-rngintelt-rngupolelt)
    - [`CyclotomicFactors(R, n): Rng, RngIntElt → [RngUPolElt]`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/creation.md#function-cyclotomicfactors-rng-rngintelt)
    - [Example: Cyclic Codes over Z4](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/creation.md#example-ex-567853)
    - [Example: Cyclic Code over a Galois Ring](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/creation.md#example-ex-63adb5)
- [Invariants](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/access.md)
  - [`# C: Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/access.md#operation-operation-code-rngintelt)
  - [`C . i: Code, RngIntElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/access.md#operation-operation-code-rngintelt-modtuprngelt)
  - [`Name(C, i): Code, RngIntElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/access.md#function-name-code-rngintelt)
  - [`Alphabet(C): Code → Rng`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/access.md#function-alphabet-code)
  - [`AmbientSpace(C): Code → ModTupRng`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/access.md#function-ambientspace-code)
  - [`Basis(C): Code → [ ModTupRngElt ]`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/access.md#function-basis-code)
  - [`Generators(C): Code → { ModTupRngElt }`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/access.md#function-generators-code)
  - [`GeneratorMatrix(C): Code → ModMatRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/access.md#function-generatormatrix-code)
  - [`Generic(C): Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/access.md#function-generic-code)
  - [`Length(C): Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/access.md#function-length-code)
  - [`PseudoDimension(C): Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/access.md#function-pseudodimension-code)
  - [`NumberOfGenerators(C): Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/access.md#function-numberofgenerators-code)
  - [`Ngens(C): Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/access.md#function-ngens-code)
  - [`ParityCheckMatrix(C): Code → ModMatRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/access.md#function-paritycheckmatrix-code)
  - [`Random(C): Code → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/access.md#function-random-code)
  - [`RSpace(C): Code → ModTupRng`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/access.md#function-rspace-code)
  - [`InformationRate(C): Code → RngPrElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/access.md#function-informationrate-code)
- [Subcodes](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/subcode.md)
  - [The Subcode Constructor](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/subcode.md#the-subcode-constructor)
    - [`sub<C | L>: Code, List → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/subcode.md#constructor-constructor-sub-code-list-code)
    - [`Subcode(C, t): Code, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/subcode.md#function-subcode-code-rngintelt)
    - [`Subcode(C, S): Code, {RngIntElt} → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/subcode.md#function-subcode-code-rngintelt-2)
    - [Example: Subcode over a Galois Ring](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/subcode.md#example-ex-89c02d)
- [Boolean Predicates](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/Boolean.md)
  - [`u in C: ModTupRngElt, Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/Boolean.md#operation-op-in-modtuprngelt-code)
  - [`u notin C: ModTupRngElt, Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/Boolean.md#operation-op-notin-modtuprngelt-code)
  - [`C subset D: Code, Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/Boolean.md#operation-op-subset-code-code)
  - [`C notsubset D: Code, Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/Boolean.md#operation-operation-notsubset-code-code-boolelt)
  - [`C eq D: Code, Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/Boolean.md#operation-op-eq-code-code)
  - [`C ne D: Code, Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/Boolean.md#operation-op-ne-code-code)
  - [`IsCyclic(C): Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/Boolean.md#function-iscyclic-code)
  - [`IsSelfDual(C): Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/Boolean.md#function-isselfdual-code)
  - [`IsSelfOrthogonal(C): Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/Boolean.md#function-isselforthogonal-code)
  - [`IsProjective(C): Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/Boolean.md#function-isprojective-code)
  - [`IsZero(u): ModTupRngElt → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/Boolean.md#function-iszero-modtuprngelt)
  - [Example: Properties of a Code over Z4](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/Boolean.md#example-ex-659440)
- [New Codes from Old](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/operation.md)
  - [Sum, Intersection, and Dual](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/operation.md#sum-intersection-and-dual)
    - [`C + D: Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/operation.md#operation-op-plus-code-code)
    - [`C meet D: Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/operation.md#operation-op-meet-code-code)
    - [`Dual(C): Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/operation.md#function-dual-code)
    - [Example: Sums and Intersections of Subcodes](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/operation.md#example-ex-e4970a)
  - [Standard Constructions](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/operation.md#standard-constructions)
    - [`DirectSum(C, D): Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/operation.md#function-directsum-code-code)
    - [`DirectProduct(C, D): Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/operation.md#function-directproduct-code-code)
    - [`C1 cat C2: Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/operation.md#operation-operation-cat-code-code-code)
    - [`ExtendCode(C): Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/operation.md#function-extendcode-code)
    - [`ExtendCode(C, n): Code, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/operation.md#function-extendcode-code-rngintelt)
    - [`PadCode(C, n): Code, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/operation.md#function-padcode-code-rngintelt)
    - [`PlotkinSum(C, D): Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/operation.md#function-plotkinsum-code-code)
    - [`PunctureCode(C, i): Code, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/operation.md#function-puncturecode-code-rngintelt)
    - [`PunctureCode(C, S): Code, { RngIntElt } → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/operation.md#function-puncturecode-code-rngintelt-2)
    - [`ShortenCode(C, i): Code, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/operation.md#function-shortencode-code-rngintelt)
    - [`ShortenCode(C, S): Code, { RngIntElt } → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/operation.md#function-shortencode-code-rngintelt-2)
    - [Example: Lengths of Combined Codes](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/operation.md#example-ex-fe796f)
    - [Example: Puncturing a Code over Z4](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/operation.md#example-ex-0c4967)
- [Codeword Operations](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md)
  - [Construction](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md#construction)
    - [`C ! [a₁, ..., aₙ]: Code, [ RngElt ] → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md#operation-op-code-rngelt)
    - [`elt< C | a₁, ..., aₙ>: Code, List → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md#constructor-constructor-elt-code-list-modtuprngelt)
    - [`C ! u: Code, ModTupRngElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md#operation-op-code-modtuprngelt)
    - [`C ! 0: Code, RngIntElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md#operation-op-code-rngintelt)
    - [Example: Creating Code Words](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md#example-ex-c7f5f7)
  - [Operations](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md#operations)
    - [`u + v: ModTupRngElt, ModTupRngElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md#operation-op-plus-modtuprngelt-modtuprngelt)
    - [`- u: ModTupRngElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md#operation-operation-modtuprngelt-modtuprngelt)
    - [`u - v: ModTupRngElt, ModTupRngElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md#operation-op-minus-modtuprngelt-modtuprngelt)
    - [`a * u: RngElt, ModTupRngElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md#operation-op-times-rngelt-modtuprngelt)
    - [`Weight(v): ModTupRngElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md#function-weight-modtuprngelt)
    - [`Distance(u, v): ModTupRngElt, ModTupRngElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md#function-distance-modtuprngelt-modtuprngelt)
    - [`Support(w): ModTupRngElt → { RngIntElt }`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md#function-support-modtuprngelt)
    - [`(u, v): ModTupRngElt, ModTupRngElt → RngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md#literal-literal-u-v-modtuprngelt-modtuprngelt-rngelt)
    - [`InnerProduct(u, v): ModTupRngElt, ModTupRngElt → RngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md#function-innerproduct-modtuprngelt-modtuprngelt)
    - [`Coordinates(C, u): Code, ModTupRngElt → [ RngFinElt ]`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md#function-coordinates-code-modtuprngelt)
    - [`Normalize(u): ModTupRngElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md#function-normalize-modtuprngelt)
    - [`Rotate(u, k): ModTupRngElt, RngIntElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md#function-rotate-modtuprngelt-rngintelt)
    - [`Rotate(~u, k): ModTupRngElt, RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md#procedure-rotate-modtuprngelt-rngintelt-ref)
    - [`Parent(w): ModTupRngElt → ModTupRng`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md#function-parent-modtuprngelt)
    - [Example: Operations on Code Words](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md#example-ex-38a7a5)
  - [Accessing Components of a Codeword](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md#accessing-components-of-a-codeword)
    - [`u[i]: ModTupRngElt, RngIntElt → RngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md#indexed-indexed-u-modtuprngelt-rngintelt-rngelt)
    - [`u[i] := x;`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/element.md#literal-literal-u-i-x)
- [Weight Distributions](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/weight-distribution.md)
  - [Hamming Weight](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/weight-distribution.md#hamming-weight)
    - [`MinimumWeight(C): Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/weight-distribution.md#function-minimumweight-code)
    - [`MinimumDistance(C): Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/weight-distribution.md#function-minimumdistance-code)
    - [`WeightDistribution(C): Code → [ <RngIntElt, RngIntElt> ]`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/weight-distribution.md#function-weightdistribution-code)
    - [`DualWeightDistribution(C): Code → [ <RngIntElt, RngIntElt> ]`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/weight-distribution.md#function-dualweightdistribution-code)
    - [Example: Weight Distribution of a Cyclic Code](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/weight-distribution.md#example-ex-bb2d09)
- [Weight Enumerators](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/weight-enumerator.md)
  - [`CompleteWeightEnumerator(C): Code → RngMPolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/weight-enumerator.md#function-completeweightenumerator-code)
  - [`WeightEnumerator(C): Code → RngMPolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/weight-enumerator.md#function-weightenumerator-code)
  - [`HammingWeightEnumerator(C): Code → RngMPolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/weight-enumerator.md#function-hammingweightenumerator-code)
  - [Example: Complete Weight Enumerator over a Galois Ring](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/weight-enumerator.md#example-ex-1d525d)
- [Bibliography](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/bibliography.md)

### Introduction

This chapter describes those functions which are applicable to linear codes over finite rings. Magma currently supports the basic facilities for codes over integer residue rings and galois rings, including cyclic codes, constructions, complete weight enumerators, and decoding. Much additional functionality specific to codes defined over $Z_4$, the integers modulo $4$, can be found in Chapter [Linear Codes over the Integer Residue Ring ${\mathbb{Z}}_4$](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/index-linear-codes-over-z4.md#chap-codez4).

For modules defined over rings with zero divisors, it is of course not possible to talk about the concept of dimension (the modules are not free). But in Magma each code over such a ring has a *unique* generator matrix corresponding to the *Howell form*. The number of rows $k$ in this unique generator matrix will be called the *pseudo-dimension* of the code. It should be noted that this pseudo-dimension is not invariant between equivalent codes, and so does not provide structural information like the dimension of a code over a finite field. Note that the rank of the generator matrix is always well-defined and unique (based on the Smith form which is well-defined over PIRs), but $k$ may sometimes be larger than the rank.

Without a concept of dimension, codes over finite rings are referenced by their cardinality. A code $C$ is called an $(n,M,d)$ *code* if it has length $n$, cardinality $M$, and minimum Hamming weight $d$.

The reader is referred to [[Wan97](https://docs.magma-maths.org/references.md#cite-wan-z4)] as a general reference on codes over Galois rings, especially linear codes over $Z_4$.

In this chapter, as for codes over finite fields, the term “code” will refer to a linear code, unless otherwise specified.

### Constructions

#### General Linear Codes

<a id="constructor-constructor-linearcode-rng-rngintelt-list-code"></a>
##### `LinearCode<R, n | L>: Rng, RngIntElt, List -> Code`

Create a code as a subspace of the $R$-space $V = R^{(n)}$ which is generated by the elements specified by the list $L$, where $L$ is a list of one or more items of the following types:

**(a)**
An element of $V$.

**(b)**
A set or sequence of elements of $V$.

**(c)**
A sequence of $n$ elements of $R$, defining an element of $V$.

**(d)**
A set or sequence of sequences of type (c).

**(e)**
A subspace of $V$.

**(f)**
A set or sequence of subspaces of $V$.

<a id="function-linearcode-modtuprng"></a>
##### `LinearCode(U): ModTupRng -> Code`

Let $V$ be the $R$-space $R^{(n)}$ and suppose that $U$ is a subspace of $V$. The effect of this function is to define the linear code $C$ corresponding to the subspace $U$.

<a id="function-linearcode-modmatrngelt"></a>
##### `LinearCode(A): ModMatRngElt -> Code`

Given a $k\ \times\ n$ matrix $A$ over the ring $R$, construct the linear code generated by the rows of $A$. Note that it is not assumed that the rank of $A$ is $k$. The effect of this constructor is otherwise identical to that described above.

<a id="function-permutationcode-modtuprngelt-grpperm"></a>
##### `PermutationCode(u, G): ModTupRngElt, GrpPerm -> Code`

Given a finite permutation group $G$ of degree $n$, and a vector $u$ belonging to the $n$-dimensional vector space $V$ over the ring $R$, construct the code $C$ corresponding to the subspace of $V$ spanned by the set of vectors obtained by applying the permutations of $G$ to the vector $u$.

<a id="example-ex-adca47"></a>
##### `Example: Octacode over Z4 (ex-adca47)`

The octacode $O_8$ over ${\mathbb{Z}}_4$ [[Wan97](https://docs.magma-maths.org/references.md#cite-wan-z4), Ex. 1.3] can be defined as follows:

```magma
> Z4 := IntegerRing(4);
> O8 := LinearCode<Z4, 8 |
>     [1,0,0,0,3,1,2,1],
>     [0,1,0,0,1,2,3,1],
>     [0,0,1,0,3,3,3,2],
>     [0,0,0,1,2,3,1,1]>;
> O8;
[8, 4, 4] Linear Code over IntegerRing(4)
Generator matrix:
[1 0 0 0 3 1 2 1]
[0 1 0 0 1 2 3 1]
[0 0 1 0 3 3 3 2]
[0 0 0 1 2 3 1 1]
```

Alternatively, if we want to see the code as a subspace of $R^{(8)}$, where $R={\mathbb{Z}}_4$, we could proceed as follows:

```magma
> O8 := LinearCode(sub<RSpace(Z4, 8) |
>     [1,0,0,0,3,1,2,1],
>     [0,1,0,0,1,2,3,1],
>     [0,0,1,0,3,3,3,2],
>     [0,0,0,1,2,3,1,1]>);
```

<a id="example-ex-11a0fe"></a>
##### `Example: Code from a Matrix over a Galois Ring (ex-11a0fe)`

We define a code by constructing a matrix over `GR`$(4, 3)$, and using its rowspace to generate the code:

```magma
> R<w> := GaloisRing(4,3);
> S := [1, 1, 0, w^2, w, w + 2, 2*w^2, 2*w^2 + w + 3];
> G := Matrix(R, 2, 4, S);
> G;
[            1             1             0           w^2]
[            w         w + 2         2*w^2 2*w^2 + w + 3]
> C := LinearCode(G);
> C;
(4, 512, 3) Linear Code over GaloisRing(2, 2, 3)
Generator matrix:
[          1           1           0         w^2]
[          0           2       2*w^2 2*w^2 + 2*w]
> #C;
512
```

<a id="example-ex-215ff7"></a>
##### `Example: Permutation Code over Z4 (ex-215ff7)`

We define $G$ to be a permutation group of degree 7 and construct the code $C$ as the ${\mathbb{Z}}_4$-code generated by applying the permutations of $G$ to a certain vector:

```magma
> G := PSL(3, 2);
> G;
Permutation group G of degree 7
    (1, 4)(6, 7)
    (1, 3, 2)(4, 7, 5)
> Z4 := IntegerRing(4);
> V := RSpace(Z4, 7);
> u := V ! [1, 0, 0, 1, 0, 1, 1];
> C := PermutationCode(u, G);
> C;
[7, 6, 2] Linear Code over IntegerRing(4)
Generator matrix:
[1 0 0 1 0 1 1]
[0 1 0 1 1 1 0]
[0 0 1 0 1 1 1]
[0 0 0 2 0 0 2]
[0 0 0 0 2 0 2]
[0 0 0 0 0 2 2]
```

#### Simple Linear Codes

<a id="function-zerocode-rng-rngintelt"></a>
##### `ZeroCode(R, n): Rng, RngIntElt -> Code`

Given a ring $R$ and positive integer $n$, return the $(n,0,n)$ code consisting of only the zero code word. By convention the minimum weight of the zero code is $n$).

<a id="function-repetitioncode-rng-rngintelt"></a>
##### `RepetitionCode(R, n): Rng, RngIntElt -> Code`

Given a ring $R$ and positive integer $n$, return the length $n$ code with minimum Hamming weight $n$, generated by the all-ones vector.

<a id="function-zerosumcode-rng-rngintelt"></a>
##### `ZeroSumCode(R, n): Rng, RngIntElt -> Code`

Given a ring $R$ and positive integer $n$, return the length $n$ code over $R$ such that for all codewords $(c_1,c_2,\ldots ,c_n)$ we have $\sum_{i} c_i =0$.

<a id="function-universecode-rng-rngintelt"></a>
##### `UniverseCode(R, n): Rng, RngIntElt -> Code`

Given a ring $R$ and positive integer $n$, return the length $n$ code with minimum Hamming weight $1$, consisting of all possible codewords.

<a id="function-randomlinearcode-rng-rngintelt-rngintelt"></a>
##### `RandomLinearCode(R, n, k): Rng, RngIntElt, RngIntElt -> Code`

Given a finite ring $R$ and positive integers $n$ and $k$, such that $0 < k \le n$, the function returns a random linear code of length $n$ over $R$ with $k$ generators.

<a id="example-ex-3c3cdf"></a>
##### `Example: Repetition and Zero Sum Codes (ex-3c3cdf)`

The repetition and zero sum codes are dual over all rings.

```magma
> R := Integers(9);
> C1 := RepetitionCode(R, 5);
> C1;
(5, 9, 5) Linear Code over IntegerRing(9)
Generator matrix:
[1 1 1 1 1]
> C2 := ZeroSumCode(R, 5);
> C2;
(5, 6561, 2) Linear Code over IntegerRing(9)
Generator matrix:
[1 0 0 0 8]
[0 1 0 0 8]
[0 0 1 0 8]
[0 0 0 1 8]
> C1 eq Dual(C2);
true
```

#### General Cyclic Codes

Cyclic codes form an important family of linear codes over all rings. A cyclic code is one which is generated by all of the cyclic shifts of a given codeword:

$$
(c_0,c_1,\ldots,c_{n-1},c_n), (c_n,c_0,\ldots,c_{n-2},c_{n-1}), \ldots,
(c_1,c_2,\ldots,c_n,c_0)
$$

Using the correspondence $(c_0,c_1,\ldots,c_n) \iff c_0 + c_1x + \cdots + c_nx^n$, the cyclic codes of length $n$ over the ring $R$ are in one-to-one correspondence with the principal ideals of $R[x]/(x^n-1)R[x]$.

<a id="function-cycliccode-modtuprngelt"></a>
##### `CyclicCode(u): ModTupRngElt -> Code`

Given a vector $u$ belonging to the $R$-space $R^{(n)}$, construct the length $n$ cyclic code generated by the right cyclic shifts of the vector $u$.

<a id="function-cycliccode-rngintelt-rngupolelt"></a>
##### `CyclicCode(n, g): RngIntElt, RngUPolElt -> Code`

Let $R$ be a ring. Given a positive integer $n$ and a univariate polynomial $g(x) \in R[x]$, construct the length $n$ cyclic code generated by $g(x)$.

<a id="function-cyclotomicfactors-rng-rngintelt"></a>
##### `CyclotomicFactors(R, n): Rng, RngIntElt -> [RngUPolElt]`

Given a Galois ring $R$ (which is possibly an integer residue ring with a prime power modulus), and a positive integer $n$ which is coprime to the characteristic of $R$, return a factorisation of $x^n - 1$ over $R$.

Note that since factorisation is not necessarily unique over $R$, the factorisation returned is the one obtained by first factoring over the residue field of $R$ and then performing Hensel lifting.

<a id="example-ex-567853"></a>
##### `Example: Cyclic Codes over Z4 (ex-567853)`

We construct some cyclic codes over ${\mathbb{Z}}_4$ by factorizing $x^n-1$ over ${\mathbb{Z}}_4$ for $n=7,23$ and using some of the irreducible factors found.

```magma
> Z4 := IntegerRing(4);
> P<x> := PolynomialRing(Z4);
> n := 7; L := CyclotomicFactors(Z4, n); L;
[
    x + 3,
    x^3 + 2*x^2 + x + 3,
    x^3 + 3*x^2 + 2*x + 3
]
> CyclicCode(n, L[1]);
[7, 6, 2] Cyclic Code over IntegerRing(4)
Generator matrix:
[1 0 0 0 0 0 3]
[0 1 0 0 0 0 3]
[0 0 1 0 0 0 3]
[0 0 0 1 0 0 3]
[0 0 0 0 1 0 3]
[0 0 0 0 0 1 3]
> CyclicCode(n, L[2]);
[7, 4, 3] Cyclic Code over IntegerRing(4)
Generator matrix:
[1 0 0 0 3 1 2]
[0 1 0 0 2 1 1]
[0 0 1 0 1 1 3]
[0 0 0 1 3 2 3]
> CyclicCode(n, L[3]);
[7, 4, 3] Cyclic Code over IntegerRing(4)
Generator matrix:
[1 0 0 0 3 2 3]
[0 1 0 0 3 1 1]
[0 0 1 0 1 1 2]
[0 0 0 1 2 1 3]
> n := 23; L := CyclotomicFactors(Z4, n); L;
[
    x + 3,
    x^11 + 2*x^10 + 3*x^9 + 3*x^7 + 3*x^6 + 3*x^5 + 2*x^4 + x + 3,
    x^11 + 3*x^10 + 2*x^7 + x^6 + x^5 + x^4 + x^2 + 2*x + 3
]
> CyclicCode(n, L[2]);
[23, 12] Cyclic Code over IntegerRing(4)
Generator matrix:
[1 0 0 0 0 0 0 0 0 0 0 0 3 1 0 0 2 3 3 3 0 3 2]
[0 1 0 0 0 0 0 0 0 0 0 0 2 1 1 0 0 0 1 1 3 2 3]
[0 0 1 0 0 0 0 0 0 0 0 0 3 3 1 1 2 3 3 0 1 2 0]
[0 0 0 1 0 0 0 0 0 0 0 0 0 3 3 1 1 2 3 3 0 1 2]
[0 0 0 0 1 0 0 0 0 0 0 0 2 2 3 3 1 3 0 1 3 2 1]
[0 0 0 0 0 1 0 0 0 0 0 0 1 1 2 3 1 2 0 1 1 0 0]
[0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 2 3 1 2 0 1 1 0]
[0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 2 3 1 2 0 1 1]
[0 0 0 0 0 0 0 0 1 0 0 0 1 3 0 1 3 3 0 2 2 1 3]
[0 0 0 0 0 0 0 0 0 1 0 0 3 2 3 0 3 2 2 3 2 1 3]
[0 0 0 0 0 0 0 0 0 0 1 0 3 0 2 3 2 2 1 1 3 1 3]
[0 0 0 0 0 0 0 0 0 0 0 1 3 0 0 2 1 1 1 0 1 2 3]
```

<a id="example-ex-63adb5"></a>
##### `Example: Cyclic Code over a Galois Ring (ex-63adb5)`

We create a cyclic code of length $5$ over `GR`$(4,2)$.

```magma
> R<w> := GR(4,2);
> P<x> := PolynomialRing(R);
> g := CyclotomicFactors(R, 5)[2];
> g;
x^2 + (3*w + 2)*x + 1
> C := CyclicCode(5, g);
> C;
(5, 4096, 3) Cyclic Code over GaloisRing(2, 2, 2)
Generator matrix:
[      1       0       0       1 3*w + 2]
[      0       1       0   w + 2   w + 2]
[      0       0       1 3*w + 2       1]
```

### Invariants

<a id="operation-operation-code-rngintelt"></a>
#### `# C: Code -> RngIntElt`

Given a code $C$, return the number of codewords belonging to $C$.

<a id="operation-operation-code-rngintelt-modtuprngelt"></a>
#### `C . i: Code, RngIntElt -> ModTupRngElt`

<a id="function-name-code-rngintelt"></a>
#### `Name(C, i): Code, RngIntElt -> ModTupRngElt`

Given a code $C$ and a positive integer $i$, return the $i$-th generator of $C$.

<a id="function-alphabet-code"></a>
#### `Alphabet(C): Code -> Rng`

The underlying ring (or alphabet) $R$ of the code $C$.

<a id="function-ambientspace-code"></a>
#### `AmbientSpace(C): Code -> ModTupRng`

The ambient space of the code $C$, i.e., the generic $R$-space $V$ in which $C$ is contained.

<a id="function-basis-code"></a>
#### `Basis(C): Code -> [ ModTupRngElt ]`

The basis of the linear code $C$, returned as a sequence of elements of $C$.

<a id="function-generators-code"></a>
#### `Generators(C): Code -> { ModTupRngElt }`

The generators for the linear code $C$, returned as a set.

<a id="function-generatormatrix-code"></a>
#### `GeneratorMatrix(C): Code -> ModMatRngElt`

The generator matrix for the linear code $C$. This gives a unique canonical generating set for the code.

<a id="function-generic-code"></a>
#### `Generic(C): Code -> Code`

Given a length $n$ code $C$ over a ring $R$, return the generic $(n, \#R^n, 1)$ code in which $C$ is contained.

<a id="function-length-code"></a>
#### `Length(C): Code -> RngIntElt`

Given a code $C$, return the block length $n$ of $C$.

<a id="function-pseudodimension-code"></a>
#### `PseudoDimension(C): Code -> RngIntElt`

<a id="function-numberofgenerators-code"></a>
#### `NumberOfGenerators(C): Code -> RngIntElt`

<a id="function-ngens-code"></a>
#### `Ngens(C): Code -> RngIntElt`

The number of generators (which equals the pseudo-dimension $k$) of the linear code $C$.

<a id="function-paritycheckmatrix-code"></a>
#### `ParityCheckMatrix(C): Code -> ModMatRngElt`

The parity check matrix for the code $C$, which can be defined as the canonical generator matrix of the dual of $C$.

<a id="function-random-code"></a>
#### `Random(C): Code -> ModTupRngElt`

A random codeword of the code $C$.

<a id="function-rspace-code"></a>
#### `RSpace(C): Code -> ModTupRng`

Given a length $n$ linear code $C$, defined as a subspace $U$ of the $n$-dimensional space $V$, return $U$ as a subspace of $V$ with basis corresponding to the rows of the generator matrix for $C$.

<a id="function-informationrate-code"></a>
#### `InformationRate(C): Code -> RngPrElt`

Given a code $C$ over a ring with cardinality $q$, return the information rate of $C$, that is, the ratio $Log_q(\#C)/n$.

### Subcodes

#### The Subcode Constructor

<a id="constructor-constructor-sub-code-list-code"></a>
##### `sub<C | L>: Code, List -> Code`

Given a length $n$ linear code $C$ over $R$, construct the subcode of $C$, generated by the elements specified by the list $L$, where $L$ is a list of one or more items of the following types:

**(a)**
An element of $C$;

**(b)**
A set or sequence of elements of $C$;

**(c)**
A sequence of $n$ elements of $R$, defining an element of $C$;

**(d)**
A set or sequence of sequences of type (c);

**(e)**
A subcode of $C$;

**(f)**
A set or sequence of subcodes of $C$.

<a id="function-subcode-code-rngintelt"></a>
##### `Subcode(C, t): Code, RngIntElt -> Code`

Given a length $n$ linear code $C$ with $k$ generators and an integer $t$, $1 \le t < k$, return a subcode of $C$ of pseudo-dimension $t$.

<a id="function-subcode-code-rngintelt-2"></a>
##### `Subcode(C, S): Code, {RngIntElt} -> Code`

Given a length $n$ linear code $C$ with $k$ generators and a set $S$ of integers, each of which lies in the range $[1,k]$, return the subcode of $C$ generated by the basis elements whose positions appear in $S$.

<a id="example-ex-89c02d"></a>
##### `Example: Subcode over a Galois Ring (ex-89c02d)`

We construct a subcode of a code over a Galois ring by multiplying each of its generators by a zero divisor.

```magma
> R<w> := GR(4,2);
> C := RandomLinearCode(R, 4, 2);
> C;
(4, 256, 3) Linear Code over GaloisRing(2, 2, 2)
Generator matrix:
[      1       0   w + 1 3*w + 2]
[      0       1 3*w + 1       1]
> #C;
256
>
> C1 := sub< C | 2*C.1, 2*C.2 >;
> C1;
(4, 16, 3) Linear Code over GaloisRing(2, 2, 2)
Generator matrix:
[      2       0 2*w + 2     2*w]
[      0       2 2*w + 2       2]
> #C1;
16
```

### Boolean Predicates

For the following operators, $C$ and $D$ are codes defined as a subset (or subspace) of the $R$-space $V$.

<a id="operation-op-in-modtuprngelt-code"></a>
#### `u in C: ModTupRngElt, Code -> BoolElt`

Return `true` if and only if the vector $u$ of $V$ belongs to the code $C$.

<a id="operation-op-notin-modtuprngelt-code"></a>
#### `u notin C: ModTupRngElt, Code -> BoolElt`

Return `true` if and only if the vector $u$ of $V$ does not belong to the code $C$.

<a id="operation-op-subset-code-code"></a>
#### `C subset D: Code, Code -> BoolElt`

Return `true` if and only if the code $C$ is a subcode of the code $D$.

<a id="operation-operation-notsubset-code-code-boolelt"></a>
#### `C notsubset D: Code, Code -> BoolElt`

Return `true` if and only if the code $C$ is not a subcode of the code $D$.

<a id="operation-op-eq-code-code"></a>
#### `C eq D: Code, Code -> BoolElt`

Return `true` if and only if the codes $C$ and $D$ are equal.

<a id="operation-op-ne-code-code"></a>
#### `C ne D: Code, Code -> BoolElt`

Return `true` if and only if the codes $C$ and $D$ are not equal.

<a id="function-iscyclic-code"></a>
#### `IsCyclic(C): Code -> BoolElt`

Return `true` if and only if the linear code $C$ is a cyclic code.

<a id="function-isselfdual-code"></a>
#### `IsSelfDual(C): Code -> BoolElt`

Return `true` if and only if the linear code $C$ is self-dual (or self-orthogonal) (i.e., $C$ equals the dual of $C$).

<a id="function-isselforthogonal-code"></a>
#### `IsSelfOrthogonal(C): Code -> BoolElt`

Return `true` if and only if the linear code $C$ is self-orthogonal; that is, return whether $C$ is contained in the dual of $C$.

<a id="function-isprojective-code"></a>
#### `IsProjective(C): Code -> BoolElt`

Returns `true` if and only if the (non-quantum) code $C$ is projective.

<a id="function-iszero-modtuprngelt"></a>
#### `IsZero(u): ModTupRngElt -> BoolElt`

Return `true` if and only if the codeword $u$ is the zero vector.

<a id="example-ex-659440"></a>
#### `Example: Properties of a Code over Z4 (ex-659440)`

We consider an [8, 7] linear code $K_8$ over $Z_4$ and examine some of its properties.

```magma
> Z4 := IntegerRing(4);
> K8 := LinearCode< Z4, 8 |
>     [1,1,1,1,1,1,1,1],
>     [0,2,0,0,0,0,0,2],
>     [0,0,2,0,0,0,0,2],
>     [0,0,0,2,0,0,0,2],
>     [0,0,0,0,2,0,0,2],
>     [0,0,0,0,0,2,0,2],
>     [0,0,0,0,0,0,2,2]>;
> K8;
[8, 7, 2] Linear Code over IntegerRing(4)
Generator matrix:
[1 1 1 1 1 1 1 1]
[0 2 0 0 0 0 0 2]
[0 0 2 0 0 0 0 2]
[0 0 0 2 0 0 0 2]
[0 0 0 0 2 0 0 2]
[0 0 0 0 0 2 0 2]
[0 0 0 0 0 0 2 2]
> IsCyclic(K8);
true
> IsSelfDual(K8);
true
> K8 eq Dual(K8);
true
```

### New Codes from Old

The operations described here produce a new code by modifying in some way the code words of a given code.

#### Sum, Intersection, and Dual

For the following operators, $C$ and $D$ are codes defined as subsets (or subspaces) of the same $R$-space $V$.

<a id="operation-op-plus-code-code"></a>
##### `C + D: Code, Code -> Code`

The (vector space) sum of the linear codes $C$ and $D$, where $C$ and $D$ are contained in the same $R$-space $V$.

<a id="operation-op-meet-code-code"></a>
##### `C meet D: Code, Code -> Code`

The intersection of the linear codes $C$ and $D$, where $C$ and $D$ are contained in the same $R$-space $V$.

<a id="function-dual-code"></a>
##### `Dual(C): Code -> Code`

The dual $D$ of the linear code $C$. The dual consists of all codewords in the $R$-space $V$ which are orthogonal to all codewords of $C$.

<a id="example-ex-e4970a"></a>
##### `Example: Sums and Intersections of Subcodes (ex-e4970a)`

Verify some simple results from the sum and intersection of subcodes.

```magma
> R<w> := GR(9,2);
> P<x> := PolynomialRing(R);
> g := x^2 + 7*w*x + 1;
> C := CyclicCode(5, g);
> C;
(5, 43046721) Cyclic Code over GaloisRing(3, 2, 2)
Generator matrix:
[  1   0   0   1   w]
[  0   1   0 2*w 2*w]
[  0   0   1   w   1]
[  0   0   0   3   0]
[  0   0   0   0   3]
>
> C1 := sub< C | C.1 >;
> C1;
(5, 81, 3) Linear Code over GaloisRing(3, 2, 2)
Generator matrix:
[1 0 0 1 w]
> C2 := sub< C | C.4 >;
> C2;
(5, 9, 1) Linear Code over GaloisRing(3, 2, 2)
Generator matrix:
[0 0 0 3 0]
> C3 := sub< C | { C.1 , C.4} >;
> C3;
(5, 729, 1) Linear Code over GaloisRing(3, 2, 2)
Generator matrix:
[1 0 0 1 w]
[0 0 0 3 0]
> (C1 + C2) eq C3;
true
> (C1 meet C3) eq C1;
true
```

#### Standard Constructions

<a id="function-directsum-code-code"></a>
##### `DirectSum(C, D): Code, Code -> Code`

Given a length $n_1$ code $C$ and a length $n_2$ code $D$, both over the same ring $R$, construct the direct sum of $C$ and $D$. The direct sum consists of all length $n_1+n_2$ vectors $u|v$, where $u \in C$ and $v \in D$.

<a id="function-directproduct-code-code"></a>
##### `DirectProduct(C, D): Code, Code -> Code`

Given a length $n_1$ code $C$ and a length $n_2$ code $D$, both over the same ring $R$, construct the direct product of $C$ and $D$. The direct product has length $n_1\cdot n_2$ and its generator matrix is the Kronecker product of the basis matrices of $C$ and $D$.

<a id="operation-operation-cat-code-code-code"></a>
##### `C1 cat C2: Code, Code -> Code`

Given codes $C1$ and $C2$, both defined over the same ring $R$, return the concatenation $C$ of $C1$ and $C2$. If $A$ and $B$ are the generator matrices of $C1$ and $C2$, respectively, the concatenation of $C1$ and $C2$ is the code with generator matrix whose rows consist of each row of $A$ concatenated with each row of $B$.

<a id="function-extendcode-code"></a>
##### `ExtendCode(C): Code -> Code`

Given a length $n$ code $C$ form a new code $C'$ from $C$ by adding the appropriate extra coordinate to each vector of $C$ such that the sum of the coordinates of the extended vector is zero.

<a id="function-extendcode-code-rngintelt"></a>
##### `ExtendCode(C, n): Code, RngIntElt -> Code`

Return the code $C$ extended $n$ times.

<a id="function-padcode-code-rngintelt"></a>
##### `PadCode(C, n): Code, RngIntElt -> Code`

Add $n$ zeros to the end of each codeword of $C$.

<a id="function-plotkinsum-code-code"></a>
##### `PlotkinSum(C, D): Code, Code -> Code`

Given codes $C$ and $D$ both over the same ring $R$ and of the same length $n$, construct the Plotkin sum of $C$ and $D$. The Plotkin sum consists of all vectors $u|u+v$, $u \in C$ and $v \in D$.

<a id="function-puncturecode-code-rngintelt"></a>
##### `PunctureCode(C, i): Code, RngIntElt -> Code`

Given a length $n$ code $C$, and an integer $i$, $1 \leq i \leq n$, construct a new code $C'$ by deleting the $i$-th coordinate from each code word of $C$.

<a id="function-puncturecode-code-rngintelt-2"></a>
##### `PunctureCode(C, S): Code, { RngIntElt } -> Code`

Given a length $n$ code $C$ and a set $S$ of distinct integers $\{ i_1, \cdots, {\mathrm{i}}_r \}$ each of which lies in the range $[1, n]$, construct a new code $C'$ by deleting the components $i_1, \cdots, i_r$ from each code word of $C$.

<a id="function-shortencode-code-rngintelt"></a>
##### `ShortenCode(C, i): Code, RngIntElt -> Code`

Given a length $n$ code $C$ and an integer $i$, $1 \leq i \leq n$, construct a new code from $C$ by selecting only those codewords of $C$ having a zero as their $i$-th component and deleting the $i$-th component from these codewords. Thus, the resulting code will have length $n-1$.

<a id="function-shortencode-code-rngintelt-2"></a>
##### `ShortenCode(C, S): Code, { RngIntElt } -> Code`

Given a length $n$ code $C$ and a set $S$ of distinct integers $\{ i_1, \cdots, {\mathrm{i}}_r\}$, each of which lies in the range $[1, n]$, construct a new code from $C$ by selecting only those codewords of $C$ having zeros in each of the coordinate positions $i_1, \cdots, i_r$, and deleting these components. Thus, the resulting code will have length $n-r$.

<a id="example-ex-fe796f"></a>
##### `Example: Lengths of Combined Codes (ex-fe796f)`

We combine codes in various ways and look at the length of the new code.

```magma
> R<w> := GR(8,2);
> C1 := RandomLinearCode(R, 4, 2);
> C2 := RandomLinearCode(R, 5, 3);
> Length(C1);
4
> Length(C2);
5
> C3 := DirectSum(C1, C2);
> Length(C3);
9
> C4 := DirectProduct(C1, C2);
> Length(C4);
20
> C5 := C1 cat C2;
> Length(C5);
9
```

<a id="example-ex-0c4967"></a>
##### `Example: Puncturing a Code over Z4 (ex-0c4967)`

We note that, in general, puncturing a code over ${\mathbb{Z}}_4$ reduces the minimum Lee distance by $2$.

```magma
> C := PreparataCode(3);
> C;
(8, 256, 4) Linear Code over IntegerRing(4)
Generator matrix:
[1 0 0 0 3 1 2 1]
[0 1 0 0 2 1 1 3]
[0 0 1 0 1 1 3 2]
[0 0 0 1 3 2 3 3]
> MinimumLeeWeight(C);
6
> C1 := PunctureCode(C,8);
> C1;
(7, 256, 3) Linear Code over IntegerRing(4)
Generator matrix:
[1 0 0 0 3 1 2]
[0 1 0 0 2 1 1]
[0 0 1 0 1 1 3]
[0 0 0 1 3 2 3]
> MinimumLeeWeight(C1);
4
```

### Codeword Operations

#### Construction

<a id="operation-op-code-rngelt"></a>
##### `C ! [a₁, ..., aₙ]: Code, [ RngElt ] -> ModTupRngElt`

<a id="constructor-constructor-elt-code-list-modtuprngelt"></a>
##### `elt< C | a₁, ..., aₙ>: Code, List -> ModTupRngElt`

Given a code $C$ which is defined as a subset of the $R$-space $R^{(n)}$, and elements $a_1, \ldots, a_n$ belonging to $R$, construct the codeword $(a_1, \ldots, a_n)$ of $C$. It is checked that the vector ($a_1, \ldots, a_n$) is an element of $C$.

<a id="operation-op-code-modtuprngelt"></a>
##### `C ! u: Code, ModTupRngElt -> ModTupRngElt`

Given a code $C$ which is defined as a subset of the $R$-space $V = R^{(n)}$, and an element $u$ belonging to $V$, create the codeword of $C$ corresponding to $u$. The function will fail if $u$ does not belong to $C$.

<a id="operation-op-code-rngintelt"></a>
##### `C ! 0: Code, RngIntElt -> ModTupRngElt`

The zero word of the code $C$.

<a id="example-ex-c7f5f7"></a>
##### `Example: Creating Code Words (ex-c7f5f7)`

We create some elements of a code over a finite ring.

```magma
> R<w> := GR(16,2);
> P<x> := PolynomialRing(R);
> L := CyclotomicFactors(R, 7);
> C := CyclicCode(7, L[2]);
> C ! [1, 2*w, 0, w+3, 7*w, 12*w+3, w+3];
(       1      2*w        0    w + 3      7*w 12*w + 3    w + 3)
> elt< C | 0, 3, 0, 2*w + 5, 6*w + 9, 4*w + 5, 14*w + 14 >;
(        0         3         0   2*w + 5   6*w + 9   4*w + 5 14*w + 14)
```

If the given vector does not lie in the given code then an error will result.

```magma
> C ! [0,0,0,0,0,0,1];

>> C ! [0,0,0,0,0,0,1];
     ^
Runtime error in '!': Result is not in the given structure
> elt< C | 1, 0, 1, 0, 1, 0, 1>;

>> elt< C | 1, 0, 1, 0, 1, 0, 1>;
      ^
Runtime error in elt< ... >: Result is not in the lhs of the constructor
```

#### Operations

<a id="operation-op-plus-modtuprngelt-modtuprngelt"></a>
##### `u + v: ModTupRngElt, ModTupRngElt -> ModTupRngElt`

Sum of the codewords $u$ and $v$, where $u$ and $v$ belong to the same linear code $C$.

<a id="operation-operation-modtuprngelt-modtuprngelt"></a>
##### `- u: ModTupRngElt -> ModTupRngElt`

Additive inverse of the codeword $u$ belonging to the linear code $C$.

<a id="operation-op-minus-modtuprngelt-modtuprngelt"></a>
##### `u - v: ModTupRngElt, ModTupRngElt -> ModTupRngElt`

Difference of the codewords $u$ and $v$, where $u$ and $v$ belong to the same linear code $C$.

<a id="operation-op-times-rngelt-modtuprngelt"></a>
##### `a * u: RngElt, ModTupRngElt -> ModTupRngElt`

Given an element $a$ belonging to the ring $R$, and a codeword $u$ belonging to the linear code $C$, return the codeword $a*u$.

<a id="function-weight-modtuprngelt"></a>
##### `Weight(v): ModTupRngElt -> RngIntElt`

The Hamming weight of the codeword $v$, i.e., the number of non-zero components of $v$.

<a id="function-distance-modtuprngelt-modtuprngelt"></a>
##### `Distance(u, v): ModTupRngElt, ModTupRngElt -> RngIntElt`

The Hamming distance between the codewords $u$ and $v$, where $u$ and $v$ belong to the same code $C$.

<a id="function-support-modtuprngelt"></a>
##### `Support(w): ModTupRngElt -> { RngIntElt }`

Given a word $w$ belonging to the length $n$ code $C$, return its support as a subset of the integer set $\{ 1 .. n \}$. The support of $w$ consists of the coordinates at which $w$ has non-zero entries.

<a id="literal-literal-u-v-modtuprngelt-modtuprngelt-rngelt"></a>
##### `(u, v): ModTupRngElt, ModTupRngElt -> RngElt`

<a id="function-innerproduct-modtuprngelt-modtuprngelt"></a>
##### `InnerProduct(u, v): ModTupRngElt, ModTupRngElt -> RngElt`

Inner product of the vectors $u$ and $v$ with respect to the Euclidean norm, where $u$ and $v$ belong to the parent vector space of the code $C$.

<a id="function-coordinates-code-modtuprngelt"></a>
##### `Coordinates(C, u): Code, ModTupRngElt -> [ RngFinElt ]`

Given a length $n$ linear code $C$ and a codeword $u$ of $C$ return the coordinates of $u$ with respect to $C$. The coordinates of $u$ are returned as a sequence $Q = [a_1, \ldots, a_k]$ of elements from the alphabet of $C$ so that $u = a_1 * C.1 + \ldots + a_k * C.k$.

<a id="function-normalize-modtuprngelt"></a>
##### `Normalize(u): ModTupRngElt -> ModTupRngElt`

Given an element $u$ of a code defined over the ring $R$, return the normalization of $u$, which is the unique vector $v$ such that $v = a\cdot u$ for some scalar $a\in R$ such that the first non-zero entry of $v$ is the canonical associate in $R$ of the first non-zero entry of $u$ ($v$ is zero if $u$ is zero).

<a id="function-rotate-modtuprngelt-rngintelt"></a>
##### `Rotate(u, k): ModTupRngElt, RngIntElt -> ModTupRngElt`

Given a vector $u$, return the vector obtained from $u$ by cyclically shifting its components to the right by $k$ coordinate positions.

<a id="procedure-rotate-modtuprngelt-rngintelt-ref"></a>
##### `Rotate(~u, k): ModTupRngElt, RngIntElt`

Given a vector $u$, destructively rotate $u$ by $k$ coordinate positions.

<a id="function-parent-modtuprngelt"></a>
##### `Parent(w): ModTupRngElt -> ModTupRng`

Given a word $w$ belonging to the code $C$, return the ambient space $V$ of $C$.

<a id="example-ex-38a7a5"></a>
##### `Example: Operations on Code Words (ex-38a7a5)`

Given a code over a finite ring, we explore various operations on its code words.

```magma
> R<w> := GR(4, 4);
> P<x> := PolynomialRing(R);
> g := x + 2*w^3 + 3*w^2 + w + 2;
> C := CyclicCode(3, g);
> C;
(3, 1048576) Cyclic Code over GaloisRing(2, 2, 4)
Generator matrix:
[          1           0     w^2 + w]
[          0           1 w^2 + w + 1]
[          0           0           2]
> u := C.1;
> v := C.2;
> u;
(      1       0 w^2 + w)
> v;
(          0           1 w^2 + w + 1)
> u + v;
(              1               1 2*w^2 + 2*w + 1)
> 2*u;
(          2           0 2*w^2 + 2*w)
> 4*u;
(0 0 0)
> Weight(u);
2
> Support(u);
{ 1, 3 }
```

#### Accessing Components of a Codeword

<a id="indexed-indexed-u-modtuprngelt-rngintelt-rngelt"></a>
##### `u[i]: ModTupRngElt, RngIntElt -> RngElt`

Given a codeword $u$ belonging to the code $C$ defined over the ring $R$, return the $i$-th component of $u$ (as an element of $R$).

<a id="literal-literal-u-i-x"></a>
##### `u[i] := x;`

Given an element $u$ belonging to a subcode $C$ of the full $R$-space $V = R^n$, a positive integer $i$, $1 \leq i\leq n$, and an element $x$ of $R$, this function returns a vector in $V$ which is $u$ with its $i$-th component redefined to be $x$.

### Weight Distributions

In the case of a linear code, weight and distance distributions are equivalent (in particular minimum weight and minimum distance are equivalent).

#### Hamming Weight

For an element $x\in{\mathbb{R}}$ for any finite ring $R$, the *Hamming weight* $w_H(x)$ is defined by:

$$
w_H(x) = 0 \iff x = 0, \qquad w_H(x) = 1 \iff x \ne 0
$$

The *Hamming weight* $w_H(v)$ of a vector $v\in {R^n}$ is defined to be the sum (in ${\mathbb{Z}}$) of the Hamming weights of its components.

The *Hamming weight* is often referred to as simply the *weight*.

<a id="function-minimumweight-code"></a>
##### `MinimumWeight(C): Code -> RngIntElt`

<a id="function-minimumdistance-code"></a>
##### `MinimumDistance(C): Code -> RngIntElt`

Determine the minimum (Hamming) weight of the words belonging to the code $C$, which is also the minimum distance between any two codewords.

<a id="function-weightdistribution-code"></a>
##### `WeightDistribution(C): Code -> [ <RngIntElt, RngIntElt> ]`

Determine the (Hamming) weight distribution for the code $C$. The distribution is returned in the form of a sequence of tuples, where the $i$-th tuple contains the $i$-th weight, $w_i$ say, and the number of codewords having weight $w_i$.

<a id="function-dualweightdistribution-code"></a>
##### `DualWeightDistribution(C): Code -> [ <RngIntElt, RngIntElt> ]`

Determine the (Hamming) weight distribution of the dual code of $C$. The distribution is returned in the form of a sequence of tuples, where the $i$-th tuple contains the $i$-th weight, $w_i$ say, and the number of codewords having weight $w_i$.

<a id="example-ex-bb2d09"></a>
##### `Example: Weight Distribution of a Cyclic Code (ex-bb2d09)`

We calculate the weight distribution of a cyclic code over the Galois ring of size $81$.

```magma
> R<w> := GR(9,2);
> P<x> := PolynomialRing(R);
> L := CyclotomicFactors(R, 4);
> g := L[3] * L[4];
> g;
x^2 + (8*w + 7)*x + w + 1
> C := CyclicCode(4, g);
> C;
(4, 6561, 3) Cyclic Code over GaloisRing(3, 2, 2)
Generator matrix:
[      1       0   w + 1 8*w + 7]
[      0       1       w 8*w + 8]
> WeightDistribution(C);
[ <0, 1>, <3, 320>, <4, 6240> ]
```

### Weight Enumerators

<a id="function-completeweightenumerator-code"></a>
#### `CompleteWeightEnumerator(C): Code -> RngMPolElt`

Let $C$ be a code over a finite ring $R$ of cardinality $q$, and suppose that the elements of $R$ are ordered in some way. Then for a codeword $v \in C$ and the $i$-th element $a \in R$, let $s_i(v)$ denote the number of components of $v$ equal to $a$.

This function returns the complete weight enumerator ${\cal W}_C(X_0, X_1, \ldots, X_{q-1})$ of $C$, which is defined by:

$$
{\cal W}_C(X_0, X_1, \ldots, X_{q-1}) =
   \sum_{v \in C}{{X_0}^{s_0(v)}{X_1}^{s_1(v)}\cdots{X_{q-1}}^{s_{q-1}(v)}}.
$$

See [[Wan97](https://docs.magma-maths.org/references.md#cite-wan-z4), p. 9] for more information. The result will lie in a global multivariate polynomial ring over ${\mathbb{Z}}$ with q variables. The angle-bracket notation may be used to assign names to the indeterminates.

<a id="function-weightenumerator-code"></a>
#### `WeightEnumerator(C): Code -> RngMPolElt`

<a id="function-hammingweightenumerator-code"></a>
#### `HammingWeightEnumerator(C): Code -> RngMPolElt`

Suppose $C$ is a code over some finite ring $R$. This function returns the Hamming weight enumerator $\hbox{Ham}_C(X, Y)$ of $C$, which is defined by:

$$
\hbox{Ham}_C(X, Y) = \sum_{v \in C}{X^{n-w_H(v)}Y^{w_H(v)}},
$$

where $w_H(v)$ is the Hamming weight function. The result will lie in a global multivariate polynomial ring over ${\mathbb{Z}}$ with two variables. The angle-bracket notation may be used to assign names to the indeterminates.

<a id="example-ex-1d525d"></a>
#### `Example: Complete Weight Enumerator over a Galois Ring (ex-1d525d)`

We compute the complete weight enumerator of a cyclic code over the Galois ring `GR`$(4, 2)$.

```magma
> R<w> := GR(4,2);
> P<x> := PolynomialRing(R);
> L := CyclotomicFactors(R, 3);
> g := L[1];
> g;
x + 3
> C := CyclicCode(3, g);
> C;
(3, 256, 2) Cyclic Code over GaloisRing(2, 2, 2)
Generator matrix:
[1 0 3]
[0 1 3]
> CWE<[X]> := CompleteWeightEnumerator(C);
> CWE;
X[1]^3 + 6*X[1]*X[2]*X[4] + 3*X[1]*X[3]^2 + 6*X[1]*X[5]*X[13] +
    6*X[1]*X[6]*X[16] + 6*X[1]*X[7]*X[15] + 6*X[1]*X[8]*X[14] +
    3*X[1]*X[9]^2 + 6*X[1]*X[10]*X[12] + 3*X[1]*X[11]^2 +
    3*X[2]^2*X[3] + 6*X[2]*X[5]*X[16] + 6*X[2]*X[6]*X[15] +
    6*X[2]*X[7]*X[14] + 6*X[2]*X[8]*X[13] + 6*X[2]*X[9]*X[12] +
    6*X[2]*X[10]*X[11] + 3*X[3]*X[4]^2 + 6*X[3]*X[5]*X[15] +
    6*X[3]*X[6]*X[14] + 6*X[3]*X[7]*X[13] + 6*X[3]*X[8]*X[16] +
    6*X[3]*X[9]*X[11] + 3*X[3]*X[10]^2 + 3*X[3]*X[12]^2 +
    6*X[4]*X[5]*X[14] + 6*X[4]*X[6]*X[13] + 6*X[4]*X[7]*X[16] +
    6*X[4]*X[8]*X[15] + 6*X[4]*X[9]*X[10] + 6*X[4]*X[11]*X[12] +
    3*X[5]^2*X[9] + 6*X[5]*X[6]*X[12] + 6*X[5]*X[7]*X[11] +
    6*X[5]*X[8]*X[10] + 3*X[6]^2*X[11] + 6*X[6]*X[7]*X[10] +
    6*X[6]*X[8]*X[9] + 3*X[7]^2*X[9] + 6*X[7]*X[8]*X[12] +
    3*X[8]^2*X[11] + 3*X[9]*X[13]^2 + 6*X[9]*X[14]*X[16] +
    3*X[9]*X[15]^2 + 6*X[10]*X[13]*X[16] + 6*X[10]*X[14]*X[15] +
    6*X[11]*X[13]*X[15] + 3*X[11]*X[14]^2 + 3*X[11]*X[16]^2 +
    6*X[12]*X[13]*X[14] + 6*X[12]*X[15]*X[16]
```

<a id="linear-codes-over-the-integer-residue-ring-mathbb-z-4"></a>
<a id="error-correcting-linear-code"></a>
<a id="chap-codez4"></a>
## Linear Codes over the Integer Residue Ring ${\mathbb{Z}}_4$

- [Introduction](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/introduction.md)
- [Constructions for ${\mathbb{Z}}_4$ Codes](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md)
  - [The Gray Map](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#the-gray-map)
    - [`GrayMap(C): Code → Map`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-graymap-code)
    - [`GrayMapImage(C): Code → [ ModTupRngElt ]`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-graymapimage-code)
    - [`HasLinearGrayMapImage(C): Code → BoolElt, Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-haslineargraymapimage-code)
    - [Example: Gray Map Image of the Octacode](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#example-ex-660fb9)
  - [Families of Codes over ${\mathbb{Z}}_4$](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#families-of-codes-over-mathbb-z-4)
    - [`KerdockCode(m): RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-kerdockcode-rngintelt)
    - [`PreparataCode(m): RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-preparatacode-rngintelt)
    - [`ReedMullerCodeZ4(r, m): RngIntElt, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-reedmullercodez4-rngintelt-rngintelt)
    - [`GoethalsCode(m): RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-goethalscode-rngintelt)
    - [`DelsarteGoethalsCode(m, delta): RngIntElt, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-delsartegoethalscode-rngintelt-rngintelt)
    - [`GoethalsDelsarteCode(m, delta): RngIntElt, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-goethalsdelsartecode-rngintelt-rngintelt)
    - [`QRCodeZ4(p): RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-qrcodez4-rngintelt)
    - [`GolayCodeZ4(e): BoolElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-golaycodez4-boolelt)
    - [`SimplexAlphaCodeZ4(k): RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-simplexalphacodez4-rngintelt)
    - [`SimplexBetaCodeZ4(k): RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-simplexbetacodez4-rngintelt)
    - [Example: Kerdock and Preparata Codes](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#example-ex-79827c)
    - [`HadamardCodeZ4(δ, m): RngIntElt, RngIntElt → CodeLinRng, Mtrx`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-hadamardcodez4-rngintelt-rngintelt)
    - [`ExtendedPerfectCodeZ4(δ, m): RngIntElt, RngIntElt → CodeLinRng, Mtrx`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-extendedperfectcodez4-rngintelt-rngintelt)
    - [Example: Hadamard Codes over Z4](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#example-ex-6e1c45)
    - [`ReedMullerCodeZ4(r, m): RngIntElt, RngIntElt → CodeLinRng`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-reedmullercodez4-rngintelt-rngintelt-2)
    - [`ReedMullerCodeQRMZ4(r, m): RngIntElt, RngIntElt → CodeLinRng`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-reedmullercodeqrmz4-rngintelt-rngintelt)
    - [`ReedMullerCodesLRMZ4(r, m): RngIntElt, RngIntElt → SeqEnum`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-reedmullercodeslrmz4-rngintelt-rngintelt)
    - [`ReedMullerCodeRMZ4(s, r, m): RngIntElt, RngIntElt, RngIntElt → CodeLinRng, Mtrx`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-reedmullercodermz4-rngintelt-rngintelt-rngintelt)
    - [Example: Nested Reed-Muller Codes over Z4](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#example-ex-797694)
    - [`ReedMullerCodesRMZ4(s, m): RngIntElt, RngIntElt → Tup`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-reedmullercodesrmz4-rngintelt-rngintelt)
    - [Example: Family of Reed-Muller Codes over Z4](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#example-ex-c9bc7a)
  - [Derived Binary Codes](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#derived-binary-codes)
    - [`BinaryResidueCode(C): Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-binaryresiduecode-code)
    - [`BinaryTorsionCode(C): Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-binarytorsioncode-code)
    - [`Z4CodeFromBinaryChain(C1, C2): Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-z4codefrombinarychain-code-code)
    - [Example: Derived Binary Codes of the Z4 Golay Code](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#example-ex-08428d)
  - [New Codes from Old](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#new-codes-from-old)
    - [`PlotkinSum(A, B): Mtrx, Mtrx → Mtrx`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-plotkinsum-mtrx-mtrx)
    - [`PlotkinSum(C, D): Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-plotkinsum-code-code)
    - [`QuaternaryPlotkinSum(A, B): Mtrx, Mtrx → Mtrx`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-quaternaryplotkinsum-mtrx-mtrx)
    - [`QuaternaryPlotkinSum(C, D): Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-quaternaryplotkinsum-code-code)
    - [`BQPlotkinSum(A, B, C): Mtrx, Mtrx, Mtrx → Mtrx`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-bqplotkinsum-mtrx-mtrx-mtrx)
    - [`BQPlotkinSum(D, E, F): Code, Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-bqplotkinsum-code-code-code)
    - [`DoublePlotkinSum(A, B, C, D): Mtrx, Mtrx, Mtrx, Mtrx → Mtrx`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-doubleplotkinsum-mtrx-mtrx-mtrx-mtrx)
    - [`DoublePlotkinSum(E, F, G, H): Code, Code, Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-doubleplotkinsum-code-code-code-code)
    - [`DualKroneckerZ4(C): CodeLinRng → CodeLinRng`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#function-dualkroneckerz4-codelinrng)
    - [Example: Plotkin Sums of Matrices and Codes](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#example-ex-b631eb)
    - [Example: Reed-Muller Codes as Plotkin Sums](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#example-ex-c3f759)
- [Invariants](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md)
  - [The Standard Form](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#the-standard-form)
    - [`StandardForm(C): Code → Code, Map`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#function-standardform-code)
    - [Example: Standard Form of a Code over Z4](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#example-ex-48fad2)
    - [`StandardFormDual(C): CodeLinRng → CodeLinRng, Map`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#function-standardformdual-codelinrng)
  - [Structures Associated with the Gray Map](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#structures-associated-with-the-gray-map)
    - [`MinRowsGeneratorMatrix(C): CodeLinRng → ModMatRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#function-minrowsgeneratormatrix-codelinrng)
    - [`MinRowsParityCheckMatrix(C): CodeLinRng → ModMatRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#function-minrowsparitycheckmatrix-codelinrng)
    - [`DualZ4(C): CodeLinRng → CodeLinRng`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#function-dualz4-codelinrng)
    - [Example: Generator Matrices with Minimum Rows](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#example-ex-3b2558)
    - [`SpanZ2CodeZ4(C): CodeLinRng → CodeLinFld`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#function-spanz2codez4-codelinrng)
    - [`KernelZ2CodeZ4(C): CodeLinRng → CodeLinRng`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#function-kernelz2codez4-codelinrng)
    - [`KernelCosetRepresentatives(C): CodeLinRng → SeqEnum, SeqEnum`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#function-kernelcosetrepresentatives-codelinrng)
    - [`DimensionOfSpanZ2(C): CodeLinRng → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#function-dimensionofspanz2-codelinrng)
    - [`RankZ2(C): CodeLinRng → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#function-rankz2-codelinrng)
    - [`DimensionOfKernelZ2(C): CodeLinRng → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#function-dimensionofkernelz2-codelinrng)
    - [Example: Kernel and Span of a Code over Z4](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#example-ex-bb9d15)
  - [Coset Representatives](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#coset-representatives)
    - [`CosetRepresentatives(C): CodeLinRng → SeqEnum`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#function-cosetrepresentatives-codelinrng)
    - [`CosetRepresentatives(C, S): CodeLinRng, CodeLinRng → SeqEnum, SeqEnum`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#function-cosetrepresentatives-codelinrng-codelinrng)
    - [Example: Coset Representatives of a Code](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#example-ex-551655)
  - [Information Space and Information Sets](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#information-space-and-information-sets)
    - [`InformationSpace(C): CodeLinRng → ModTupRng, ModTupFld, Map, Map`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#function-informationspace-codelinrng)
    - [Example: Information Space of a Code over Z4](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#example-ex-5fc04a)
    - [`InformationSet(C): CodeLinRng → ModTupRng, ModTupFld, Map, Map`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#function-informationset-codelinrng)
    - [`IsInformationSet(C, I): CodeLinRng, [RngIntElt] → BoolElt, BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#function-isinformationset-codelinrng-rngintelt)
    - [Example: Information Sets of a Hadamard Code](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#example-ex-1d41b7)
  - [Syndrome Space and Coset Leaders](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#syndrome-space-and-coset-leaders)
    - [`SyndromeSpace(C): CodeLinRng → ModTupRng, ModTupFld`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#function-syndromespace-codelinrng)
    - [`Syndrome(u, C): ModTupFldElt, CodeLinRng → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#function-syndrome-modtupfldelt-codelinrng)
    - [`Syndrome(u, C): ModTupRngElt, CodeLinRng → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#function-syndrome-modtuprngelt-codelinrng)
    - [`CosetLeaders(C): CodeLinRng → SetIndx, Map`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#function-cosetleaders-codelinrng)
    - [Example: Syndrome Space and Coset Leaders](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#example-ex-5bce83)
  - [Miscellaneous Functions](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#miscellaneous-functions)
    - [`Correlation(v): ModTupRngElt → RngQuadElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#function-correlation-modtuprngelt)
- [Weight Distributions](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md)
  - [Hamming Weight](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#hamming-weight)
    - [`MinimumWeight(C): Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#function-minimumweight-code)
    - [`MinimumDistance(C): Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#function-minimumdistance-code)
    - [`WeightDistribution(C): Code → [ <RngIntElt, RngIntElt> ]`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#function-weightdistribution-code)
    - [`DualWeightDistribution(C): Code → [ <RngIntElt, RngIntElt> ]`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#function-dualweightdistribution-code)
    - [Example: Weight Distribution of a Quadratic Residue Code](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#example-ex-601dad)
  - [Lee Weight](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#lee-weight)
    - [`LeeWeight(a): RngIntRes → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#function-leeweight-rngintres)
    - [`LeeWeight(v): ModTupRngElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#function-leeweight-modtuprngelt)
    - [`LeeDistance(u, v): ModTupRngElt, ModTupRngElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#function-leedistance-modtuprngelt-modtuprngelt)
    - [`MinimumLeeWeight(C): Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#function-minimumleeweight-code)
    - [`MinimumLeeDistance(C): Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#function-minimumleedistance-code)
    - [`LeeWeightDistribution(C): Code → SeqEnum`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#function-leeweightdistribution-code)
    - [`DualLeeWeightDistribution(C): Code → SeqEnum`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#function-dualleeweightdistribution-code)
    - [`WordsOfLeeWeight(C, w): Code, RngIntElt → SetEnum`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#function-wordsofleeweight-code-rngintelt)
    - [`WordsOfBoundedLeeWeight(C, l, u): Code, RngIntElt, RngIntElt → SetEnum`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#function-wordsofboundedleeweight-code-rngintelt-rngintelt)
    - [Example: Lee Weight Distribution](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#example-ex-587036)
  - [Euclidean Weight](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#euclidean-weight)
    - [`EuclideanWeight(a): RngIntRes → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#function-euclideanweight-rngintres)
    - [`EuclideanWeight(v): ModTupRngElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#function-euclideanweight-modtuprngelt)
    - [`EuclideanDistance(u, v): ModTupRngElt, ModTupRngElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#function-euclideandistance-modtuprngelt-modtuprngelt)
    - [`MinimumEuclideanWeight(C): Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#function-minimumeuclideanweight-code)
    - [`MinimumEuclideanDistance(C): Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#function-minimumeuclideandistance-code)
    - [`EuclideanWeightDistribution(C): Code → SeqEnum`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#function-euclideanweightdistribution-code)
    - [`DualEuclideanWeightDistribution(C): Code → SeqEnum`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#function-dualeuclideanweightdistribution-code)
    - [Example: Euclidean Weight Distribution](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#example-ex-9f8213)
- [Weight Enumerators](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-enumerator.md)
  - [`CompleteWeightEnumerator(C): Code → RngMPolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-enumerator.md#function-completeweightenumerator-code)
  - [`SymmetricWeightEnumerator(C): Code → RngMPolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-enumerator.md#function-symmetricweightenumerator-code)
  - [`WeightEnumerator(C): Code → RngMPolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-enumerator.md#function-weightenumerator-code)
  - [`HammingWeightEnumerator(C): Code → RngMPolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-enumerator.md#function-hammingweightenumerator-code)
  - [`LeeWeightEnumerator(C): Code → RngMPolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-enumerator.md#function-leeweightenumerator-code)
  - [`EuclideanWeightEnumerator(C): Code → RngMPolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-enumerator.md#function-euclideanweightenumerator-code)
  - [Example: Weight Enumerators of the Octacode](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-enumerator.md#example-ex-92ee64)
- [Decoding](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md)
  - [Coset Decoding](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#coset-decoding)
    - [`CosetDecode(C, u : parameters): CodeLinRng, ModTupFldElt → BoolElt, ModTupRngElt, ModTupFldElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#function-cosetdecode-codelinrng-modtupfldelt)
    - [`CosetDecode(C, u : parameters): CodeLinRng, ModTupRngElt → BoolElt, ModTupRngElt, ModTupFldElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#function-cosetdecode-codelinrng-modtuprngelt)
    - [`CosetDecode(C, Q : parameters): CodeLinRng, [ModTupFldElt] → SeqEnum, SeqEnum, SeqEnum`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#function-cosetdecode-codelinrng-modtupfldelt-2)
    - [`CosetDecode(C, Q : parameters): CodeLinRng, [ModTupRngElt] → SeqEnum, SeqEnum, SeqEnum`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#function-cosetdecode-codelinrng-modtuprngelt-2)
    - [Example: Coset Decoding of a Hadamard Code](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#example-ex-68b44c)
  - [Syndrome Decoding](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#syndrome-decoding)
    - [`SyndromeDecode(C, u): CodeLinRng, ModTupFldElt → BoolElt, ModTupRngElt, ModTupFldElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#function-syndromedecode-codelinrng-modtupfldelt)
    - [`SyndromeDecode(C, u): CodeLinRng, ModTupRngElt → BoolElt, ModTupRngElt, ModTupFldElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#function-syndromedecode-codelinrng-modtuprngelt)
    - [`SyndromeDecode(C, Q): CodeLinRng, [ModTupFldElt] → SeqEnum, SeqEnum, SeqEnum`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#function-syndromedecode-codelinrng-modtupfldelt-2)
    - [`SyndromeDecode(C, Q): CodeLinRng, [ModTupRngElt] → SeqEnum, SeqEnum, SeqEnum`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#function-syndromedecode-codelinrng-modtuprngelt-2)
    - [Example: Syndrome Decoding of a Hadamard Code](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#example-ex-1a7dd2)
  - [Lifted Decoding](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#lifted-decoding)
    - [`LiftedDecode(C, u : parameters): CodeLinRng, ModTupFldElt → BoolElt, ModTupRngElt, ModTupFldElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#function-lifteddecode-codelinrng-modtupfldelt)
    - [`LiftedDecode(C, u : parameters): CodeLinRng, ModTupRngElt → BoolElt, ModTupRngElt, ModTupFldElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#function-lifteddecode-codelinrng-modtuprngelt)
    - [`LiftedDecode(C, Q : parameters): CodeLinRng, [ModTupFldElt] → SeqEnum, SeqEnum, SeqEnum`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#function-lifteddecode-codelinrng-modtupfldelt-2)
    - [`LiftedDecode(C, Q : parameters): CodeLinRng, [ModTupRngElt] → SeqEnum, SeqEnum, SeqEnum`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#function-lifteddecode-codelinrng-modtuprngelt-2)
    - [Example: Lifted Decoding of a Hadamard Code](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#example-ex-403c77)
  - [Permutation Decoding](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#permutation-decoding)
    - [`IsPermutationDecodeSet(C, I, S, s): CodeLinRng, [RngIntElt], [GrpPermElt], RngIntElt → BoolElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#function-ispermutationdecodeset-codelinrng-rngintelt-grppermelt-rngintelt)
    - [`PermutationDecode(C, I, S, s, u): CodeLinRng, [RngIntElt], [GrpPermElt], RngIntElt, ModTupFldElt → BoolElt, ModTupRngElt, ModTupFldElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#function-permutationdecode-codelinrng-rngintelt-grppermelt-rngintelt-modtupfldelt)
    - [`PermutationDecode(C, I, S, s, u): CodeLinRng, [RngIntElt], [GrpPermElt], RngIntElt, ModTupRngElt → BoolElt, ModTupRngElt, ModTupFldElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#function-permutationdecode-codelinrng-rngintelt-grppermelt-rngintelt-modtuprngelt)
    - [`PermutationDecode(C, I, S, s, Q): CodeLinRng, [RngIntElt], [GrpPermElt], RngIntElt, [ModTupFldElt] → [BoolElt], [ModTupRngElt], [ModTupFldElt]`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#function-permutationdecode-codelinrng-rngintelt-grppermelt-rngintelt-modtupfldelt-2)
    - [`PermutationDecode(C, I, S, s, Q): CodeLinRng, [RngIntElt], [GrpPermElt], RngIntElt, [ModTupRngElt] → [BoolElt], [ModTupRngElt], [ModTupFldElt]`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#function-permutationdecode-codelinrng-rngintelt-grppermelt-rngintelt-modtuprngelt-2)
    - [Example: Permutation Decoding of a Hadamard Code](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#example-ex-446a9b)
    - [`PDSetHadamardCodeZ4(δ, m): RngIntElt, RngIntElt → SeqEnum, SeqEnum, SeqEnum, SeqEnum, SeqEnum`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#function-pdsethadamardcodez4-rngintelt-rngintelt)
    - [`PDSetKerdockCodeZ4(m): RngIntElt → SeqEnum, SeqEnum, SeqEnum, SeqEnum`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#function-pdsetkerdockcodez4-rngintelt)
    - [Example: Checking a PD-Set for a Hadamard Code](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#example-ex-a6009d)
- [Automorphism Groups](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/aut_group.md)
  - [`PermutationGroupHadamardCodeZ4(δ, m): RngIntElt, RngIntElt → GrpPerm, Mtrx`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/aut_group.md#function-permutationgrouphadamardcodez4-rngintelt-rngintelt)
  - [`PAutHadamardCodeZ4(δ, m): RngIntElt, RngIntElt → GrpPerm, Mtrx`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/aut_group.md#function-pauthadamardcodez4-rngintelt-rngintelt)
  - [`PermutationGroupHadamardCodeZ4Order(δ, m): RngIntElt, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/aut_group.md#function-permutationgrouphadamardcodez4order-rngintelt-rngintelt)
  - [`PAutHadamardCodeZ4Order(δ, m): RngIntElt, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/aut_group.md#function-pauthadamardcodez4order-rngintelt-rngintelt)
  - [`PermutationGroupExtendedPerfectCodeZ4(δ, m): RngIntElt, RngIntElt → GrpPerm, Mtrx`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/aut_group.md#function-permutationgroupextendedperfectcodez4-rngintelt-rngintelt)
  - [`PAutExtendedPerfectCodeZ4(δ, m): RngIntElt, RngIntElt → GrpPerm, Mtrx`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/aut_group.md#function-pautextendedperfectcodez4-rngintelt-rngintelt)
  - [`PermutationGroupExtendedPerfectCodeZ4Order(δ, m): RngIntElt, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/aut_group.md#function-permutationgroupextendedperfectcodez4order-rngintelt-rngintelt)
  - [`PAutExtendedPerfectCodeZ4Order(δ, m): RngIntElt, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/aut_group.md#function-pautextendedperfectcodez4order-rngintelt-rngintelt)
  - [Example: Permutation Automorphisms of a Hadamard Code](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/aut_group.md#example-ex-61ad8c)
  - [`PermutationGroup(C): CodeLinRng → GrpPerm`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/aut_group.md#function-permutationgroup-codelinrng)
  - [`PermutationGroupGrayMapImage(C): CodeLinRng → GrpPerm`](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/aut_group.md#function-permutationgroupgraymapimage-codelinrng)
  - [Example: Permutation Group of a Code over Z4](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/aut_group.md#example-ex-326517)
- [Bibliography](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/bibliography.md)

### Introduction

In Chapter [Linear Codes over Finite Rings](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/index-linear-codes-over-finite-rings.md#chap-coderng) basic functions for working with codes over a finite ring are described. Because of the large amount of machinery developed specifically for ${\mathbb{Z}}_4$-codes, this chapter will be devoted to this special case. The functionality available for ${\mathbb{Z}}_4$-codes consists of the machinery described in chapter [Linear Codes over Finite Rings](https://docs.magma-maths.org/CodingTheory/LinearCodesOverFiniteRings/index-linear-codes-over-finite-rings.md#chap-coderng) together with the contents of this chapter.

This chapter includes constructions for some families of codes over ${\mathbb{Z}}_4$ (see sections [Families of Codes over ${\mathbb{Z}}_4$](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#sec-constfamilies) and [New Codes from Old](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#sec-plotkin)), efficient functions for computing the rank and dimension of the kernel of any code over ${\mathbb{Z}}_4$ (Section [Structures Associated with the Gray Map](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#sec-rankkernel)), as well as general functions for computing coset representatives for a subcode in a code over ${\mathbb{Z}}_4$ (Section [Coset Representatives](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/z4-invar.md#sec-cosetrep)). In addition, there are functions for computing the permutation automorphism group for Hadamard and extended perfect codes over ${\mathbb{Z}}_4$, and their cardinal (Section [Automorphism Groups](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/aut_group.md#sec-aut)). Finally, various algorithms for decoding codes over ${\mathbb{Z}}_4$ are also provided (Section [Decoding](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/decoding.md#sec-decoding)).

Error correcting codes over ${\mathbb{Z}}_4$ are often referred to as *quaternary* codes. Important concepts when discussing quaternary codes are *Lee weight* and the *Gray map*, which maps linear codes over ${\mathbb{Z}}_4$ to (possibly non-linear) codes over ${\mathbb{Z}}_2$. Many good non-linear binary codes can be defined as the images of simple linear quaternary codes. A code over ${\mathbb{Z}}_4$ is a subgroup of ${\mathbb{Z}}_4^n$, so it is isomorphic to an abelian structure ${\mathbb{Z}}_2^\gamma \times {\mathbb{Z}}_4^\delta$ and we will say that it is of type $2^\gamma4^\delta$, or simply that it has $2^{\gamma+2\delta}$ codewords. As general references on the available functions in Magma for codes over ${\mathbb{Z}}_4$, the reader is referred to [[HKC+94](https://docs.magma-maths.org/references.md#cite-sole), [Wan97](https://docs.magma-maths.org/references.md#cite-wan-z4)].

For general references on the material in this chapter, the reader is referred to the bibliography included at the end of this chapter.

The machinery described in this chapter largely corresponds to Version 2.0 of the package *Codes over* $\Z_4$*: A Magma Package* which has been developed by Roland D. Barrolleta, Jaume Pernas, Jaume Pujol, and Mercè Villanueva of the Combinatoric, Coding and Security Group (CCSG) at the Universitat Autònoma de Barcelona.

<a id="constructions-for-mathbb-z-4-codes"></a>
<a id="constructions"></a>
<a id="sec-z4-constructions"></a>
### Constructions for ${\mathbb{Z}}_4$ Codes

<a id="gray-map"></a>
<a id="sec-gray-map"></a>
#### The Gray Map

For an element $x\in{\mathbb{Z}}_4$, the *Gray map* $\phi: {\mathbb{Z}}_4 \rightarrow {\mathbb{Z}}_2^2$ is defined by:

$$
0 \mapsto 00,\ \ 1\mapsto 01,\ \ 2\mapsto 11,\ \ 3\mapsto 10.
$$

This map is extended to a map from ${\mathbb{Z}}_4^n$ onto ${\mathbb{Z}}_2^{2n}$ in the obvious way (by concatenating the images of each component). The resulting map is a weight- and distance-preserving map from ${\mathbb{Z}}_4^n$ (with Lee weight metric) to ${\mathbb{Z}}_2^{2n}$ (with Hamming weight metric). See [[Wan97](https://docs.magma-maths.org/references.md#cite-wan-z4), Chapter 3] for more information (but note that that author uses a different ordering of the components of the image of a vector).

<a id="function-graymap-code"></a>
##### `GrayMap(C): Code -> Map`

Given a ${\mathbb{Z}}_4$-linear code $C$, this function returns the Gray map for $C$. This is the map $\phi$ from $C$ to ${\bf F}_{2}^{2n}$, as defined above.

<a id="function-graymapimage-code"></a>
##### `GrayMapImage(C): Code -> [ ModTupRngElt ]`

Given a ${\mathbb{Z}}_4$-linear code $C$, this function returns the image of $C$ under the Gray map as a sequence of vectors in ${\bf F}_{2}^{2n}$. As the resulting image may not be a ${\bf F}_{2}$-linear code, a sequence of vectors is returned rather than a code.

<a id="function-haslineargraymapimage-code"></a>
##### `HasLinearGrayMapImage(C): Code -> BoolElt, Code`

Given a ${\mathbb{Z}}_4$-linear code $C$, this function returns true if and only if the image of $C$ under the Gray map is a ${\bf F}_{2}$-linear code. If so, the function also returns the image $B$ as a ${\bf F}_{2}$-linear code, together with the bijection $\phi: C \rightarrow B$.

<a id="example-ex-660fb9"></a>
##### `Example: Gray Map Image of the Octacode (ex-660fb9)`

Let $\phi(O_8)$ be the image of the octacode $O_8$ under the Gray map. This image is not a ${\bf F}_{2}$-linear code, but it is the non-linear $(8, 256, 6)$ Nordstrom-Robinson code [[Wan97](https://docs.magma-maths.org/references.md#cite-wan-z4), Ex.3.4]. The statements below demonstrate that the Hamming weight distribution of the ${\bf F}_{2}$ image is identical to the Lee weight distribution of the linear ${\mathbb{Z}}_4$ code.

```magma
> Z4 := IntegerRing(4);
> O8 := LinearCode<Z4, 8 |
>     [1,0,0,0,3,1,2,1],
>     [0,1,0,0,1,2,3,1],
>     [0,0,1,0,3,3,3,2],
>     [0,0,0,1,2,3,1,1]>;
> HasLinearGrayMapImage(O8);
false
> NR := GrayMapImage(O8);
> #NR;
256
> LeeWeightDistribution(O8);
[ <0, 1>, <6, 112>, <8, 30>, <10, 112>, <16, 1> ]
> {* Weight(v): v in NR *};
{* 0, 16, 6^^112, 8^^30, 10^^112 *}
```

After defining the code $K_8$, the images of some codewords under the Gray map are found.

```magma
> Z4 := IntegerRing(4);
> K8 := LinearCode< Z4, 8 |
>     [1,1,1,1,1,1,1,1],
>     [0,2,0,0,0,0,0,2],
>     [0,0,2,0,0,0,0,2],
>     [0,0,0,2,0,0,0,2],
>     [0,0,0,0,2,0,0,2],
>     [0,0,0,0,0,2,0,2],
>     [0,0,0,0,0,0,2,2]>;
> f := GrayMap(K8);
> K8.1;
(1 1 1 1 1 1 1 1)
> f(K8.1);
(0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1)
> K8.2;
(0 2 0 0 0 0 0 2)
> f(K8.2);
(0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 1)
```

The image of $K_8$ under the Gray map is a linear code over ${\bf F}_{2}$.

```magma
> l, B, g := HasLinearGrayMapImage(K8);
> l;
true
> B;
[16, 8, 4] Linear Code over GF(2)
Generator matrix:
[1 0 0 1 0 1 0 1 0 1 0 1 0 1 1 0]
[0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1]
[0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 1]
[0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1]
[0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1]
[0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 1]
[0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1]
[0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1]
> g(K8.1) in B;
true
```

<a id="families-of-codes-over-mathbb-z-4"></a>
<a id="families"></a>
<a id="sec-constfamilies"></a>
#### Families of Codes over ${\mathbb{Z}}_4$

This section presents some standard constructions for ${\mathbb{Z}}_4$-linear codes. Further constructions will become available in the near future.

<a id="function-kerdockcode-rngintelt"></a>
##### `KerdockCode(m): RngIntElt -> Code`

Given an integer $m\ge 2$, return the quaternary Kerdock code $K(m)$ of length $2^m-1$ defined by a default primitive polynomial $h\in{\mathbb{Z}}_4[x]$ of degree $m$.

<a id="function-preparatacode-rngintelt"></a>
##### `PreparataCode(m): RngIntElt -> Code`

Given an integer $m\ge 2$, return the quaternary Preparata code $P(m)$ of length $2^m-1$ defined by a default primitive polynomial $h\in{\mathbb{Z}}_4[x]$ of degree $m$.

<a id="function-reedmullercodez4-rngintelt-rngintelt"></a>
##### `ReedMullerCodeZ4(r, m): RngIntElt, RngIntElt -> Code`

Given an integer $m \ge 2$ and an integer $r$ such that $0 \le r \le m$ this function returns the $r$-th order Reed-Muller code over ${\mathbb{Z}}_4$ of length $2^m$.

<a id="function-goethalscode-rngintelt"></a>
##### `GoethalsCode(m): RngIntElt -> Code`

Given a positive integer $m$, where m must be an odd and greater than or equal to 3, return the Goethals code of length $2^m$.

<a id="function-delsartegoethalscode-rngintelt-rngintelt"></a>
##### `DelsarteGoethalsCode(m, delta): RngIntElt, RngIntElt -> Code`

Return the Delsarte-Goethals Code of length $2^m$.

<a id="function-goethalsdelsartecode-rngintelt-rngintelt"></a>
##### `GoethalsDelsarteCode(m, delta): RngIntElt, RngIntElt -> Code`

Return the Goethals-Delsarte code of length $2^m$

<a id="function-qrcodez4-rngintelt"></a>
##### `QRCodeZ4(p): RngIntElt -> Code`

Given a prime number $p$ such that $2$ is a quadratic residue modulo $p$, return the quadratic residue code of length $p$ over ${\mathbb{Z}}_4$.

<a id="function-golaycodez4-boolelt"></a>
##### `GolayCodeZ4(e): BoolElt -> Code`

Return the Golay Code over ${\mathbb{Z}}_4$. If $e$ is `true` then return the extended Golay Code

<a id="function-simplexalphacodez4-rngintelt"></a>
##### `SimplexAlphaCodeZ4(k): RngIntElt -> Code`

Return the simplex alpha code over ${\mathbb{Z}}_4$ of degree $k$.

<a id="function-simplexbetacodez4-rngintelt"></a>
##### `SimplexBetaCodeZ4(k): RngIntElt -> Code`

Return the simplex beta code over ${\mathbb{Z}}_4$ of degree $k$.

<a id="example-ex-79827c"></a>
##### `Example: Kerdock and Preparata Codes (ex-79827c)`

The minimum Lee weights of some default Kerdock and Preparata codes are found.

```magma
> PreparataCode(3);
(8, 256, 4) Linear Code over IntegerRing(4)
Generator matrix:
[1 0 0 0 3 1 2 1]
[0 1 0 0 2 1 1 3]
[0 0 1 0 1 1 3 2]
[0 0 0 1 3 2 3 3]
> MinimumLeeWeight($1);
6
> KerdockCode(4);
[16, 5, 8] Linear Code over IntegerRing(4)
Generator matrix:
[1 0 0 0 0 1 1 3 0 3 3 0 2 1 2 3]
[0 1 0 0 0 2 3 3 3 2 1 3 0 0 1 1]
[0 0 1 0 0 3 1 0 3 0 3 1 1 3 2 2]
[0 0 0 1 0 2 1 3 0 1 2 3 1 3 3 0]
[0 0 0 0 1 1 3 0 3 3 0 2 1 2 1 3]
> MinimumLeeWeight($1);
12
> KerdockCode(5);
(32, 4096, 16) Linear Code over IntegerRing(4)
Generator matrix:
[1 0 0 0 0 0 3 3 3 2 0 3 2 2 0 3 0 1 0 1 3 1 1 0 3 1 2 3 2 2 3 3]
[0 1 0 0 0 0 3 2 2 1 2 3 1 0 2 3 3 1 1 1 0 0 2 1 3 0 3 1 1 0 1 2]
[0 0 1 0 0 0 1 0 3 0 1 3 1 3 0 3 3 2 1 0 2 3 3 2 2 2 2 0 3 3 1 3]
[0 0 0 1 0 0 1 2 1 1 0 2 1 3 3 1 3 2 2 0 1 1 2 3 3 1 0 3 2 1 0 0]
[0 0 0 0 1 0 0 1 2 1 1 0 2 1 3 3 1 3 2 2 0 1 1 2 3 3 1 0 3 2 1 0]
[0 0 0 0 0 1 1 1 2 0 1 2 2 0 1 0 3 0 3 1 3 3 0 1 3 2 1 2 2 1 3 1]
> MinimumLeeWeight($1);
28
```

<a id="function-hadamardcodez4-rngintelt-rngintelt"></a>
##### `HadamardCodeZ4(δ, m): RngIntElt, RngIntElt -> CodeLinRng, Mtrx`

Given an integer $m\geq 1$ and an integer $\delta$ such that $1\leq \delta \leq \lfloor (m+1)/2 \rfloor$, return a Hadamard code over ${\mathbb{Z}}_4$ of length $2^{m-1}$ and type $2^\gamma 4^\delta$, where $\gamma=m+1-2\delta$. Moreover, return a generator matrix with $\gamma+\delta$ rows constructed in a recursive way from the `Plotkin` and `BQPlotkin` constructions defined in Section [New Codes from Old](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#sec-plotkin).

A Hadamard code over ${\mathbb{Z}}_4$ of length $2^{m-1}$ is a code over ${\mathbb{Z}}_4$ such that, after the Gray map, give a binary (not necessarily linear) code with the same parameters as the binary Hadamard code of length $2^{m}$.

<a id="function-extendedperfectcodez4-rngintelt-rngintelt"></a>
##### `ExtendedPerfectCodeZ4(δ, m): RngIntElt, RngIntElt -> CodeLinRng, Mtrx`

Given an integer $m\geq 2$ and an integer $\delta$ such that $1\leq \delta \leq \lfloor (m+1)/2 \rfloor$, return an extended perfect code over ${\mathbb{Z}}_4$ of length $2^{m-1}$, such that its dual code is of type $2^\gamma 4^\delta$, where $\gamma=m+1-2\delta$. Moreover, return a generator matrix constructed in a recursive way from the `Plotkin` and `BQPlotkin` constructions defined in Section [New Codes from Old](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#sec-plotkin).

An extended perfect code over ${\mathbb{Z}}_4$ of length $2^{m-1}$ is a code over ${\mathbb{Z}}_4$ such that, after the Gray map, give a binary (not necessarily linear) code with the same parameters as the binary extended perfect code of length $2^{m}$.

<a id="example-ex-6e1c45"></a>
##### `Example: Hadamard Codes over Z4 (ex-6e1c45)`

Some codes over ${\mathbb{Z}}_4$ whose images under the Gray map are binary codes having the same parameters as some well-known families of binary linear codes are explored.

First, a Hadamard code $C$ over ${\mathbb{Z}}_4$ of length $8$ and type $2^14^2$ is defined. The matrix $Gc$ is the quaternary matrix used to generate $C$ and obtained by a recursive method from `Plotkin` and `BQPlotkin` constructions.

```magma
> C, Gc := HadamardCodeZ4(2,4);
> C;
((8, 4^2 2^1)) Linear Code over IntegerRing(4)
Generator matrix:
[1 0 3 2 1 0 3 2]
[0 1 2 3 0 1 2 3]
[0 0 0 0 2 2 2 2]
> Gc;
[1 1 1 1 1 1 1 1]
[0 1 2 3 0 1 2 3]
[0 0 0 0 2 2 2 2]
> HasLinearGrayMapImage(C);
true [16, 5, 8] Linear Code over GF(2)
Generator matrix:
[1 0 0 0 0 1 1 1 0 1 1 1 1 0 0 0]
[0 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1]
[0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1]
[0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0]
[0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1]
Mapping from: CodeLinRng: C to [16, 5, 8] Linear Code over GF(2) given by a rule
```

Then, an extended perfect code $D$ over ${\mathbb{Z}}_4$ of length $8$ is defined, such that its dual code is of type $2^14^2$. The matrix $Gd$ is the quaternary matrix which is used to generate $D$ and obtained in a recursive way from `Plotkin` and `BQPlotkin` constructions. Note that the code $D$ is the Kronecker dual code of $C$.

```magma
> D, Gd := ExtendedPerfectCodeZ4(2,4);
> D;
((8, 4^5 2^1)) Linear Code over IntegerRing(4)
Generator matrix:
[1 0 0 1 0 0 1 3]
[0 1 0 1 0 0 2 2]
[0 0 1 1 0 0 1 1]
[0 0 0 2 0 0 0 2]
[0 0 0 0 1 0 3 2]
[0 0 0 0 0 1 2 3]
> Gd;
[1 1 1 1 1 1 1 1]
[0 1 2 3 0 1 2 3]
[0 0 1 1 0 0 1 1]
[0 0 0 2 0 0 0 2]
[0 0 0 0 1 1 1 1]
[0 0 0 0 0 1 2 3]

> DualKroneckerZ4(C) eq D;
true
```

<a id="function-reedmullercodez4-rngintelt-rngintelt-2"></a>
##### `ReedMullerCodeZ4(r, m): RngIntElt, RngIntElt -> CodeLinRng`

<a id="function-reedmullercodeqrmz4-rngintelt-rngintelt"></a>
##### `ReedMullerCodeQRMZ4(r, m): RngIntElt, RngIntElt -> CodeLinRng`

Given an integer $m\geq 2$ and an integer $r$ such that $0\leq r\leq m$, the $r$-th order Reed-Muller code over ${\mathbb{Z}}_4$ of length $2^m$ is returned.

The binary image under the modulo 2 map is the binary linear $r$-th order Reed-Muller code of length $2^m$. For $r=1$ and $r=m-2$, the function returns the quaternary linear Kerdock and Preparata code, respectively.

<a id="function-reedmullercodeslrmz4-rngintelt-rngintelt"></a>
##### `ReedMullerCodesLRMZ4(r, m): RngIntElt, RngIntElt -> SeqEnum`

Given an integer $m\geq 1$ and an integer $r$ such that $0\leq r\leq m$, a set of $r$-th order Reed-Muller codes over ${\mathbb{Z}}_4$ of length $2^{m-1}$ is returned.

The binary image under the Gray map of any of these codes is a binary (not necessarily linear) code with the same parameters as the binary linear $r$-th order Reed-Muller code of length $2^m$. Note that for these codes neither the usual inclusion nor duality properties of the binary linear Reed-Muller family are satisfied.

<a id="function-reedmullercodermz4-rngintelt-rngintelt-rngintelt"></a>
##### `ReedMullerCodeRMZ4(s, r, m): RngIntElt, RngIntElt, RngIntElt -> CodeLinRng, Mtrx`

Given an integer $m\geq 1$, an integer $r$ such that $0\leq r \leq m$, and an integer $s$ such that $0\leq s \leq \lfloor (m-1)/2 \rfloor$, return a $r$-th order Reed-Muller code over ${\mathbb{Z}}_4$ of length $2^{m-1}$, denoted by $RM_s(r,m)$, as well as the generator matrix used in the recursive construction.

The binary image under the Gray map is a binary (not necessarily linear) code with the same parameters as the binary linear $r$-th order Reed-Muller code of length $2^m$. Note that the inclusion and duality properties are also satisfied, that is, the code $RM_s(r-1,m)$ is a subcode of $RM_s(r,m)$, $r>0$, and the code $RM_s(r,m)$ is the Kronecker dual code of $RM_s(m-r-1,m)$, $r<m$.

<a id="example-ex-797694"></a>
##### `Example: Nested Reed-Muller Codes over Z4 (ex-797694)`

Taking the Reed-Muller codes $RM_1(1,4)$ and $RM_1(2,4)$, it can be seen that the former is a subcode of the latter. Note that $RM_1(1,4)$ and $RM_1(2,4)$ are the same as the ones given in Example [Hadamard Codes over Z4](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#example-ex-6e1c45) by `HadamardCodeZ4(2,4)` and `ExtendedPerfectCodeZ4(2,4)`, respectively.

```magma
> C1,G1 := ReedMullerCodeRMZ4(1,1,4);
> C2,G2 := ReedMullerCodeRMZ4(1,2,4);
> C1;
((8, 4^2 2^1)) Linear Code over IntegerRing(4)
Generator matrix:
[1 0 3 2 1 0 3 2]
[0 1 2 3 0 1 2 3]
[0 0 0 0 2 2 2 2]
> C2;
((8, 4^5 2^1)) Linear Code over IntegerRing(4)
Generator matrix:
[1 0 0 1 0 0 1 3]
[0 1 0 1 0 0 2 2]
[0 0 1 1 0 0 1 1]
[0 0 0 2 0 0 0 2]
[0 0 0 0 1 0 3 2]
[0 0 0 0 0 1 2 3]
> C1 subset C2;
true
> DualKroneckerZ4(C2) eq C1;
true
```

<a id="function-reedmullercodesrmz4-rngintelt-rngintelt"></a>
##### `ReedMullerCodesRMZ4(s, m): RngIntElt, RngIntElt -> Tup`

Let $m$ be an integer $m\geq 1$, and $s$ an integer such that $0\leq s \leq \lfloor (m-1)/2 \rfloor$. This function returns a sequence containing the family of Reed-Muller codes over ${\mathbb{Z}}_4$ of length $2^{m-1}$, that is, the codes $RM_s(r,m)$, for all $0\leq r\leq m$.

The binary image of these codes under the Gray map gives a family of binary (not necessarily linear) codes with the same parameters as the binary linear Reed-Muller family of codes of length $2^m$. Note that $RM_s(0,m) \subset RM_s(1,m) \subset \dots \subset RM_s(m,m)$

<a id="example-ex-c9bc7a"></a>
##### `Example: Family of Reed-Muller Codes over Z4 (ex-c9bc7a)`

The family of Reed-Muller codes over ${\mathbb{Z}}_4$ of length $2^2$ given by $s=0$ is constructed.

```magma
> F := ReedMullerCodesRMZ4(0,3);
> F;
[((4, 4^0 2^1)) Cyclic Linear Code over IntegerRing(4)
Generator matrix:
[2 2 2 2],
((4, 4^1 2^2)) Cyclic Linear Code over IntegerRing(4)
Generator matrix:
[1 1 1 1]
[0 2 0 2]
[0 0 2 2],
((4, 4^3 2^1)) Cyclic Linear Code over IntegerRing(4)
Generator matrix:
[1 0 0 1]
[0 1 0 1]
[0 0 1 1]
[0 0 0 2],
((4, 4^4 2^0)) Cyclic Linear Code over IntegerRing(4)
Generator matrix:
[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]]

> F[1] subset F[2] and F[2] subset F[3] and F[3] subset F[4];
true
```

#### Derived Binary Codes

As well as the binary image of a quaternary code under the Gray map (see section [The Gray Map](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#sec-gray-map)), there are also two other associated canonical binary codes. They are known the *residue* and *torsion* codes, the former being a subcode of the latter.

From any binary code-subcode pair $C_1 \subset C_2$, a quaternary code $C$ can be constructed such that the residue and torsion codes of $C$ will be $C_1$ and $C_2$ respectively. Note that this quaternary code is not unique.

<a id="function-binaryresiduecode-code"></a>
##### `BinaryResidueCode(C): Code -> Code`

Given a quaternary code $C$, return the binary code formed by taking each codeword in $C$ modulo $2$. This is known as the *binary residue code* of $C$.

<a id="function-binarytorsioncode-code"></a>
##### `BinaryTorsionCode(C): Code -> Code`

Given a quaternary code $C$, return the binary code formed by the support of each codeword in $C$ which is zero modulo $2$. This is known as the *binary torsion code* of $C$.

<a id="function-z4codefrombinarychain-code-code"></a>
##### `Z4CodeFromBinaryChain(C1, C2): Code, Code -> Code`

Given binary code $C_1$ and $C_2$ such that $C_1 \subset C_2$, return a quaternary code such that its binary residue code is $C_1$ and its binary torsion code is $C_2$.

<a id="example-ex-08428d"></a>
##### `Example: Derived Binary Codes of the Z4 Golay Code (ex-08428d)`

This example shows that the derived binary codes of the ${\mathbb{Z}}_4$ Golay code, are in fact equal to the binary Golay code.

```magma
> C := GolayCodeZ4(false);
> C;
(23, 4^12 2^0)) Cyclic Code over IntegerRing(4)
Generator matrix:
[1 0 0 0 0 0 0 0 0 0 0 0 3 1 0 0 2 3 3 3 0 3 2]
[0 1 0 0 0 0 0 0 0 0 0 0 2 1 1 0 0 0 1 1 3 2 3]
[0 0 1 0 0 0 0 0 0 0 0 0 3 3 1 1 2 3 3 0 1 2 0]
[0 0 0 1 0 0 0 0 0 0 0 0 0 3 3 1 1 2 3 3 0 1 2]
[0 0 0 0 1 0 0 0 0 0 0 0 2 2 3 3 1 3 0 1 3 2 1]
[0 0 0 0 0 1 0 0 0 0 0 0 1 1 2 3 1 2 0 1 1 0 0]
[0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 2 3 1 2 0 1 1 0]
[0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 2 3 1 2 0 1 1]
[0 0 0 0 0 0 0 0 1 0 0 0 1 3 0 1 3 3 0 2 2 1 3]
[0 0 0 0 0 0 0 0 0 1 0 0 3 2 3 0 3 2 2 3 2 1 3]
[0 0 0 0 0 0 0 0 0 0 1 0 3 0 2 3 2 2 1 1 3 1 3]
[0 0 0 0 0 0 0 0 0 0 0 1 3 0 0 2 1 1 1 0 1 2 3]
>
> CRes := BinaryResidueCode(C);
> CTor := BinaryTorsionCode(C);
> CRes eq CTor;
true
> CRes:Minimal;
[23, 12, 7] Linear Code over GF(2)
> AreEq, _ := IsEquivalent( CRes, GolayCode(GF(2), false) );
> AreEq;
true
```

Note that the canonical code over ${\mathbb{Z}}_4$ corresponding to the derived binary codes $CRes$ and $CTor$ is different to the initial ${\mathbb{Z}}_4$ code $C$.

```magma
> C1 := Z4CodeFromBinaryChain(CRes, CTor);
> C1:Minimal;
(23, 16777216) Linear Code over IntegerRing(4)
> C eq C1;
false
```

<a id="z4-new-from-old"></a>
<a id="sec-plotkin"></a>
#### New Codes from Old

The functions described in this section produce a new code over ${\mathbb{Z}}_4$ by modifying in some way the codewords of some given codes over ${\mathbb{Z}}_4$.

<a id="function-plotkinsum-mtrx-mtrx"></a>
##### `PlotkinSum(A, B): Mtrx, Mtrx -> Mtrx`

Given matrices $A$ and $B$ both over the same ring and with the same number of columns, return the $P_{AB}$ matrix over the same ring of $A$ and $B$, where

$$
P_{AB} = \left( \begin{matrix}A & A \\
                                0 & B\end{matrix} \right).
$$

<a id="function-plotkinsum-code-code"></a>
##### `PlotkinSum(C, D): Code, Code -> Code`

Given codes $C$ and $D$ both over the same ring and of the same length, construct the Plotkin sum of $C$ and $D$. The Plotkin sum consists of all vectors of the form $(u | u + v)$, where $u \in C$ and $v\in D$.

Note that the Plotkin sum is computed using generator matrices for $C$ and $D$ and the `PlotkinSum` function for matrices. Thus, this function returns the code over ${\mathbb{Z}}_4$ generated by the matrix $P_{AB}$ defined above, where $A$ and $B$ are the generator matrices for $C$ and $D$, respectively.

<a id="function-quaternaryplotkinsum-mtrx-mtrx"></a>
##### `QuaternaryPlotkinSum(A, B): Mtrx, Mtrx -> Mtrx`

Given two matrices $A$ and $B$ over ${\mathbb{Z}}_4$, both with the same number of columns, return the $QP_{AB}$ matrix over ${\mathbb{Z}}_4$, where

$$
QP_{AB} = \left( \begin{matrix}A & A & A & A \\
                                 0 & B & 2B & 3B\end{matrix} \right).
$$

<a id="function-quaternaryplotkinsum-code-code"></a>
##### `QuaternaryPlotkinSum(C, D): Code, Code -> Code`

Given two codes $C$ and $D$ over ${\mathbb{Z}}_4$, both of the same length, construct the Quaternary Plotkin sum of $C$ and $D$. The Quaternary Plotkin sum is a code over ${\mathbb{Z}}_4$ that consists of all vectors of the form $(u, u + v, u + 2v, u + 3v)$, where $u \in C$ and $v \in D$.

Note that the Quaternary Plotkin sum is computed using generator matrices of $C$ and $D$ and the `QuaternaryPlotkinSum` function for matrices, that is, this function returns the code over ${\mathbb{Z}}_4$ generated by the matrix $QP_{AB}$ defined above, where $A$ and $B$ are generators matrices of $C$ and $D$, respectively.

<a id="function-bqplotkinsum-mtrx-mtrx-mtrx"></a>
##### `BQPlotkinSum(A, B, C): Mtrx, Mtrx, Mtrx -> Mtrx`

Given three matrices $A$, $B$, and $C$ over ${\mathbb{Z}}_4$, all with the same number of columns, return the $BQP_{ABC}$ matrix over ${\mathbb{Z}}_4$, where

$$
BQP_{ABC} = \left( \begin{matrix}A & A & A & A\\
                                   0 & B' & 2B' & 3B'\\
                                   0 & 0 & \hat{B} & \hat{B}\\
                                   0 & 0 & 0 & C\end{matrix} \right),
$$

$B'$ is obtained from $B$ replacing the twos with ones in the rows of order two, and $\hat{B}$ is obtained from $B$ removing the rows of order two.

<a id="function-bqplotkinsum-code-code-code"></a>
##### `BQPlotkinSum(D, E, F): Code, Code, Code -> Code`

Given three codes $D$, $E$, and $F$ over $\Z_4$, all of the same length, construct the BQ Plotkin sum of $D$, $E$, and $F$. Let $Ge$ be a generator matrix for $E$ of type $2^\gamma 4^\delta$. The code $E'$ over $\Z_4$ is obtained from $E$ by replacing the twos with ones in the $\gamma$ rows of order two of $Ge$, and the code $\hat{E}$ over $\Z_4$ is obtained from $E$ removing the $\gamma$ rows of order two of $Ge$.

The BQ Plotkin sum is a code over $\Z_4$ that consists of all vectors of the form $(u, u + v', u + 2v' + \hat{v}, u + 3v' + \hat{v} + z)$, where $u \in Gd$, $v' \in Ge'$ $\hat{v} \in \hat{Ge}$, and $z \in Gf$, where $Gd$, $Ge'$, $\hat{Ge}$, and $Gf$ are generator matrices for $D$, $E'$, $\hat{E}$, and $F$, respectively.

Note that the BQPlotkin sum is computed using generator matrices of $D$, $E$ and $F$ and the `BQPlotkinSum` function for matrices. However, this function does not necessarily return the same code over $\Z_4$ as that generated by the matrix $QP_{ABC}$ defined above, where $A$, $B$, and $C$ are generators matrices of $D$, $E$, and $F$, respectively, as shown in Example [Plotkin Sums of Matrices and Codes](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#example-ex-b631eb).

<a id="function-doubleplotkinsum-mtrx-mtrx-mtrx-mtrx"></a>
##### `DoublePlotkinSum(A, B, C, D): Mtrx, Mtrx, Mtrx, Mtrx -> Mtrx`

Given four matrices $A$, $B$, $C$, and $D$ over ${\mathbb{Z}}_4$, all with the same number of columns, return the $DP_{ABC}$ matrix over ${\mathbb{Z}}_4$, where

$$
DP_{ABCD} = \left( \begin{matrix}A & A & A & A\\
                                   0 & B & 2B & 3B\\
                                   0 & 0 & C & C\\
                                   0 & 0 & 0 & D\end{matrix} \right).
$$

<a id="function-doubleplotkinsum-code-code-code-code"></a>
##### `DoublePlotkinSum(E, F, G, H): Code, Code, Code, Code -> Code`

Given four codes $E$, $F$, $G$, and $H$ over $\Z_4$, all of the same length, construct the Double Plotkin sum of $E$, $F$, $G$, and $H$. The Double Plotkin sum is a code over $\Z_4$ that consists of all vectors of the form $(u, u + v, u + 2v + z, u + 3v + z + t)$, where $u \in E$, $v \in F$, $z \in G$, and $t \in H$.

Note that the Double Plotkin sum is computed using generator matrices of $E$, $F$, $G$ and $H$ and the `DoublePlotkinSum` function for matrices, that is, this function returns the code over $\Z_4$ generated by the matrix $DP_{ABCD}$ defined above, where $A$, $B$, $C$, and $D$ are generator matrices for $E$, $F$, $G$, and $H$, respectively.

<a id="function-dualkroneckerz4-codelinrng"></a>
##### `DualKroneckerZ4(C): CodeLinRng -> CodeLinRng`

Given a code $C$ over ${\mathbb{Z}}_4$ of length $2^m$, return its Kronecker dual code. The Kronecker dual code of $C$ is $C_{\otimes}^\perp = \{x \in {\mathbb{Z}}_4^{2^m} : x \cdot K_{2^m} \cdot y^t=0, \forall y \in C \},$ where $K_{2^m}=\otimes_{j=1}^{m} K_2$, $K_2=\left(\begin{matrix}1 & 0\\ 0 & 3\end{matrix} \right)$ and $\otimes$ denotes the Kronecker product of matrices. Equivalently, $K_{2^m}$ is a quaternary matrix of length $2^m$ with the vector $(1,3,3,1,3,1,1,3,\ldots )$ in the main diagonal and zeros elsewhere.

<a id="example-ex-b631eb"></a>
##### `Example: Plotkin Sums of Matrices and Codes (ex-b631eb)`

The purpose of this example is to show that the codes over ${\mathbb{Z}}_4$ constructed from the `BQPlotkinSum` function for matrices are not necessarily the same as the ones constructed from the `BQPlotkinSum` function for codes.

```magma
> Z4:=IntegerRing(4);
> Ga:=Matrix(Z4,1,2,[1,1]);
> Gb:=Matrix(Z4,2,2,[1,2,0,2]);
> Gc:=Matrix(Z4,1,2,[2,2]);
> Ca:=LinearCode(Ga);
> Cb:=LinearCode(Gb);
> Cc:=LinearCode(Gc);
> C:=LinearCode(BQPlotkinSum(Ga,Gb,Gc));
> D:=BQPlotkinSum(Ca,Cb,Cc);
> C eq D;
false
```

<a id="example-ex-c3f759"></a>
##### `Example: Reed-Muller Codes as Plotkin Sums (ex-c3f759)`

```magma
> Ga := GeneratorMatrix(ReedMullerCodeRMZ4(1,2,3));
> Gb := GeneratorMatrix(ReedMullerCodeRMZ4(1,1,3));
> Gc := GeneratorMatrix(ReedMullerCodeRMZ4(1,0,3));
> C := ReedMullerCodeRMZ4(1,2,4);
> Cp := LinearCode(PlotkinSum(Ga, Gb));
> C eq Cp;
true
> D := ReedMullerCodeRMZ4(2,2,5);
> Dp := LinearCode(BQPlotkinSum(Ga, Gb, Gc));
> D eq Dp;
true
```

### Invariants

#### The Standard Form

A ${\mathbb{Z}}_4$-linear code is in *standard form* if its generator matrix is of the form:

$$
\begin{pmatrix}I_{k_1} & A        & B \\ 0       & 2I_{k_2} & 2C\end{pmatrix}
$$

where $I_{k_1}$ and $I_{k_2}$ are the $k_1\times k_1$ and $k_2\times k_2$ identity matrices, respectively, $A$ and $C$ are ${\mathbb{Z}}_2$-matrices, and $B$ is a ${\mathbb{Z}}_4$-matrix. Any ${\mathbb{Z}}_4$-linear code $C$ is permutation-equivalent to a code $S$ which is in standard form. Furthermore, the integers $k_1$ and $k_2$, defined above, are unique [[Wan97](https://docs.magma-maths.org/references.md#cite-wan-z4), Prop. 1.1].

<a id="function-standardform-code"></a>
##### `StandardForm(C): Code -> Code, Map`

This function, given any ${\mathbb{Z}}_4$-linear code $C$, returns a permutation-equivalent code $S$ in standard form, together with the corresponding isomorphism from $C$ onto $S$.

<a id="example-ex-48fad2"></a>
##### `Example: Standard Form of a Code over Z4 (ex-48fad2)`

The standard form is computed for a small ${\mathbb{Z}}_4$ code. Note that the number of rows in the generator matrix of the standard code may be less than that in the original code.

```magma
> Z4 := IntegerRing(4);
> C := LinearCode<Z4, 4 | [2,2,1,1], [0,2,0,2]>;
> C;
[4, 3, 2] Linear Code over IntegerRing(4)
Generator matrix:
[2 0 1 3]
[0 2 0 2]
[0 0 2 2]
> S, f := StandardForm(C);
> S;
[4, 2, 2] Linear Code over IntegerRing(4)
Generator matrix:
[1 1 2 2]
[0 2 2 0]
> #S;
8
> #C;
8
> f(C.1);
(1 3 0 2)
> f(C.2);
(0 2 2 0)
> f(C.3);
(2 2 0 0)
> S.1@@f;
(2 2 1 1)
> S.2@@f;
(0 2 0 2)
```

<a id="function-standardformdual-codelinrng"></a>
##### `StandardFormDual(C): CodeLinRng -> CodeLinRng, Map`

Given a code $C$ over ${\mathbb{Z}}_4$ of length $n$, return the dual of a permutation-equivalent code $S$ in standard form, together with the corresponding isomorphism from the dual of $C$ onto the dual of $S$. Since $S$ is generated by a matrix of the form

$$
\begin{pmatrix}I_{k_1} & A        & B \\ 0       & 2I_{k_2} & 2C\end{pmatrix}
$$

the dual of $S$ is generated by the matrix

$$
\begin{pmatrix}-(AC+B)^t & C^t & I_{n-k_1-k_2} \\ 2A^t & 2I_{k_2} & 0\end{pmatrix}
$$

where $I_{k_1}$ and $I_{k_2}$ are the $k_1 \times k_1$ and $k_2 \times k_2$ identity matrices, respectively, $A$ and $C$ are ${\mathbb{Z}}_2$-matrices, and $B$ is a ${\mathbb{Z}}_4$-matrix.

<a id="z4-standard-form"></a>
<a id="sec-rankkernel"></a>
#### Structures Associated with the Gray Map

<a id="function-minrowsgeneratormatrix-codelinrng"></a>
##### `MinRowsGeneratorMatrix(C): CodeLinRng -> ModMatRngElt`

A generator matrix for the code $C$ over ${\mathbb{Z}}_4$ of length $n$ and type $2^\gamma 4^\delta$, with the minimum number of rows, that is with $\gamma + \delta$ rows: $\gamma$ rows of order two and $\delta$ rows of order four. It also returns the parameters $\gamma$ and $\delta$.

<a id="function-minrowsparitycheckmatrix-codelinrng"></a>
##### `MinRowsParityCheckMatrix(C): CodeLinRng -> ModMatRngElt`

A parity check matrix for the code $C$ over ${\mathbb{Z}}_4$ of length $n$ and type $2^\gamma 4^\delta$, with the minimum number of rows, that is, with $\gamma$ rows of order two and $n-\gamma-\delta$ rows of order four. This function should be faster for most codes over ${\mathbb{Z}}_4$ than the general function `ParityCheckMatrix(C)` for codes over finite rings. Another parity check matrix for the code $C$ can be obtained as the generator matrix of the dual of $C$ with the minimum number of rows, that is, as `MinRowsGeneratorMatrix(DualZ4(C))`.

<a id="function-dualz4-codelinrng"></a>
##### `DualZ4(C): CodeLinRng -> CodeLinRng`

The dual $D$ of the code $C$ over ${\mathbb{Z}}_4$ of length $n$. The dual consists of all codewords in the ${\mathbb{Z}}_4$-space $V={\mathbb{Z}}_4^n$ which are orthogonal to all codewords of $C$. This function should be faster for most codes over ${\mathbb{Z}}_4$ than the general function `Dual(C)` for codes over finite rings.

<a id="example-ex-3b2558"></a>
##### `Example: Generator Matrices with Minimum Rows (ex-3b2558)`

```magma
> C := HadamardCodeZ4(3, 11);
> G, gamma, delta := MinRowsGeneratorMatrix(C);
> Nrows(G) eq gamma + delta;
true
> deltaH := Length(C) - gamma - delta;
> H1 := MinRowsParityCheckMatrix(C);
> Nrows(H1) eq gamma + deltaH;
true
> H2 := MinRowsGeneratorMatrix(DualZ4(C));
> Nrows(H2) eq gamma + deltaH;
true

> time D := Dual(C);
Time: 24.660
> time D4 := DualZ4(C);
Time: 0.340
> D eq D4, D4 eq LinearCode(H1), D4 eq LinearCode(H2);
true true true

> DualS, f := StandardFormDual(C);
> DualS eq LinearCode(Matrix([f(H1[i]) : i in [1..Nrows(H1)]]));
true
```

<a id="function-spanz2codez4-codelinrng"></a>
##### `SpanZ2CodeZ4(C): CodeLinRng -> CodeLinFld`

Given a code $C$ over ${\mathbb{Z}}_4$ of length $n$, return $S_C=\Phi^{-1}(S_{bin})$ as a code over ${\mathbb{Z}}_4$, and the linear span of $C_{bin}$, $S_{bin}=\langle C_{bin} \rangle$, as a binary linear code of length $2n$, where $C_{bin}=\Phi(C)$ and $\Phi$ is the Gray map.

<a id="function-kernelz2codez4-codelinrng"></a>
##### `KernelZ2CodeZ4(C): CodeLinRng -> CodeLinRng`

Given a code $C$ over ${\mathbb{Z}}_4$ of length $n$, return its kernel $K_C$ as a subcode over ${\mathbb{Z}}_4$ of $C$, and $K_{bin}=\Phi(K_C)$ as a binary linear subcode of $C_{bin}$ of length $2n$, where $C_{bin}=\Phi(C)$ and $\Phi$ is the Gray map.

The kernel $K_C$ contains the codewords $v$ such that $2v*u \in C$ for all $u \in C$, where $*$ denotes the component-wise product. Equivalently, the kernel $K_{bin}=\Phi(K_C)$ contains the codewords $c\in C_{bin}$ such that $c+C_{bin}=C_{bin}$, where $C_{bin}=\Phi(C)$ and $\Phi$ is the Gray map.

<a id="function-kernelcosetrepresentatives-codelinrng"></a>
##### `KernelCosetRepresentatives(C): CodeLinRng -> SeqEnum, SeqEnum`

Given a code $C$ over ${\mathbb{Z}}_4$ of length $n$, return the coset representatives $[c_1,\ldots, c_t]$ as a sequence of codewords of $C$, such that $C=K_C \cup \bigcup_{i=1}^t \big( K_C+c_i \big)$, where $K_C$ is the kernel of $C$ as a subcode over ${\mathbb{Z}}_4$. It also returns the coset representatives of the corresponding binary code $C_{bin}=\Phi(C)$ as a sequence of binary codewords $[\Phi(c_1), \ldots, \Phi(c_t)]$, such that $C_{bin}=K_{bin} \cup \bigcup_{i=1}^t \big( K_{bin}+\Phi(c_i)\big)$, where $K_{bin}=\Phi(K_C)$ and $\Phi$ is the Gray map.

<a id="function-dimensionofspanz2-codelinrng"></a>
##### `DimensionOfSpanZ2(C): CodeLinRng -> RngIntElt`

<a id="function-rankz2-codelinrng"></a>
##### `RankZ2(C): CodeLinRng -> RngIntElt`

Given a code $C$ over ${\mathbb{Z}}_4$, return the dimension of the linear span of $C_{bin}$, that is, the dimension of $\langle C_{bin} \rangle$, where $C_{bin}=\Phi(C)$ and $\Phi$ is the Gray map.

<a id="function-dimensionofkernelz2-codelinrng"></a>
##### `DimensionOfKernelZ2(C): CodeLinRng -> RngIntElt`

Given a code $C$ over ${\mathbb{Z}}_4$, return the dimension of the Gray map image of its kernel $K_C$ over ${\mathbb{Z}}_4$, that is the dimension of $K_{bin}=\Phi(K_C)$, where $\Phi$ is the Gray map. Note that $K_{bin}$ is always a binary linear code.

<a id="example-ex-bb9d15"></a>
##### `Example: Kernel and Span of a Code over Z4 (ex-bb9d15)`

```magma
> C := ReedMullerCodeRMZ4(0,3,5);
> DimensionOfKernelZ2(C);
20
> DimensionOfSpanZ2(C);
27
> K, Kb := KernelZ2CodeZ4(C);
> S, Sb := SpanZ2CodeZ4(C);
> K subset C;
true
> C subset S;
true
> Dimension(Kb) eq DimensionOfKernelZ2(C);
true
> Dimension(Sb) eq DimensionOfSpanZ2(C);
true
```

<a id="coset-reps"></a>
<a id="sec-cosetrep"></a>
#### Coset Representatives

<a id="function-cosetrepresentatives-codelinrng"></a>
##### `CosetRepresentatives(C): CodeLinRng -> SeqEnum`

Given a code $C$ over ${\mathbb{Z}}_4$ of length $n$, with ambient space $V={\mathbb{Z}}_4^n$, return a set of coset representatives (not necessarily of minimal weight in their cosets) for $C$ in $V$ as an indexed set of vectors from $V$. The set of coset representatives $\{c_0, c_1, \ldots, c_t \}$ satisfies the two conditions that $c_0$ is the zero codeword, and $V=\bigcup_{i=0}^t \big( C+c_i \big)$. Note that this function is only applicable when $V$ and $C$ are small.

<a id="function-cosetrepresentatives-codelinrng-codelinrng"></a>
##### `CosetRepresentatives(C, S): CodeLinRng, CodeLinRng -> SeqEnum, SeqEnum`

Given a code $C$ over ${\mathbb{Z}}_4$ of length $n$, and a subcode $S$ over ${\mathbb{Z}}_4$ of $C$, return a set of coset representatives (not necessarily of minimal weight in their cosets) for $S$ in $C$ as an indexed set of codewords from $C$. The set of coset representatives $\{c_0, c_1, \ldots, c_t \}$ satisfies the two conditions that $c_0$ is the zero codeword, and $C= \bigcup_{i=0}^t \big( S+c_i \big)$. Note that this function is only applicable when $S$ and $C$ are small.

<a id="example-ex-551655"></a>
##### `Example: Coset Representatives of a Code (ex-551655)`

```magma
> C := LinearCode<Integers(4), 4 | [[1,0,0,3],[0,1,1,3]]>;
> L := CosetRepresentatives(C);
> Set(RSpace(Integers(4),4)) eq {v+ci : v in Set(C), ci in L};
true

> K := KernelZ2CodeZ4(C);
> L := CosetRepresentatives(C, K);
> {C!0} join Set(KernelCosetRepresentatives(C)) eq L;
true
> Set(C) eq {v+ci : v in Set(K), ci in L};
true
```

<a id="info-space-and-sets"></a>
<a id="sec-infosets"></a>
#### Information Space and Information Sets

<a id="function-informationspace-codelinrng"></a>
##### `InformationSpace(C): CodeLinRng -> ModTupRng, ModTupFld, Map, Map`

Given a code $C$ over ${\mathbb{Z}}_4$ of length $n$ and type $2^\gamma 4^\delta$, return the ${\mathbb{Z}}_4$-submodule of ${\mathbb{Z}}_4^{\gamma+\delta}$ isomorphic to ${\mathbb{Z}}_2^\gamma \times {\mathbb{Z}}_4^\delta$ such that the first $\gamma$ coordinates are of order two, that is, the space of information vectors for $C$. The function also returns the $(\gamma+2\delta)$-dimensional binary vector space, which is the space of information vectors for the corresponding binary code $C_{bin}=\Phi(C)$, where $\Phi$ is the Gray map. Finally, for the encoding process, it also returns the corresponding isomorphisms $f$ and $f_{bin}$ from these spaces of information vectors onto $C$ and $C_{bin}$, respectively.

<a id="example-ex-5fc04a"></a>
##### `Example: Information Space of a Code over Z4 (ex-5fc04a)`

```magma
> C := LinearCode<Integers(4), 4 | [[2,0,0,2],[0,1,1,3]]>;
> R, V, f, fbin := InformationSpace(C);
> G := MinRowsGeneratorMatrix(C);

> (#R eq #C) and (#V eq #C);
true
> Set([f(i) : i in R]) eq Set(C);
true
> Set([i*G : i in R]) eq Set(C);
false

> i := R![2,3];
> c := f(i);
> c;
(2 3 3 3)
> c in C;
true
> i*G eq c;
false

> ibin := V![1,1,0];
> cbin := fbin(ibin);
> cbin;
(1 1 1 0 1 0 1 0)
> cbin in GrayMapImage(C);
true
> cbin eq GrayMap(C)(c);
true
```

<a id="function-informationset-codelinrng"></a>
##### `InformationSet(C): CodeLinRng -> ModTupRng, ModTupFld, Map, Map`

Given a code $C$ over ${\mathbb{Z}}_4$ of length $n$ and type $2^\gamma 4^\delta$, return an information set $I=[i_1,\ldots,i_{\gamma+\delta}] \subseteq \{1,\ldots,n\}$ for $C$ such that the code $C$ punctured on $\{1,\ldots,n\} \backslash \{i_{\gamma+1},\ldots, i_{\gamma+\delta} \}$ is of type $4^\delta$, and the corresponding information set $\Phi(I)=[2i_1-1,\ldots, 2i_\gamma-1, 2i_{\gamma+1}-1, 2i_{\gamma+1},  \ldots, 2i_{\gamma+\delta}-1, 2i_{\gamma+\delta}] \subseteq \{1,\ldots,2n\}$ for the binary code $C_{bin}=\Phi(C)$, where $\Phi$ is the Gray map. The information sets $I$ and $\Phi(I)$ are returned as a sequence of $\gamma+\delta$ and $\gamma+2\delta$ integers, giving the coordinate positions that correspond to the information set of $C$ and $C_{bin}$, respectively.

An information set $I$ for $C$ is an ordered set of $\gamma+\delta$ coordinate positions such that $|C^I|=2^{\gamma}4^\delta$, where $C^I=\{v^I : v\in C \}$ and $v^I$ is the vector $v$ restricted to the $I$ coordinates. An information set $J$ for $C_{bin}$ is an ordered set of $\gamma+2\delta$ coordinate positions such that $|{C^{J}_{bin}}|=2^{\gamma+2\delta}$.

<a id="function-isinformationset-codelinrng-rngintelt"></a>
##### `IsInformationSet(C, I): CodeLinRng, [RngIntElt] -> BoolElt, BoolElt`

Given a code $C$ over ${\mathbb{Z}}_4$ of length $n$ and type $2^\gamma 4^\delta$ and a sequence $I \subseteq \{1,\ldots,n \}$ or $I \subseteq \{1,\ldots,2n \}$, return `true` if and only if $I\subseteq \{1,\ldots,n \}$ is an information set for $C$. This function also returns another boolean, which is `true` if and only if $I \subseteq \{1,\ldots,2n \}$ is an information set for the corresponding binary code $C_{bin}=\Phi(C)$, where $\Phi$ is the Gray map.

An information set $I$ for $C$ is an ordered set of $\gamma+\delta$ coordinate positions such that $|C^I|=2^{\gamma}4^\delta$, where $C^I=\{v^I : v\in C \}$ and $v^I$ is the vector $v$ restricted to the $I$ coordinates. An information set $J$ for $C_{bin}$ is an ordered set of $\gamma+2\delta$ coordinate positions such that $|{C^{J}_{bin}}|=2^{\gamma+2\delta}$.

<a id="example-ex-1d41b7"></a>
##### `Example: Information Sets of a Hadamard Code (ex-1d41b7)`

```magma
> C := HadamardCodeZ4(3,6);
> C;
((32, 4^3 2^1)) Linear Code over IntegerRing(4)
Generator matrix:
[1 0 3 2 0 3 2 1 3 2 1 0 2 1 0 3 1 0 3 2 0 3 2 1 3 2 1 0 2 1 0 3]
[0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3]
[0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]

> I, Ibin := InformationSet(C);
> I;
[ 16, 28, 31, 32 ]
> Ibin;
[ 31, 55, 56, 61, 62, 63, 64 ]
> #PunctureCode(C, {1..32} diff Set(I)) eq #C;
true
> Cbin := GrayMapImage(C);
> V := VectorSpace(GF(2), 7);
> #{V![c[i] : i in Ibin] : c in Cbin} eq #Cbin;
true

> IsInformationSet(C, I);
true false
> IsInformationSet(C, Ibin);
false true

> IsInformationSet(C, [1, 2, 5, 17]);
true false
> IsInformationSet(C, [1, 2, 3, 4, 9, 10, 33]);
false true

> D := LinearCode<Integers(4), 5 | [[2,0,0,2,0],[0,2,0,2,2],[0,0,2,2,0]]>;
> IsInformationSet(D, [1,3,5]);
true true
```

<a id="syndrome-space-coset-leaders"></a>
<a id="sec-syndrome"></a>
#### Syndrome Space and Coset Leaders

<a id="function-syndromespace-codelinrng"></a>
##### `SyndromeSpace(C): CodeLinRng -> ModTupRng, ModTupFld`

Given a code $C$ over ${\mathbb{Z}}_4$ of length $n$ and type $2^\gamma 4^\delta$, return the ${\mathbb{Z}}_4$-submodule of ${\mathbb{Z}}_4^{n-\delta}$ isomorphic to ${\mathbb{Z}}_2^\gamma \times {\mathbb{Z}}_4^{n-\gamma-\delta}$ such that the first $\gamma$ coordinates are of order two, that is, the space of syndrome vectors for $C$. The function also returns the $(2n-2\delta-\gamma)$-dimensional binary vector space, which is the space of syndrome vectors for the corresponding binary code $C_{bin}=\Phi(C)$, where $\Phi$ is the Gray map. Note that these spaces are computed by using the function `InformationSpace(C)` applied to the dual code of $C$, produced by function `DualZ4(C)`.

<a id="function-syndrome-modtupfldelt-codelinrng"></a>
##### `Syndrome(u, C): ModTupFldElt, CodeLinRng -> ModTupRngElt`

<a id="function-syndrome-modtuprngelt-codelinrng"></a>
##### `Syndrome(u, C): ModTupRngElt, CodeLinRng -> ModTupRngElt`

Given a code $C$ over ${\mathbb{Z}}_4$ of length $n$ and type $2^\gamma 4^\delta$, and a vector $u$ from the ambient space $V={\mathbb{Z}}_4^n$ or $V_2={\mathbb{Z}}_2^{2n}$, construct the syndrome of $u$ relative to the code $C$. This will be an element of the syndrome space of $C$, considered as the ${\mathbb{Z}}_4$-submodule of ${\mathbb{Z}}_4^{n-\delta}$ isomorphic to ${\mathbb{Z}}_2^\gamma \times {\mathbb{Z}}_4^{n-\gamma-\delta}$ such that the first $\gamma$ coordinates are of order two.

<a id="function-cosetleaders-codelinrng"></a>
##### `CosetLeaders(C): CodeLinRng -> SetIndx, Map`

Given a code $C$ over ${\mathbb{Z}}_4$ of length $n$, with ambient space $V={\mathbb{Z}}_4^{n}$, return a set of coset leaders (vectors of minimal Lee weight in their cosets) for $C$ in $V$ as an indexed set of vectors from $V$. This function also returns a map from the syndrome space of $C$ onto the coset leaders (mapping a syndrome into its corresponding coset leader). Note that this function is only applicable when $V$ and $C$ are small.

<a id="example-ex-5bce83"></a>
##### `Example: Syndrome Space and Coset Leaders (ex-5bce83)`

```magma
> C := LinearCode<Integers(4), 4 | [[2,0,0,2],[0,1,1,3]]>;
> R, V, f, fbin := InformationSpace(C);
> Rs, Vs := SyndromeSpace(C);

> #R * #Rs eq 4^Length(C);
true
> #V * #Vs eq 4^Length(C);
true

> i := R![2,3];
> c := f(i);
> c;
(2 3 3 3)
> u := c;
> u[2] := u[2] + 3;
> u;
(2 2 3 3)

> s := Syndrome(u, C);
> s in Rs;
true
> H := Transpose(MinRowsGeneratorMatrix(Dual(C)));
> s eq u*H;
true

> L, mapCosetLeaders := CosetLeaders(C);
> ev := mapCosetLeaders(s);
> ev;
(0 3 0 0)
> ev in L;
true
> u - ev eq c;
true
```

#### Miscellaneous Functions

<a id="function-correlation-modtuprngelt"></a>
##### `Correlation(v): ModTupRngElt -> RngQuadElt`

Let $v$ be a codeword over ${\mathbb{Z}}_4$. Define $w_j = \#\{k : v[k] = j\}$ for $j = 0,\ldots,3$. Then the *correlation* of $v$ is the Gaussian integer $(w_0 - w_2) + i*(w_1 - w_3)$.

### Weight Distributions

In the case of a linear code, weight and distance distributions are equivalent (in particular minimum weight and minimum distance are equivalent).

#### Hamming Weight

For an element $x\in R$ for any finite ring $R$, the *Hamming weight* $w_H(x)$ is defined by:

$$
w_H(x) = 0 \iff x = 0, \qquad w_H(x) = 1 \iff x \ne 0
$$

The *Hamming weight* $w_H(v)$ of a vector $v\in {R^n}$ is defined to be the sum (in ${\mathbb{Z}}$) of the Hamming weights of its components.

The *Hamming weight* is often referred to as simply the *weight*.

<a id="function-minimumweight-code"></a>
##### `MinimumWeight(C): Code -> RngIntElt`

<a id="function-minimumdistance-code"></a>
##### `MinimumDistance(C): Code -> RngIntElt`

Determine the minimum (Hamming) weight of the words belonging to the code $C$, which is also the minimum distance between any two codewords.

<a id="function-weightdistribution-code"></a>
##### `WeightDistribution(C): Code -> [ <RngIntElt, RngIntElt> ]`

Determine the (Hamming) weight distribution for the code $C$. The distribution is returned in the form of a sequence of tuples, where the $i$-th tuple contains the $i$-th weight, $w_i$ say, and the number of codewords having weight $w_i$.

<a id="function-dualweightdistribution-code"></a>
##### `DualWeightDistribution(C): Code -> [ <RngIntElt, RngIntElt> ]`

Determine the (Hamming) weight distribution of the dual code of $C$. The distribution is returned in the form of a sequence of tuples, where the $i$-th tuple contains the $i$-th weight, $w_i$ say, and the number of codewords having weight $w_i$.

<a id="example-ex-601dad"></a>
##### `Example: Weight Distribution of a Quadratic Residue Code (ex-601dad)`

In this example, the weight distribution of a quadratic residue code over ${\mathbb{Z}}_4$ and its dual are computed.

```magma
> C := QRCodeZ4(17);
> C;

((17, 4^9 2^0)) Cyclic Linear Code over IntegerRing(4)

Generator matrix:
[1 0 0 0 0 0 0 0 0 1 1 3 0 3 0 3 1]
[0 1 0 0 0 0 0 0 0 3 0 2 3 1 3 1 2]
[0 0 1 0 0 0 0 0 0 2 1 2 2 1 1 1 3]
[0 0 0 1 0 0 0 0 0 1 3 0 2 1 1 0 2]
[0 0 0 0 1 0 0 0 0 2 3 1 0 0 1 3 2]
[0 0 0 0 0 1 0 0 0 2 0 1 1 2 0 3 1]
[0 0 0 0 0 0 1 0 0 3 1 1 1 2 2 1 2]
[0 0 0 0 0 0 0 1 0 2 1 3 1 3 2 0 3]
[0 0 0 0 0 0 0 0 1 1 3 0 3 0 3 1 1]

> WeightDistribution(C);
[ <0, 1>, <5, 34>, <6, 68>, <7, 748>, <8, 2567>, <9, 6817>, <10, 17612>,
  <11, 34340>, <12, 50014>, <13, 56168>, <14, 50728>, <15, 30872>,
  <16, 9826>, <17, 2349> ]

> DualWeightDistribution(C);
[ <0, 1>, <6, 68>, <8, 935>, <9, 1632>, <10, 4148>, <11, 8568>, <12, 12886>,
  <13, 14280>, <14, 11968>, <15, 7752>, <16, 2890>, <17, 408> ]
```

<a id="lee"></a>
<a id="sec-lee-weight"></a>
#### Lee Weight

For an element $x\in{\mathbb{Z}}_4$, the *Lee weight* $w_L(x)$ is defined by:

$$
w_L(0) = 0,\quad w_L(1) = w_L(3) = 1,\quad w_L(2) = 2.
$$

The *Lee weight* $w_L(v)$ of a vector $v\in{{\mathbb{Z}}_4^n}$ is defined to be the sum (in ${\mathbb{Z}}$) of the Lee weights of its components. See [[Wan97](https://docs.magma-maths.org/references.md#cite-wan-z4), p. 16].

<a id="function-leeweight-rngintres"></a>
##### `LeeWeight(a): RngIntRes -> RngIntElt`

The Lee weight of the element $a\in{\mathbb{Z}}_4$.

<a id="function-leeweight-modtuprngelt"></a>
##### `LeeWeight(v): ModTupRngElt -> RngIntElt`

The Lee weight of the codeword $v$.

<a id="function-leedistance-modtuprngelt-modtuprngelt"></a>
##### `LeeDistance(u, v): ModTupRngElt, ModTupRngElt -> RngIntElt`

The Lee distance between the codewords $u$ and $v$, where $u$ and $v$ belong to the same code $C$. This is defined to be the Lee weight of $(u - v)$.

<a id="function-minimumleeweight-code"></a>
##### `MinimumLeeWeight(C): Code -> RngIntElt`

<a id="function-minimumleedistance-code"></a>
##### `MinimumLeeDistance(C): Code -> RngIntElt`

The minimum Lee weight of the code $C$.

<a id="function-leeweightdistribution-code"></a>
##### `LeeWeightDistribution(C): Code -> SeqEnum`

The Lee weight distribution of the code $C$.

<a id="function-dualleeweightdistribution-code"></a>
##### `DualLeeWeightDistribution(C): Code -> SeqEnum`

The Lee weight distribution of the dual of the code $C$ (see `LeeWeightDistribution`)

<a id="function-wordsofleeweight-code-rngintelt"></a>
##### `WordsOfLeeWeight(C, w): Code, RngIntElt -> SetEnum`

```magma
NumWords: RngIntElt                    Default: Infinity()
```

Given a linear code $C$, return the set of all words of $C$ having Lee weight $w$. If `NumWords` is set to a non-negative integer $c$, then the algorithm will terminate after a total of $c$ words have been found.

<a id="function-wordsofboundedleeweight-code-rngintelt-rngintelt"></a>
##### `WordsOfBoundedLeeWeight(C, l, u): Code, RngIntElt, RngIntElt -> SetEnum`

```magma
NumWords: RngIntElt                    Default: Infinity()
```

Given a linear code $C$, return the set of all words of $C$ having Lee weight between $l$ and $u$, inclusive. If `NumWords` is set to a non-negative integer $c$, then the algorithm will terminate after a total of $c$ words have been found.

<a id="example-ex-587036"></a>
##### `Example: Lee Weight Distribution (ex-587036)`

We calculate the Lee weight distribution of a Reed Muller code over ${\mathbb{Z}}_4$ and enumerate all words of Lee weight $8$.

```magma
> C := ReedMullerCodeZ4(1, 3);
> C;
(8, 256, 4) Linear Code over IntegerRing(4)
Generator matrix:
[1 0 0 0 3 1 2 1]
[0 1 0 0 2 1 1 3]
[0 0 1 0 1 1 3 2]
[0 0 0 1 3 2 3 3]
> LeeWeightDistribution(C);
[ <0, 1>, <6, 112>, <8, 30>, <10, 112>, <16, 1> ]
> W := WordsOfLeeWeight(C, 8);
> #W;
30
```

<a id="euclidean"></a>
<a id="sec-euclidean-weight"></a>
#### Euclidean Weight

For an element $x\in{\mathbb{Z}}_4$, the *Euclidean weight* $w_E(x)$ is defined by:

$$
w_E(0) = 0,\quad w_E(1) = w_E(3) = 1, \quad w_E(2) = 4.
$$

The *Euclidean weight* $w_E(v)$ of a vector $v\in{{\mathbb{Z}}_4^n}$ is defined to be the sum (in ${\mathbb{Z}}$) of the Euclidean weights of its components. See [[Wan97](https://docs.magma-maths.org/references.md#cite-wan-z4), p. 16].

<a id="function-euclideanweight-rngintres"></a>
##### `EuclideanWeight(a): RngIntRes -> RngIntElt`

The Euclidean weight of the element $a\in{\mathbb{Z}}4$.

<a id="function-euclideanweight-modtuprngelt"></a>
##### `EuclideanWeight(v): ModTupRngElt -> RngIntElt`

The Euclidean weight of the ${\mathbb{Z}}_4$-codeword $v$.

<a id="function-euclideandistance-modtuprngelt-modtuprngelt"></a>
##### `EuclideanDistance(u, v): ModTupRngElt, ModTupRngElt -> RngIntElt`

The Euclidean distance between the ${\mathbb{Z}}_4$-codewords $u$ and $v$, where $u$ and $v$ belong to the same code $C$. This is defined to be the Euclidean weight of $(u - v)$.

<a id="function-minimumeuclideanweight-code"></a>
##### `MinimumEuclideanWeight(C): Code -> RngIntElt`

<a id="function-minimumeuclideandistance-code"></a>
##### `MinimumEuclideanDistance(C): Code -> RngIntElt`

The minimum Euclidean weight of the ${\mathbb{Z}}_4$-code C.

<a id="function-euclideanweightdistribution-code"></a>
##### `EuclideanWeightDistribution(C): Code -> SeqEnum`

The Euclidean weight distribution of the ${\mathbb{Z}}_4$-code C.

<a id="function-dualeuclideanweightdistribution-code"></a>
##### `DualEuclideanWeightDistribution(C): Code -> SeqEnum`

The Euclidean weight distribution of the dual of the ${\mathbb{Z}}_4$-code C.

<a id="example-ex-9f8213"></a>
##### `Example: Euclidean Weight Distribution (ex-9f8213)`

The Euclidean weight distribution is calculated for a quadratic residue code over ${\mathbb{Z}}_4$

```magma
> C := QRCodeZ4(17);
> C;
(17, 262144) Cyclic Code over IntegerRing(4)
Generator matrix:
[1 0 0 0 0 0 0 0 0 1 1 3 0 3 0 3 1]
[0 1 0 0 0 0 0 0 0 3 0 2 3 1 3 1 2]
[0 0 1 0 0 0 0 0 0 2 1 2 2 1 1 1 3]
[0 0 0 1 0 0 0 0 0 1 3 0 2 1 1 0 2]
[0 0 0 0 1 0 0 0 0 2 3 1 0 0 1 3 2]
[0 0 0 0 0 1 0 0 0 2 0 1 1 2 0 3 1]
[0 0 0 0 0 0 1 0 0 3 1 1 1 2 2 1 2]
[0 0 0 0 0 0 0 1 0 2 1 3 1 3 2 0 3]
[0 0 0 0 0 0 0 0 1 1 3 0 3 0 3 1 1]
> EuclideanWeightDistribution(C);
[ <0, 1>, <7, 136>, <8, 170>, <9, 170>, <10, 408>, <11, 544>, <12, 986>,
<13, 1768>, <14, 3128>, <15, 5032>, <16, 6120>, <17, 6360>, <18, 8432>,
<19, 12512>, <20, 12682>, <21, 11152>, <22, 14416>, <23, 17680>, <24, 16048>,
<25, 15164>, <26, 17952>, <27, 16864>, <28, 13328>, <29, 14144>, <30, 14144>,
<31, 10064>, <32, 7837>, <33, 8024>, <34, 6800>, <35, 4896>, <36, 3485>,
<37, 2992>, <38, 2992>, <39, 1768>, <40, 510>, <41, 1258>, <42, 1224>,
<44, 238>, <45, 408>, <46, 136>, <47, 136>, <48, 34>, <68, 1> ]
```

### Weight Enumerators

<a id="function-completeweightenumerator-code"></a>
#### `CompleteWeightEnumerator(C): Code -> RngMPolElt`

Let $C$ be a code over a finite ring $R$ of cardinality $q$, and suppose that the elements of $R$ are ordered in some way. Then for a codeword $v \in C$ and the $i$-th element $a \in R$, let $s_i(v)$ denote the number of components of $v$ equal to $a$.

This function returns the complete weight enumerator ${\cal W}_C(X_0, X_1, \ldots, X_{q-1})$ of $C$, which is defined by:

$$
{\cal W}_C(X_0, X_1, \ldots, X_{q-1}) =
   \sum_{v \in C}{{X_0}^{s_0(v)}{X_1}^{s_1(v)}\cdots{X_{q-1}}^{s_{q-1}(v)}}.
$$

See [[Wan97](https://docs.magma-maths.org/references.md#cite-wan-z4), p. 9] for more information. The result will lie in a global multivariate polynomial ring over ${\mathbb{Z}}$ with q variables. The angle-bracket notation may be used to assign names to the indeterminates.

<a id="function-symmetricweightenumerator-code"></a>
#### `SymmetricWeightEnumerator(C): Code -> RngMPolElt`

Suppose $C$ is a ${\mathbb{Z}}_4$-code. This function returns the symmetric weight enumerator $\hbox{swe}_C(X_0, X_1, X_2)$ of $C$, which is defined by:

$$
\hbox{swe}_C(X_0, X_1, X_2) = {\cal W}_C(X_0, X_1, X_2, X_1),
$$

where ${\cal W}_C$ is the complete weight enumerator, defined above. See [[Wan97](https://docs.magma-maths.org/references.md#cite-wan-z4), p. 14] for more information. The result will lie in a global multivariate polynomial ring over ${\mathbb{Z}}$ with three variables. The angle-bracket notation may be used to assign names to the indeterminates.

<a id="function-weightenumerator-code"></a>
#### `WeightEnumerator(C): Code -> RngMPolElt`

<a id="function-hammingweightenumerator-code"></a>
#### `HammingWeightEnumerator(C): Code -> RngMPolElt`

Suppose $C$ is a code over some finite ring $R$. This function returns the Hamming weight enumerator $\hbox{Ham}_C(X, Y)$ of $C$, which is defined by:

$$
\hbox{Ham}_C(X, Y) = \sum_{v \in C}{X^{n-w_H(v)}Y^{w_H(v)}},
$$

where $w_H(v)$ is the Hamming weight function. The result will lie in a global multivariate polynomial ring over ${\mathbb{Z}}$ with two variables. The angle-bracket notation may be used to assign names to the indeterminates.

<a id="function-leeweightenumerator-code"></a>
#### `LeeWeightEnumerator(C): Code -> RngMPolElt`

Suppose $C$ is a ${\mathbb{Z}}_4$-code. This function returns the Lee weight enumerator $\hbox{Lee}_C(X, Y)$ of $C$, which is defined by:

$$
\hbox{Lee}_C(X, Y) = \sum_{v \in C}{X^{2*n-w_L(v)}Y^{w_L(v)}},
$$

where $w_L(v)$ is the Lee weight function, defined in Section [Lee Weight](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#sec-lee-weight). The result will lie in a global multivariate polynomial ring over ${\mathbb{Z}}$ with two variables. The angle-bracket notation may be used to assign names to the indeterminates.

<a id="function-euclideanweightenumerator-code"></a>
#### `EuclideanWeightEnumerator(C): Code -> RngMPolElt`

Suppose $C$ is a ${\mathbb{Z}}_4$-code. This function returns the Euclidean weight enumerator $\hbox{Euclidean}_C(X, Y)$ of $C$, which is defined by:

$$
\hbox{Euclidean}_C(X, Y) = \sum_{v \in C}{X^{4*n-w_E(v)}Y^{w_E(v)}},
$$

where $w_E(v)$ is the Euclidean weight function, defined in Section [Euclidean Weight](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/weight-distribution.md#sec-euclidean-weight). The result will lie in a global multivariate polynomial ring over ${\mathbb{Z}}$ with two variables. The angle-bracket notation may be used to assign names to the indeterminates.

<a id="example-ex-92ee64"></a>
#### `Example: Weight Enumerators of the Octacode (ex-92ee64)`

Several different weight enumerators are calculated for the octacode. To ensure the polynomials print out nicely, names are assigned to the polynomial ring indeterminates in each case. These names will persist if further calls to these functions (over ${\mathbb{Z}}_4$) are made.

```magma
> Z4 := IntegerRing(4);
> O8 := LinearCode<Z4, 8 |
>     [1,0,0,0,3,1,2,1],
>     [0,1,0,0,1,2,3,1],
>     [0,0,1,0,3,3,3,2],
>     [0,0,0,1,2,3,1,1]>;
> #O8;
256
> CWE<X0,X1,X2,X3> := CompleteWeightEnumerator(O8);
> CWE;
X0^8 + 14*X0^4*X2^4 + 56*X0^3*X1^3*X2*X3 + 56*X0^3*X1*X2*X3^3 +
    56*X0*X1^3*X2^3*X3 + 56*X0*X1*X2^3*X3^3 + X1^8 + 14*X1^4*X3^4 +
    X2^8 + X3^8
> SWE<X0,X1,X2> := SymmetricWeightEnumerator(O8);
> SWE;
X0^8 + 14*X0^4*X2^4 + 112*X0^3*X1^4*X2 + 112*X0*X1^4*X2^3 + 16*X1^8 +
    X2^8
> HWE<X,Y> := HammingWeightEnumerator(O8);
> HWE;
X^8 + 14*X^4*Y^4 + 112*X^3*Y^5 + 112*X*Y^7 + 17*Y^8
> LeeWeightEnumerator(O8);
X^16 + 112*X^10*Y^6 + 30*X^8*Y^8 + 112*X^6*Y^10 + Y^16
> EuclideanWeightEnumerator(O8);
X^32 + 128*X^24*Y^8 + 126*X^16*Y^16 + Y^32
```

<a id="sec-decoding"></a>
<a id="id1"></a>
### Decoding

This section describes functions for decoding vectors from the ambient space of a code over $\Z_4$, or the corresponding space over $\Z_2$ under the Gray map, using four different algorithms: coset decoding, syndrome decoding, lifted decoding, and permutation decoding. The reader is referred to [[FCPV08](https://docs.magma-maths.org/references.md#cite-fepuvi08), [FCPV10](https://docs.magma-maths.org/references.md#cite-fepuvi08a), [VZP15](https://docs.magma-maths.org/references.md#cite-vzp2015)] for more information on coset decoding; to [[HKC+94](https://docs.magma-maths.org/references.md#cite-sole), [MS78](https://docs.magma-maths.org/references.md#cite-sloane), [Wan97](https://docs.magma-maths.org/references.md#cite-wan-z4)] on syndrome decoding; to [[BZ01](https://docs.magma-maths.org/references.md#cite-lift), [GV98](https://docs.magma-maths.org/references.md#cite-lift2)] on lifted decoding; and to [[BV16a](https://docs.magma-maths.org/references.md#cite-bv2015b), [BV16b](https://docs.magma-maths.org/references.md#cite-bv2015a), [BBFCV15](https://docs.magma-maths.org/references.md#cite-bebofevi)] on permutation decoding.

#### Coset Decoding

<a id="function-cosetdecode-codelinrng-modtupfldelt"></a>
##### `CosetDecode(C, u : parameters): CodeLinRng, ModTupFldElt -> BoolElt, ModTupRngElt, ModTupFldElt`

<a id="function-cosetdecode-codelinrng-modtuprngelt"></a>
##### `CosetDecode(C, u : parameters): CodeLinRng, ModTupRngElt -> BoolElt, ModTupRngElt, ModTupFldElt`

```magma
MinWeightCode  : RngIntElt                    Default: 
MinWeightKernel: RngIntElt                    Default: 
```

Given a code $C$ over $\Z_4$ of length $n$, and a vector $u$ from the ambient space $V=\Z_4^n$ or $V_2=\Z_2^{2n}$, attempt to decode $u$ with respect to $C$. If the decoding algorithm succeeds in computing a vector $u'\in C$ as the decoded version of $u \in V$, then the function returns `true`, $u'$, and $\Phi(u')$, where $\Phi$ is the Gray map. If the decoding algorithm does not succeed in decoding $u$, then the function returns `false`, the zero vector in $V$, and the zero vector in $V_2$.

The coset decoding algorithm considers the binary linear code $C_u=C_{bin} \cup (C_{bin}+\Phi(u))$, when $C_{bin}=\Phi(C)$ is linear. On the other hand, when $C_{bin}$ is nonlinear, we have $C_{bin}=\bigcup_{i=0}^t ( K_{bin}+\Phi(c_i))$, where $K_{bin}=\Phi(K_C)$, $K_C$ is the kernel of $C$ as a subcode over ${\mathbb{Z}}_4$, $[c_0,c_1,\ldots,c_t]$ are the coset representatives of $C$ with respect to $K_C$ (not necessarily of minimal weight in their cosets) and $c_0$ is the zero codeword. In this case, the algorithm considers the binary linear codes $K_0=K_{bin}\cup (K_{bin}+\Phi(u))$, $K_1=K_{bin} \cup (K_{bin}+\Phi(c_1)+\Phi(u))$, $\ldots$, $K_t=K_{bin} \cup (K_{bin}+ \Phi(c_t)+\Phi(u))$.

If the parameter `MinWeightCode` is not assigned, then the minimum weight of $C$, which coincides with the minimum weight of $C_{bin}$, denoted by $d$, is computed. Note that the minimum distance of $C_{bin}$ coincides with its minimum weight. If $C_{bin}$ is linear and the minimum weight of $C_u$ is less than $d$, then $\Phi(u')=\Phi(u)+e$, where $e$ is a word of minimum weight of $C_u$; otherwise, the decoding algorithm returns `false`. On the other hand, if $C_{bin}$ is nonlinear and the minimum weight of $\cup_{i=0}^t K_i$ is less than the minimum weight of $K_{bin}$, then $\Phi(u')=\Phi(u)+e$, where $e$ is a word of minimum weight of $\cup_{i=0}^t K_i$; otherwise, the decoding algorithm returns `false`. If the parameter `MinWeightKernel` is not assigned, then the minimum Hamming weight of $K_{bin}$ is computed.

<a id="function-cosetdecode-codelinrng-modtupfldelt-2"></a>
##### `CosetDecode(C, Q : parameters): CodeLinRng, [ModTupFldElt] -> SeqEnum, SeqEnum, SeqEnum`

<a id="function-cosetdecode-codelinrng-modtuprngelt-2"></a>
##### `CosetDecode(C, Q : parameters): CodeLinRng, [ModTupRngElt] -> SeqEnum, SeqEnum, SeqEnum`

```magma
MinWeightCode  : RngIntElt                    Default: 
MinWeightKernel: RngIntElt                    Default: 
```

Given a code $C$ over ${\mathbb{Z}}_4$ of length $n$, and a sequence $Q$ of vectors from the ambient space $V={\mathbb{Z}}_4^n$ or $V_2={\mathbb{Z}}_2^{2n}$, attempt to decode the vectors of $Q$ with respect to $C$. This function is similar to the function `CosetDecode(C, u)` except that rather than decoding a single vector, it decodes a sequence of vectors and returns a sequence of booleans and two sequences of decoded vectors corresponding to the given sequence. The algorithm used and effect of the parameters `MinWeightCode` and `MinWeightKernel` are identical to those for the function `CosetDecode(C, u)`.

<a id="example-ex-68b44c"></a>
##### `Example: Coset Decoding of a Hadamard Code (ex-68b44c)`

Starting with the Hadamard code $C$ over ${\mathbb{Z}}_4$ of length 16 and type $2^04^3$, a codeword $c \in C$ is selected and then perturbed to give a vector $u$ in the ambient space of $C$. The vector $u$ is then decoded to recover $c$.

```magma
> C := HadamardCodeZ4(3, 5);
> C;
((16, 4^3 2^0)) Linear Code over IntegerRing(4)
Generator matrix:
[1 0 3 2 0 3 2 1 3 2 1 0 2 1 0 3]
[0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3]
[0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3]
> d := MinimumLeeDistance(C);
> t := Floor((d-1)/2);
> t;
7
> c := C ! [1,1,1,1,2,2,2,2,3,3,3,3,0,0,0,0];
> c in C;
true
> u := c;
> u[5] := u[5] + 2;
> u[12] := u[12] + 1;
> u[13] := u[13] + 3;
> u[16] := u[16] + 2;
> c;
(1 1 1 1 2 2 2 2 3 3 3 3 0 0 0 0)
> u;
(1 1 1 1 0 2 2 2 3 3 3 0 3 0 0 2)
> grayMap := GrayMap(UniverseCode(Integers(4), Length(C)));
> grayMap(c-u);
(0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 1)
> isDecoded, uDecoded := CosetDecode(C, u : MinWeightCode := d);
> isDecoded;
true
> uDecoded eq c;
true
```

#### Syndrome Decoding

<a id="function-syndromedecode-codelinrng-modtupfldelt"></a>
##### `SyndromeDecode(C, u): CodeLinRng, ModTupFldElt -> BoolElt, ModTupRngElt, ModTupFldElt`

<a id="function-syndromedecode-codelinrng-modtuprngelt"></a>
##### `SyndromeDecode(C, u): CodeLinRng, ModTupRngElt -> BoolElt, ModTupRngElt, ModTupFldElt`

Given a code $C$ over $\Z_4$ of length $n$, and a vector $u$ from the ambient space $V=\Z_4^n$ or $V_2=\Z_2^{2n}$, attempt to decode $u$ with respect to $C$. The decoding algorithm always succeeds in computing a vector $u'\in C$ as the decoded version of $u \in V$, and the function returns `true`, $u'$, and $\Phi(u')$, where $\Phi$ is the Gray map. Although the function never returns `false`, the first output parameter `true` is given to be consistent with the other decoding functions.

The syndrome decoding algorithm consists of computing a table pairing each possible syndrome $s$ with a vector of minimum Lee weight $e_s$, called coset leader, in the coset of $C$ containing all vectors having syndrome $s$. After receiving a vector $u$, its syndrome $s$ is computed using the parity check matrix. Then, $u$ is decoded into the codeword $c=u-e_s$.

<a id="function-syndromedecode-codelinrng-modtupfldelt-2"></a>
##### `SyndromeDecode(C, Q): CodeLinRng, [ModTupFldElt] -> SeqEnum, SeqEnum, SeqEnum`

<a id="function-syndromedecode-codelinrng-modtuprngelt-2"></a>
##### `SyndromeDecode(C, Q): CodeLinRng, [ModTupRngElt] -> SeqEnum, SeqEnum, SeqEnum`

Given a code $C$ over ${\mathbb{Z}}_4$ of length $n$, and a sequence $Q$ of vectors from the ambient space $V={\mathbb{Z}}_4^n$ or $V_2={\mathbb{Z}}_2^{2n}$, attempt to decode the vectors of $Q$ with respect to $C$. This function is similar to the function `SyndromeDecode(C, u)` except that rather than decoding a single vector, it decodes a sequence of vectors and returns a sequence of booleans and two sequences of decoded vectors corresponding to the given sequence. The algorithm used is the same as that of function `SyndromeDecode(C, u)`.

<a id="example-ex-1a7dd2"></a>
##### `Example: Syndrome Decoding of a Hadamard Code (ex-1a7dd2)`

The Hadamard code $C$ over ${\mathbb{Z}}_4$ of length 8 and type $2^14^2$ is constructed. Next information bits are encoded using $C$ and three errors are introduced to give the vector $u$. Then $u$ is decoded by calculating its syndrome and applying the map, given by the CosetLeaders function, to the syndrome to recover the original vector.

```magma
> C := HadamardCodeZ4(2, 4);
> C;
((8, 4^2 2^1, 8)) Linear Code over IntegerRing(4)
Generator matrix:
[1 0 3 2 1 0 3 2]
[0 1 2 3 0 1 2 3]
[0 0 0 0 2 2 2 2]
> t := Floor((MinimumLeeDistance(C)-1)/2);
> t;
3
> R, V, f, fbin := InformationSpace(C);
> i := R![2,1,0];
> c := f(i);
> c;
(1 0 3 2 3 2 1 0)
> u := c;
> u[5] := u[5] + 3;
> u[7] := u[7] + 2;
> c;
(1 0 3 2 3 2 1 0)
> u;
(1 0 3 2 2 2 3 0)
> grayMap := GrayMap(UniverseCode(Integers(4), Length(C)));
> grayMap(c-u);
(0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0)
> isDecoded, uDecoded := SyndromeDecode(C, u);
> isDecoded;
true
> uDecoded eq c;
true

> L, mapCosetLeaders := CosetLeaders(C);
> ev := mapCosetLeaders(Syndrome(u, C));
> ev;
(0 0 0 0 3 0 2 0)
> u - ev eq c;
true
```

#### Lifted Decoding

<a id="function-lifteddecode-codelinrng-modtupfldelt"></a>
##### `LiftedDecode(C, u : parameters): CodeLinRng, ModTupFldElt -> BoolElt, ModTupRngElt, ModTupFldElt`

<a id="function-lifteddecode-codelinrng-modtuprngelt"></a>
##### `LiftedDecode(C, u : parameters): CodeLinRng, ModTupRngElt -> BoolElt, ModTupRngElt, ModTupFldElt`

```magma
AlgMethod: MonStgElt                    Default: "Euclidean"
```

Given a code $C$ over $\Z_4$ of length $n$, and a vector $u$ from the ambient space $V=\Z_4^n$ or $V_2=\Z_2^{2n}$, attempt to decode $u$ with respect to $C$. If the decoding algorithm succeeds in computing a vector $u'\in C$ as the decoded version of $u \in V$, then the function returns `true`, $u'$, and $\Phi(u')$, where $\Phi$ is the Gray map. If the decoding algorithm does not succeed in decoding $u$, then the function returns `false`, the zero vector in $V$, and the zero vector in $V_2$ (in the Euclidean case it may happen that $u'$ is not in $C$ because there are too many errors in $u$ to correct).

The lifted decoding algorithm comprises lifting decoding algorithms for two binary linear codes $C_0$ and $C_1$, being the residue and torsion codes of $C$. Let $t_0$ and $t_1$ be the error-correcting capability of $C_0$ and $C_1$, respectively. Assume the received vector $u=c+e$, where $c\in C$ and $e \in V$ is the error vector. Then, the lifted decoding algorithm can correct all error vectors $e$ such that $\tau_1+\tau_3 \leq t_0$ and $\tau_2+\tau_3 \leq t_1$, where $\tau_i$ is the number of occurrences of $i$ in $e$.

In the decoding process, the function `Decode(C, u)` for linear codes is used. The available algorithms for linear codes are: syndrome decoding and a Euclidean algorithm, which operates on alternant codes (BCH, Goppa, and Reed–Solomon codes, etc.). If $C_0$ or $C_1$ is alternant, the Euclidean algorithm is used by default, but the syndrome algorithm will be used if the parameter `AlgMethod` is assigned the value `"Syndrome"`. For non-alternant codes $C_0$ and $C_1$, only syndrome decoding is possible, so the parameter `AlgMethod` is not relevant.

<a id="function-lifteddecode-codelinrng-modtupfldelt-2"></a>
##### `LiftedDecode(C, Q : parameters): CodeLinRng, [ModTupFldElt] -> SeqEnum, SeqEnum, SeqEnum`

<a id="function-lifteddecode-codelinrng-modtuprngelt-2"></a>
##### `LiftedDecode(C, Q : parameters): CodeLinRng, [ModTupRngElt] -> SeqEnum, SeqEnum, SeqEnum`

```magma
AlgMethod: MonStgElt                    Default: "Euclidean"
```

Given a code $C$ over ${\mathbb{Z}}_4$ of length $n$, and a sequence $Q$ of vectors from the ambient space $V={\mathbb{Z}}_4^n$ or $V_2={\mathbb{Z}}_2^{2n}$, attempt to decode the vectors of $Q$ with respect to $C$. This function is similar to the function `LiftedDecode(C, u)` except that rather than decoding a single vector, it decodes a sequence of vectors and returns a sequence of booleans and two sequences of decoded vectors corresponding to the given sequence. The algorithm used and effect of the parameter `AlgMethod` are the same as for `LiftedDecode(C, u)`.

<a id="example-ex-403c77"></a>
##### `Example: Lifted Decoding of a Hadamard Code (ex-403c77)`

The Hadamard code $C$ over ${\mathbb{Z}}_4$ of length 8 and type $2^{1}4^{2}$ is constructed. Then an information word is encoded using $C$, three errors are introduced into the codeword $c$ and then $c$ is recovered by using the lifted decoding algorithm.

```magma
> C := HadamardCodeZ4(2, 4);
> C;
((8, 4^2 2^1, 8)) Linear Code over IntegerRing(4)
Generator matrix:
[1 0 3 2 1 0 3 2]
[0 1 2 3 0 1 2 3]
[0 0 0 0 2 2 2 2]
> d := MinimumLeeDistance(C);
> t := Floor((d-1)/2);
> t;
3
> C0 := BinaryResidueCode(C);
> C1 := BinaryTorsionCode(C);
> t0 := Floor((MinimumDistance(C0)-1)/2);
> t1 := Floor((MinimumDistance(C1)-1)/2);
> t0, t1;
1 1
```

Using the lifted decoding, it is possible to correct all error vectors $e$ such that $\tau_1+\tau_3 \leq t_0=1$ and $\tau_2+\tau_3 \leq t_1=1$, where $\tau_i$ is the number of occurrences of $i$ in $e$. The following statements show that it is not possible to correct the error vector $e=(0 0 0 0 3 0 2 0)$ since $\tau_2+\tau_3=2 > 1$, but it is possible to correct the error vector $e=(0 0 0 0 1 0 2 0)$ since $\tau_1+\tau_3=1 \leq 1$ and $\tau_2+\tau_3=1 \leq 1$.

```magma
> R, V, f, fbin := InformationSpace(C);
> i := R![2,1,0];
> c := f(i);
> c;
(1 0 3 2 3 2 1 0)

> u := c;
> u[5] := u[5] + 3;
> u[7] := u[7] + 2;
> c;
(1 0 3 2 3 2 1 0)
> u;
(1 0 3 2 2 2 3 0)
> e := u - c;
> e;
(0 0 0 0 3 0 2 0)

> isDecoded, uDecoded := LiftedDecode(C, u);
> isDecoded;
true
> uDecoded eq c;
false

> u := c;
> u[5] := u[5] + 1;
> u[7] := u[7] + 2;
> c;
(1 0 3 2 3 2 1 0)
> u;
(1 0 3 2 0 2 3 0)
> e := u - c;
> e;
(0 0 0 0 1 0 2 0)

> isDecoded, uDecoded := LiftedDecode(C, u);
> isDecoded;
true
> uDecoded eq c;
true
```

#### Permutation Decoding

Let $C$ be a code over ${\mathbb{Z}}_4$ of length $n$ and type $2^\gamma 4^\delta$ and $C_{bin}=\Phi(C)$, where $\Phi$ is the Gray map. A subset $S \subseteq {\operatorname{Sym}}(2n)$ is an $s$-PD-set for $C_{bin}$ with respect to a subset of coordinate positions $I\subseteq \{1,\ldots,2n\}$ if $S$ is a subset of the permutation automorphism group of $C_{bin}$, $I$ is an information set for $C_{bin}$, and every $s$-set of coordinate positions in $\{1,\ldots,2n\}$ is moved out of the information set $I$ by at least one element of $S$, where $1\leq s \leq t$ and $t$ is the error-correcting capability of $C_{bin}$.

If $I=[i_1,\ldots, i_{\gamma+\delta}] \subseteq \{1,\ldots,n \}$ is an information set for $C$ such that the code obtained by puncturing $C$ at positions $\{1,\ldots,n\} \backslash \{i_{\gamma+1},\ldots, i_{\gamma+\delta} \}$ is of type $4^\delta$, then $\Phi(I)=[2i_1-1,\ldots, 2i_\gamma-1, 2i_{\gamma+1}-1, 2i_{\gamma+1},  \ldots, 2i_{\gamma+\delta}-1, 2i_{\gamma+\delta}]$ is an information set for $C_{bin}$. It is also easy to see that if $S$ is a subset of the permutation automorphism group of $C$, that is, $S \subseteq {\operatorname{PAut}}(C) \subseteq {\operatorname{Sym}}(n)$, then $\Phi(S)=[ \Phi(\tau) : \tau \in S] \subseteq  {\operatorname{PAut}}(C_{bin}) \subseteq {\operatorname{Sym}}(2n)$, where

$$
\Phi(\tau)(i)=\cases{
2\tau(i/2), &if $i$  is even, \\
2\tau((i+1)/2) -1 &if $i$  is odd.\\}
$$

Given a subset of coordinate positions $I\subseteq \{1,\ldots, n\}$ and a subset $S \subseteq {\operatorname{Sym}}(n)$, in order to check that $\Phi(S)$ is an $s$-PD-set for $C_{bin}$ with respect to $\Phi(I)$, it is enough to check that $S$ is a subset of the permutation automorphism group of $C$, $I$ is an information set for $C$, and every $s$-set of coordinate positions in $\{1,\ldots,n\}$ is moved out of the information set $I$ by at least one element of $S$ [[BV16a](https://docs.magma-maths.org/references.md#cite-bv2015b), [BV16b](https://docs.magma-maths.org/references.md#cite-bv2015a)].

<a id="function-ispermutationdecodeset-codelinrng-rngintelt-grppermelt-rngintelt"></a>
##### `IsPermutationDecodeSet(C, I, S, s): CodeLinRng, [RngIntElt], [GrpPermElt], RngIntElt -> BoolElt`

Given a code $C$ over ${\mathbb{Z}}_4$ of length $n$ and type $2^\gamma 4^\delta$, a sequence $I \subseteq \{1,\ldots,2n \}$, a sequence $S$ of elements in the symmetric group ${\operatorname{Sym}}(2n)$ of permutations on the set $\{1,\ldots,2n \}$, and an integer $s\geq 1$, return `true` if and only if $S$ is an $s$-PD-set for $C_{bin}=\Phi(C)$, where $\Phi$ is the Gray map, with respect to the information set $I$.

The arguments $I$ and $S$ can also be given as a sequence $I \subseteq \{1,\ldots,n \}$ and a sequence $S$ of elements in the symmetric group ${\operatorname{Sym}}(n)$ of permutations on the set $\{1,\ldots,n \}$, respectively. In this case, the function returns `true` if and only if $\Phi(S)$ is an $s$-PD-set for $C_{bin}=\Phi(C)$ with respect to the information set $\Phi(I)$, where $\Phi(I)$ and $\Phi(S)$ are the sequences defined as above.

Depending on the length of the code $C$, its type, and the integer $s$, this function could take some time to compute whether $S$ or $\Phi(S)$ is an $s$-PD-set for $C_{bin}$ with respect to $I$ or $\Phi(I)$, respectively. Specifically, if the function returns `true`, it is necessary to check $\sum_{i=1}^s {{|I|}\choose{i}} \cdot {{N-|I|}\choose{s-i}}$ $s$-sets, where $N=n$ and $|I|=\gamma+\delta$ when $I$ is given as an information set for $C$, or $N=2n$ and $|I|=\gamma+2\delta$ when $I$ is given as an information set for $C_{bin}$.

The verbose flag `IsPDSetFlag` is set to level 0 by default. If it is set to level 1, the total time used to check the condition is shown. Moreover, the reason why the function returns `false` is also shown, that is, whether $I$ is not an information set, $S$ is not a subset of the permutation automorphism group or $S$ is not an $s$-PD-set. If it is set to level 2, the percentage of the computation process performed is also printed.

<a id="function-permutationdecode-codelinrng-rngintelt-grppermelt-rngintelt-modtupfldelt"></a>
##### `PermutationDecode(C, I, S, s, u): CodeLinRng, [RngIntElt], [GrpPermElt], RngIntElt, ModTupFldElt -> BoolElt, ModTupRngElt, ModTupFldElt`

<a id="function-permutationdecode-codelinrng-rngintelt-grppermelt-rngintelt-modtuprngelt"></a>
##### `PermutationDecode(C, I, S, s, u): CodeLinRng, [RngIntElt], [GrpPermElt], RngIntElt, ModTupRngElt -> BoolElt, ModTupRngElt, ModTupFldElt`

The arguments for the intrinsic are as follows:

- $C$ is a code over ${\mathbb{Z}}_4$ of length $n$ and type $2^\gamma 4^\delta$;
- $I=[i_1,\ldots, i_{\gamma+\delta}] \subseteq \{1,\ldots,n \}$ is the information set for $C$ given as a sequence of coordinate positions such that the code obtained by puncturing $C$ at coordinate positions $\{1,\ldots,n\} \backslash \{i_{\gamma+1},\ldots,i_{\gamma+1},\ldots, i_{\gamma+\delta} \}$ is of type $4^\delta$;
- $S$ is a sequence such that either $S$ or $\Phi(S)$ is an $s$-PD-set for $C_{bin}=\Phi(C)$, where $\Phi$ is the Gray map, with respect to $\Phi(I)$;
- $s$ is an integer such that $s \in \{1,\ldots,t\}$ where $t$ is the error-correcting capability of $C_{bin}$;
- $u$ is a vector from the ambient space $V={\mathbb{Z}}_4^n$ or $V_2={\mathbb{Z}}_2^{2n}$.

Given the above assumptions, the function attempts to decode $u$ with respect to $C$. If the decoding algorithm succeeds in computing a vector $u'\in C$ as the decoded version of $u \in V$, then the function returns the values `true`, $u'$, and $\Phi(u')$. If the decoding algorithm does not succeed in decoding $u$, then the function returns the values `false`, the zero vector in $V$, and the zero vector in $V_2$.

Assume that the received vector $\Phi(u)=c+e$, where $u \in V$, $c \in C_{bin}$, and $e \in V_2$ is the error vector with at most $t$ errors. The permutation decoding algorithm proceeds by moving all errors in the received vector $\Phi(u)$ out of the information positions. That is, the nonzero coordinates of $e$ are moved out of the information set $\Phi(I)$ for $C_{bin}$, by using an automorphism of $C_{bin}$.

Note that $\Phi(I)$ and $\Phi(S)$ are the sequences defined as above. Moreover, the function does not check whether $I$ is an information set for $C$, nor whether $S$ or $\Phi(S)$ is an $s$-PD-set for $C_{bin}$ with respect to $\Phi(I)$, nor that $s\leq t$.

<a id="function-permutationdecode-codelinrng-rngintelt-grppermelt-rngintelt-modtupfldelt-2"></a>
##### `PermutationDecode(C, I, S, s, Q): CodeLinRng, [RngIntElt], [GrpPermElt], RngIntElt, [ModTupFldElt] -> [BoolElt], [ModTupRngElt], [ModTupFldElt]`

<a id="function-permutationdecode-codelinrng-rngintelt-grppermelt-rngintelt-modtuprngelt-2"></a>
##### `PermutationDecode(C, I, S, s, Q): CodeLinRng, [RngIntElt], [GrpPermElt], RngIntElt, [ModTupRngElt] -> [BoolElt], [ModTupRngElt], [ModTupFldElt]`

Given

- a code $C$ over ${\mathbb{Z}}_4$ of length $n$ and type $2^\gamma 4^\delta$;
- an information set $I=[i_1,\ldots, i_{\gamma+\delta}] \subseteq \{1,\ldots,n \}$ for $C$ as a sequence of coordinate positions, such that the code $C$ punctured on $\{1,\ldots,n\} \backslash \{i_{\gamma+1},\ldots, i_{\gamma+\delta} \}$ is of type $4^\delta$;
- a sequence $S$ such that either $S$ or $\Phi(S)$ is an $s$-PD-set for $C_{bin}=\Phi(C)$, where $\Phi$ is the Gray map, with respect to $\Phi(I)$;
- an integer $s \in \{1,\ldots,t\}$, where $t$ is the error-correcting capability of $C_{bin}$;
- and a sequence $Q$ of vectors from the ambient space $V={\mathbb{Z}}_4^n$ or $V_2={\mathbb{Z}}_2^{2n}$,

  attempt to decode the vectors of $Q$ with respect to $C$. This function is similar to the version of `PermutationDecode` that decodes a single vector except that it decodes a sequence of vectors and returns a sequence of booleans and two sequences of decoded vectors corresponding to the given sequence. The algorithm used is the same as that used by the single vector version of `PermutationDecode`.

<a id="example-ex-446a9b"></a>
##### `Example: Permutation Decoding of a Hadamard Code (ex-446a9b)`

First the Hadamard code $C$ over ${\mathbb{Z}}_4$ of length 32 and type $2^14^3$ is constructed. It is known that $I=[17,1,2,5]$ is an information set for $C$ and $S=\{ \pi^i : 1\leq i \leq 8 \}$, where $\pi=(1,24,26,15,3,22,28,13)$ $(2, 23, 27, 14, 4, 21, 25, 16)$ $(5, 11, 32, 20, 7, 9, 30, 18)$ $(6, 10, 29, 19, 8,$ $12, 31,17)$, is a subset of the permutation automorphism group of $C$ such that $\Phi(S)$ is a 7-PD-set for $C_{bin}=\Phi(C)$ with respect to $\Phi(I)$. Then, choosing a codeword $c$ of $C$, $c$ is perturbed by the addition of an error vector to give a new vector $u$, and finally permutation decoding is applied to $u$ to recover $c$.

```magma
> C := HadamardCodeZ4(3, 6);
> C;
((32, 4^3 2^1)) Linear Code over IntegerRing(4)
Generator matrix:
[1 0 3 2 0 3 2 1 3 2 1 0 2 1 0 3 1 0 3 2 0 3 2 1 3 2 1 0 2 1 0 3]
[0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3]
[0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]
> t := Floor((MinimumLeeDistance(C) - 1)/2);
> t;
15
> I := [17, 1, 2, 5];
> p := Sym(32)!(1, 24, 26, 15, 3, 22, 28, 13)(2, 23, 27, 14, 4, 21, 25, 16)
>                 (5, 11, 32, 20, 7, 9, 30, 18)(6, 10, 29, 19, 8, 12, 31,17);
> S := [ p^i : i in [1..8] ];
> SetVerbose("IsPDSetFlag", 2);
> IsPermutationDecodeSet(C, I, S, 7);
Checking whether I is an information set...
Checking whether S is in the permutation automorphism group...
Checking whether S is an s-PD-set...
10 %
20 %
30 %
40 %
50 %
60 %
70 %
80 %
90 %
Took 136.430 seconds (CPU time)
true
> SetVerbose("IsPDSetFlag", 0);
> c := C ! [1,2,3,0,0,1,2,3,3,0,1,2,2,3,0,1,3,0,1,2,2,3,0,1,1,2,3,0,0,1,2,3];
> c in C;
true
> u := c;
> u[1] := c[1] + 2;
> u[2] := c[2] + 2;
> u[3] := c[3] + 1;
> u[16] := c[16] + 3;
> u[27] := c[27] + 1;
> u in C;
false
> LeeDistance(u, c);
7

> grayMap := GrayMap(UniverseCode(Integers(4), Length(C)));
> cbin := grayMap(c);
> ubin := grayMap(u);
> Distance(ubin, cbin);
7
> isDecoded, uDecoded, ubinDecoded := PermutationDecode(C, I, S, 7, u);
> isDecoded;
true
> uDecoded eq c;
true
> ubinDecoded eq cbin;
true

> isDecoded, uDecoded, ubinDecoded := PermutationDecode(C, I, S, 7, ubin);
> isDecoded;
true
> uDecoded eq c;
true
> ubinDecoded eq cbin;
true
```

<a id="function-pdsethadamardcodez4-rngintelt-rngintelt"></a>
##### `PDSetHadamardCodeZ4(δ, m): RngIntElt, RngIntElt -> SeqEnum, SeqEnum, SeqEnum, SeqEnum, SeqEnum`

```magma
AlgMethod: MonStgElt                    Default: "Deterministic"
```

Given an integer $m\geq 5$, and an integer $\delta$ such that $3\leq \delta \leq \lfloor (m+1)/2 \rfloor$, the Hadamard code $C$ over ${\mathbb{Z}}_4$ of length $n=2^{m-1}$ and type $2^\gamma 4^\delta$, where $\gamma=m+1-2\delta$, given by the function `HadamardCodeZ4(\delta, m)`, is considered. The function returns an information set $I=[i_1,\ldots,i_{\gamma+\delta}] \subseteq \{1,\ldots, n \}$ for $C$ together with a subset $S$ of the permutation automorphism group of $C$ such that $\Phi(S)$ is an $s$-PD-set for $C_{bin}=\Phi(C)$ with respect to $\Phi(I)$, where $\Phi$ is the Gray map and $\Phi(I)$ and $\Phi(S)$ are defined above. The function also returns the information set $\Phi(I)$ and the $s$-PD-set $\Phi(S)$. For $m\geq 1$ and $1 \leq \delta \leq 2$, the Gray map image of $C$ is linear and it is possible to find an $s$-PD-set for $C_{bin}=\Phi(C)$, for any $s\leq \left \lfloor {2^{m}/(m+1)} \right \rfloor -1$, by using the function `PDSetHadamardCode(m)`.

The information sets $I$ and $\Phi(I)$ are returned as sequences of $\gamma+\delta$ and $\gamma+2\delta$ integers, giving the coordinate positions that correspond to the information sets for $C$ and $C_{bin}$, respectively. The sets $S$ and $\Phi(S)$ are also returned as sequences of elements in the symmetric groups ${\operatorname{Sym}}(n)$ and ${\operatorname{Sym}}(2n)$ of permutations on the set $\{1,\ldots,n \}$ and $\{1,\ldots,2n \}$, respectively.

A deterministic algorithm is used by default. In this case, the function returns the $s$-PD-set of size $s+1$ with $s=\lfloor{(2^{2\delta-2}-\delta)/\delta} \rfloor$, which is the maximum value of $s$ when $\gamma=0$, as described in [[BV16b](https://docs.magma-maths.org/references.md#cite-bv2015a)]. If the parameter `AlgMethod` is assigned the value `"Nondeterministic"`, the function tries to improve the previous result by finding an $s$-PD-set of size $s+1$ such that $\lfloor{(2^{2\delta-2}-\delta)/\delta} \rfloor \leq s \leq \lfloor{(2^{m-1}+\delta-m-1)/(m+1-\delta)} \rfloor$. In this case, the function starts from the maximum value of $s$ and decreases it if the $s$-PD-set is not found after a specified time.

<a id="function-pdsetkerdockcodez4-rngintelt"></a>
##### `PDSetKerdockCodeZ4(m): RngIntElt -> SeqEnum, SeqEnum, SeqEnum, SeqEnum`

Given an integer $m\geq 4$ such that $2^m-1$ is not a prime number, the Kerdock code $C$ over ${\mathbb{Z}}_4$ of length $n=2^m$ and type $4^{m+1}$, given by the function `KerdockCodeZ4(m)` is considered. The function returns the information set $I=[1,\ldots,m+1]$ for $C$ together with a subset $S$ of the permutation automorphism group of $C$ such that $\Phi(S)$ is an $s$-PD-set for $C_{bin}=\Phi(C)$ with respect to $\Phi(I)$, where $\Phi$ is the Gray map and $\Phi(I)$ and $\Phi(S)$ are defined above. The function also returns the information set $\Phi(I)=[1,\ldots,2m+2]$ and the $s$-PD-set $\Phi(S)$. The size of the $s$-PD-set $S$ is always $\lambda = s+1$, where $\lambda$ is the greatest divisor of $2^m-1$ such that $\lambda \leq 2^m/(m+1)$.

The information sets $I$ and $\Phi(I)$ are returned as sequences of $m+1$ and $2m+2$ integers, giving the coordinate positions that correspond to the information sets for $C$ and $C_{bin}$, respectively. The sets $S$ and $\Phi(S)$ are also returned as sequences of elements in the symmetric groups ${\operatorname{Sym}}(n)$ and ${\operatorname{Sym}}(2n)$ of permutations on the sets $\{1,\ldots,n \}$ and $\{1,\ldots,2n \}$, respectively. The $s$-PD-set $S$ contains the $s+1$ permutations described in [[BV16a](https://docs.magma-maths.org/references.md#cite-bv2015b)].

<a id="example-ex-a6009d"></a>
##### `Example: Checking a PD-Set for a Hadamard Code (ex-a6009d)`

A 4-PD-set $S$ of size 5 for the Hadamard code $C$ over ${\mathbb{Z}}_4$ of length 16 and type $2^04^3$ is constructed. A check that it really is a 4-PD-set for $C$ is then made. Note that $\lfloor{(2^{2\delta-2}-\delta)/\delta} \rfloor=4$. Finally, a codeword $c$ of $C$ is selected, perturbed by an error vector $e$ to give a vector $u$, to which permutation decoding is applied to recover $c$.

```magma
> C := HadamardCodeZ4(3, 5);

> I, S, Ibin, Sbin := PDSetHadamardCodeZ4(3, 5);
> s := #Sbin-1; s;
4
> s eq Floor((2^(2*3-2)-3)/3);
true
> IsPermutationDecodeSet(C, I, S, s);
true
> IsPermutationDecodeSet(C, Ibin, Sbin, s);
true

> c := C ! [3,2,1,0,1,0,3,2,3,2,1,0,1,0,3,2];
> R := UniverseCode(Integers(4), Length(C));
> u := R ! [2,3,2,0,1,0,3,2,3,2,1,0,1,0,3,3];
> u in C;
false
> LeeDistance(u, c);
4
> grayMap := GrayMap(R);
> cbin := grayMap(c);

> isDecoded, uDecoded, ubinDecoded := PermutationDecode(C, I, S, 4, u);
> isDecoded;
true
> uDecoded eq c;
true
> ubinDecoded eq cbin;
true
```

For the Hadamard code $C$ over ${\mathbb{Z}}_4$ of length 32 and type $2^14^3$, a $4$-PD-set of size $5$ can be constructed either by using the deterministic method (by default), or by using a nondeterministic method to obtain an $s$-PD-set of size $s+1$ with $4\leq s \leq 7$. In both cases, the given sets are checked for really being $s$-PD-sets for $C$.

```magma
> C := HadamardCodeZ4(3, 6);

> I, S, Ibin, Sbin := PDSetHadamardCodeZ4(3, 6);
> s := #Sbin-1; s;
4
> IsPermutationDecodeSet(C, I, S, s);
true

> I, S, Ibin, Sbin := PDSetHadamardCodeZ4(3, 6 : AlgMethod := "Nondeterministic");
> s := #Sbin-1; s;
6
> IsPermutationDecodeSet(C, I, S, s);
true
```

Finally, a 2-PD-set of size 3 is constructed for the Kerdock code of length 16 and type $2^0 4^5$, and formally checked for being a 2-PD-set for this code.

```magma
> C := KerdockCode(4);

> I, S, Ibin, Sbin := PDSetKerdockCodeZ4(4);
> IsPermutationDecodeSet(C, I, S, 2);
true
> IsPermutationDecodeSet(C, Ibin, Sbin, 2);
true
```

<a id="aut-group"></a>
<a id="sec-aut"></a>
### Automorphism Groups

<a id="function-permutationgrouphadamardcodez4-rngintelt-rngintelt"></a>
#### `PermutationGroupHadamardCodeZ4(δ, m): RngIntElt, RngIntElt -> GrpPerm, Mtrx`

<a id="function-pauthadamardcodez4-rngintelt-rngintelt"></a>
#### `PAutHadamardCodeZ4(δ, m): RngIntElt, RngIntElt -> GrpPerm, Mtrx`

Given an integer $m\geq 1$ and an integer $\delta$ such that $1\leq \delta \leq \lfloor (m+1)/2 \rfloor$, this function returns the permutation group $G$ of a Hadamard code over ${\mathbb{Z}}_4$ of length $2^{m-1}$ and type $2^\gamma 4^\delta$, where $\gamma=m+1-2\delta$. The group $G$ contains all permutations of the coordinates which preserve the code. Thus only permutation of coordinates is allowed, and the degree of $G$ is always $2^{m-1}$. Moreover, the generator matrix with $\gamma+\delta$ rows used to generate the code is returned. This matrix is constructed in a recursive way using the `Plotkin` and `BQPlotkin` constructions defined in Section [New Codes from Old](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#sec-plotkin).

<a id="function-permutationgrouphadamardcodez4order-rngintelt-rngintelt"></a>
#### `PermutationGroupHadamardCodeZ4Order(δ, m): RngIntElt, RngIntElt -> RngIntElt`

<a id="function-pauthadamardcodez4order-rngintelt-rngintelt"></a>
#### `PAutHadamardCodeZ4Order(δ, m): RngIntElt, RngIntElt -> RngIntElt`

Given an integer $m\geq 1$ and an integer $\delta$ such that $1\leq \delta \leq \lfloor (m+1)/2 \rfloor$, return the order of the permutation group $G$ of a Hadamard code over ${\mathbb{Z}}_4$ of length $2^{m-1}$ and type $2^\gamma 4^\delta$, where $\gamma=m+1-2\delta$. The group $G$ contains all permutations of the coordinates which preserve the code.

<a id="function-permutationgroupextendedperfectcodez4-rngintelt-rngintelt"></a>
#### `PermutationGroupExtendedPerfectCodeZ4(δ, m): RngIntElt, RngIntElt -> GrpPerm, Mtrx`

<a id="function-pautextendedperfectcodez4-rngintelt-rngintelt"></a>
#### `PAutExtendedPerfectCodeZ4(δ, m): RngIntElt, RngIntElt -> GrpPerm, Mtrx`

Given an integer $m\geq 2$ and an integer $\delta$ such that $1\leq \delta \leq \lfloor (m+1)/2 \rfloor$, return the permutation group $G$ of an extended perfect code over ${\mathbb{Z}}_4$ of length $2^{m-1}$, such that its dual code is of type $2^\gamma 4^\delta$, where $\gamma=m+1-2\delta$. The group $G$ contains all permutations of the coordinates which preserve the code. Thus only permutation of coordinates is allowed, and the degree of $G$ is always $2^{m-1}$. Moreover, the generator matrix with $\gamma+\delta$ rows used to generate the code is returned. This matrix is constructed in a recursive way using the Plotkin and BQPlotkin constructions defined in Section [New Codes from Old](https://docs.magma-maths.org/CodingTheory/LinearCodesOverZ4/constructions.md#sec-plotkin).

<a id="function-permutationgroupextendedperfectcodez4order-rngintelt-rngintelt"></a>
#### `PermutationGroupExtendedPerfectCodeZ4Order(δ, m): RngIntElt, RngIntElt -> RngIntElt`

<a id="function-pautextendedperfectcodez4order-rngintelt-rngintelt"></a>
#### `PAutExtendedPerfectCodeZ4Order(δ, m): RngIntElt, RngIntElt -> RngIntElt`

Given an integer $m\geq 2$ and an integer $\delta$ such that $1\leq \delta \leq \lfloor (m+1)/2 \rfloor$, return the order of the permutation group $G$ of an extended perfect code over ${\mathbb{Z}}_4$ of length $2^{m-1}$, such that its dual code is of type $2^\gamma 4^\delta$, where $\gamma=m+1-2\delta$. The group $G$ contains all permutations of the coordinates which preserve the code.

<a id="example-ex-61ad8c"></a>
#### `Example: Permutation Automorphisms of a Hadamard Code (ex-61ad8c)`

```magma
> C := HadamardCodeZ4(2,4);
> PAut := PAutHadamardCodeZ4(2,4);
> PAut;
Permutation group PAut acting on a set of cardinality 8
    (1, 2)(3, 4)(5, 6)(7, 8)
    (2, 4)(6, 8)
    (5, 7)(6, 8)
    (1, 5)(3, 7)
> {p : p in Sym(8) | C^p eq C} eq Set(PAut);
true
> #PAut eq PAutHadamardCodeZ4Order(2,4);
true
> d := 2; m := 4; g := m+1-2*d;
> PAutHadamardCodeZ4Order(d, m) eq
>  #GL(d-1,Integers(4))*#GL(g,Integers(2))*2^g*4^((g+1)*(d-1));
true
> d := 4; m := 8; g := m+1-2*d;
> PAutHadamardCodeZ4Order(d, m) eq
>   #GL(d-1,Integers(4))*#GL(g,Integers(2))*2^g*4^((g+1)*(d-1));
true
> PAutHadamardCodeZ4(2,4) eq PAutExtendedPerfectCodeZ4(2,4);
true
```

<a id="function-permutationgroup-codelinrng"></a>
#### `PermutationGroup(C): CodeLinRng -> GrpPerm`

The permutation group $G$ of the linear code $C$ of length $n$ over the ring $R$, where $G$ is the group of all permutation-action permutations which preserve the code. Thus only permutation of coordinates is allowed, and the degree of $G$ is always $n$.

<a id="function-permutationgroupgraymapimage-codelinrng"></a>
#### `PermutationGroupGrayMapImage(C): CodeLinRng -> GrpPerm`

Given a code $C$ over ${\mathbb{Z}}_4$ of length $n$, return the permutation group $G_{bin}$ of $C_{bin}=\Phi(C)$, where $G_{bin}$ is the group of all permutation-action permutations which preserve the binary code $C_{bin}$ of length $2n$ and $\Phi$ is the Gray map. Thus only permutation of coordinates is allowed, and the degree of $G_{bin}$ is always $2n$.

<a id="example-ex-326517"></a>
#### `Example: Permutation Group of a Code over Z4 (ex-326517)`

```magma
> C := HadamardCodeZ4(2,4);
> PAutC := PermutationGroup(C);
> PAutC eq PAutHadamardCodeZ4(2,4);
true
> #PAutC eq PAutHadamardCodeZ4Order(2,4);
true
> {p : p in Sym(8) | C^p eq C} eq Set(PAutC);
true

> Cbin := GrayMapImage(C);
> PAutCbin := PermutationGroupGrayMapImage(C);
> {p : p in PAutCbin | Set(Cbin)^p eq Set(Cbin)} eq Set(PAutCbin);
true
```

<a id="error-correcting-additive-code"></a>
<a id="chap-codeadd"></a>
## Additive Codes

- [Introduction](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/introduction.md)
- [Construction of Additive Codes](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/creation.md)
  - [Construction of General Additive Codes](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/creation.md#construction-of-general-additive-codes)
    - [`AdditiveCode<F, K, n | L>: FldFin, RngIntElt, List → Code`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/creation.md#constructor-constructor-additivecode-fldfin-rngintelt-list-code)
    - [`AdditiveCode(G): ModMatRngElt → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/creation.md#function-additivecode-modmatrngelt)
    - [`AdditiveCode(K, G): FldFin, ModMatRngElt → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/creation.md#function-additivecode-fldfin-modmatrngelt)
    - [Example: Linear and Additive Codes Compared](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/creation.md#example-ex-f9cba7)
    - [Example: Additive Code from a Matrix](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/creation.md#example-ex-9d93b8)
    - [`AdditiveCode(K, C): FldFin, Code → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/creation.md#function-additivecode-fldfin-code)
    - [Example: Additive Code from a Linear Code](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/creation.md#example-ex-8b74a8)
    - [Example: Viewing an Additive Code over a Subfield](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/creation.md#example-ex-770cac)
  - [Some Trivial Additive Codes](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/creation.md#some-trivial-additive-codes)
    - [`AdditiveZeroCode(F, K, n): FldFin, FldFin, RngIntElt → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/creation.md#function-additivezerocode-fldfin-fldfin-rngintelt)
    - [`AdditiveRepetitionCode(F, K, n): FldFin, FldFin, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/creation.md#function-additiverepetitioncode-fldfin-fldfin-rngintelt)
    - [`AdditiveZeroSumCode(F, K, n): FldFin, FldFin, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/creation.md#function-additivezerosumcode-fldfin-fldfin-rngintelt)
    - [`AdditiveUniverseCode(F, K, n): FldFin, FldFin, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/creation.md#function-additiveuniversecode-fldfin-fldfin-rngintelt)
    - [`RandomAdditiveCode(F, K, n, k): FldFin, FldFin, RngIntElt, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/creation.md#function-randomadditivecode-fldfin-fldfin-rngintelt-rngintelt)
    - [Example: Chain of Trivial Additive Codes](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/creation.md#example-ex-24f23c)
- [Invariants of an Additive Code](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/access.md)
  - [The Ambient Space and Alphabet](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/access.md#the-ambient-space-and-alphabet)
    - [`Alphabet(C): Code → Rng`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/access.md#function-alphabet-code)
    - [`Field(C): Code → Rng`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/access.md#function-field-code)
    - [`CoefficientField(C): Code → Rng`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/access.md#function-coefficientfield-code)
    - [`AmbientSpace(C): Code → ModTupRng`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/access.md#function-ambientspace-code)
    - [`Generic(C): Code → Code`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/access.md#function-generic-code)
    - [Example: Alphabet and Coefficient Field](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/access.md#example-ex-b0a75c)
  - [Basic Numerical Invariants](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/access.md#basic-numerical-invariants)
    - [`Length(C): Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/access.md#function-length-code)
    - [`Dimension(C): Code → FldRatElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/access.md#function-dimension-code)
    - [`NumberOfGenerators(C): Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/access.md#function-numberofgenerators-code)
    - [`Ngens(C): Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/access.md#function-ngens-code)
    - [`# C: Code → RngIntElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/access.md#operation-operation-code-rngintelt)
    - [`InformationRate(C): Code → FldPrElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/access.md#function-informationrate-code)
  - [The Code Space](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/access.md#the-code-space)
    - [`GeneratorMatrix(C): Code → ModMatFldElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/access.md#function-generatormatrix-code)
    - [`BasisMatrix(C): Code → ModMatRngElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/access.md#function-basismatrix-code)
    - [`Basis(C): Code → [ ModTupRngElt ]`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/access.md#function-basis-code)
    - [`Generators(C): Code → { ModTupFldElt }`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/access.md#function-generators-code)
    - [`C . i: Code, RngIntElt → ModTupFldElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/access.md#operation-operation-code-rngintelt-modtupfldelt)
  - [The Dual Space](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/access.md#the-dual-space)
    - [`Dual(C): CodeAdd → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/access.md#function-dual-codeadd)
    - [`ParityCheckMatrix(C): Code → ModMatFldElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/access.md#function-paritycheckmatrix-code)
- [Operations on Codewords](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md)
  - [Construction of a Codeword](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#construction-of-a-codeword)
    - [`C ! [a₁, ..., aₙ]: Code, [ RngElt ] → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#operation-op-code-rngelt)
    - [`elt< C | a₁, ..., aₙ>: Code, List → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#constructor-constructor-elt-code-list-modtuprngelt)
    - [`C ! u: Code, ModTupRngElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#operation-op-code-modtuprngelt)
    - [`C ! 0: Code, RngIntElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#operation-op-code-rngintelt)
    - [`Random(C): Code → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#function-random-code)
  - [Arithmetic Operations on Codewords](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#arithmetic-operations-on-codewords)
    - [`u + v: ModTupRngElt, ModTupRngElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#operation-op-plus-modtuprngelt-modtuprngelt)
    - [`- u: ModTupRngElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#operation-operation-modtuprngelt-modtuprngelt)
    - [`u - v: ModTupRngElt, ModTupRngElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#operation-op-minus-modtuprngelt-modtuprngelt)
    - [`a * u: RngElt, ModTupRngElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#operation-op-times-rngelt-modtuprngelt)
    - [`Normalize(u): ModTupRngElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#function-normalize-modtuprngelt)
  - [Distance and Weight](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#distance-and-weight)
    - [`Distance(u, v): ModTupRngElt, ModTupRngElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#function-distance-modtuprngelt-modtuprngelt)
    - [`Weight(u): ModTupRngElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#function-weight-modtuprngelt)
  - [Vector Space and Related Operations](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#vector-space-and-related-operations)
    - [`(u, v): ModTupRngElt, ModTupRngElt → RngElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#literal-literal-u-v-modtuprngelt-modtuprngelt-rngelt)
    - [`InnerProduct(u, v): ModTupRngElt, ModTupRngElt → RngElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#function-innerproduct-modtuprngelt-modtuprngelt)
    - [`TraceInnerProduct(K, u, v): FldFin, ModTupFldElt, ModTupFldElt → FldFinElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#function-traceinnerproduct-fldfin-modtupfldelt-modtupfldelt)
    - [`Support(w): ModTupRngElt → { RngIntElt }`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#function-support-modtuprngelt)
    - [`Coordinates(C, u): Code, ModTupRngElt → [ RngFinElt ]`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#function-coordinates-code-modtuprngelt)
    - [`Parent(w): ModTupRngElt → ModTupRng`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#function-parent-modtuprngelt)
    - [`Rotate(u, k): ModTupRngElt, RngIntElt → ModTupRngElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#function-rotate-modtuprngelt-rngintelt)
    - [`Rotate(~u, k): ModTupRngElt, RngIntElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#procedure-rotate-modtuprngelt-rngintelt-ref)
    - [`Trace(u, S): ModTupFldElt, FldFin → ModTupFldElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#function-trace-modtupfldelt-fldfin)
    - [`Trace(u): ModTupFldElt → ModTupFldElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#function-trace-modtupfldelt)
  - [Predicates for Codewords](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#predicates-for-codewords)
    - [`u eq v: ModTupRngElt, ModTupRngElt → BoolElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#operation-op-eq-modtuprngelt-modtuprngelt)
    - [`u ne v: ModTupRngElt, ModTupRngElt → BoolElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#operation-op-ne-modtuprngelt-modtuprngelt)
    - [`IsZero(u): ModTupRngElt → BoolElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#function-iszero-modtuprngelt)
  - [Accessing Components of a Codeword](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#accessing-components-of-a-codeword)
    - [`u[i]: ModTupRngElt, RngIntElt → RngElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#literal-literal-u-i-modtuprngelt-rngintelt-rngelt)
    - [`u[i] := x;`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/element.md#literal-literal-u-i-x)
- [Subcodes](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/subcode.md)
  - [The Subcode Constructor](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/subcode.md#the-subcode-constructor)
    - [`sub<C | L>: CodeAdd, List → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/subcode.md#constructor-constructor-sub-codeadd-list-codeadd)
    - [`Subcode(C, k): CodeAdd, RngIntElt → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/subcode.md#function-subcode-codeadd-rngintelt)
    - [`Subcode(C, S): CodeAdd, { RngIntElt } → Code`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/subcode.md#function-subcode-codeadd-rngintelt-2)
    - [`SubcodeBetweenCode(C1, C2, k): CodeAdd, CodeAdd, RngIntElt → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/subcode.md#function-subcodebetweencode-codeadd-codeadd-rngintelt)
    - [`SubcodeWordsOfWeight(C, w): CodeAdd, RngIntElt → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/subcode.md#function-subcodewordsofweight-codeadd-rngintelt)
    - [`SubcodeWordsOfWeight(C, S): CodeAdd, { RngIntElt } → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/subcode.md#function-subcodewordsofweight-codeadd-rngintelt-2)
    - [Example: Subcode between Two Codes](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/subcode.md#example-ex-18722c)
  - [Sum, Intersection, and Dual](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/subcode.md#sum-intersection-and-dual)
    - [`C + D: CodeAdd, CodeAdd → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/subcode.md#operation-op-plus-codeadd-codeadd)
    - [`C meet D: Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/subcode.md#operation-op-meet-code-code)
    - [`Dual(C): Code → Code`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/subcode.md#function-dual-code)
  - [Membership and Equality](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/subcode.md#membership-and-equality)
    - [`u in C: ModTupRngElt, CodeAdd → BoolElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/subcode.md#operation-op-in-modtuprngelt-codeadd)
    - [`u notin C: ModTupRngElt, CodeAdd → BoolElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/subcode.md#operation-op-notin-modtuprngelt-codeadd)
    - [`C subset D: Code, Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/subcode.md#operation-op-subset-code-code)
    - [`C notsubset D: Code, Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/subcode.md#operation-operation-notsubset-code-code-boolelt)
    - [`C eq D: Code, Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/subcode.md#operation-op-eq-code-code)
    - [`C ne D: Code, Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/subcode.md#operation-op-ne-code-code)
- [Properties of Codes](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/Boolean.md)
  - [`IsSelfDual(C): Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/Boolean.md#function-isselfdual-code)
  - [`IsSelfOrthogonal(C): Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/Boolean.md#function-isselforthogonal-code)
  - [`IsPerfect(C): Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/Boolean.md#function-isperfect-code)
  - [`IsProjective(C): Code → BoolElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/Boolean.md#function-isprojective-code)
  - [`IsAdditiveProjective(C): CodeAdd → BoolElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/Boolean.md#function-isadditiveprojective-codeadd)
- [The Weight Distribution](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/structural.md)
  - [The Minimum Weight](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/structural.md#the-minimum-weight)
    - [`MinimumWeight(C: parameters): CodeAdd → RngIntElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/structural.md#function-minimumweight-codeadd)
    - [`MinimumDistance(C: parameters): CodeAdd → RngIntElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/structural.md#function-minimumdistance-codeadd)
    - [Example: Minimum Weight of an Additive Code](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/structural.md#example-ex-1dafbe)
  - [The Weight Distribution](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/structural.md#id1)
    - [`WeightDistribution(C): CodeAdd → [ <RngIntElt, RngIntElt> ]`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/structural.md#function-weightdistribution-codeadd)
    - [`DualWeightDistribution(C): CodeAdd → [ <RngIntElt, RngIntElt> ]`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/structural.md#function-dualweightdistribution-codeadd)
  - [The Weight Enumerator](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/structural.md#the-weight-enumerator)
    - [`WeightEnumerator(C): CodeAdd → RngMPolElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/structural.md#function-weightenumerator-codeadd)
    - [`CompleteWeightEnumerator(C): CodeAdd → RngMPolElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/structural.md#function-completeweightenumerator-codeadd)
    - [`CompleteWeightEnumerator(C, u): Code, ModTupFldElt → RngMPolElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/structural.md#function-completeweightenumerator-code-modtupfldelt)
  - [The MacWilliams Transform](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/structural.md#the-macwilliams-transform)
    - [`MacWilliamsTransform(n, k, q, W): RngIntElt, RngIntElt, RngIntElt, [ <RngIntElt, RngIntElt> ] → [ <RngIntElt, RngIntElt> ]`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/structural.md#function-macwilliamstransform-rngintelt-rngintelt-rngintelt-rngintelt-rngintelt)
  - [Words](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/structural.md#words)
    - [`Words(C, w: parameters): Code, RngIntElt → { ModTupFldElt }`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/structural.md#function-words-code-rngintelt)
    - [`NumberOfWords(C, w): Code, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/structural.md#function-numberofwords-code-rngintelt)
    - [`WordsOfBoundedWeight(C, l, u: parameters): Code, RngIntElt, RngIntElt → { ModTupFldElt }`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/structural.md#function-wordsofboundedweight-code-rngintelt-rngintelt)
- [Families of Linear Codes](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/families.md)
  - [Cyclic Codes](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/families.md#cyclic-codes)
    - [`AdditiveCyclicCode(v): ModTupFldElt → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/families.md#function-additivecycliccode-modtupfldelt)
    - [`AdditiveCyclicCode(K, v): FldFin, ModTupFldElt → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/families.md#function-additivecycliccode-fldfin-modtupfldelt)
    - [`AdditiveCyclicCode(Q): [ModTupFldElt] → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/families.md#function-additivecycliccode-modtupfldelt-2)
    - [`AdditiveCyclicCode(K, Q): FldFin, [ModTupFldElt] → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/families.md#function-additivecycliccode-fldfin-modtupfldelt-2)
    - [`AdditiveCyclicCode(n, f): RngIntElt, RngUPolElt → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/families.md#function-additivecycliccode-rngintelt-rngupolelt)
    - [`AdditiveCyclicCode(K, n, f): FldFin, RngIntElt, RngUPolElt → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/families.md#function-additivecycliccode-fldfin-rngintelt-rngupolelt)
    - [`AdditiveCyclicCode(n, Q): RngIntElt, [RngUPolElt] → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/families.md#function-additivecycliccode-rngintelt-rngupolelt-2)
    - [`AdditiveCyclicCode(K, n, Q): FldFin, RngIntElt, [RngUPolElt] → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/families.md#function-additivecycliccode-fldfin-rngintelt-rngupolelt-2)
    - [`AdditiveCyclicCode(v4, v2): ModTupFldElt, ModTupFldElt → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/families.md#function-additivecycliccode-modtupfldelt-modtupfldelt)
    - [`AdditiveCyclicCode(n, f4, f2): RngIntElt, RngUPolElt, RngUPolElt → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/families.md#function-additivecycliccode-rngintelt-rngupolelt-rngupolelt)
  - [Quasicyclic Codes](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/families.md#quasicyclic-codes)
    - [`AdditiveQuasiCyclicCode(n, Q): RngIntElt, SeqEnum[RngUPolElt] → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/families.md#function-additivequasicycliccode-rngintelt-seqenum-rngupolelt)
    - [`AdditiveQuasiCyclicCode(K, n, Q): FldFin, RngIntElt, SeqEnum[RngUPolElt] → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/families.md#function-additivequasicycliccode-fldfin-rngintelt-seqenum-rngupolelt)
    - [`AdditiveQuasiCyclicCode(n, Q, h): RngIntElt, SeqEnum[RngUPolElt], RngIntElt → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/families.md#function-additivequasicycliccode-rngintelt-seqenum-rngupolelt-rngintelt)
    - [`AdditiveQuasiCyclicCode(K, n, Q, h): FldFin, RngIntElt, SeqEnum[RngUPolElt], RngIntElt → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/families.md#function-additivequasicycliccode-fldfin-rngintelt-seqenum-rngupolelt-rngintelt)
    - [`AdditiveQuasiCyclicCode(Q): SeqEnum[ModTupFldElt] → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/families.md#function-additivequasicycliccode-seqenum-modtupfldelt)
    - [`AdditiveQuasiCyclicCode(K, Q): FldFin, SeqEnum[ModTupFldElt] → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/families.md#function-additivequasicycliccode-fldfin-seqenum-modtupfldelt)
    - [`AdditiveQuasiCyclicCode(Q, h): SeqEnum[ModTupFldElt], RngIntElt → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/families.md#function-additivequasicycliccode-seqenum-modtupfldelt-rngintelt)
    - [`AdditiveQuasiCyclicCode(K, Q, h): FldFin, SeqEnum[ModTupFldElt], RngIntElt → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/families.md#function-additivequasicycliccode-fldfin-seqenum-modtupfldelt-rngintelt)
- [New Codes from Old](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/operation.md)
  - [Standard Constructions](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/operation.md#standard-constructions)
    - [`AugmentCode(C): CodeAdd → Code`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/operation.md#function-augmentcode-codeadd)
    - [`CodeComplement(C, S): Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/operation.md#function-codecomplement-code-code)
    - [`DirectSum(C, D): Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/operation.md#function-directsum-code-code)
    - [`DirectSum(Q): [Code] → Code`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/operation.md#function-directsum-code)
    - [`DirectProduct(C, D): Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/operation.md#function-directproduct-code-code)
    - [`ExtendCode(C): CodeAdd → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/operation.md#function-extendcode-codeadd)
    - [`ExtendCode(C, n): Code, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/operation.md#function-extendcode-code-rngintelt)
    - [`PadCode(C, n): CodeAdd, RngIntElt → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/operation.md#function-padcode-codeadd-rngintelt)
    - [`PlotkinSum(C1, C2): Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/operation.md#function-plotkinsum-code-code)
    - [`PlotkinSum(C1, C2, C3: parameters): Code, Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/operation.md#function-plotkinsum-code-code-code)
    - [`PunctureCode(C, i): CodeAdd, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/operation.md#function-puncturecode-codeadd-rngintelt)
    - [`PunctureCode(C, S): CodeAdd, { RngIntElt } → Code`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/operation.md#function-puncturecode-codeadd-rngintelt-2)
    - [`ShortenCode(C, i): Code, RngIntElt → Code`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/operation.md#function-shortencode-code-rngintelt)
    - [`ShortenCode(C, S): Code, { RngIntElt } → Code`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/operation.md#function-shortencode-code-rngintelt-2)
  - [Combining Codes](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/operation.md#combining-codes)
    - [`C1 cat C2: CodeAdd, CodeAdd → CodeAdd`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/operation.md#operation-operation-cat-codeadd-codeadd-codeadd)
    - [`Juxtaposition(C1, C2): Code, Code → Code`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/operation.md#function-juxtaposition-code-code)
- [Automorphism Group](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/additive-automorphisms.md)
  - [`AutomorphismGroup(C): CodeAdd → GrpPerm`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/additive-automorphisms.md#function-automorphismgroup-codeadd)
  - [`PermutationGroup(C): CodeAdd → GrpPerm`](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/additive-automorphisms.md#function-permutationgroup-codeadd)

### Introduction

The concept of linear codes over a finite field (see Chapter [Linear Codes over Finite Fields](https://docs.magma-maths.org/CodingTheory/LinearCodes/index-linear-codes.md#chap-codefld)) can be generalized to the notion of an *additive* code. Given a finite field $F$ and the space of all $n$-tuples of $F$, an additive code is a subset of $F^{(n)}$ which is a $K$-linear subspace for some subfield $K \subseteq F$.

Additive codes have become increasingly important recently due to their application to the construction of quantum error-correcting codes, though they are also of interest in their own right. A Magma package for quantum error-correcting codes is built on the machinery for additive codes.

In Magma an additive code has both an *alphabet* $F$ and a *coefficient field* $K$, which is a subfield of $F$. An error-correcting code is considered to be defined by its wordset, so there may be several different ways of presenting a given code using different coefficient fields.

Since a given code may be presented over different coefficient rings, the *dimension* $k$ of an additive code is defined relative to the alphabet of the code, $\#C = (\#F)^k$, leading to the possibility of *fractional* dimensions. Consequently, the number of generators of an additive code will not equal its dimension, there being $[F:K]$ times as many generators. So a length $n$ $K$-additive code over $F$ has between zero and $n*[F:K]$ generators.

For example, consider the two length $3$ vectors over $F_4$: $(1,0,\omega^2),(0,\omega,0)$. The linear code generated by these vectors consists of all scalar multiples and sums, resulting in a total of $4^2 = 16$ vectors. But the $F_2$-additive code generated by these two vectors contains *only their sums*, resulting in a total of $2^2 = 4$ vectors. These vectors are $(0,0,0),(1,0,\omega^2),(0,\omega,0),(1,\omega,\omega^2)$. The alphabet of this code is $F_4$, its coefficient field is $F_2$, it has $2$ generators and is of dimension $1$.

A length $n$, dimension $k$ $K$-additive code over $F$ with $k_g$ generators is represented in Magma as an $[n, k\,:\,k_g]$ $K$-additive code over $F$. The concepts of weight, distance and their respective distributions and enumerators transfer directly from linear codes. An $[n, k\,:\,k_g, d]$ $K$-additive code over $F$ is a $K$-linear subset of $F^{(n)}$ which has fractional dimension $k$, $k_g$ generators, and a minimum weight of $d$.

As a general rule, additive and linear codes may be used interchangeably. Indeed any linear code can be expressed as an additive code, using either its alphabet or any subfield as its coefficient field. So any linear code over a finite field, of type `CodeLinFld`, is in fact also an additive code, of type `CodeAdd`. The theory of purely linear codes is more general than that of additive codes so unfortunately not all operations are transferable.

### Construction of Additive Codes

#### Construction of General Additive Codes

<a id="constructor-constructor-additivecode-fldfin-rngintelt-list-code"></a>
##### `AdditiveCode<F, K, n | L>: FldFin, RngIntElt, List -> Code`

Create the $K$-additive code in $F^{(n)}$ of length $n$ which is generated by the elements specified by the list $L$, where $K$ is a subfield of $F$ and $L$ is one or more items of the following types:

**(a)**
An element of $F^{(n)}$;

**(b)**
A set or sequence of elements of $F^{(n)}$;

**(c)**
A sequence of $n$ elements of $F$, defining an element of $F^{(n)}$;

**(d)**
A set or sequence of sequences of type (c);

**(e)**
A subcode of $F^{(n)}$;

<a id="function-additivecode-modmatrngelt"></a>
##### `AdditiveCode(G): ModMatRngElt -> CodeAdd`

<a id="function-additivecode-fldfin-modmatrngelt"></a>
##### `AdditiveCode(K, G): FldFin, ModMatRngElt -> CodeAdd`

Given a matrix $G$ over a field $F$ and a subfield $K$ of $F$, return the $K$-additive code over $F$ generated by the rows of $G$. If no coefficient field $K$ is specified, then the prime field of $F$ is used.

<a id="example-ex-f9cba7"></a>
##### `Example: Linear and Additive Codes Compared (ex-f9cba7)`

Starting with two linearly independent vectors in ${\mathbb{F}}_4^{(3)}$, we compare the linear code over $F_4$ they generate with the corresponding $F_2$-additive code.

```magma
> F<w> := GF(4);
> G := Matrix(F, 2, 3, [1,0,w^2,0,w,0]);
> G;
[  1   0 w^2]
[  0   w   0]
> C1 := LinearCode(G);
> C2 := AdditiveCode(GF(2), G);
> #C1;
16
> #C2;
4
> C2 subset C1;
true
```

The codewords of $C_2$ are arise only through addition of the generators: scalar multiplication is not permitted.

```magma
> { v : v in C2 };
{
    (  1   w w^2),
    (  0   0   0),
    (  1   0 w^2),
    (  0   w   0)
}
```

<a id="example-ex-9d93b8"></a>
##### `Example: Additive Code from a Matrix (ex-9d93b8)`

We define an ${\bf F}_{2}$-additive code over ${\bf F}_{8}$ by constructing a random matrix and considering the code generated by its rows. Note that the number of generators exceeds the length of the code.

```magma
> K<w> := GF(8);
> M := KMatrixSpace(K, 5, 4);
> C := AdditiveCode(GF(2), Random(M));
> C;
[4, 1 2/3 : 5] GF(2)-Additive Code over GF(2^3)
Generator matrix:
[  1   1 w^2   0]
[  w w^2   w   1]
[w^2 w^2 w^2   1]
[  0 w^4 w^4 w^5]
[  0   0   1   0]
> WeightDistribution(C);
[ <0, 1>, <1, 1>, <2, 2>, <3, 9>, <4, 19> ]
> C;
[4, 1 2/3 : 5, 1] GF(2)-Additive Code over GF(2^3)
Generator matrix:
[  1   1 w^2   0]
[  w w^2   w   1]
[w^2 w^2 w^2   1]
[  0 w^4 w^4 w^5]
[  0   0   1   0]
```

<a id="function-additivecode-fldfin-code"></a>
##### `AdditiveCode(K, C): FldFin, Code -> CodeAdd`

Given a code (linear or additive) $C$ over some finite field $F$, and a subfield $K$ of $F$ such that the wordset of $C$ forms a $K$-linear subspace, then return $C$ as a $K$-additive code.

<a id="example-ex-8b74a8"></a>
##### `Example: Additive Code from a Linear Code (ex-8b74a8)`

Any linear code can be regarded as an additive code with respect to a subfield of its alphabet.

```magma
> C := RandomLinearCode(GF(4), 8, 3);
> C:Minimal;
[8, 3, 4] Linear Code over GF(2^2)
> A1 := AdditiveCode(GF(4), C);
> A1:Minimal;
[8, 3 : 3, 4] GF(2^2)-Additive Code over GF(2^2)
> { v : v in C } eq {v : v in A1 };
true
>
> A2 := AdditiveCode(GF(2), C);
> A2:Minimal;
[8, 3 : 6, 4] GF(2)-Additive Code over GF(2^2)
> { v : v in C } eq {v : v in A2 };
true
```

<a id="example-ex-770cac"></a>
##### `Example: Viewing an Additive Code over a Subfield (ex-770cac)`

A $K$-additive code over $F$ can be viewed as an $E$-additive code for any subfield $E \subseteq K$.

```magma
> C4 := RandomAdditiveCode(GF(16), GF(4), 8, 5);
> C4:Minimal;
[8, 2 1/2 : 5] GF(2^2)-Additive Code over GF(2^4)
>
> C2 := AdditiveCode(GF(2), C4);
> C2:Minimal;
[8, 2 1/2 : 10] GF(2)-Additive Code over GF(2^4)
> { v : v in C2 } eq {v : v in C4 };
true
```

But for any $E$ such that $K \subset E \subseteq F$ we can create an $E$-additive code if and only if the wordset is in fact an $E$-linear subspace.

```magma
> C2:Minimal;
[8, 2 1/2 : 10] GF(2)-Additive Code over GF(2^4)
> A1 := AdditiveCode(GF(4), C2);
> A1 eq C4;
true
> A2 := AdditiveCode(GF(16), C2);

>> A2 := AdditiveCode(GF(16), C2);
                     ^
Runtime error in 'AdditiveCode': Code is not additive over given field
```

#### Some Trivial Additive Codes

<a id="function-additivezerocode-fldfin-fldfin-rngintelt"></a>
##### `AdditiveZeroCode(F, K, n): FldFin, FldFin, RngIntElt -> CodeAdd`

Given a field $F$ and subfield $K \subseteq F$ along with a positive integer $n$, return the $[n,0,n]$ code consisting of only the zero code word, (where the minimum weight is by convention equal to $n$).

<a id="function-additiverepetitioncode-fldfin-fldfin-rngintelt"></a>
##### `AdditiveRepetitionCode(F, K, n): FldFin, FldFin, RngIntElt -> Code`

Given a field $F$ and subfield $K \subseteq F$ along with a positive integer $n$, return the $[n,1,n]$ code consisting of all repeating codewords.

<a id="function-additivezerosumcode-fldfin-fldfin-rngintelt"></a>
##### `AdditiveZeroSumCode(F, K, n): FldFin, FldFin, RngIntElt -> Code`

Given a field $F$ and subfield $K \subseteq F$ along with a positive integer $n$, return the $[n,n-1,2]$ $K$-additive code over $F$ such that for all codewords $(c_1,c_2,\ldots ,c_n)$, we have $\sum_{i} c_i =0$.

<a id="function-additiveuniversecode-fldfin-fldfin-rngintelt"></a>
##### `AdditiveUniverseCode(F, K, n): FldFin, FldFin, RngIntElt -> Code`

Given a field $F$ and subfield $K \subseteq F$ along with a positive integer $n$, return the $[n,n,1]$ $K$-additive code over $F$ consisting of all possible codewords.

<a id="function-randomadditivecode-fldfin-fldfin-rngintelt-rngintelt"></a>
##### `RandomAdditiveCode(F, K, n, k): FldFin, FldFin, RngIntElt, RngIntElt -> Code`

Given a field $F$ and subfield $K \subseteq F$ along with positive integers $n$ and $k$, such that $0 < k \le n*[F:K]$, and $k$, return a random $K$-additive code of length $n$ and $k$ generators over the field $F$.

<a id="example-ex-24f23c"></a>
##### `Example: Chain of Trivial Additive Codes (ex-24f23c)`

Over any finite field chain $K \subseteq F$, the zero code of length $n$ is contained in every code of length $n$, and similarly every code of length $n$ is contained in the universe code of length $n$.

```magma
> F := GF(9);
> K := GF(3);
> U := AdditiveUniverseCode(F, K, 5);
> Z := AdditiveZeroCode(F, K, 5);
> R := RandomAdditiveCode(F, K, 5, 2);
> (Z subset R) and (R subset U);
true
```

### Invariants of an Additive Code

#### The Ambient Space and Alphabet

A length $n$ additive code has an alphabet $F$ and coefficient field $K \subseteq F$. The code consists of codewords which are a $K$-linear subspace of $F^{(n)}$.

<a id="function-alphabet-code"></a>
##### `Alphabet(C): Code -> Rng`

<a id="function-field-code"></a>
##### `Field(C): Code -> Rng`

The underlying field (or alphabet) of the codewords of the additive code $C$. A length $n$ additive code with alphabet $F$ consists of codewords from $F^{(n)}$.

<a id="function-coefficientfield-code"></a>
##### `CoefficientField(C): Code -> Rng`

The field over which the codewords of the additive code $C$ are considered linear. This will be a subfield of the alphabet of $C$.

<a id="function-ambientspace-code"></a>
##### `AmbientSpace(C): Code -> ModTupRng`

The ambient space of the additive code $C$, i.e. the generic $R$-space $V$ in which $C$ is contained.

<a id="function-generic-code"></a>
##### `Generic(C): Code -> Code`

Given a length $n$ additive code $C$, return the generic $[n, n, 1]$ code in which $C$ is contained.

<a id="example-ex-b0a75c"></a>
##### `Example: Alphabet and Coefficient Field (ex-b0a75c)`

A code can often be represented using several different coefficient fields.

```magma
> F<w> := GF(5,4);
> K := GF(5,2);
> C := RandomAdditiveCode(F, K, 12, 5);
> C:Minimal;
[12, 2 1/2 : 5] GF(5^2)-Additive Code over GF(5^4)
> #C;
9765625
> Alphabet(C);
Finite field of size 5^4
> CoefficientField(C);
Finite field of size 5^2
>
> C1 := AdditiveCode(GF(5), C);
> C1:Minimal;
[12, 2 1/2 : 10] GF(5)-Additive Code over GF(5^4)
> #C1;
9765625
> Alphabet(C1);
Finite field of size 5^4
> CoefficientField(C1);
Finite field of size 5
```

#### Basic Numerical Invariants

<a id="function-length-code"></a>
##### `Length(C): Code -> RngIntElt`

Return the block length $n$ of an additive code $C$.

<a id="function-dimension-code"></a>
##### `Dimension(C): Code -> FldRatElt`

The (rational) dimension $k$ of $C$. If the alphabet of $C$ is $F$, then the dimension is defined by the equation $\#C = (\#F)^k$.

Note that since any basis of the additive code $C$ is relative to the coefficient field $K$, this dimension is not necessarily equal to the number of generators of $C$ and is not even necessarily integral.

<a id="function-numberofgenerators-code"></a>
##### `NumberOfGenerators(C): Code -> RngIntElt`

<a id="function-ngens-code"></a>
##### `Ngens(C): Code -> RngIntElt`

The number of generators of the additive code $C$. Note that if the coefficient ring of $C$ is not the same as its alphabet then this will be different from the dimension of $C$.

<a id="operation-operation-code-rngintelt"></a>
##### `# C: Code -> RngIntElt`

Given an additive code $C$, return the number of codewords belonging to $C$.

<a id="function-informationrate-code"></a>
##### `InformationRate(C): Code -> FldPrElt`

The information rate of the $[n, k]$ code $C$. This is the ratio $k/n$.

#### The Code Space

<a id="function-generatormatrix-code"></a>
##### `GeneratorMatrix(C): Code -> ModMatFldElt`

<a id="function-basismatrix-code"></a>
##### `BasisMatrix(C): Code -> ModMatRngElt`

The generator matrix for an $[n, k(k_g)]$ $K$-additive code $C$ over $F$ is a $k_g \times n$ matrix over $F$, whose $k_g$ rows form a basis for $C$ when considered as vectors over $K$.

<a id="function-basis-code"></a>
##### `Basis(C): Code -> [ ModTupRngElt ]`

<a id="function-generators-code"></a>
##### `Generators(C): Code -> { ModTupFldElt }`

A basis for the $K$-additive code $C$, returned as a sequence of codewords over the alphabet of $C$, which generate the code over $K$.

<a id="operation-operation-code-rngintelt-modtupfldelt"></a>
##### `C . i: Code, RngIntElt -> ModTupFldElt`

Given an $[n, k(k_g)]$ $K$-additive code $C$ and a positive integer $i$, $1 \le i \le k_g$, return the $i$-th element of the current basis of $C$ over $K$.

#### The Dual Space

<a id="function-dual-codeadd"></a>
##### `Dual(C): CodeAdd -> CodeAdd`

The code that is dual to the code $C$. For an additive code $C$, this is the nullspace with respect to the trace inner product of the coefficient field.

<a id="function-paritycheckmatrix-code"></a>
##### `ParityCheckMatrix(C): Code -> ModMatFldElt`

The parity check matrix for the code $C$, returned as an element of ${\operatorname{Hom}}(V, U)$.

### Operations on Codewords

#### Construction of a Codeword

<a id="operation-op-code-rngelt"></a>
##### `C ! [a₁, ..., aₙ]: Code, [ RngElt ] -> ModTupRngElt`

<a id="constructor-constructor-elt-code-list-modtuprngelt"></a>
##### `elt< C | a₁, ..., aₙ>: Code, List -> ModTupRngElt`

Given a length $n$ additive code $C$ with alphabet $F$, then the codewords of $C$ lie in $F^{(n)}$. Given elements $a_1, \ldots, a_n$ belonging to $F$, construct the codeword $(a_1, \ldots, a_n)$ of $C$. A check is made that the vector ($a_1, \ldots, a_n$) is an element of $C$.

<a id="operation-op-code-modtuprngelt"></a>
##### `C ! u: Code, ModTupRngElt -> ModTupRngElt`

Given an additive code $C$ which is defined as a subset of the $F$-space $V = F^{(n)}$, and an element $u$ belonging to $V$, create the codeword of $C$ corresponding to $u$. The function will fail if $u$ does not belong to $C$.

<a id="operation-op-code-rngintelt"></a>
##### `C ! 0: Code, RngIntElt -> ModTupRngElt`

The zero word of the additive code $C$.

<a id="function-random-code"></a>
##### `Random(C): Code -> ModTupRngElt`

A random codeword of the additive code $C$.

#### Arithmetic Operations on Codewords

<a id="operation-op-plus-modtuprngelt-modtuprngelt"></a>
##### `u + v: ModTupRngElt, ModTupRngElt -> ModTupRngElt`

Sum of the codewords $u$ and $v$, where $u$ and $v$ belong to the same linear code $C$.

<a id="operation-operation-modtuprngelt-modtuprngelt"></a>
##### `- u: ModTupRngElt -> ModTupRngElt`

Additive inverse of the codeword $u$ belonging to the linear code $C$.

<a id="operation-op-minus-modtuprngelt-modtuprngelt"></a>
##### `u - v: ModTupRngElt, ModTupRngElt -> ModTupRngElt`

Difference of the codewords $u$ and $v$, where $u$ and $v$ belong to the same linear code $C$.

<a id="operation-op-times-rngelt-modtuprngelt"></a>
##### `a * u: RngElt, ModTupRngElt -> ModTupRngElt`

Given an element $a$ belonging to the alphabet $F$, and a codeword $u$ belonging to the additive code $C$, return the codeword $a*u$.

<a id="function-normalize-modtuprngelt"></a>
##### `Normalize(u): ModTupRngElt -> ModTupRngElt`

Normalize a codeword $u$ of an additive code $C$, returning a scalar multiple of $u$ such that its first non-zero entry is $1$.

#### Distance and Weight

<a id="function-distance-modtuprngelt-modtuprngelt"></a>
##### `Distance(u, v): ModTupRngElt, ModTupRngElt -> RngIntElt`

The Hamming distance between the codewords $u$ and $v$, where $u$ and $v$ belong to the same additive code $C$.

<a id="function-weight-modtuprngelt"></a>
##### `Weight(u): ModTupRngElt -> RngIntElt`

The Hamming weight of the codeword $u$, i.e., the number of non-zero components of $u$.

#### Vector Space and Related Operations

<a id="literal-literal-u-v-modtuprngelt-modtuprngelt-rngelt"></a>
##### `(u, v): ModTupRngElt, ModTupRngElt -> RngElt`

<a id="function-innerproduct-modtuprngelt-modtuprngelt"></a>
##### `InnerProduct(u, v): ModTupRngElt, ModTupRngElt -> RngElt`

Inner product of the vectors $u$ and $v$ with respect to the Euclidean norm, where $u$ and $v$ belong to the parent vector space of the code $C$.

<a id="function-traceinnerproduct-fldfin-modtupfldelt-modtupfldelt"></a>
##### `TraceInnerProduct(K, u, v): FldFin, ModTupFldElt, ModTupFldElt -> FldFinElt`

Given vectors $u$ and $v$ defined over a finite field $L$ and a subfield $K$ of $L$, this function returns the trace of the inner product of the vectors $u$ and $v$ with respect to $K$.

<a id="function-support-modtuprngelt"></a>
##### `Support(w): ModTupRngElt -> { RngIntElt }`

Given a word $w$ belonging to the $[n, k]$ code $C$, return its support as a subset of the integer set $\{ 1 .. n \}$. The support of $w$ consists of the coordinates at which $w$ has non-zero entries.

<a id="function-coordinates-code-modtuprngelt"></a>
##### `Coordinates(C, u): Code, ModTupRngElt -> [ RngFinElt ]`

Given an $[n, k\, :\,k_g]$ $K$-additive code $C$ and a codeword $u$ of $C$ return the coordinates of $u$ with respect to the current basis of $C$. The coordinates of $u$ are returned as a sequence $Q = [a_1, \ldots, a_{k_g}]$ of elements from $K$ such that $u = a_1 * C.1 + \ldots + a_{k_g} * C.{k_g}$.

<a id="function-parent-modtuprngelt"></a>
##### `Parent(w): ModTupRngElt -> ModTupRng`

Given a word $w$ belonging to the code $C$, return the ambient space $V$ of $C$.

<a id="function-rotate-modtuprngelt-rngintelt"></a>
##### `Rotate(u, k): ModTupRngElt, RngIntElt -> ModTupRngElt`

Given a vector $u$, return the vector obtained from $u$ by cyclically shifting its components to the right by $k$ coordinate positions.

<a id="procedure-rotate-modtuprngelt-rngintelt-ref"></a>
##### `Rotate(~u, k): ModTupRngElt, RngIntElt`

Given a vector $u$, destructively rotate $u$ by $k$ coordinate positions.

<a id="function-trace-modtupfldelt-fldfin"></a>
##### `Trace(u, S): ModTupFldElt, FldFin -> ModTupFldElt`

<a id="function-trace-modtupfldelt"></a>
##### `Trace(u): ModTupFldElt -> ModTupFldElt`

Given a vector $u$ with components in $K$, and a subfield $S$ of $K$, construct the vector with components in $S$ obtained from $u$ by taking the trace of each component with respect to $S$. If $S$ is omitted, it is taken to be the prime field of $K$.

#### Predicates for Codewords

<a id="operation-op-eq-modtuprngelt-modtuprngelt"></a>
##### `u eq v: ModTupRngElt, ModTupRngElt -> BoolElt`

The function returns `true` if and only if the codewords $u$ and $v$ belonging to the same additive code are equal.

<a id="operation-op-ne-modtuprngelt-modtuprngelt"></a>
##### `u ne v: ModTupRngElt, ModTupRngElt -> BoolElt`

The function returns `true` if and only if the codewords $u$ and $v$ belonging to the same additive code are not equal.

<a id="function-iszero-modtuprngelt"></a>
##### `IsZero(u): ModTupRngElt -> BoolElt`

The function returns `true` if and only if the codeword $u$ is the zero vector.

#### Accessing Components of a Codeword

<a id="literal-literal-u-i-modtuprngelt-rngintelt-rngelt"></a>
##### `u[i]: ModTupRngElt, RngIntElt -> RngElt`

Given a codeword $u$ belonging to the code $C$ defined over the ring $R$, return the $i$-th component of $u$ (as an element of $R$).

<a id="literal-literal-u-i-x"></a>
##### `u[i] := x;`

Given an element $u$ belonging to a subcode $C$ of the full $R$-space $V = R^n$, a positive integer $i$, $1 \leq i\leq n$, and an element $x$ of $R$, this function returns a vector in $V$ which is $u$ with its $i$-th component redefined to be $x$.

### Subcodes

#### The Subcode Constructor

<a id="constructor-constructor-sub-codeadd-list-codeadd"></a>
##### `sub<C | L>: CodeAdd, List -> CodeAdd`

Given a $K$-additive linear code $C$ over $F$, construct the subcode of $C$, generated (over $K$) by the elements specified by the list $L$, where $L$ is a list of one or more items of the following types:

**(a)**
An element of $C$;

**(b)**
A set or sequence of elements of $C$;

**(c)**
A sequence of $n$ elements of $F$, defining an element of $C$;

**(d)**
A set or sequence of sequences of type (c);

**(e)**
A subcode of $C$;

<a id="function-subcode-codeadd-rngintelt"></a>
##### `Subcode(C, k): CodeAdd, RngIntElt -> CodeAdd`

Given an additive code $C$ and an integer $k$, where $k$ is less than the number of generators of $C$, then return a subcode of $C$ with $k$ generators.

<a id="function-subcode-codeadd-rngintelt-2"></a>
##### `Subcode(C, S): CodeAdd, { RngIntElt } -> Code`

Suppose $C$ is an additive code and $S$ is a set of positive integers, each of which is less than the number of generators of $C$. The function returns the subcode of $C$ generated by the generators of $C$ indexed by $S$.

<a id="function-subcodebetweencode-codeadd-codeadd-rngintelt"></a>
##### `SubcodeBetweenCode(C1, C2, k): CodeAdd, CodeAdd, RngIntElt -> CodeAdd`

Given an additive code $C_1$ and a subcode $C_2$ of $C_1$, return a subcode of $C_1$ with $k$ generators containing $C_2$.

<a id="function-subcodewordsofweight-codeadd-rngintelt"></a>
##### `SubcodeWordsOfWeight(C, w): CodeAdd, RngIntElt -> CodeAdd`

Given a length $n$ additive code $C$ and an integer which lies in the range $[1,n]$, return the subcode of $C$ generated by those words of $C$ of weight $w$.

<a id="function-subcodewordsofweight-codeadd-rngintelt-2"></a>
##### `SubcodeWordsOfWeight(C, S): CodeAdd, { RngIntElt } -> CodeAdd`

Given a length $n$ additive code $C$ and a set $S$ of integers, each of which lies in the range $[1,n]$, return the subcode of $C$ generated by those words of $C$ whose weights lie in $S$.

<a id="example-ex-18722c"></a>
##### `Example: Subcode between Two Codes (ex-18722c)`

We give an example of how `SubcodeBetweenCode` may be used to create a code nested in between a subcode pair.

```magma
> F<w> := GF(8);
> C1 := AdditiveRepetitionCode(F, GF(2), 6);
> C1;
[6, 1 : 3, 6] GF(2)-Additive Code over GF(2^3)
Generator matrix:
[  1   1   1   1   1   1]
[  w   w   w   w   w   w]
[w^2 w^2 w^2 w^2 w^2 w^2]
> C3 := AdditiveZeroSumCode(F, GF(2), 6);
> C3;
[6, 5 : 15, 2] GF(2)-Additive Code over GF(2^3)
Generator matrix:
[  1   0   0   0   0   1]
[  w   0   0   0   0   w]
[w^2   0   0   0   0 w^2]
[  0   1   0   0   0   1]
[  0   w   0   0   0   w]
[  0 w^2   0   0   0 w^2]
[  0   0   1   0   0   1]
[  0   0   w   0   0   w]
[  0   0 w^2   0   0 w^2]
[  0   0   0   1   0   1]
[  0   0   0   w   0   w]
[  0   0   0 w^2   0 w^2]
[  0   0   0   0   1   1]
[  0   0   0   0   w   w]
[  0   0   0   0 w^2 w^2]
> C1 subset C3;
true
> C2 := SubcodeBetweenCode(C3, C1, 11);
> C2;
[6, 3 2/3 : 11] GF(2)-Additive Code over GF(2^3)
Generator matrix:
[  1   0   0   0   1   0]
[  w   0   0   0   w   0]
[w^2   0   0 w^2 w^2 w^2]
[  0   1   0   0   0   1]
[  0   w   0   0   0   w]
[  0 w^2   0   0   0 w^2]
[  0   0   1   0   0   1]
[  0   0   w   0   0   w]
[  0   0 w^2   0   0 w^2]
[  0   0   0   1   0   1]
[  0   0   0   w   0   w]
> (C1 subset C2) and (C2 subset C3);
true
```

#### Sum, Intersection, and Dual

For the following operators, $C$ and $D$ are additive codes defined as subsets (or subspaces) of the same $R$-space $F^n$.

<a id="operation-op-plus-codeadd-codeadd"></a>
##### `C + D: CodeAdd, CodeAdd -> CodeAdd`

Given two additive codes which have the same length, which are defined over the same alphabet, and which have the same coefficient ring $F$, return the sum of these two codes with respect to $F$.

<a id="operation-op-meet-code-code"></a>
##### `C meet D: Code, Code -> Code`

The intersection of the additive codes $C$ and $D$.

<a id="function-dual-code"></a>
##### `Dual(C): Code -> Code`

The code that is dual to the code $C$. For an additive code $C$, this is the code generated by the nullspace of $C$, relative to the trace inner product.

#### Membership and Equality

<a id="operation-op-in-modtuprngelt-codeadd"></a>
##### `u in C: ModTupRngElt, CodeAdd -> BoolElt`

Return `true` if and only if the vector $u$ of $V$ belongs to the additive code $C$, where $V$ is the generic vector space containing $C$.

<a id="operation-op-notin-modtuprngelt-codeadd"></a>
##### `u notin C: ModTupRngElt, CodeAdd -> BoolElt`

Return `true` if and only if the vector $u$ does not belong to the additive code $C$, where $V$ is the generic vector space containing $C$.

<a id="operation-op-subset-code-code"></a>
##### `C subset D: Code, Code -> BoolElt`

Return `true` if and only if the wordset of the code $C$ is a subset of the wordset of the code $D$. (Either code may possibly be additive).

<a id="operation-operation-notsubset-code-code-boolelt"></a>
##### `C notsubset D: Code, Code -> BoolElt`

Return `true` if and only if the wordset of the code $C$ is not a subset of the wordset of the code $D$. (Either code may possibly be additive).

<a id="operation-op-eq-code-code"></a>
##### `C eq D: Code, Code -> BoolElt`

Return `true` if and only if the codes $C$ and $D$ have the same wordsets. (Either code may possibly be additive).

<a id="operation-op-ne-code-code"></a>
##### `C ne D: Code, Code -> BoolElt`

Return `true` if and only if the codes $C$ and $D$ have different wordsets. (Either code may possibly be additive).

### Properties of Codes

For the following operators, $C$ and $D$ are codes defined as a subset (or subspace) of the vector space $V$.

<a id="function-isselfdual-code"></a>
#### `IsSelfDual(C): Code -> BoolElt`

Return `true` if and only if the linear code $C$ is self-dual (or self-orthogonal) (i.e. $C$ equals the dual of $C$).

<a id="function-isselforthogonal-code"></a>
#### `IsSelfOrthogonal(C): Code -> BoolElt`

Return `true` if and only if the linear code $C$ is self-orthogonal (i.e. $C$ is contained in the dual of $C$).

<a id="function-isperfect-code"></a>
#### `IsPerfect(C): Code -> BoolElt`

Return `true` if and only if the linear code $C$ is perfect; that is, if and only if the cardinality of $C$ is equal to the size of the sphere packing bound of $C$.

<a id="function-isprojective-code"></a>
#### `IsProjective(C): Code -> BoolElt`

Returns `true` if and only if the (non-quantum) code $C$ is projective over its alphabet.

<a id="function-isadditiveprojective-codeadd"></a>
#### `IsAdditiveProjective(C): CodeAdd -> BoolElt`

Returns `true` if and only if the additive code $C$ is projective over its coefficient field. It is possible that some of the columns may not be independent with respect to the alphabet of the code.

### The Weight Distribution

#### The Minimum Weight

An adaptation of the minimum weight algorithm for linear codes (see Section [The Minimum Weight](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#code-lin-minweight)) has been developed for additive codes by Markus Grassl and Greg White.

From a user’s perspective, the description given in [The Minimum Weight](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#code-lin-minweight) is sufficient to understand the additive case. The algorithm is still new, and has yet to be optimised to its full potential.

<a id="function-minimumweight-codeadd"></a>
##### `MinimumWeight(C: parameters): CodeAdd -> RngIntElt`

<a id="function-minimumdistance-codeadd"></a>
##### `MinimumDistance(C: parameters): CodeAdd -> RngIntElt`

```magma
RankLowerBound: RngIntElt                      Default: 0
MaximumTime   : RngReSubElt                    Default: Infinity()
```

Determine the minimum weight of the words belonging to the code $C$, which is also the minimum distance between any two codewords. The parameter `RankLowerBound` sets a minimum rank on the information sets used in the calculation, while the parameter `MaximumTime` sets a time limit (in seconds of “user time”) after which the calculation is aborted.

By setting the verbose flag `"Code"`, information about the progress of the computation can be printed. An example to demonstrate the interpretation of the verbose output follows:

```magma
> SetVerbose("Code", true);
> SetSeed(1);
> MinimumWeight(RandomAdditiveCode(GF(4),GF(2),82,39));
GF(2)-Additive code over GF(4) of length 82 with 39 generators.
Is not cyclic
Lower Bound: 1, Upper Bound: 64
Constructed 5 distinct generator matrices
Total Ranks:     21  20  20  20  20
Relative Ranks:  21  20  20  20   1
Starting search for low weight codewords... 0.020
     Discarding non-contributing rank 1 matrix
Enumerating using 1 generator at a time:
     New codeword identified of weight 48, time 0.020
     New codeword identified of weight 46, time 0.020
     New codeword identified of weight 44, time 0.020
     New codeword identified of weight 42, time 0.020
   Completed Matrix  1:  lower =  5, upper = 42. Time so far: 0.030
     New codeword identified of weight 41, time 0.030
   Completed Matrix  2:  lower =  6, upper = 41. Time so far: 0.030
   Completed Matrix  3:  lower =  7, upper = 41. Time so far: 0.040
     New codeword identified of weight 40, time 0.040
   Completed Matrix  4:  lower =  8, upper = 40. Time so far: 0.040
Enumerating using 2 generators at a time:
     New codeword identified of weight 37, time 0.050
   Completed Matrix  1:  lower =  9, upper = 37. Time so far: 0.050
   Completed Matrix  2:  lower = 10, upper = 37. Time so far: 0.050
   Completed Matrix  3:  lower = 11, upper = 37. Time so far: 0.060
     New codeword identified of weight 36, time 0.060
   Completed Matrix  4:  lower = 12, upper = 36. Time so far: 0.060
Enumerating using 3 generators at a time:
     New codeword identified of weight 34, time 0.070
   Completed Matrix  1:  lower = 13, upper = 34. Time so far: 0.070
     New codeword identified of weight 33, time 0.080
   Completed Matrix  2:  lower = 14, upper = 33. Time so far: 0.090
   Completed Matrix  3:  lower = 15, upper = 33. Time so far: 0.100
   Completed Matrix  4:  lower = 16, upper = 33. Time so far: 0.110
Enumerating using 4 generators at a time:
     New codeword identified of weight 32, time 0.120
   Completed Matrix  1:  lower = 17, upper = 32. Time so far: 0.170
   Completed Matrix  2:  lower = 18, upper = 32. Time so far: 0.250
   Completed Matrix  3:  lower = 19, upper = 32. Time so far: 0.320
   Completed Matrix  4:  lower = 20, upper = 32. Time so far: 0.390
Termination predicted with 7 generators at matrix 4
Enumerating using 5 generators at a time:
   Completed Matrix  1:  lower = 21, upper = 32. Time so far: 0.960
   Completed Matrix  2:  lower = 22, upper = 32. Time so far: 1.570
   Completed Matrix  3:  lower = 23, upper = 32. Time so far: 2.160
   Completed Matrix  4:  lower = 24, upper = 32. Time so far: 2.750
Termination predicted at 118 s (1 m 57 s) with 7 generators at matrix 4
Enumerating using 6 generators at a time:
   Completed Matrix  1:  lower = 25, upper = 32. Time so far: 6.680
   Completed Matrix  2:  lower = 26, upper = 32. Time so far: 10.969
   Completed Matrix  3:  lower = 27, upper = 32. Time so far: 15.149
   Completed Matrix  4:  lower = 28, upper = 32. Time so far: 19.440
Termination predicted at 114 s (1 m 54 s) with 7 generators at matrix 4
Enumerating using 7 generators at a time:
   Completed Matrix  1:  lower = 29, upper = 32. Time so far: 41.739
   Completed Matrix  2:  lower = 30, upper = 32. Time so far: 66.239
   Completed Matrix  3:  lower = 31, upper = 32. Time so far: 90.780
   Completed Matrix  4:  lower = 32, upper = 32. Time so far: 115.510
Final Results: lower = 32, upper = 32, Total time: 115.510
32
```

Verbose output can be invaluable in the case of lengthy minimum weight calculations.

The algorithm constructs different (equivalent) generator matrices, each of which has pivots in different column positions of the code, called its *information set*. The *relative rank* of a generator matrix is the size of its information set independent of the previously constructed matrices.

When enumerating all generators taken $r$ at a time, once $r$ exceeds the difference between the total rank of a matrix, and its relative rank, the lower bound on the minimum weight will be incremented by $1$ for that step.

The upper bound on the minimum weight is determined by the minimum weight of codewords that are enumerated. As soon as these bounds become equal, the computation is complete.

<a id="example-ex-1dafbe"></a>
##### `Example: Minimum Weight of an Additive Code (ex-1dafbe)`

We illustrate the much greater efficiency of the minimum weight algorithm compared to computing the full weight distribution.

```magma
> SetVerbose("Code",true);
> C := RandomAdditiveCode(GF(9),GF(3),39,25);
> MinimumWeight(C);
GF(3)-Additive code over GF(9) of length 39 with 25 generators. Is not cyclic
Lower Bound: 1, Upper Bound: 28
Constructed 4 distinct generator matrices
Total Ranks:     13  13  13  13
Relative Ranks:  13  13  12   1
Starting search for low weight codewords... 0.009
     Discarding non-contributing rank 1 matrix
Enumerating using 1 generator at a time:
     New codeword identified of weight 25, time 0.009
     New codeword identified of weight 23, time 0.009
     New codeword identified of weight 21, time 0.009
   Completed Matrix  1:  lower =  3, upper = 21. Time so far: 0.009
   Completed Matrix  2:  lower =  4, upper = 21. Time so far: 0.009
   Completed Matrix  3:  lower =  5, upper = 21. Time so far: 0.009
Enumerating using 2 generators at a time:
     New codeword identified of weight 20, time 0.009
     New codeword identified of weight 19, time 0.009
     New codeword identified of weight 18, time 0.009
   Completed Matrix  1:  lower =  6, upper = 18. Time so far: 0.009
   Completed Matrix  2:  lower =  7, upper = 18. Time so far: 0.019
   Completed Matrix  3:  lower =  8, upper = 18. Time so far: 0.019
Enumerating using 3 generators at a time:
     New codeword identified of weight 17, time 0.070
   Completed Matrix  1:  lower =  9, upper = 17. Time so far: 0.089
   Completed Matrix  2:  lower = 10, upper = 17. Time so far: 0.149
   Completed Matrix  3:  lower = 11, upper = 17. Time so far: 0.210
Enumerating using 4 generators at a time:
   Completed Matrix  1:  lower = 12, upper = 17. Time so far: 1.379
   Completed Matrix  2:  lower = 13, upper = 17. Time so far: 2.539
   Completed Matrix  3:  lower = 14, upper = 17. Time so far: 3.719
Termination predicted at 49 s with 5 generators at matrix 3
Enumerating using 5 generators at a time:
   Completed Matrix  1:  lower = 15, upper = 17. Time so far: 19.409
   Completed Matrix  2:  lower = 16, upper = 17. Time so far: 35.019
   Completed Matrix  3:  lower = 17, upper = 17. Time so far: 50.649
Final Results: lower = 17, upper = 17, Total time: 50.649
17
> time WeightDistribution(C);
[ <0, 1>, <17, 2>, <18, 58>, <19, 496>, <20, 4000>, <21, 29608>, <22, 194760>,
<23, 1146680>, <24, 6126884>, <25, 29400612>, <26, 126624092>, <27, 487889854>,
<28, 1672552654>, <29, 5075315756>, <30, 13534236754>, <31, 31434430104>, <32,
62869109200>, <33, 106686382216>, <34, 150616653852>, <35, 172132748756>, <36,
153007413552>, <37, 99247655566>, <38, 41788710876>, <39, 8571983110> ]
Time: 224142.820
```

<a id="id1"></a>
#### The Weight Distribution

<a id="function-weightdistribution-codeadd"></a>
##### `WeightDistribution(C): CodeAdd -> [ <RngIntElt, RngIntElt> ]`

This function determines the weight distribution for the code $C$. The distribution is returned in the form of a sequence of tuples, where the $i$-th tuple contains the $i$-th weight, $w_i$ say, and the number of codewords having weight $w_i$.

<a id="function-dualweightdistribution-codeadd"></a>
##### `DualWeightDistribution(C): CodeAdd -> [ <RngIntElt, RngIntElt> ]`

The weight distribution of the code which is dual to the additive code $C$ (see `WeightDistribution`).

#### The Weight Enumerator

<a id="function-weightenumerator-codeadd"></a>
##### `WeightEnumerator(C): CodeAdd -> RngMPolElt`

The (Hamming) weight enumerator $W_C(x, y)$ for the additive code $C$. The weight enumerator is defined by

$$
W_C(x, y) = \sum_{u \in C}{x^{n-wt(u)}y^{wt(u)}}.
$$

<a id="function-completeweightenumerator-codeadd"></a>
##### `CompleteWeightEnumerator(C): CodeAdd -> RngMPolElt`

The complete weight enumerator ${\cal W}_C(z_0, \ldots, z_{q-1})$ for the additive code $C$ where $q$ is the size of the alphabet $E$ of $C$. Let the $q$ elements of $E$ be denoted by $\omega_0, \ldots, \omega_{q-1}$. If $E$ is a prime field, we let $\omega_i$ be $i$ (i.e. take the natural representation of each number). If $E$ is a non-prime field, we let $\omega_0$ be the zero element of $E$ and let $\omega_i$ be $\alpha^{i-1}$ for $i = 1 \ldots q - 1$ where $\alpha$ is the primitive element of $E$. Now for a codeword $u$ of $C$, let $s_i(u)$ be the number of components of $u$ equal to $\omega_i$. The complete weight enumerator is defined by

$$
{\cal W}_C(z_0, \ldots, z_{q-1}) =
   \sum_{u \in C}{{z_0}^{s_0(u)}\ldots{z_{q-1}}^{s_{q-1}(u)}}.
$$

<a id="function-completeweightenumerator-code-modtupfldelt"></a>
##### `CompleteWeightEnumerator(C, u): Code, ModTupFldElt -> RngMPolElt`

The complete weight enumerator ${\cal W}_{C+u}(z_0, \ldots, z_{q-1})$ for the coset $C+u$, where $u$ is an element of the generic vector space for the code $C$.

#### The MacWilliams Transform

<a id="function-macwilliamstransform-rngintelt-rngintelt-rngintelt-rngintelt-rngintelt"></a>
##### `MacWilliamsTransform(n, k, q, W): RngIntElt, RngIntElt, RngIntElt, [ <RngIntElt, RngIntElt> ] -> [ <RngIntElt, RngIntElt> ]`

Let $C$ be a hypothetical $[n, k]$ linear code over a finite field of cardinality $q$. Let $W$ be the weight distribution of $C$ (in the form as returned by the function `WeightDistribution`). This function applies the MacWilliams transform to $W$ to obtain the weight distribution $W'$ of the dual code of $C$. The transform is a combinatorial algorithm based on $n$, $k$, $q$, and $W$ alone. Thus $C$ itself need not exist—the function simply works with the sequence of integer pairs supplied by the user. Furthermore, if $W$ is not the weight distribution of an actual code, the result $W'$ will be meaningless and even negative weights may be returned.

#### Words

The functions in this section only apply to codes over finite fields.

<a id="function-words-code-rngintelt"></a>
##### `Words(C, w: parameters): Code, RngIntElt -> { ModTupFldElt }`

```magma
Cutoff    : RngIntElt                    Default: Infinity()
StoreWords: BoolElt                      Default: true
```

Given a linear code $C$ defined over a finite field, return the set of all words of $C$ having weight $w$. If `Cutoff` is set to a non-negative integer $c$, then the algorithm will terminate after a total of $c$ words have been found. If `StoreWords` is `true` then the words generated will be stored internally.

<a id="function-numberofwords-code-rngintelt"></a>
##### `NumberOfWords(C, w): Code, RngIntElt -> RngIntElt`

Given a linear code $C$ defined over a finite field, return the number of words of $C$ having weight $w$.

<a id="function-wordsofboundedweight-code-rngintelt-rngintelt"></a>
##### `WordsOfBoundedWeight(C, l, u: parameters): Code, RngIntElt, RngIntElt -> { ModTupFldElt }`

```magma
Cutoff    : RngIntElt                    Default: Infinity()
StoreWords: BoolElt                      Default: true
```

Given a linear code $C$ defined over a finite field, return the set of all words of $C$ having weight between $l$ and $u$, inclusive. If `Cutoff` is set to a non-negative integer $c$, then the algorithm will terminate after a total of $c$ words have been found. If `StoreWords` is `true` then any words of a *single weight* generated will be stored internally.

### Families of Linear Codes

#### Cyclic Codes

While cyclic linear codes are always generated by a single generating polynomial (vector), this is not the case for additive codes. Cyclic additive codes may be created in Magma using either a single generator, or a sequence of generators.

In the important case of $GF(2)$-additive vectors over $GF4$, all cyclic codes can be described in terms of two generators with one generator taken over $GF(4)$ and the other over $GF(2)$. A special function is provided for this construction.

<a id="function-additivecycliccode-modtupfldelt"></a>
##### `AdditiveCyclicCode(v): ModTupFldElt -> CodeAdd`

<a id="function-additivecycliccode-fldfin-modtupfldelt"></a>
##### `AdditiveCyclicCode(K, v): FldFin, ModTupFldElt -> CodeAdd`

<a id="function-additivecycliccode-modtupfldelt-2"></a>
##### `AdditiveCyclicCode(Q): [ModTupFldElt] -> CodeAdd`

<a id="function-additivecycliccode-fldfin-modtupfldelt-2"></a>
##### `AdditiveCyclicCode(K, Q): FldFin, [ModTupFldElt] -> CodeAdd`

Given either a single vector $v$ or sequence of vectors $Q$ over some finite field $F$, return the $K$-additive code over $F$ generated by all shifts of the inputs. The field $K$ must be a subfield of $F$ and if it is the prime subfield of $F$, it may be omitted.

<a id="function-additivecycliccode-rngintelt-rngupolelt"></a>
##### `AdditiveCyclicCode(n, f): RngIntElt, RngUPolElt -> CodeAdd`

<a id="function-additivecycliccode-fldfin-rngintelt-rngupolelt"></a>
##### `AdditiveCyclicCode(K, n, f): FldFin, RngIntElt, RngUPolElt -> CodeAdd`

<a id="function-additivecycliccode-rngintelt-rngupolelt-2"></a>
##### `AdditiveCyclicCode(n, Q): RngIntElt, [RngUPolElt] -> CodeAdd`

<a id="function-additivecycliccode-fldfin-rngintelt-rngupolelt-2"></a>
##### `AdditiveCyclicCode(K, n, Q): FldFin, RngIntElt, [RngUPolElt] -> CodeAdd`

Given either a single polynomial $f$ or sequence $Q$ of polynomials over some finite field $F$, return the $K$-additive code of length $n$ over $F$ generated by all shifts of the inputs. The field $K$ must be a subfield of $F$, and if it is the prime subfield of $F$, it may be omitted.

<a id="function-additivecycliccode-modtupfldelt-modtupfldelt"></a>
##### `AdditiveCyclicCode(v4, v2): ModTupFldElt, ModTupFldElt -> CodeAdd`

Given two vectors of equal length $n$, where $v_4$ is over $GF(4)$ and $v_2$ is over $GF(2)$, return the $F_2$–additive code generated by all of their cyclic shifts. Note that for the case of $GF(2)$-additive codes over $GF(4)$, two generators suffice to generate any such code.

<a id="function-additivecycliccode-rngintelt-rngupolelt-rngupolelt"></a>
##### `AdditiveCyclicCode(n, f4, f2): RngIntElt, RngUPolElt, RngUPolElt -> CodeAdd`

Given two polynomials $f_4$ and $f_2$, where $f_4$ is over $GF(4)$ and $f_2$ is over $GF(2)$, return the $F_2$–additive code of length $n$ generated by all of their cyclic shifts. The degree of the polynomials $f_4$ and $f_2$ must not exceed $n-1$. Note that for the case of $GF(2)$-additive codes over $GF(4)$, two generators suffice to generate any such code.

#### Quasicyclic Codes

Quasicyclic codes are a generalisation of cyclic codes. In Magma quasicyclic codes consist of horizontally joined cyclic blocks.

<a id="function-additivequasicycliccode-rngintelt-seqenum-rngupolelt"></a>
##### `AdditiveQuasiCyclicCode(n, Q): RngIntElt, SeqEnum[RngUPolElt] -> CodeAdd`

<a id="function-additivequasicycliccode-fldfin-rngintelt-seqenum-rngupolelt"></a>
##### `AdditiveQuasiCyclicCode(K, n, Q): FldFin, RngIntElt, SeqEnum[RngUPolElt] -> CodeAdd`

Given an integer $n$, and a sequence $Q$ of polynomials over some finite field $F$, return the $K$–additive quasicyclic code, whose cyclic blocks are generated by the polynomials in $Q$. The field $K$ must be a subfield of $F$, and if it is the prime subfield of $F$, it may be omitted.

<a id="function-additivequasicycliccode-rngintelt-seqenum-rngupolelt-rngintelt"></a>
##### `AdditiveQuasiCyclicCode(n, Q, h): RngIntElt, SeqEnum[RngUPolElt], RngIntElt -> CodeAdd`

<a id="function-additivequasicycliccode-fldfin-rngintelt-seqenum-rngupolelt-rngintelt"></a>
##### `AdditiveQuasiCyclicCode(K, n, Q, h): FldFin, RngIntElt, SeqEnum[RngUPolElt], RngIntElt -> CodeAdd`

Given an integer $n$, and a sequence $Q$ of polynomials over some finite field $F$, and an integer $h$, then return the $K$–additive quasicyclic code, whose cyclic blocks are generated by the polynomials in $Q$ and stacked $2$-dimensionally of height $h$. The field $K$ must be a subfield of $F$, and if it is the prime subfield of $F$, it may be omitted.

<a id="function-additivequasicycliccode-seqenum-modtupfldelt"></a>
##### `AdditiveQuasiCyclicCode(Q): SeqEnum[ModTupFldElt] -> CodeAdd`

<a id="function-additivequasicycliccode-fldfin-seqenum-modtupfldelt"></a>
##### `AdditiveQuasiCyclicCode(K, Q): FldFin, SeqEnum[ModTupFldElt] -> CodeAdd`

Given a sequence $Q$ of vectors over some finite field $F$, then return the $K$–additive quasicyclic code, whose cyclic blocks are generated by the vectors in $Q$. The field $K$ must be a subfield of $F$, and if it is the prime subfield of $F$, it may be omitted.

<a id="function-additivequasicycliccode-seqenum-modtupfldelt-rngintelt"></a>
##### `AdditiveQuasiCyclicCode(Q, h): SeqEnum[ModTupFldElt], RngIntElt -> CodeAdd`

<a id="function-additivequasicycliccode-fldfin-seqenum-modtupfldelt-rngintelt"></a>
##### `AdditiveQuasiCyclicCode(K, Q, h): FldFin, SeqEnum[ModTupFldElt], RngIntElt -> CodeAdd`

Given a sequence $Q$ of vectors over some finite field $F$, and an integer $h$, then return the $K$–additive quasicyclic code, whose cyclic blocks are generated by the vectors in $Q$ and stacked $2$-dimensionally of height $h$. The field $K$ must be a subfield of $F$, and if it is the prime subfield of $F$, it may be omitted.

### New Codes from Old

The operations described here produce a new code by modifying in some way the codewords of a given code.

#### Standard Constructions

<a id="function-augmentcode-codeadd"></a>
##### `AugmentCode(C): CodeAdd -> Code`

Construct a new additive code by including the all-ones vector with the words of the additive code $C$.

<a id="function-codecomplement-code-code"></a>
##### `CodeComplement(C, S): Code, Code -> Code`

Given a subcode $S$ of the code $C$, return a code $C'$ such that $C=S + C'$. Both $C$ and $S$ must be defined over the same field.

<a id="function-directsum-code-code"></a>
##### `DirectSum(C, D): Code, Code -> Code`

Given codes $C$ and $D$, form the code that is direct sum of $C$ and $D$. The direct sum consists of all vectors $u|v$, where $u \in C$ and $v \in D$.

<a id="function-directsum-code"></a>
##### `DirectSum(Q): [Code] -> Code`

Given a sequence of codes $Q = [C_1, \dots, C_r]$, all defined over the same field $F$, construct the direct sum of the $C_i$.

<a id="function-directproduct-code-code"></a>
##### `DirectProduct(C, D): Code, Code -> Code`

Given an $[n_1, k_1]$ code $C$ and an $[n_2, k_2]$ code $D$, both over the same ring $R$, construct the direct product of $C$ and $D$. The direct product has length $n_1\cdot n_2$ and its generator matrix is the Kronecker product of the basis matrices of $C$ and $D$.

<a id="function-extendcode-codeadd"></a>
##### `ExtendCode(C): CodeAdd -> CodeAdd`

Given an $[n, k, d]$ additive code $C$, form a new code $C'$ from $C$ by adding the appropriate extra coordinate to each vector of $C$ such that the sum of the coordinates of the extended vector is zero.

<a id="function-extendcode-code-rngintelt"></a>
##### `ExtendCode(C, n): Code, RngIntElt -> Code`

Return the code obtained by extending the code $C$ extended $n$ times.

<a id="function-padcode-codeadd-rngintelt"></a>
##### `PadCode(C, n): CodeAdd, RngIntElt -> CodeAdd`

Add $n$ zeros to the end of each codeword of the code $C$.

<a id="function-plotkinsum-code-code"></a>
##### `PlotkinSum(C1, C2): Code, Code -> Code`

Given codes $C_1$ and $C_2$ defined over the same alphabet, return the code consisting of all vectors of the form $u|u+v$, where $u \in C1$ and $v \in C2$. Zeros are appended where needed to make up any length differences in the two codes.

<a id="function-plotkinsum-code-code-code"></a>
##### `PlotkinSum(C1, C2, C3: parameters): Code, Code, Code -> Code`

```magma
a: FldFinElt                    Default: -1
```

Given three codes $C_1$, $C_2$, and $C_3$ defined over the same alphabet $K$, return the code consisting of all vectors of the form $u|u+a*v|u+v+w$, where $u \in C1$, $v \in C2$, and $w \in C3$. The default value of the multiplier $a$ is a primitive element of $K$. Zeros are appended where needed to ensure that every codeword has the same length.

<a id="function-puncturecode-codeadd-rngintelt"></a>
##### `PunctureCode(C, i): CodeAdd, RngIntElt -> Code`

Given an $[n, k]$ code $C$, and an integer $i$, $1 \leq i \leq n$, construct a new code $C'$ by deleting the $i$-th coordinate from each code word of $C$.

<a id="function-puncturecode-codeadd-rngintelt-2"></a>
##### `PunctureCode(C, S): CodeAdd, { RngIntElt } -> Code`

Given an $[n, k]$ code $C$ and a set $S$ of distinct integers $\{ i_1, \cdots, {\mathrm{i}}_r \}$ each of which lies in the range $[1, n]$, construct a new code $C'$ by deleting the components $i_1, \cdots, i_r$ from each code word of $C$.

<a id="function-shortencode-code-rngintelt"></a>
##### `ShortenCode(C, i): Code, RngIntElt -> Code`

Given an $[n, k]$ code $C$ and an integer $i$, $1 \leq i \leq n$, construct a new code from $C$ by selecting only those codewords of $C$ having a zero as their $i$-th component and deleting the $i$-th component from these codewords. Thus, the resulting code will have length $n-1$.

<a id="function-shortencode-code-rngintelt-2"></a>
##### `ShortenCode(C, S): Code, { RngIntElt } -> Code`

Given an $[n, k]$ code $C$ and a set $S$ of distinct integers $\{ i_1, \cdots, {\mathrm{i}}_r\}$, each of which lies in the range $[1, n]$, construct a new code from $C$ by selecting only those codewords of $C$ having zeros in each of the coordinate positions $i_1, \cdots, i_r$, and deleting these components. Thus, the resulting code will have length $n-r$.

#### Combining Codes

<a id="operation-operation-cat-codeadd-codeadd-codeadd"></a>
##### `C1 cat C2: CodeAdd, CodeAdd -> CodeAdd`

Given codes $C1$ and $C2$, both defined over the same field $K$, return the concatenation $C$ of $C1$ and $C2$. The generators of the resultant code are the concatenations of the generators of $C1$ and $C2$.

<a id="function-juxtaposition-code-code"></a>
##### `Juxtaposition(C1, C2): Code, Code -> Code`

Given an $[n_1,k,d_1]$ code $C1$ and an $[n_2,k,d_2]$ code $C2$ of the same dimension, where both codes are defined over the same field $K$, this function returns a $[n_1+n_2,k,\geq  d_1+d_2]$ code whose generator matrix is `HorizontalJoin(A, B)`, where $A$ and $B$ are the generator matrices for codes $C1$ and $C2$, respectively.

### Automorphism Group

<a id="function-automorphismgroup-codeadd"></a>
#### `AutomorphismGroup(C): CodeAdd -> GrpPerm`

The automorphism group of the additive code $C$. Currently, this function is only available for additive codes over $GF(4)$.

<a id="function-permutationgroup-codeadd"></a>
#### `PermutationGroup(C): CodeAdd -> GrpPerm`

The subgroup of the automorphism group of the additive code $C$ consisting of permutations of the coordinates. Currently, this function is only available for additive codes over $GF(4)$.

<a id="error-correcting-quantum-code"></a>
<a id="chap-codequantum"></a>
## Quantum Codes

- [Introduction](https://docs.magma-maths.org/CodingTheory/QuantumCodes/introduction.md)
- [Constructing Quantum Codes](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md)
  - [Construction of General Quantum Codes](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#construction-of-general-quantum-codes)
    - [`QuantumCode(S): Code → CodeQuantum`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#function-quantumcode-code)
    - [Example: Quantum Code from an Even Linear Code](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#example-ex-1cf7b5)
    - [Example: Extended Format Stabilizer Code](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#example-ex-ddc82a)
    - [Example: Self-Dual Quantum Code Construction](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#example-ex-ca78b6)
    - [Example: Quantum Code from an Additive Code](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#example-ex-f692ec)
    - [`QuantumCode(M): ModMatRngElt → CodeQuantum`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#function-quantumcode-modmatrngelt)
    - [Example: Quantum Code from a Stabilizer Matrix](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#example-ex-863e76)
    - [`QuantumCode(G): Grph → CodeQuantum`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#function-quantumcode-grph)
    - [Example: Hexacode from a Wheel Graph](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#example-ex-29ea9f)
    - [Example: Dodecacode from a Graph](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#example-ex-d4d3a5)
    - [`RandomQuantumCode(F, n, k): FldFin, RngIntElt, RngIntElt → CodeQuantum`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#function-randomquantumcode-fldfin-rngintelt-rngintelt)
    - [Example: Random Quantum Code](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#example-ex-27cad1)
    - [`Subcode(Q, k): CodeQuantum, RngIntElt → CodeQuantum`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#function-subcode-codequantum-rngintelt)
  - [Construction of Special Quantum Codes](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#construction-of-special-quantum-codes)
    - [`Hexacode() → CodeQuantum`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#function-hexacode)
    - [`Dodecacode() → CodeQuantum`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#function-dodecacode)
  - [CSS Codes](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#css-codes)
    - [`CSSCode(C1, C2): Code, Code → CodeQuantum`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#function-csscode-code-code)
    - [`CalderbankShorSteaneCode(C1, C2): Code, Code → CodeQuantum`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#function-calderbankshorsteanecode-code-code)
    - [Example: CSS Construction from a Hamming Code](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#example-ex-37614f)
  - [Cyclic Quantum Codes](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#cyclic-quantum-codes)
    - [`QuantumCyclicCode(v): ModTupFldElt → CodeAdd`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#function-quantumcycliccode-modtupfldelt)
    - [`QuantumCyclicCode(Q): [ModTupFldElt] → CodeAdd`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#function-quantumcycliccode-modtupfldelt-2)
    - [Example: Cyclic Quantum Code from a Vector](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#example-ex-0477fe)
    - [`QuantumCyclicCode(n, f): RngIntElt, RngUPolElt → CodeAdd`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#function-quantumcycliccode-rngintelt-rngupolelt)
    - [`QuantumCyclicCode(n, Q): RngIntElt, [RngUPolElt] → CodeAdd`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#function-quantumcycliccode-rngintelt-rngupolelt-2)
    - [Example: Cyclic Quantum Codes from Polynomials](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#example-ex-87e469)
    - [`QuantumCyclicCode(v4, v2): ModTupFldElt, ModTupFldElt → CodeAdd`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#function-quantumcycliccode-modtupfldelt-modtupfldelt)
    - [Example: Cyclic Quantum Code from Quaternary and Binary Vectors](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#example-ex-088686)
  - [Quasi-Cyclic Quantum Codes](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#quasi-cyclic-quantum-codes)
    - [`QuantumQuasiCyclicCode(n, Q): RngIntElt, SeqEnum[RngUPolElt] → CodeAdd`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#function-quantumquasicycliccode-rngintelt-seqenum-rngupolelt)
    - [`QuantumQuasiCyclicCode(Q): SeqEnum[ModTupFldElt] → CodeAdd`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#function-quantumquasicycliccode-seqenum-modtupfldelt)
    - [Example: Quasi-Cyclic Quantum Codes](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#example-ex-efccba)
- [Access Functions](https://docs.magma-maths.org/CodingTheory/QuantumCodes/access.md)
  - [`QuantumBasisElement(F): FldFin → FldFinElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/access.md#function-quantumbasiselement-fldfin)
  - [Example: Quantum Basis Element](https://docs.magma-maths.org/CodingTheory/QuantumCodes/access.md#example-ex-2560f5)
  - [`StabilizerCode(Q): CodeQuantum → CodeAdd`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/access.md#function-stabilizercode-codequantum)
  - [`StabiliserCode(Q): CodeQuantum → CodeAdd`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/access.md#function-stabilisercode-codequantum)
  - [`StabilizerMatrix(Q): CodeQuantum → ModMatFldElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/access.md#function-stabilizermatrix-codequantum)
  - [`StabiliserMatrix(Q): CodeQuantum → ModMatFldElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/access.md#function-stabilisermatrix-codequantum)
  - [`NormalizerCode(Q): CodeQuantum → CodeAdd`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/access.md#function-normalizercode-codequantum)
  - [`NormaliserCode(Q): CodeQuantum → CodeAdd`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/access.md#function-normalisercode-codequantum)
  - [`NormalizerMatrix(Q): CodeQuantum → ModMatFldElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/access.md#function-normalizermatrix-codequantum)
  - [`NormaliserMatrix(Q): CodeQuantum → ModMatFldElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/access.md#function-normalisermatrix-codequantum)
  - [Quantum Error Group](https://docs.magma-maths.org/CodingTheory/QuantumCodes/access.md#quantum-error-group)
    - [`QuantumErrorGroup(p, n): RngIntElt, RngIntElt → GrpPC`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/access.md#function-quantumerrorgroup-rngintelt-rngintelt)
    - [`QuantumBinaryErrorGroup(n): RngIntElt → GrpPC`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/access.md#function-quantumbinaryerrorgroup-rngintelt)
    - [Example: Commutativity in the Quantum Error Group](https://docs.magma-maths.org/CodingTheory/QuantumCodes/access.md#example-ex-442960)
    - [`QuantumErrorGroup(Q): CodeQuantum → GrpPC`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/access.md#function-quantumerrorgroup-codequantum)
    - [`StabilizerGroup(Q): CodeQuantum → GrpPC`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/access.md#function-stabilizergroup-codequantum)
    - [`StabiliserGroup(Q): CodeQuantum → GrpPC`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/access.md#function-stabilisergroup-codequantum)
    - [`StabilizerGroup(Q, G): CodeQuantum, GrpPC → GrpPC`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/access.md#function-stabilizergroup-codequantum-grppc)
    - [`StabiliserGroup(Q, G): CodeQuantum, GrpPC → GrpPC`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/access.md#function-stabilisergroup-codequantum-grppc)
    - [Example: Stabilizer Group of a Quantum Code](https://docs.magma-maths.org/CodingTheory/QuantumCodes/access.md#example-ex-1844d0)
    - [Example: Compatible Stabilizer Groups](https://docs.magma-maths.org/CodingTheory/QuantumCodes/access.md#example-ex-8f08f4)
- [Inner Products and Duals](https://docs.magma-maths.org/CodingTheory/QuantumCodes/inner-products.md)
  - [`SymplecticInnerProduct(v1, v2): ModTupFldElt, ModTupFldElt → FldFinElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/inner-products.md#function-symplecticinnerproduct-modtupfldelt-modtupfldelt)
  - [Example: Symplectic Products Compared](https://docs.magma-maths.org/CodingTheory/QuantumCodes/inner-products.md#example-ex-176f6b)
  - [Example: Symplectic Product Formats](https://docs.magma-maths.org/CodingTheory/QuantumCodes/inner-products.md#example-ex-f66c0e)
  - [`SymplecticDual(C): CodeAdd → CodeAdd`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/inner-products.md#function-symplecticdual-codeadd)
  - [`IsSymplecticSelfDual(C): CodeAdd → BoolElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/inner-products.md#function-issymplecticselfdual-codeadd)
  - [`IsSymplecticSelfOrthogonal(C): CodeAdd → BoolElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/inner-products.md#function-issymplecticselforthogonal-codeadd)
  - [Example: Symplectically Orthogonal Vectors](https://docs.magma-maths.org/CodingTheory/QuantumCodes/inner-products.md#example-ex-b98847)
  - [Example: Symplectic Self-Orthogonality of Vectors](https://docs.magma-maths.org/CodingTheory/QuantumCodes/inner-products.md#example-ex-937695)
- [Weight Distribution and Minimum Weight](https://docs.magma-maths.org/CodingTheory/QuantumCodes/weight-distribution.md)
  - [`WeightDistribution(Q): CodeQuantum → SeqEnum, SeqEnum, SeqEnum`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/weight-distribution.md#function-weightdistribution-codequantum)
  - [Example: Weight Distributions of a Quantum Code](https://docs.magma-maths.org/CodingTheory/QuantumCodes/weight-distribution.md#example-ex-839de5)
  - [`MinimumWeight(Q): CodeQuantum → RngIntElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/weight-distribution.md#function-minimumweight-codequantum)
  - [Example: Minimum Weight of a Quantum Code](https://docs.magma-maths.org/CodingTheory/QuantumCodes/weight-distribution.md#example-ex-9556d5)
  - [`IsPure(Q): CodeQuantum → BoolElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/weight-distribution.md#function-ispure-codequantum)
  - [Example: Purity of Best Known Quantum Codes](https://docs.magma-maths.org/CodingTheory/QuantumCodes/weight-distribution.md#example-ex-e05555)
- [New Codes From Old](https://docs.magma-maths.org/CodingTheory/QuantumCodes/combining-codes.md)
  - [`DirectSum(Q1, Q2): CodeQuantum, CodeQuantum → CodeQuantum`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/combining-codes.md#function-directsum-codequantum-codequantum)
  - [`ExtendCode(Q): CodeQuantum → CodeQuantum`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/combining-codes.md#function-extendcode-codequantum)
  - [`ExtendCode(Q, m): CodeQuantum, RngIntElt → CodeQuantum`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/combining-codes.md#function-extendcode-codequantum-rngintelt)
  - [`PunctureCode(Q, i): CodeQuantum, RngIntElt → CodeQuantum`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/combining-codes.md#function-puncturecode-codequantum-rngintelt)
  - [`PunctureCode(Q, I): CodeQuantum, SetEnum → CodeQuantum`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/combining-codes.md#function-puncturecode-codequantum-setenum)
  - [`ShortenCode(Q, i): CodeQuantum, RngIntElt → CodeQuantum`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/combining-codes.md#function-shortencode-codequantum-rngintelt)
  - [`ShortenCode(Q, I): CodeQuantum, SetEnum → CodeQuantum`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/combining-codes.md#function-shortencode-codequantum-setenum)
  - [`C ^ tau: CodeQuantum, GrpPermElt → CodeQuantum`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/combining-codes.md#operation-op-pow-codequantum-grppermelt)
  - [Example: Combining Stabilizer Codes](https://docs.magma-maths.org/CodingTheory/QuantumCodes/combining-codes.md#example-ex-31e314)
- [Best Known Quantum Codes](https://docs.magma-maths.org/CodingTheory/QuantumCodes/best-known-quantum-codes.md)
  - [`QECC(F, n, k): FldFin, RngIntElt, RngIntElt → CodeQuantum, BoolElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/best-known-quantum-codes.md#function-qecc-fldfin-rngintelt-rngintelt)
  - [`BKQC(F, n, k): FldFin, RngIntElt, RngIntElt → CodeQuantum, BoolElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/best-known-quantum-codes.md#function-bkqc-fldfin-rngintelt-rngintelt)
  - [`BestKnownQuantumCode(F, n, k): FldFin, RngIntElt, RngIntElt → CodeQuantum, BoolElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/best-known-quantum-codes.md#function-bestknownquantumcode-fldfin-rngintelt-rngintelt)
  - [Example: Weight Distribution of a Best Known Quantum Code](https://docs.magma-maths.org/CodingTheory/QuantumCodes/best-known-quantum-codes.md#example-ex-4ef878)
  - [Example: Self-Dual Quantum Codes](https://docs.magma-maths.org/CodingTheory/QuantumCodes/best-known-quantum-codes.md#example-ex-aece57)
  - [Example: Tracing a Best Known Quantum Code Construction](https://docs.magma-maths.org/CodingTheory/QuantumCodes/best-known-quantum-codes.md#example-ex-e5b5cc)
- [Best Known Bounds](https://docs.magma-maths.org/CodingTheory/QuantumCodes/best-known-quantum-bounds.md)
  - [`QECCLowerBound(F, n, k): FldFin, RngIntElt, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/best-known-quantum-bounds.md#function-qecclowerbound-fldfin-rngintelt-rngintelt)
  - [`QECCUpperBound(F, n, k): FldFin, RngIntElt, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/best-known-quantum-bounds.md#function-qeccupperbound-fldfin-rngintelt-rngintelt)
  - [Example: Best Known Quantum Bounds](https://docs.magma-maths.org/CodingTheory/QuantumCodes/best-known-quantum-bounds.md#example-ex-9d1cfb)
- [Automorphism Group](https://docs.magma-maths.org/CodingTheory/QuantumCodes/additive-automorphisms.md)
  - [`AutomorphismGroup(Q): CodeQuantum → GrpPerm`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/additive-automorphisms.md#function-automorphismgroup-codequantum)
  - [`PermutationGroup(Q): CodeQuantum → GrpPerm`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/additive-automorphisms.md#function-permutationgroup-codequantum)
  - [Example: Automorphism Group of the Dodecacode](https://docs.magma-maths.org/CodingTheory/QuantumCodes/additive-automorphisms.md#example-ex-9f0d8a)
  - [Example: Automorphism Groups of the Hexacode](https://docs.magma-maths.org/CodingTheory/QuantumCodes/additive-automorphisms.md#example-ex-320db8)
- [Hilbert Spaces](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md)
  - [`HilbertSpace(F, n): FldCom, RngIntElt → HilbSpc`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#function-hilbertspace-fldcom-rngintelt)
  - [`Field(H): HilbSpc → FldCom`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#function-field-hilbspc)
  - [`NumberOfQubits(H): HilbSpc → RngIntElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#function-numberofqubits-hilbspc)
  - [`Nqubits(H): HilbSpc → RngIntElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#function-nqubits-hilbspc)
  - [`Dimension(H): HilbSpc → RngIntElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#function-dimension-hilbspc)
  - [`IsDenselyRepresented(H): HilbSpc → RngIntElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#function-isdenselyrepresented-hilbspc)
  - [`H1 eq H2: HilbSpc, HilbSpc → BoolElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#operation-op-eq-hilbspc-hilbspc)
  - [`H1 ne H2: HilbSpc, HilbSpc → BoolElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#operation-op-ne-hilbspc-hilbspc)
  - [Example: Dense and Sparse Hilbert Spaces](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#example-ex-a2ce0e)
  - [Creation of Quantum States](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#creation-of-quantum-states)
    - [`QuantumState(H, v): HilbSpc, ModTupFldElt → HilbSpcElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#function-quantumstate-hilbspc-modtupfldelt)
    - [`QuantumState(H, v): HilbSpc, MtrxSprs → HilbSpcElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#function-quantumstate-hilbspc-mtrxsprs)
    - [`H ! i: HilbSpc, RngIntElt → HilbSpcElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#operation-op-hilbspc-rngintelt)
    - [`H ! s: HilbSpc, [RngIntElt] → HilbSpcElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#operation-op-hilbspc-rngintelt-2)
    - [`SetPrintKetsInteger(b): BoolElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#procedure-setprintketsinteger-boolelt)
    - [Example: Quantum State from a Coefficient Vector](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#example-ex-1f7466)
    - [Example: Quantum State from Basis States](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#example-ex-9b3454)
  - [Manipulation of Quantum States](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#manipulation-of-quantum-states)
    - [`a * e: FldComElt, HilbSpcElt → HilbSpcElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#operation-op-times-fldcomelt-hilbspcelt)
    - [`- e: HilbSpcElt → HilbSpcElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#operation-operation-hilbspcelt-hilbspcelt)
    - [`e1 + e2: HilbSpcElt, HilbSpcElt → HilbSpcElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#operation-op-plus-hilbspcelt-hilbspcelt)
    - [`e1 - e2: HilbSpcElt, HilbSpcElt → HilbSpcElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#operation-op-minus-hilbspcelt-hilbspcelt)
    - [`Normalisation(e): HilbSpcElt → HilbSpcElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#function-normalisation-hilbspcelt)
    - [`Normalisation(~e): HilbSpcElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#procedure-normalisation-hilbspcelt-ref)
    - [`Normalization(e): HilbSpcElt → HilbSpcElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#function-normalization-hilbspcelt)
    - [`Normalization(~e): HilbSpcElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#procedure-normalization-hilbspcelt-ref)
    - [`NormalisationCoefficient(e): HilbSpc → FldComElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#function-normalisationcoefficient-hilbspc)
    - [`NormalizationCoefficient(e): HilbSpc → FldComElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#function-normalizationcoefficient-hilbspc)
    - [`e1 eq e2: HilbSpcElt, HilbSpcElt → BoolElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#operation-op-eq-hilbspcelt-hilbspcelt)
    - [`e1 ne e2: HilbSpcElt, HilbSpcElt → BoolElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#operation-op-ne-hilbspcelt-hilbspcelt)
    - [Example: Normalisation of Quantum States](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#example-ex-d9a8c5)
  - [Inner Product and Probabilities of Quantum States](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#inner-product-and-probabilities-of-quantum-states)
    - [`InnerProduct(e1, e2): HilbSpcElt, HilbSpcElt → HilbSpcElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#function-innerproduct-hilbspcelt-hilbspcelt)
    - [`ProbabilityDistribution(e): HilbSpcElt → Mtrx`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#function-probabilitydistribution-hilbspcelt)
    - [`Probability(e, i): HilbSpcElt, RngIntElt → FldReElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#function-probability-hilbspcelt-rngintelt)
    - [`Probability(e, v): HilbSpcElt, RngIntElt → FldReElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#function-probability-hilbspcelt-rngintelt-2)
    - [`PrintProbabilityDistribution(e): HilbSpcElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#procedure-printprobabilitydistribution-hilbspcelt)
    - [`PrintSortedProbabilityDistribution(e): HilbSpcElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#procedure-printsortedprobabilitydistribution-hilbspcelt)
    - [Example: Probabilities of a Quantum State](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#example-ex-c0f168)
    - [Example: Sorted Probabilities of a Quantum State](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#example-ex-10594e)
  - [Unitary Transformations on Quantum States](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#unitary-transformations-on-quantum-states)
    - [`BitFlip(e, k): HilbSpcElt, RngIntElt → HilbSpcElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#function-bitflip-hilbspcelt-rngintelt)
    - [`BitFlip(~e, k): HilbSpcElt, RngIntElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#procedure-bitflip-hilbspcelt-rngintelt-ref)
    - [`BitFlip(e, B): HilbSpcElt, {RngIntElt} → HilbSpcElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#function-bitflip-hilbspcelt-rngintelt-2)
    - [`BitFlip(~e, B): HilbSpcElt, {RngIntElt}`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#procedure-bitflip-hilbspcelt-rngintelt-ref-2)
    - [`PhaseFlip(e, k): HilbSpcElt, RngIntElt → HilbSpcElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#function-phaseflip-hilbspcelt-rngintelt)
    - [`PhaseFlip(~e, k): HilbSpcElt, RngIntElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#procedure-phaseflip-hilbspcelt-rngintelt-ref)
    - [`PhaseFlip(e, B): HilbSpcElt, {RngIntElt} → HilbSpcElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#function-phaseflip-hilbspcelt-rngintelt-2)
    - [`PhaseFlip(~e, B): HilbSpcElt, {RngIntElt}`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#procedure-phaseflip-hilbspcelt-rngintelt-ref-2)
    - [`ControlledNot(e, B, k): HilbSpcElt, {RngIntElt}, RngIntElt → HilbSpcElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#function-controllednot-hilbspcelt-rngintelt-rngintelt)
    - [`ControlledNot(~e, B, k): HilbSpcElt, {RngIntElt}, RngIntElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#procedure-controllednot-hilbspcelt-rngintelt-rngintelt-ref)
    - [`HadamardTrasformation(e): HilbSpcElt → HilbSpcElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#function-hadamardtrasformation-hilbspcelt)
    - [`HadamardTrasformation(~e): HilbSpcElt`](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#procedure-hadamardtrasformation-hilbspcelt-ref)
    - [Example: Unitary Transformations of a Quantum State](https://docs.magma-maths.org/CodingTheory/QuantumCodes/hilbert-space.md#example-ex-360d11)
- [Bibliography](https://docs.magma-maths.org/CodingTheory/QuantumCodes/bibliography.md)

### Introduction

Interest in quantum computing has grown rapidly following the discovery by Peter Shor in 1994 of a polynomial-time algorithm for integer factorization [[Sho94](https://docs.magma-maths.org/references.md#cite-shorfactoring)]. In a classical computer a sequence of $N$ binary digits defines one specific configuration among the $2^N$ possible values. However, in a quantum computer a collection of $N$ “qubits” has a state function (in ‘ket’ notation) $| \psi \rangle$ in a *Hilbert space*, which can be in a superposition of all $2^N$ possible values

$$
| \psi \rangle = \sum_{{\bf v}\in {\mathbb{Z}}_2^N} \alpha_{\bf v}| {\bf v} \rangle,
\qquad \alpha_{\bf v}\in {\mathbb{C}}, \quad \sum_{\bf v}|\alpha_{\bf v}|^2 = 1.
$$

A basic theorem in quantum information theory states that it is impossible to clone a quantum state. Since this implies that it is not possible to copy quantum information, it was initially believed that error-correction would be impossible on a quantum computer. However, in 1995 Shor showed that it *was* possible to encode quantum information in such a way that errors can be corrected, assuming an error model in which errors occur independently in distinct qubits [[Sho95a](https://docs.magma-maths.org/references.md#cite-shorqecc)].

Following this discovery, a class of quantum error-correcting codes known as *stabilizer codes* were developed. In [[CRSS98](https://docs.magma-maths.org/references.md#cite-crss)] (which is the major reference for this chapter of the Magma Handbook), it was shown that stabilizer codes can be represented in terms of additive codes over finite fields (see chapter [Additive Codes](https://docs.magma-maths.org/CodingTheory/AdditiveCodes/index-additive-codes.md#chap-codeadd) for a description of additive codes). This remarkable result reduces the problem of constructing fault-tolerant encodings on a continuous Hilbert space to that of constructing certain discrete codes, allowing the use of many of the tools developed in classical coding theory.

The current Magma package for quantum codes deals exclusively with finite field representations of stabilizer codes. It is important to keep in mind that, although a quantum code is *represented* by a code over a finite field, an actual quantum code is in fact a totally different object. The full theory behind quantum stabilizer codes will not be described here, for that the reader should consult the main reference [[CRSS98](https://docs.magma-maths.org/references.md#cite-crss)]. A brief synopsis will outline how the finite field representation of a stabilizer code is to be interpreted, and the specifics of this representation in Magma.

Many of the conventions and functions for classical error-correcting code types in Magma can be ambiguous in the context of quantum codes. For this reason the handbook should be carefully consulted before assuming that any particular aspect of a quantum code follows naturally from classical coding theory definitions.

The reduction of the problem of continuous errors on a Hilbert space to a problem employing a discrete finite field representation is achieved by confining attention to a finite *error group*. An element of the error group, acting on the $N$ qubits, is expressed as a combination of bit flip errors, designated by the operator $X$, and phase shift errors, designated by the operator $Z$ (as well as an overall phase factor that will be ignored here):

$$
X({\bf a})Z({\bf b}) | {\bf v} \rangle = (-1)^{{\bf v}\cdot {\bf b}} | {\bf v}+ {\bf a} \rangle
$$

The error group is given by the set $\{ X({\bf a})Z({\bf b}) : {\bf a}, {\bf b}\in {\mathbb{Z}}_2^n \}$ and its elements can be written as length $2N$ binary vectors $({\bf a}|{\bf b})$. An error represented by such a vector in Magma is said to be in *extended format* which is distinct from the default representation. A more common (and practical) representation is as the element ${\bf w}$ of $F_{4}^{(N)}$ given by ${\bf w}= {\bf a}+ \omega {\bf b},$ where $\omega$ is a primitive element of $GF(4)$. This representation is referred to as the *compact format*, and is the default format used in Magma for quantum codes. Note that this is slightly different to the representation $\widehat{{\bf w}} = \omega {\bf a}+ \overline{\omega} {\bf b}$ used in [[CRSS98](https://docs.magma-maths.org/references.md#cite-crss)] for binary quantum codes, but they are equivalent: ${\bf w}= \overline{\omega} * \widehat{{\bf w}}$.

The Magma package also supports non-binary quantum codes, which are obtained by generalizing from the binary case in a natural way. For quantum codes based on qubits over $GF(q)$, the compact format in $GF(q^2)$ will be ${\bf w}= {\bf a}+ \lambda {\bf b},$ where $\lambda$ is a fixed element returned by the function `QuantumBasisElement`$(GF(q))$.

A symplectic inner product is defined on the group of errors, in its representation as a set of $GF(q)$-vectors. For vectors in extended format this is defined by

$$
({\bf a}_1|{\bf b}_1)*({\bf a}_2|{\bf b}_2) = {\bf a}_1 \cdot {\bf b}_2 - {\bf a}_2 \cdot {\bf b}_1
$$

In compact format (over $GF(4)$) the equivalent inner product is defined by

$$
{\bf w}_1 * {\bf w}_2 = {\rm Trace}({\bf w}_1 \cdot \overline{{\bf w}}_2).
$$

Since the commutator of two errors is given by

$$
\begin{aligned}\Big[ \big(X({\bf a}_1)&Z({\bf b}_1)\big)\big(X({\bf a}_2)Z({\bf b}_2)\big) -
      \big(X({\bf a}_2)Z({\bf b}_2)\big)\big(X({\bf a}_1)Z({\bf b}_1)\big)\Big] | {\bf v} \rangle \\
 &= (-1)^{{\bf v}\cdot{\bf b}_2 + ({\bf v}+{\bf a}_2)\cdot{\bf b}_1}| {\bf v}+{\bf a}_1+{\bf a}_2 \rangle
      + (-1)^{{\bf v}\cdot{\bf b}_1 + ({\bf v}+{\bf a}_1)\cdot{\bf b}_2}| {\bf v}+{\bf a}_1+{\bf a}_2 \rangle \\
 &= \Big[ (-1)^{{\bf a}_2\cdot{\bf b}_1} - (-1)^{{\bf a}_1\cdot{\bf b}_2} \Big]
          (-1)^{{\bf v}\cdot({\bf b}_1-{\bf b}_2)}| {\bf v}+{\bf a}_1+{\bf a}_2 \rangle \\
 &= \Big[1 - \delta_{{\bf a}_1\cdot{\bf b}_2,\,{\bf a}_2\cdot{\bf b}_1} \Big] \cdots\end{aligned}
$$

then clearly errors will commute if and only if their finite field representations are orthogonal with respect to the symplectic inner product.

A quantum stabilizer code is defined by an abelian subgroup of the error group. In the context of its finite field representation this translates to a self-orthogonal additive code under the symplectic inner product. So a quantum stabilizer code $Q$ is defined by a symplectic self-orthogonal additive code $S$, which is (with some redundancy) termed the stabilizer code of $Q$.

The error-correcting capability of a code is determined by the set of errors which can not be detected. For classical linear codes these undetectable errors are precisely the non-zero codewords of the code, while for a quantum code, the undetectable errors are given by the set $S^\perp \backslash S,$ where $S^\perp$ is the symplectic dual of $S$.

The most important measure of the ability of a quantum code to correct errors is its *minimum weight*, that is, is the minimum of the weights of the words of $S^\perp \backslash S$. An exception to this definition occurs in the case of quantum codes having dimension zero, which are defined by symplectic self-dual stabilizer codes. These are termed “self-dual quantum codes” and are defined to have a minimum weight equal to the (classical) minimum weight of their stabilizer code.

### 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(q^2)$ (compact format) or as a length $2n$ additive code over $GF(q)$ (extended format). If $Q$ is a quantum code with generator matrix $G_1$ in compact format, and generator matrix $G_2 = (A|B)$ in extended format, then

$$
G_1 = A + \lambda B,
$$

where $\lambda$ is a fixed element returned by the function `QuantumBasisElement`$(GF(q))$. 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(q^2)$ will generate an $[[n,n/2-k]]$ quantum stabilizer code. A (compact format) additive symplectic self-orthogonal code $C$ over $GF(q^2)$ will give a quantum code of the same length and “dimension” $\log_q(N)$, where $N$ is the number of code words in $C$.

#### Construction of General Quantum Codes

<a id="function-quantumcode-code"></a>
##### `QuantumCode(S): Code -> CodeQuantum`

```magma
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(q^2)$. If `ExtendedFormat` is set `true`, then $S$ is interpreted as being in extended format, that is, a length $2n$ additive code over $GF(q)$.

<a id="example-ex-1cf7b5"></a>
##### `Example: Quantum Code from an Even Linear Code (ex-1cf7b5)`

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(q^2)$ is displayed.

```magma
> 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]
```

<a id="example-ex-ddc82a"></a>
##### `Example: Extended Format Stabilizer Code (ex-ddc82a)`

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 ([Quantum Code from an Even Linear Code](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#example-ex-1cf7b5)) is equivalent to a length $12$ binary additive code in extended format.

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

```magma
> 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]
```

<a id="example-ex-ca78b6"></a>
##### `Example: Self-Dual Quantum Code Construction (ex-ca78b6)`

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$.

```magma
> 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]
```

<a id="example-ex-f692ec"></a>
##### `Example: Quantum Code from an Additive Code (ex-f692ec)`

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.

```magma
> 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.

```magma
> 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]
```

<a id="function-quantumcode-modmatrngelt"></a>
##### `QuantumCode(M): ModMatRngElt -> CodeQuantum`

```magma
ExtendedFormat: BoolElt                    Default: false
```

Given a matrix $M$ over $GF(q^2)$ 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(q^2)$. 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)$.

<a id="example-ex-863e76"></a>
##### `Example: Quantum Code from a Stabilizer Matrix (ex-863e76)`

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 [Quantum Code from an Additive Code](https://docs.magma-maths.org/CodingTheory/QuantumCodes/creation.md#example-ex-f692ec) could have also been constructed as follows:

```magma
> 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]
```

<a id="function-quantumcode-grph"></a>
##### `QuantumCode(G): Grph -> CodeQuantum`

Given a graph $G$, return the self-dual (dimension $0$) quantum code defined by the adjacency matrix of $G$.

<a id="example-ex-29ea9f"></a>
##### `Example: Hexacode from a Wheel Graph (ex-29ea9f)`

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.

```magma
> 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)
```

<a id="example-ex-d4d3a5"></a>
##### `Example: Dodecacode from a Graph (ex-d4d3a5)`

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](https://docs.magma-maths.org/references.md#cite-danielsonmasters)]. In order to employ modular arithmetic, the graph vertices are numbered from $0$ to $11$.

```magma
> 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)
```

<a id="function-randomquantumcode-fldfin-rngintelt-rngintelt"></a>
##### `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 \ge k$, this function returns a random $[[n,k]]$ quantum stabilizer code over $F$. The field $F$ is assumed to be given in compact format.

<a id="example-ex-27cad1"></a>
##### `Example: Random Quantum Code (ex-27cad1)`

We construct a random $[[10, 6]]$ quantum code over $GF(4)$.

```magma
> 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]
```

<a id="function-subcode-codequantum-rngintelt"></a>
##### `Subcode(Q, k): CodeQuantum, RngIntElt -> CodeQuantum`

Given a quantum code $Q$ of dimension $k_Q \ge k$ then return a subcode of $Q$ of dimension $k$.

#### Construction of Special Quantum Codes

<a id="function-hexacode"></a>
##### `Hexacode() -> CodeQuantum`

Return the $[[6,0,4]]$ self-dual quantum hexacode.

<a id="function-dodecacode"></a>
##### `Dodecacode() -> CodeQuantum`

Return the $[[12,0,6]]$ self-dual quantum dodecacode.

#### CSS Codes

<a id="function-csscode-code-code"></a>
##### `CSSCode(C1, C2): Code, Code -> CodeQuantum`

<a id="function-calderbankshorsteanecode-code-code"></a>
##### `CalderbankShorSteaneCode(C1, C2): Code, Code -> CodeQuantum`

Given two classical linear binary codes $C_1$ and $C_2$ of length $n$ such that $C_2$ is a subcode of $C_1$, form a quantum code using the construction of Calderbank, Shor, and Steane [[CS96](https://docs.magma-maths.org/references.md#cite-css1), [Ste96a](https://docs.magma-maths.org/references.md#cite-css2), [Ste96b](https://docs.magma-maths.org/references.md#cite-css3)].

<a id="example-ex-37614f"></a>
##### `Example: CSS Construction from a Hamming Code (ex-37614f)`

Let $C_1$ denote the $[7,4,3]$ Hamming code and $C_2$ denote its dual. Observing that $C_1$ contains $C_2$, we may apply the CSS construction using $C_1$ and $C_2$ to obtain a $[[7,1,3]]$ code.

```magma
> 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](https://docs.magma-maths.org/references.md#cite-crss)] for generating polynomials which give rise to symplectic self-orthogonal stabilizer codes.

<a id="function-quantumcycliccode-modtupfldelt"></a>
##### `QuantumCyclicCode(v): ModTupFldElt -> CodeAdd`

<a id="function-quantumcycliccode-modtupfldelt-2"></a>
##### `QuantumCyclicCode(Q): [ModTupFldElt] -> CodeAdd`

```magma
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.

<a id="example-ex-0477fe"></a>
##### `Example: Cyclic Quantum Code from a Vector (ex-0477fe)`

A large number of good cyclic quantum codes exist. For example, the best known binary self-dual quantum code of length $15$ is cyclic.

```magma
> 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)
```

<a id="function-quantumcycliccode-rngintelt-rngupolelt"></a>
##### `QuantumCyclicCode(n, f): RngIntElt, RngUPolElt -> CodeAdd`

<a id="function-quantumcycliccode-rngintelt-rngupolelt-2"></a>
##### `QuantumCyclicCode(n, Q): RngIntElt, [RngUPolElt] -> CodeAdd`

```magma
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.

<a id="example-ex-87e469"></a>
##### `Example: Cyclic Quantum Codes from Polynomials (ex-87e469)`

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]]$.

```magma
> 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)
```

<a id="function-quantumcycliccode-modtupfldelt-modtupfldelt"></a>
##### `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 $v_4$ is over $GF(4)$ and $v_2$ 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.

<a id="example-ex-088686"></a>
##### `Example: Cyclic Quantum Code from Quaternary and Binary Vectors (ex-088686)`

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.

```magma
> 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.

<a id="function-quantumquasicycliccode-rngintelt-seqenum-rngupolelt"></a>
##### `QuantumQuasiCyclicCode(n, Q): RngIntElt, SeqEnum[RngUPolElt] -> CodeAdd`

```magma
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.

<a id="function-quantumquasicycliccode-seqenum-modtupfldelt"></a>
##### `QuantumQuasiCyclicCode(Q): SeqEnum[ModTupFldElt] -> CodeAdd`

```magma
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).

<a id="example-ex-efccba"></a>
##### `Example: Quasi-Cyclic Quantum Codes (ex-efccba)`

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]]$.

```magma
> 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)
```

### Access Functions

<a id="function-quantumbasiselement-fldfin"></a>
#### `QuantumBasisElement(F): FldFin -> FldFinElt`

Given a finite field $F = GF(q)$, return the element $\lambda \in GF(q^2)$ in the degree $2$ extension of $F$ which connects the extended and compact formats. For a vector $({\bf a}| {\bf b})$ in extended format over $F$, the corresponding compact vector is ${\bf w}= {\bf a}+ \lambda {\bf b}$.

<a id="example-ex-2560f5"></a>
#### `Example: Quantum Basis Element (ex-2560f5)`

The argument to `QuantumBasisElement` is the base field $GF(q)$; the returned element $\lambda$ lies in the quadratic extension $GF(q^2)$.

```magma
> Parent(QuantumBasisElement(GF(2)));
Finite field of size 2^2
> Parent(QuantumBasisElement(GF(3)));
Finite field of size 3^2
```

For $q = 2$ the element $\lambda$ is the generator $w$ of $GF(4)$, and it converts an extended-format vector $(a|b)$ over $GF(2)$ into its compact form $a + \lambda b$ over $GF(4)$.

```magma
> F<w> := GF(4);
> lambda := QuantumBasisElement(GF(2));
> lambda eq w;
true
> a := [GF(2) | 1, 0];
> b := [GF(2) | 0, 1];
> [ a[i] + lambda*b[i] : i in [1..#a] ];
[ 1, w ]
```

<a id="function-stabilizercode-codequantum"></a>
#### `StabilizerCode(Q): CodeQuantum -> CodeAdd`

<a id="function-stabilisercode-codequantum"></a>
#### `StabiliserCode(Q): CodeQuantum -> CodeAdd`

```magma
ExtendedFormat: BoolElt                    Default: false
```

The additive stabiliser code $S$ which defines the quantum code $Q$. By default $S$ is returned in the compact format of a length $n$ code over $GF(q^2)$, but if `ExtendedFormat` is set to `true`, then it will be returned in extended format as a length $2n$ code over $GF(q)$.

<a id="function-stabilizermatrix-codequantum"></a>
#### `StabilizerMatrix(Q): CodeQuantum -> ModMatFldElt`

<a id="function-stabilisermatrix-codequantum"></a>
#### `StabiliserMatrix(Q): CodeQuantum -> ModMatFldElt`

```magma
ExtendedFormat: BoolElt                    Default: false
```

Given a quantum code $Q$ return the additive stabiliser matrix $M$ defining $Q$. By default $M$ is returned in the compact format of a length $n$ code over $GF(q^2)$, but if `ExtendedFormat` is set to `true`, then it will be returned in the extended format as a length $2n$ code over $GF(q)$.

<a id="function-normalizercode-codequantum"></a>
#### `NormalizerCode(Q): CodeQuantum -> CodeAdd`

<a id="function-normalisercode-codequantum"></a>
#### `NormaliserCode(Q): CodeQuantum -> CodeAdd`

```magma
ExtendedFormat: BoolElt                    Default: false
```

The additive normalizer code $N$ which defines the quantum code $Q$. By default $N$ is returned in the compact format of a length $n$ code over $GF(q^2)$, but if `ExtendedFormat` is set to `true`, then it will be returned in extended format as a length $2n$ code over $GF(q)$.

<a id="function-normalizermatrix-codequantum"></a>
#### `NormalizerMatrix(Q): CodeQuantum -> ModMatFldElt`

<a id="function-normalisermatrix-codequantum"></a>
#### `NormaliserMatrix(Q): CodeQuantum -> ModMatFldElt`

```magma
ExtendedFormat: BoolElt                    Default: false
```

Given a quantum code $Q$ return the additive normalizer matrix $M$ defining $Q$. By default $M$ is returned in the compact format of a length $n$ code over $GF(q^2)$, but if `ExtendedFormat` is set to `true`, then it will be returned in the extended format as a length $2n$ code over $GF(q)$.

#### Quantum Error Group

As described in the introduction to this chapter, vectors over a finite field used to describe a quantum stabilizer code actually represent elements of the corresponding quantum error group. For a $p$-ary $N$ qubit system (where $p$ is prime) this error group is the extra-special group with order $2^{2N+1}$ consisting of combinations of $N$ bit-flip errors, $N$ phase flip errors, and an overall phase shift. All groups in this section use a polycyclic group representation.

<a id="function-quantumerrorgroup-rngintelt-rngintelt"></a>
##### `QuantumErrorGroup(p, n): RngIntElt, RngIntElt -> GrpPC`

Return the abelian group representing all possible errors for a length $n$ $p$-ary qubit system, which is an extra-special group of order $p^{2n + 1}$ with $2n+1$ generators. The generators correspond to the qubit-flip operators $X(i)$, the phase-flip operators $Z(i)$, and an overall phase multiplication $W$ by the $p$-th root of unity. The generators appear in the order $X(1),Z(1),\ldots,X(n),Z(n),W$.

<a id="function-quantumbinaryerrorgroup-rngintelt"></a>
##### `QuantumBinaryErrorGroup(n): RngIntElt -> GrpPC`

Return the abelian group representing all possible errors on a length $n$ binary qubit system, which is an extra special group of order $2^{2n-1}$.

<a id="example-ex-442960"></a>
##### `Example: Commutativity in the Quantum Error Group (ex-442960)`

The image of a vector in the error group is easily obtained from its extended format representation. We illustrate the connection between symplectic orthogonality as a vector, and commutativity as an element of the error group.

```magma
> n := 5;
> VSn  := VectorSpace(GF(2), n);
> VS2n := VectorSpace(GF(2), 2*n);
> E := QuantumBinaryErrorGroup(n);
> BitFlips   := [E.i : i in [1..2*n] | IsOdd(i)  ];
> PhaseFlips := [E.i : i in [1..2*n] | IsEven(i) ];
```

We first take two vectors which are not orthogonal and show their images in the error group do not commute.

```magma
> v1a := VSn ! [0,1,1,0,1]; v1b := VSn ! [0,1,1,0,1];
> v1  := VS2n ! HorizontalJoin(v1a, v1b);
> v2a := VSn ! [1,0,1,1,0]; v2b := VSn ! [0,1,0,1,1];
> v2  := VS2n ! HorizontalJoin(v2a, v2b);
> SymplecticInnerProduct(v1,v2 : ExtendedFormat := true);
1
>
> e1 := &*[ BitFlips[i]   : i in Support(v1a) ] *
>       &*[ PhaseFlips[i] : i in Support(v1b) ];
> e2 := &*[ BitFlips[i]   : i in Support(v2a) ] *
>       &*[ PhaseFlips[i] : i in Support(v2b) ];
> e1*e2 eq e2*e1;
false
```

Next a pair of orthogonal vectors is shown to commute.

```magma
> v1a := VSn ! [1,1,0,1,0]; v1b := VSn ! [0,0,1,1,0];
> v1  := VS2n ! HorizontalJoin(v1a, v1b);
> v2a := VSn ! [0,1,1,1,0]; v2b := VSn ! [0,1,1,1,0];
> v2  := VS2n ! HorizontalJoin(v2a, v2b);
> SymplecticInnerProduct(v1,v2 : ExtendedFormat := true);
0
>
> e1 := &*[ BitFlips[i]   : i in Support(v1a) ] *
>       &*[ PhaseFlips[i] : i in Support(v1b) ];
> e2 := &*[ BitFlips[i]   : i in Support(v2a) ] *
>       &*[ PhaseFlips[i] : i in Support(v2b) ];
> e1*e2 eq e2*e1;
true
```

<a id="function-quantumerrorgroup-codequantum"></a>
##### `QuantumErrorGroup(Q): CodeQuantum -> GrpPC`

For a quantum code $Q$ of length $n$, return the group of all errors on $n$ qubits. This is the full error group, the ambient space containing all possible errors.

<a id="function-stabilizergroup-codequantum"></a>
##### `StabilizerGroup(Q): CodeQuantum -> GrpPC`

<a id="function-stabilisergroup-codequantum"></a>
##### `StabiliserGroup(Q): CodeQuantum -> GrpPC`

Return the abelian group of errors that defines the quantum code $Q$, which is a subgroup of the group returned by `QuantumErrorGroup(Q)`.

<a id="function-stabilizergroup-codequantum-grppc"></a>
##### `StabilizerGroup(Q, G): CodeQuantum, GrpPC -> GrpPC`

<a id="function-stabilisergroup-codequantum-grppc"></a>
##### `StabiliserGroup(Q, G): CodeQuantum, GrpPC -> GrpPC`

Given a quantum code $Q$ with error group $G$ (an extra-special group), return the abelian group of errors of $Q$ as a subgroup of $G$.

<a id="example-ex-1844d0"></a>
##### `Example: Stabilizer Group of a Quantum Code (ex-1844d0)`

The stabilizer group of any quantum stabilizer code over $GF(4)$ will be abelian.

```magma
> F<w> := GF(4);
> Q := RandomQuantumCode(F, 10, 6);
> G := StabilizerGroup(Q);
> IsAbelian(G);
true
```

<a id="example-ex-8f08f4"></a>
##### `Example: Compatible Stabilizer Groups (ex-8f08f4)`

In order to make stabilizer groups from distinct codes compatible with one another, the groups must be created within the same super-structure. This is done by first creating a copy of the full error group, and then generating each instance of a stabilizer group as a subgroup.

In this example, the intersection of the stabilizer groups of two random codes is formed. An error group $E$ which will be a common over group for the two stabilizer groups is first created.

```magma
> F<w> := GF(4);
> Q1 := RandomQuantumCode(F, 15, 8);
> Q2 := RandomQuantumCode(F, 15, 8);
>
> E := QuantumErrorGroup(Q1);
> S1 := StabilizerGroup(Q1, E);
> S2 := StabilizerGroup(Q2, E);
> #(S1 meet S2);
2
```

### Inner Products and Duals

The functions described in this section use the symplectic inner product defined for quantum codes.

<a id="function-symplecticinnerproduct-modtupfldelt-modtupfldelt"></a>
#### `SymplecticInnerProduct(v1, v2): ModTupFldElt, ModTupFldElt -> FldFinElt`

```magma
ExtendedFormat: BoolElt                    Default: false
```

Let $v1$ and $v2$ be two vectors belonging to the vector space $K^{(n)}$, where $K$ is a finite field. This function returns the inner product of $v1$ and $v2$ with respect to the symplectic inner product used for quantum codes. The symplectic inner product in extended format is defined by $(a|b)*(c|d) = ad - bc$, and its definition transfers naturally to the compact format.

Let $p$ be the characteristic of $K$. In extended format the intrinsic returns ${\rm Tr}_{K/GF(p)}(ad - bc)$. In compact format $K = GF(q^2)$ and each coordinate is written as $a + \lambda b$ with $a, b \in GF(q)$ (where $\lambda$ is `QuantumBasisElement`$(GF(q))$); the product $ad - bc$ is formed over $GF(q)$ and the intrinsic returns ${\rm Tr}_{GF(q)/GF(p)}(ad - bc)$, the trace from $GF(q)$ rather than the absolute trace from $GF(q^2)$. In both cases the return value lies in the prime field $GF(p)$ (for example $GF(2)$ when $K = GF(4)$), not in $K$ in general. For binary quantum codes whose compact format is over $GF(4)$ this amounts to `Trace`$(v_1 \cdot \overline{v}_2)$.

This product is an alternating $GF(p)$-bilinear form on $K^{(n)}$ regarded as a vector space over $GF(p)$, but in general it is neither $K$-valued nor $K$-bilinear. To evaluate a $K$-valued alternating form attached to the $K$-space itself, attach the form to the space with `SymplecticSpace` (or `VectorSpace(K,n,J)`) and use `InnerProduct`; see Chapter [Polar Spaces](https://docs.magma-maths.org/MatricesLinearAlgebra/PolarSpaces/index-polar-spaces.md#chappolarspace).

<a id="example-ex-176f6b"></a>
#### `Example: Symplectic Products Compared (ex-176f6b)`

The coding-theory product and an attached alternating form can give different values for vectors with the same coordinates.

```magma
> F<w> := GF(4);
> V := VectorSpace(F,2);
> v := V![1,0];
> x := V![1,w];
> coding := SymplecticInnerProduct(v,x);
> coding;
0
> Parent(coding);
Finite field of size 2
> J := Matrix(F,2,2,[0,1,-1,0]);
> W := SymplecticSpace(J);
> ordinary := InnerProduct(W![1,0],W![1,w]);
> ordinary;
w
> Parent(ordinary);
Finite field of size 2^2
```

<a id="example-ex-f66c0e"></a>
#### `Example: Symplectic Product Formats (ex-f66c0e)`

Writing each coordinate of the compact vector $[w,0]$ over $GF(4)$ as $a + \lambda b$ with $\lambda = w$ (so $w = 0 + \lambda$ and $0 = 0$) gives the extended vector $[0,0,1,0]$ over $GF(2)$. Both formats yield the same symplectic inner product.

```magma
> F<w> := GF(4);
> V := VectorSpace(F, 2);
> compact := SymplecticInnerProduct(V![w,0], V![1,0]);
> compact;
1
> W := VectorSpace(GF(2), 4);
> extended := SymplecticInnerProduct(W![0,0,1,0], W![1,0,0,0] : ExtendedFormat);
> extended;
1
> compact eq extended;
true
```

<a id="function-symplecticdual-codeadd"></a>
#### `SymplecticDual(C): CodeAdd -> CodeAdd`

```magma
ExtendedFormat: BoolElt                    Default: false
```

The dual of the additive (or possibly linear) code $C$ with respect to the symplectic inner product. By default, $C$ is interpreted as being in the compact format (a length $n$ code over $GF(q^2)$), but if `ExtendedFormat` is set to `true`, then it will be interpreted as being in extended format (a code of length $2n$ over $GF(q)$).

<a id="function-issymplecticselfdual-codeadd"></a>
#### `IsSymplecticSelfDual(C): CodeAdd -> BoolElt`

```magma
ExtendedFormat: BoolElt                    Default: false
```

Return `true` if the code $C$ is equal to its symplectic dual and `false` otherwise. By default, $C$ is interpreted as being in the compact format (a length $n$ code over $GF(q^2)$), but if `ExtendedFormat` is set to `true`, then it will be interpreted as being in extended format (a code of length $2n$ over $GF(q)$).

<a id="function-issymplecticselforthogonal-codeadd"></a>
#### `IsSymplecticSelfOrthogonal(C): CodeAdd -> BoolElt`

```magma
ExtendedFormat: BoolElt                    Default: false
```

Return `true` if the code $C$ is contained in its symplectic dual. By default, $C$ is interpreted as being in the compact format (a length $n$ code over $GF(q^2)$), but if `ExtendedFormat` is set to `true`, then it will be interpreted as being in extended format (a code of length $2n$ over $GF(q)$).

<a id="example-ex-b98847"></a>
#### `Example: Symplectically Orthogonal Vectors (ex-b98847)`

Vectors which are symplectically orthogonal to one another can be used to construct symplectic self-orthogonal codes.

```magma
> F<w> := GF(4);
> V5 := VectorSpace(F, 5);
> v := V5 ! [1,0,w,0,1];
> w := V5 ! [w,1,0,w,w];
> SymplecticInnerProduct(v,w);
0
> C := AdditiveCode<F, GF(2), 5 | v, w>;
> C;
[5, 1 : 2] GF(2)-Additive Code over GF(2^2)
Generator matrix:
[  1   0   w   0   1]
[  w   1   0   w   w]
> D := SymplecticDual(C);
> D;
[5, 4 : 8] GF(2)-Additive Code over GF(2^2)
Generator matrix:
[  1   0   0   0   1]
[  w   0   0   0   w]
[  0   1   0   0   0]
[  0   w   0   0   1]
[  0   0   1   0   w]
[  0   0   w   0   0]
[  0   0   0   1   1]
[  0   0   0   w   0]
> C subset D;
true
> Q := QuantumCode(C);
> Q;
[[5, 3]] Quantum code over GF(2^2), stabilised by:
[  1   0   w   0   1]
[  w   1   0   w   w]
```

<a id="example-ex-937695"></a>
#### `Example: Symplectic Self-Orthogonality of Vectors (ex-937695)`

Any vector over $GF(4)$ will be symplectically orthogonal to itself.

```magma
> V5 := VectorSpace(GF(4), 5);
> { SymplecticInnerProduct(v, v) : v in V5 };
{ 0 }
```

### Weight Distribution and Minimum Weight

The weight distribution of a quantum code $Q$ consists of three separate distributions:

- The weight distribution of the stabilizer code $S$.
- The weight distribution of the symplectic dual $S^\perp$ of $S$.
- The weight distribution of the codewords in $S^\perp \backslash S$. Note that this set is not a linear space.

For a quantum code $Q$ with stabilizer code $S$, the weights of the undetectable errors are the weights of the codewords in $S^\perp \backslash S$.

For a quantum code to be considered *pure*, its minimum weight must be less than or equal to the weight of its stabilizer code.

<a id="function-weightdistribution-codequantum"></a>
#### `WeightDistribution(Q): CodeQuantum -> SeqEnum, SeqEnum, SeqEnum`

Given a quantum code $Q$ with stabiliser code $S$, return its weight distribution. Recall that the quantum weight distribution comprises the weight distributions of $S$, $S^\perp$, and $S^\perp \backslash S$. The function returns each distribution as a separate value. Each weight distribution is returned in the form of a sequence of tuples consisting of a weight and the number of code words of that weight.

<a id="example-ex-839de5"></a>
#### `Example: Weight Distributions of a Quantum Code (ex-839de5)`

Looking at a small quantum code from the database of best known codes. Its first weight distribution is of its stabilizer code $S$, the second of its normalizer code $S^\perp$, and the final weight distribution is of those non-zero codewords in $S^\perp \backslash S$.

```magma
> F<w> := GF(4);
> Q := QECC(GF(4),6,3);
> Q;
[[6, 3, 2]] Quantum code over GF(2^2), stabilised by:
[  1   0   1   1   1   0]
[  w   w   w   w   w   w]
[  0   1   0   0   0   1]
> WD_S, WD_N, WD := WeightDistribution(Q);
> WD_S eq WeightDistribution(StabiliserCode(Q));
true
> WD_N eq WeightDistribution(NormaliserCode(Q));
true
> WD;
[ <2, 28>, <3, 56>, <4, 154>, <5, 168>, <6, 98> ]
```

<a id="function-minimumweight-codequantum"></a>
#### `MinimumWeight(Q): CodeQuantum -> RngIntElt`

```magma
Method        : MonStgElt                      Default: "Auto"
RankLowerBound: RngIntElt                      Default: 0
MaximumTime   : RngReSubElt                    Default: Infinity()
```

For the quantum code $Q$ with stabilizer code $S$, return the minimum weight of $Q$, which is the minimum weight of the codewords in $S^\perp \backslash S$. For self-dual quantum codes (those of dimension $0$), the minimum weight is defined to be the minimum weight of $S$. The default algorithm is based on the minimum weight algorithm for classical linear codes which is described in detail in section [The Minimum Weight](https://docs.magma-maths.org/CodingTheory/LinearCodes/structural.md#code-lin-minweight). For a description of the algorithm and its variable argument parameters please consult the full description provided there. The minimum weight may alternatively be calculated by finding the complete weight distribution. This algorithm may be selected by setting the value of the variable argument `Method` to “`Distribution`”.

<a id="example-ex-9556d5"></a>
#### `Example: Minimum Weight of a Quantum Code (ex-9556d5)`

The verbose output can be used in long minimum weight calculations to estimate the remaining running time. The algorithm terminates once the lower bound reaches the upper bound. The example below finishes in a very short period of time.

```magma
> F<w> := GF(4);
> V5 := VectorSpace(F, 5);
> gens := [V5| [0,0,1,w,w], [0,1,1,w,1], [0,0,1,0,w^2],
>              [0,0,1,w,1], [0,0,1,0,1], [1,w,1,w,w^2],
>              [1,1,1,w^2,w], [0,1,w,1,w^2] ];
> Q := QuantumQuasiCyclicCode(gens : LinearSpan := true);
> Q:Minimal;
[[40, 30]] Quantum code over GF(2^2)
> SetVerbose("Code",true);
> MinimumWeight(Q);
Quantum GF(2)-Additive code over GF(4) of length 40 with 70 generators.
Lower Bound: 1, Upper Bound: 40
Constructed 2 distinct generator matrices
Total Ranks:     35  35
Relative Ranks:  35   5
Time Taken: 0.14
Starting search for low weight codewords... (reset timings)
Enumerating using 1 generator at a time:
     New codeword identified of weight 6, time 0.00
     New codeword identified of weight 4, time 0.00
     Discarding non-contributing rank 5 matrix
     New Total Ranks:     35
     New Relative Ranks:  35
   Completed Matrix  1:  lower =  2, upper =  4. Elapsed: 0.00s
Termination predicted with 3 generators at matrix 1
Enumerating using 2 generators at a time:
   Completed Matrix  1:  lower =  3, upper =  4. Elapsed: 0.00s
Termination predicted with 3 generators at matrix 1
predicting enumerating (1820) 60725 vectors (0.000000% of 40 40 code)
Enumerating using 3 generators at a time:
   Completed Matrix  1:  lower =  4, upper =  4. Elapsed: 0.03s
Final Results: lower = 4, upper = 4, Total time: 0.03
4
```

<a id="function-ispure-codequantum"></a>
#### `IsPure(Q): CodeQuantum -> BoolElt`

Return `true` if $Q$ is a *pure* quantum code. That is, if the minimum weight of $Q$ is less than or equal to the minimum weight of its stabiliser code.

<a id="example-ex-e05555"></a>
#### `Example: Purity of Best Known Quantum Codes (ex-e05555)`

Many good codes are impure, the purity of best known quantum codes of length $15$ are investigated.

```magma
> F<w> := GF(4);
> n := 15;
> time {* IsPure(QECC(F, n, k)) : k in [1..n] *};
{* false^^10, true^^5 *}
Time: 0.410
```

### New Codes From Old

<a id="function-directsum-codequantum-codequantum"></a>
#### `DirectSum(Q1, Q2): CodeQuantum, CodeQuantum -> CodeQuantum`

Given an $[[n_1,k_1,d_1]]$ quantum code $Q_1$, and an $[[n_2,k_2,d_2]]$ quantum code $Q_2$, return the $[[n_1+n_n,k_1+k_2, \min\{d_1,d_2\}]]$ quantum code which is their direct product.

<a id="function-extendcode-codequantum"></a>
#### `ExtendCode(Q): CodeQuantum -> CodeQuantum`

Given an $[[n,k,d]]$ quantum code $Q$, return the extended $[[n+1,k,d]]$ quantum code.

<a id="function-extendcode-codequantum-rngintelt"></a>
#### `ExtendCode(Q, m): CodeQuantum, RngIntElt -> CodeQuantum`

Perform $m$ extensions on the $[[n,k,d]]$ quantum code $Q$, returning the extended $[[n+m,k,d]]$ quantum code.

<a id="function-puncturecode-codequantum-rngintelt"></a>
#### `PunctureCode(Q, i): CodeQuantum, RngIntElt -> CodeQuantum`

Given a $[[n,k,d]]$ quantum code $Q$, and a coordinate position $i$, return the $[[n-1,k,d'>=d-1]]$ quantum code produced by puncturing at position $i$.

<a id="function-puncturecode-codequantum-setenum"></a>
#### `PunctureCode(Q, I): CodeQuantum, SetEnum -> CodeQuantum`

Given a $[[n,k,d]]$ quantum code $Q$, and a set of coordinate positions $I$ of size $s$, return the $[[n-s,k,d'>=d-s]]$ quantum code produced by puncturing at the positions in $I$.

<a id="function-shortencode-codequantum-rngintelt"></a>
#### `ShortenCode(Q, i): CodeQuantum, RngIntElt -> CodeQuantum`

Given a $[[n,k,d]]$ quantum code $Q$, and a coordinate position $i$, return the $[[n-1,k'>=k-1,d'>=d]]$ quantum code produced by shortening at position $i$.

This process will not necessarily result in a valid (symplectic self-orthogonal) quantum code, and an error will be given if it fails.

<a id="function-shortencode-codequantum-setenum"></a>
#### `ShortenCode(Q, I): CodeQuantum, SetEnum -> CodeQuantum`

Given a $[[n,k,d]]$ quantum code $Q$, and a set of coordinate positions $I$ of size $s$, return the $[[n-s,k'>=k-s,d'>=d]]$ quantum code produced by shortening at the positions in $I$.

This process will not necessarily result in a valid (symplectic self-orthogonal) quantum code, and an error will be given if it fails.

<a id="operation-op-pow-codequantum-grppermelt"></a>
#### `C ^ tau: CodeQuantum, GrpPermElt -> CodeQuantum`

Applies the permutation $\tau$ to the coordinates of the quantum code $C$.

<a id="example-ex-31e314"></a>
#### `Example: Combining Stabilizer Codes (ex-31e314)`

Good quantum codes can be created by combining stabilizer codes, using methods which are not general enough to warrant a specific quantum code function. This example creates a $[[28,8,6]]$ quantum code from $[[14,8,3]]$ and $[[14,0,6]]$ quantum codes using a Plotkin sum. It relies on the stabilizer codes forming a subcode chain, as described in Theorem $12$ in [[CRSS98](https://docs.magma-maths.org/references.md#cite-crss)].

```magma
> 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];
> Q1 := QuantumQuasiCyclicCode([v1, v2] : LinearSpan := true);
> _ := MinimumWeight(Q1);
> Q1:Minimal;
[[14, 0, 6]] self-dual Quantum code over GF(2^2)
>
> v1 := V7 ! [1,0,1,1,1,0,0];
> v2 := V7 ! [1,w^2,w,w,1,0,w^2];
> Q2 := QuantumQuasiCyclicCode([v1, v2] : LinearSpan := true);
> _ := MinimumWeight(Q2);
> Q2:Minimal;
[[14, 8, 3]] Quantum code over GF(2^2)
>
> S1 := StabilizerCode(Q1);
> S2 := StabilizerCode(Q2);
> S2 subset S1;
true
>
> S3 := PlotkinSum(SymplecticDual(S1), S2);
> Q3 := QuantumCode(S3);
> _ := MinimumWeight(Q3);
> Q3:Minimal;
[[28, 8, 6]] Quantum code over GF(2^2)
```

### Best Known Quantum Codes

An $[[n, k]]$ quantum stabiliser code $Q$ is said to be a *best known* $[[n, k]]$ *quantum code* (BKQC) if $C$ has the highest minimum weight among all known $[[n, k]]$ quantum codes. The acronym QECC (Quantum Error Correcting Code) will be used to more easily distinguish from the best known linear codes database (BKLC).

Magma currently has a database for binary quantum codes, though it should be noted that these codes are considered to be over the alphabet $GF(4)$, not $GF(2)$. The database for codes over $GF(4)$ currently contains constructions of all best known quantum codes of length $35$. This includes self-dual quantum codes up to length $35$, which are stored in the database as dimension $0$ quantum codes.

Quantum codes of length up to $12$ are optimal, in the sense that their minimum weights meet the upper bound. Thus the user has access to $665$ best-known binary quantum codes.

The Magma QECC database uses the tables of bounds and constructions compiled by Markus Grassl (Karlsruhe), available online at [[Grab](https://docs.magma-maths.org/references.md#cite-grasslweb)], which are based on the results in [[CRSS98](https://docs.magma-maths.org/references.md#cite-crss)]. Good codes have also been contributed by Eric Rains and Zlatko Varbanov.

The user can display the method used to construct a particular QECC code through use of a verbose mode, triggered by the verbose flag `BestCode`. When it is set to `true`, all of the functions in this section will output the steps involved in each code they construct.

<a id="function-qecc-fldfin-rngintelt-rngintelt"></a>
#### `QECC(F, n, k): FldFin, RngIntElt, RngIntElt -> CodeQuantum, BoolElt`

<a id="function-bkqc-fldfin-rngintelt-rngintelt"></a>
#### `BKQC(F, n, k): FldFin, RngIntElt, RngIntElt -> CodeQuantum, BoolElt`

<a id="function-bestknownquantumcode-fldfin-rngintelt-rngintelt"></a>
#### `BestKnownQuantumCode(F, n, k): FldFin, RngIntElt, RngIntElt -> CodeQuantum, BoolElt`

Given a finite field $F$, and positive integers $n$ and $k$ such that $k \le n$, return an $[[n,k]]$ quantum code over $F$ which has the largest minimum weight among all known $[[n,k]]$ quantum codes. A second boolean return value signals whether or not the desired code exists in the database.

The database currently exists for $GF(4)$ (which are in fact binary quantum codes) up to length $35$.

<a id="example-ex-4ef878"></a>
#### `Example: Weight Distribution of a Best Known Quantum Code (ex-4ef878)`

The weight distribution of a small best known quantum code is calculated, verifying its minimum weight. Note that the *larger* the dimension of a quantum code, the easier it is to calculate its weight distribution.

```magma
> F<w> := GF(4);
> Q := QECC(F,25,16);
> Q:Minimal;
[[25, 16, 3]] Quantum code over GF(2^2)
> time WD_S, WD_N, WD := WeightDistribution(Q);
Time: 0.010
> WD_S;
[ <0, 1>, <1, 2>, <2, 1>, <14, 4>, <15, 16>, <16, 38>, <17, 79>, <18, 126>, <19,
129>, <20, 77>, <21, 27>, <22, 9>, <23, 3> ]
> WD_N;
[ <0, 1>, <1, 2>, <2, 1>, <3, 399>, <4, 6527>, <5, 75363>, <6, 707543>, <7,
5404369>, <8, 34084490>, <9, 180107319>, <10, 804255370>, <11, 3052443894>, <12,
9883860222>, <13, 27348684334>, <14, 64649758926>, <15, 130286413858>, <16,
222912028997>, <17, 321704696752>, <18, 387985433701>, <19, 385943417035>, <20,
310898936275>, <21, 197566276671>, <22, 95232787563>, <23, 32688613821>, <24,
7109768160>, <25, 735493959> ]
> WD;
[ <3, 399>, <4, 6527>, <5, 75363>, <6, 707543>, <7, 5404369>, <8, 34084490>, <9,
180107319>, <10, 804255370>, <11, 3052443894>, <12, 9883860222>, <13,
27348684334>, <14, 64649758922>, <15, 130286413842>, <16, 222912028959>, <17,
321704696673>, <18, 387985433575>, <19, 385943416906>, <20, 310898936198>, <21,
197566276644>, <22, 95232787554>, <23, 32688613818>, <24, 7109768160>, <25,
735493959> ]
```

So the $[[25,16]]$ code is impure, and has a minimum distance of $3$.

<a id="example-ex-aece57"></a>
#### `Example: Self-Dual Quantum Codes (ex-aece57)`

Unlike linear codes, dimension $0$ quantum codes are non-trivial and are the subject of much study. These are the *self-dual* quantum codes, which form a special subclass of quantum stabilizer codes. It can be seen that a length $n$ self-dual code is described by a $n\times n$ generator matrix, an indication of the non-triviality of its structure.

```magma
> F<w> := GF(4);
> C := QECC(GF(4),8, 0);
> C;
[[8, 0, 4]] self-dual Quantum code over GF(2^2), stabilised by:
[  1   0   0   1   0   1   1   0]
[  w   0   0   w   0   w   w   0]
[  0   1   0   1   0   1   0   1]
[  0   w   0   w   0   w   0   w]
[  0   0   1   1   0   0   1   1]
[  0   0   w   w   0   0   w   w]
[  0   0   0   0   1   1   1   1]
[  0   0   0   0   w   w   w   w]
```

<a id="example-ex-e5b5cc"></a>
#### `Example: Tracing a Best Known Quantum Code Construction (ex-e5b5cc)`

The verbose flag `BestCode` will show the method by which the best code is constructed in the database. In this example the construction of a $[[25, 11, 4]]$ quantum code is described.

```magma
> SetVerbose("BestCode",true);
> F<w> := GF(4);
> Q := QECC(F,25,11);
Construction of a [[ 25 , 11 , 4 ]] Quantum Code:
[1]:  [[40, 30, 4]] Quantum code over GF(2^2)
        QuasiCyclicCode of length 40 stacked to height 2 with generating
        polynomials: 1,  w^2*x^4 + w*x^3 + w^2*x^2 + w*x + w^2,  x^4 + w^2*x^2 +
        w^2*x + w^2,  x^4 + w*x^3 + x^2,  w*x^4 + x^3 + w^2*x,  w*x^4 + x^3 +
        x^2 + x,  w^2*x^4 + x^2 + w*x,  x^4 + w^2*x^3 + w^2*x^2 + x + 1,  w,
        x^4 + w^2*x^3 + x^2 + w^2*x + 1,  w*x^4 + x^2 + x + 1,  w*x^4 + w^2*x^3
        + w*x^2,  w^2*x^4 + w*x^3 + x,  w^2*x^4 + w*x^3 + w*x^2 + w*x,  x^4 +
        w*x^2 + w^2*x,  w*x^4 + x^3 + x^2 + w*x + w
[2]:  [[21, 11, 4]] Quantum code over GF(2^2)
        Shortening of [1] at { 2, 3, 4, 6, 8, 9, 10, 12, 13, 14, 15, 16, 18, 19,
        21, 24, 28, 34, 37 }
[3]:  [[25, 11, 4]] Quantum code over GF(2^2)
        ExtendCode [2] by 4
> Q:Minimal;
[[25, 11, 4]] Quantum code over GF(2^2)
```

### Best Known Bounds

Along with the database of best known quantum codes in the previous section, there is also a database of best known upper and lower bounds on the maximal possible minimum weights of quantum codes. The upper bounds are not currently known with much accuracy, while the lower bounds match the minimum weights of the best known quantum codes database.

<a id="function-qecclowerbound-fldfin-rngintelt-rngintelt"></a>
#### `QECCLowerBound(F, n, k): FldFin, RngIntElt, RngIntElt -> RngIntElt`

Return the best known lower bound on the maximal minimum distance of $[[n, k]]$ quantum codes over $F$. The bounds are currently available for binary quantum codes (which corresponds to $F = GF(4)$) up to length $35$.

<a id="function-qeccupperbound-fldfin-rngintelt-rngintelt"></a>
#### `QECCUpperBound(F, n, k): FldFin, RngIntElt, RngIntElt -> RngIntElt`

Return the best known upper bound on the minimum distance of $[[n, k]]$ quantum codes over $F$. The bounds are currently available for binary quantum codes (which corresponds to $F = GF(4)$) up to length $35$.

<a id="example-ex-9d1cfb"></a>
#### `Example: Best Known Quantum Bounds (ex-9d1cfb)`

The best known lower bound on the minimum weight will always correspond to the best known quantum code from the Magma database. In this example the first code is in fact optimal, while the second one does not meet the upper bound, and so there is a theoretical possibility of an improvement.

```magma
> F<w> := GF(4);
> Q1 := QECC(F, 20, 10);
> Q1:Minimal;
[[20, 10, 4]] Quantum code over GF(2^2)
> QECCLowerBound(F, 20, 10);
4
> QECCUpperBound(F, 20, 10);
4
>
> Q2 := QECC(F, 25, 13);
> Q2:Minimal;
[[25, 13, 4]] Quantum code over GF(2^2)
> QECCLowerBound(F, 25, 13);
4
> QECCUpperBound(F, 25, 13);
5
```

### Automorphism Group

Automorphisms acting on a quantum code are a slight generalization of those which act on the underlying additive stabilizer code. Automorphisms consists of both a permutation action on the columns of a stabilizer code, combined with a monomial action on the individual columns which permute the values.

The automorphism group of a length $n$ additive stabilizer code over ${\mathbb{F}}_4$ is a subgroup of $Z_3 \wr Sym(n)$ of order $3*n!$. However the automorphism group of the quantum code it generates is a subgroup of $Sym(3) \wr Sym(n)$ of order $3!*n!$ because of the more general action on the values in the columns.

In Magma automorphisms are returned as permutations, either as length $3n$ permutations for the full monomial action on a code, or as length $n$ permutations when the automorphism is restricted to only the permutation action on the columns.

<a id="function-automorphismgroup-codequantum"></a>
#### `AutomorphismGroup(Q): CodeQuantum -> GrpPerm`

The automorphism group of the quantum code $Q$. Currently this function only applies to binary quantum codes.

<a id="function-permutationgroup-codequantum"></a>
#### `PermutationGroup(Q): CodeQuantum -> GrpPerm`

The subgroup of the automorphism group of the quantum code $Q$ consisting of those automorphisms which permute the coordinates of codewords. Currently this function only applies to binary quantum codes.

<a id="example-ex-9f0d8a"></a>
#### `Example: Automorphism Group of the Dodecacode (ex-9f0d8a)`

The full automorphism group and its subgroup of coordinate permutations are calculated for the dodecacode.

```magma
> F<w> := GF(4);
> Q := Dodecacode();
> Q;
[[12, 0, 6]] self-dual Quantum code over GF(2^2), stabilised by:
[  1   0   0   0   0   0 w^2 w^2   0   w   1   w]
[  w   0   0   0   0   0   w   0   w   w   w   1]
[  0   1   0   0   0   0   1   0   1 w^2 w^2   1]
[  0   w   0   0   0   0   0   w   1   w   w   w]
[  0   0   1   0   0   0   0   1   1   1 w^2 w^2]
[  0   0   w   0   0   0 w^2   1 w^2   w   w   0]
[  0   0   0   1   0   0   w   w   1   1   0   1]
[  0   0   0   w   0   0   w   1   w w^2 w^2   0]
[  0   0   0   0   1   0   w   w   w   0   1   w]
[  0   0   0   0   w   0 w^2   1   1 w^2   0   w]
[  0   0   0   0   0   1 w^2 w^2 w^2   1   0 w^2]
[  0   0   0   0   0   w   w   1   0   1   w   w]
>
> AutomorphismGroup(Q);
Permutation group acting on a set of cardinality 36
Order = 648 = 2^3 * 3^4
    (1, 4, 32)(2, 5, 33)(3, 6, 31)(7, 13, 29)(8, 14, 30)(9, 15, 28)(10, 35, 22)
        (11, 36, 23)(12, 34, 24)(16, 19, 26)(17, 20, 27)(18, 21, 25)
    (4, 23, 8, 29, 10, 20, 18, 36, 32)(5, 24, 9, 30, 11, 21, 16, 34, 33)
        (6, 22, 7, 28, 12, 19, 17, 35, 31)(13, 14, 15)(25, 27, 26)
    (7, 35)(8, 36)(9, 34)(10, 20)(11, 21)(12, 19)(13, 26)(14, 27)(15, 25)
        (16, 30)(17, 28)(18, 29)(22, 31)(23, 32)(24, 33)
    (4, 29, 18)(5, 30, 16)(6, 28, 17)(7, 19, 31)(8, 20, 32)(9, 21, 33)
        (10, 36, 23)(11, 34, 24)(12, 35, 22)
> PermutationGroup(Q);
Permutation group acting on a set of cardinality 12
    (1, 7, 9, 3, 5, 11)(2, 8, 10, 4, 6, 12)
    (1, 2)(3, 4)(5, 10)(6, 9)(7, 12)(8, 11)
    (2, 4)(5, 9)(6, 12)(7, 11)(8, 10)
```

<a id="example-ex-320db8"></a>
#### `Example: Automorphism Groups of the Hexacode (ex-320db8)`

The automorphism group for a quantum code is larger than that of its stabilizer code. In this example that is shown for the Hexacode.

```magma
> F<w> := GF(4);
> Q := Hexacode();
> Q:Minimal;
[[6, 0, 4]] self-dual Quantum code over GF(2^2)
> A_Q := AutomorphismGroup(Q);
> A_Q;
Permutation group A_Q acting on a set of cardinality 18
Order = 2160 = 2^4 * 3^3 * 5
    (1, 4)(2, 6)(3, 5)(7, 8)(10, 12)(13, 14)(17, 18)
    (2, 3)(5, 6)(7, 8)(10, 18)(11, 16)(12, 17)(13, 14)
    (4, 7)(5, 8)(6, 9)(13, 17)(14, 16)(15, 18)
    (7, 13)(8, 14)(9, 15)(10, 17)(11, 16)(12, 18)
    (7, 12)(8, 10)(9, 11)(13, 18)(14, 17)(15, 16)
> S := StabilizerCode(Q);
> A_S := AutomorphismGroup(S);
> A_S;
Permutation group A_S acting on a set of cardinality 18
Order = 180 = 2^2 * 3^2 * 5
    (1, 4)(2, 5)(3, 6)(7, 13)(8, 14)(9, 15)
    (4, 7, 12)(5, 8, 10)(6, 9, 11)(13, 15, 14)(16, 18, 17)
    (4, 6, 5)(7, 14, 11)(8, 15, 12)(9, 13, 10)(16, 18, 17)
> A_S subset A_Q;
true
```

### Hilbert Spaces

In this first release, Magma offers a basic package for creating and computing with quantum Hilbert spaces. A Hilbert space in Magma can either be *densely* or *sparsely* represented, depending on how many qubits are required and how dense the desired quantum states will be. While a dense representation has a speed advantage in computations, the sparse representation uses less memory. Currently there are capabilities for doing basic unitary transformations and manipulations of quantum states.

In future versions, functionality will be added for more complex unitary transformations and measurements, allowing for a more general simulation of quantum computations. There will also be machinery for encoding quantum states using quantum error correcting codes, and testing their effectiveness by simulating a noisy quantum channel and decoding the results.

<a id="function-hilbertspace-fldcom-rngintelt"></a>
#### `HilbertSpace(F, n): FldCom, RngIntElt -> HilbSpc`

```magma
IsDense: BoolElt                    Default: 
```

Given a complex field $F$ and a positive integer $n$, return then quantum Hilbert Space on $n$ qubits over $F$.

If the variable argument `IsDense` is set to either `true` or `false` then return a densely or sparsely represented quantum space respectively. If no value is set for `IsDense` then Magma will decide automatically.

<a id="function-field-hilbspc"></a>
#### `Field(H): HilbSpc -> FldCom`

Given a Hilbert space $H$, return the complex field over which the coefficients of states of $H$ are defined.

<a id="function-numberofqubits-hilbspc"></a>
#### `NumberOfQubits(H): HilbSpc -> RngIntElt`

<a id="function-nqubits-hilbspc"></a>
#### `Nqubits(H): HilbSpc -> RngIntElt`

Given a Hilbert space $H$, return the number of qubits which comprises the space.

<a id="function-dimension-hilbspc"></a>
#### `Dimension(H): HilbSpc -> RngIntElt`

Given a Hilbert space $H$, return its dimension. This is $2^n$, where $n$ is the number of qubits of $H$.

<a id="function-isdenselyrepresented-hilbspc"></a>
#### `IsDenselyRepresented(H): HilbSpc -> RngIntElt`

Return `true` if the quantum Hilbert space $H$ uses a dense representation.

<a id="operation-op-eq-hilbspc-hilbspc"></a>
#### `H1 eq H2: HilbSpc, HilbSpc -> BoolElt`

Return `true` if the Hilbert spaces are equal.

<a id="operation-op-ne-hilbspc-hilbspc"></a>
#### `H1 ne H2: HilbSpc, HilbSpc -> BoolElt`

Return `true` if the Hilbert spaces are not equal.

<a id="example-ex-a2ce0e"></a>
#### `Example: Dense and Sparse Hilbert Spaces (ex-a2ce0e)`

A Hilbert space over $5$ qubits will by default be a densely represented quantum space. It can however be manually chosen to use a sparse representation, it can be seen that these two space are not considered equal.

```magma
> F<i> := ComplexField(4);
> H := HilbertSpace(F, 5);
> H;
A densely represented Hilbert Space on 5 qubits to precision 4
> Dimension(H);
32
> IsDenselyRepresented(H);
true
>
> H1 := HilbertSpace(F, 5 : IsDense := false);
> H1;
A sparely represented Hilbert Space on 5 qubits to precision 4
> IsDenselyRepresented(H1);
false
> H eq H1;
false
```

#### Creation of Quantum States

<a id="function-quantumstate-hilbspc-modtupfldelt"></a>
##### `QuantumState(H, v): HilbSpc, ModTupFldElt -> HilbSpcElt`

<a id="function-quantumstate-hilbspc-mtrxsprs"></a>
##### `QuantumState(H, v): HilbSpc, MtrxSprs -> HilbSpcElt`

Given a Hilbert space $H$ and coefficients $v$ (which can be either a dense or a sparse vector), of length equal to the dimension of $H$, then return the quantum state in $H$ defined by $v$.

<a id="operation-op-hilbspc-rngintelt"></a>
##### `H ! i: HilbSpc, RngIntElt -> HilbSpcElt`

Return the $i$-th quantum basis state of the Hilbert space $H$. This corresponds to the basis state whose qubits giving a binary representation of $i$.

<a id="operation-op-hilbspc-rngintelt-2"></a>
##### `H ! s: HilbSpc, [RngIntElt] -> HilbSpcElt`

Given a sequence $s$ of binary values, whose length is equal to the number of qubits of the Hilbert space $H$, return the quantum basis state corresponding to $s$.

<a id="procedure-setprintketsinteger-boolelt"></a>
##### `SetPrintKetsInteger(b): BoolElt`

Input is a boolean value $b$, which controls a global variable determining the way quantum states are printed. If set to `false` (which is the default) then values in basis kets will be printed as binary sequences such as $| 1010 \rangle$. If set to `true` then basis kets will be printed using integer values to represent the binary sequences, the previous example becoming $| 5 \rangle$.

<a id="example-ex-1f7466"></a>
##### `Example: Quantum State from a Coefficient Vector (ex-1f7466)`

One way to create a quantum state is to specify each coefficient of the state with a vector of length equal to the dimension of the Hilbert space.

```magma
> F<i> := ComplexField(4);
> H := HilbertSpace(F, 4);
> KS := KSpace(F, Dimension(H));
> v := KS! [F| i,    1,    0, -i,
>              2,    0,    0, 1+i,
>              -i-1, -3*i, 7, 0.5,
>              2.5*i, 0,   0, 1.2];
> v;
(1.000*i 1.000 0.0000 -1.000*i 2.000 0.0000 0.0000 1.000 + 1.000*i
    -1.000 - 1.000*i -3.000*i 7.000 0.5000 2.500*i 0.0000 0.0000
    1.200)
> e := QuantumState(H, v);
> e;
1.000*i|0000> + |1000> - 1.000*i|1100> + 2.000|0010> + (1.000 +
1.000*i)|1110> - (1.000 + 1.000*i)|0001> - 3.000*i|1001> + 7.000|0101>
+ 0.5000|1101> + 2.500*i|0011> + 1.200|1111>
```

<a id="example-ex-9b3454"></a>
##### `Example: Quantum State from Basis States (ex-9b3454)`

Quantum states can be created by combining basis states, input as either integer values or binary sequences.

```magma
> F<i> := ComplexField(4);
> H := HilbertSpace(F, 12);
> Dimension(H);
4096
> e1 := H!1 + (1+i)*(H!76) - H!3000;
> e1;
|100000000000> + (1.000 + 1.000*i)|001100100000> - |000111011101>
> e2 := H![1,0,1,1,1,0,0,0,1,1,0,0] - H![1,1,0,1,0,0,0,0,1,1,0,1];
> e2;
|101110001100> - |110100001101>
```

By using the function `SetPrintKetsInteger` basis states can also be printed as either integer values of binary sequences.

```magma
> SetPrintKetsInteger(true);
> e1;
|1> + (1.000 + 1.000*i)|76> - |3000>
> e2;
|797> - |2827>
```

#### Manipulation of Quantum States

<a id="operation-op-times-fldcomelt-hilbspcelt"></a>
##### `a * e: FldComElt, HilbSpcElt -> HilbSpcElt`

Given a complex scalar value $a$, multiply the coefficients of the quantum state $e$ by $a$.

<a id="operation-operation-hilbspcelt-hilbspcelt"></a>
##### `- e: HilbSpcElt -> HilbSpcElt`

Negate all coefficients of the quantum state $e$.

<a id="operation-op-plus-hilbspcelt-hilbspcelt"></a>
##### `e1 + e2: HilbSpcElt, HilbSpcElt -> HilbSpcElt`

<a id="operation-op-minus-hilbspcelt-hilbspcelt"></a>
##### `e1 - e2: HilbSpcElt, HilbSpcElt -> HilbSpcElt`

Addition and subtraction of the quantum states $e_1$ and $e_2$.

<a id="function-normalisation-hilbspcelt"></a>
##### `Normalisation(e): HilbSpcElt -> HilbSpcElt`

<a id="procedure-normalisation-hilbspcelt-ref"></a>
##### `Normalisation(~e): HilbSpcElt`

<a id="function-normalization-hilbspcelt"></a>
##### `Normalization(e): HilbSpcElt -> HilbSpcElt`

<a id="procedure-normalization-hilbspcelt-ref"></a>
##### `Normalization(~e): HilbSpcElt`

Normalize the coefficients of the quantum state $e$, giving an equivalent state whose normalization coefficient is equal to one. Available either as a procedure or a function.

<a id="function-normalisationcoefficient-hilbspc"></a>
##### `NormalisationCoefficient(e): HilbSpc -> FldComElt`

<a id="function-normalizationcoefficient-hilbspc"></a>
##### `NormalizationCoefficient(e): HilbSpc -> FldComElt`

Return the normalisation coefficient of the quantum state $e$

<a id="operation-op-eq-hilbspcelt-hilbspcelt"></a>
##### `e1 eq e2: HilbSpcElt, HilbSpcElt -> BoolElt`

Return `true` if and only if the quantum states $e_1$ and $e_2$ are equal. States are still considered equal if they have different normalizations.

<a id="operation-op-ne-hilbspcelt-hilbspcelt"></a>
##### `e1 ne e2: HilbSpcElt, HilbSpcElt -> BoolElt`

Return `true` if and only if the quantum states $e_1$ and $e_2$ are not equal. States are still considered equal if they have different normalizations.

<a id="example-ex-d9a8c5"></a>
##### `Example: Normalisation of Quantum States (ex-d9a8c5)`

Although a quantum state can be expressed with any normalisation, in reality a quantum state occupies a ray in a Hilbert space. So two quantum states are still considered equal if they lie on the same ray.

```magma
> F<i> := ComplexField(8);
> H := HilbertSpace(F, 1);
> e := H!0 + H!1;
> e;
|0> + |1>
> NormalisationCoefficient(e);
2.0000000
> e1 := Normalisation(e);
> e1;
0.70710678|0> + 0.70710678|1>
> NormalisationCoefficient(e1);
0.99999999
> e eq e1;
true
```

#### Inner Product and Probabilities of Quantum States

<a id="function-innerproduct-hilbspcelt-hilbspcelt"></a>
##### `InnerProduct(e1, e2): HilbSpcElt, HilbSpcElt -> HilbSpcElt`

Return the inner product of the quantum states $e_1$ and $e_2$.

<a id="function-probabilitydistribution-hilbspcelt"></a>
##### `ProbabilityDistribution(e): HilbSpcElt -> Mtrx`

Return the probability distribution of the quantum state as a vector over the reals.

<a id="function-probability-hilbspcelt-rngintelt"></a>
##### `Probability(e, i): HilbSpcElt, RngIntElt -> FldReElt`

Return the probability of basis state $i$ being returned as the result of a measurement on the quantum state $e$.

<a id="function-probability-hilbspcelt-rngintelt-2"></a>
##### `Probability(e, v): HilbSpcElt, RngIntElt -> FldReElt`

Given a binary vector $v$ of length equal to the number of qubits in the quantum state $e$, return the probability of basis state corresponding to $v$ being returned as the result of a measurement on $e$.

<a id="procedure-printprobabilitydistribution-hilbspcelt"></a>
##### `PrintProbabilityDistribution(e): HilbSpcElt`

Print the probability distribution of the quantum state.

<a id="procedure-printsortedprobabilitydistribution-hilbspcelt"></a>
##### `PrintSortedProbabilityDistribution(e): HilbSpcElt`

```magma
Max           : RngIntElt                    Default: Infinity()
MinProbability: RngIntElt                    Default: 0
```

Print the probability distribution of the quantum state in sorted order, with the most probable states printed first.

If the variable argument `Max` is set to a positive integer, then it will denote the maximum number of basis states to be printed.

If the variable argument `MinProbability` is set to some integer between $1$ and $100$, then it will denote the minimum probability of any basis state to be printed. This is useful for investigating those basis states which will are the likely results of any measurement.

<a id="example-ex-c0f168"></a>
##### `Example: Probabilities of a Quantum State (ex-c0f168)`

From a quantum state it is possible to either access the full probability distribution, or the probabilities of individual basis states.

```magma
> F<i> := ComplexField(4);
> H := HilbertSpace(F, 3);
> e := -0.5*H!0 + 6*i*H!3 + 7*H!4 - (1+i)*H!7;
> ProbabilityDistribution(e);
(0.002865 0.0000 0.0000 0.4126 0.5616 0.0000 0.0000 0.02292)
> Probability(e, 0);
0.002865
> Probability(e, 1);
0.0000
```

It is also possible to print out the full probability distribution.

```magma
> PrintProbabilityDistribution(e);
Non-zero probabilities:
|000>:  0.2865%
|110>:  41.26%
|001>:  56.16%
|111>:  2.292%
```

<a id="example-ex-10594e"></a>
##### `Example: Sorted Probabilities of a Quantum State (ex-10594e)`

It is usually only those basis states with large probabilities that are of interest. With the function `PrintSortedProbabilitydistribution` these basis states can be identified.

```magma
> F<i> := ComplexField(4);
> H := HilbertSpace(F, 4);
> KS := KSpace(F, 2^4);
> v := KS! [F| i,   11,   0, -3*i,
>              2,   0,    0, 6+i,
>             -i-1, -3*i, 7, -0.5,
>             2.5*i, 0,   0, 9.2];
> e := QuantumState(H, v);
> e;
1.000*i|0000> + 11.00|1000> - 3.000*i|1100> + 2.000|0010> + (6.000 +
1.000*i)|1110> - (1.000 + 1.000*i)|0001> - 3.000*i|1001> + 7.000|0101>
- 0.5000|1101> + 2.500*i|0011> + 9.200|1111>
> PrintSortedProbabilityDistribution(e);
Non-zero probabilities:
|1000>:         37.45%
|1111>:         26.19%
|0101>:         15.16%
|1110>:         11.45%
|1100>:         2.785%
|1001>:         2.785%
|0011>:         1.934%
|0010>:         1.238%
|0001>:         0.6190%
|0000>:         0.3095%
|1101>:         0.07737%
```

A useful way to isolate the important basis states is to provide a minimum cutoff probability.

```magma
> PrintSortedProbabilityDistribution(e: MinProbability := 15);
Non-zero probabilities:
|1000>:         37.45%
|1111>:         26.19%
|0101>:         15.16%
Reached Minimum Percentage
```

Another way is to supply the maximum number basis states that should be printed. A combination of these methods can also be used

```magma
> PrintSortedProbabilityDistribution(e: Max := 6);
Non-zero probabilities:
|1000>:         37.45%
|1111>:         26.19%
|0101>:         15.16%
|1110>:         11.45%
|1100>:         2.785%
|1001>:         2.785%
Reached Maximum count
```

#### Unitary Transformations on Quantum States

In this first release Magma offers a small selection of unitary transformations on quantum states. In future versions this list will be expanded to include more complex operations.

<a id="function-bitflip-hilbspcelt-rngintelt"></a>
##### `BitFlip(e, k): HilbSpcElt, RngIntElt -> HilbSpcElt`

<a id="procedure-bitflip-hilbspcelt-rngintelt-ref"></a>
##### `BitFlip(~e, k): HilbSpcElt, RngIntElt`

Flip the value of the $k$-th qubit of the quantum state $e$.

<a id="function-bitflip-hilbspcelt-rngintelt-2"></a>
##### `BitFlip(e, B): HilbSpcElt, {RngIntElt} -> HilbSpcElt`

<a id="procedure-bitflip-hilbspcelt-rngintelt-ref-2"></a>
##### `BitFlip(~e, B): HilbSpcElt, {RngIntElt}`

Given a set of positive integers $B$, flip the value of the qubits of the quantum state $e$ indexed by the entries in $B$.

<a id="function-phaseflip-hilbspcelt-rngintelt"></a>
##### `PhaseFlip(e, k): HilbSpcElt, RngIntElt -> HilbSpcElt`

<a id="procedure-phaseflip-hilbspcelt-rngintelt-ref"></a>
##### `PhaseFlip(~e, k): HilbSpcElt, RngIntElt`

Flip the phase on the $k$-th qubit of the quantum state $e$.

<a id="function-phaseflip-hilbspcelt-rngintelt-2"></a>
##### `PhaseFlip(e, B): HilbSpcElt, {RngIntElt} -> HilbSpcElt`

<a id="procedure-phaseflip-hilbspcelt-rngintelt-ref-2"></a>
##### `PhaseFlip(~e, B): HilbSpcElt, {RngIntElt}`

Given a set of positive integers $B$, flip the phase on the qubits of the quantum state $e$ indexed by the entries in $B$.

<a id="function-controllednot-hilbspcelt-rngintelt-rngintelt"></a>
##### `ControlledNot(e, B, k): HilbSpcElt, {RngIntElt}, RngIntElt -> HilbSpcElt`

<a id="procedure-controllednot-hilbspcelt-rngintelt-rngintelt-ref"></a>
##### `ControlledNot(~e, B, k): HilbSpcElt, {RngIntElt}, RngIntElt`

Flip the $k$-th bit of the quantum state $e$ if all bits contained in $B$ are set to $1$.

<a id="function-hadamardtrasformation-hilbspcelt"></a>
##### `HadamardTrasformation(e): HilbSpcElt -> HilbSpcElt`

<a id="procedure-hadamardtrasformation-hilbspcelt-ref"></a>
##### `HadamardTrasformation(~e): HilbSpcElt`

Perform a Hadamard transformation on the quantum state $e$, which must be densely represented.

<a id="example-ex-360d11"></a>
##### `Example: Unitary Transformations of a Quantum State (ex-360d11)`

The behaviours of several of the available unitary transformations are displayed on a quantum state.

```magma
> F<i> := ComplexField(4);
> H := HilbertSpace(F, 4);
> e := H!0 + H!3 + H!6 + H!15;
> PhaseFlip(~e, 4); e;
|0000> + |1100> + |0110> - |1111>
> ControlledNot(~e, {1,2}, 4); e;
|0000> + |0110> - |1110> + |1101>
> BitFlip(~e, 2); e;
|0100> + |0010> - |1010> + |1001>
> ControlledNot(~e, {2}, 3); e;
|0010> - |1010> + |0110> + |1001>
```

## Pseudo-Random Bit Sequences

- [Introduction](https://docs.magma-maths.org/CodingTheory/PseudoRandomBitSequences/introduction.md)
- [Linear Feedback Shift Registers](https://docs.magma-maths.org/CodingTheory/PseudoRandomBitSequences/lfsr.md)
  - [`LFSRSequence(C, S, t): RngUPolElt, SeqEnum, RngIntElt → SeqEnum`](https://docs.magma-maths.org/CodingTheory/PseudoRandomBitSequences/lfsr.md#function-lfsrsequence-rngupolelt-seqenum-rngintelt)
  - [`LFSRStep(C, S): RngUPolElt, SeqEnum → SeqEnum`](https://docs.magma-maths.org/CodingTheory/PseudoRandomBitSequences/lfsr.md#function-lfsrstep-rngupolelt-seqenum)
  - [`BerlekampMassey(S): SeqEnum → RngUPolElt, RngIntElt`](https://docs.magma-maths.org/CodingTheory/PseudoRandomBitSequences/lfsr.md#function-berlekampmassey-seqenum)
  - [`ConnectionPolynomial(S): SeqEnum → RngUPolElt, RngIntElt`](https://docs.magma-maths.org/CodingTheory/PseudoRandomBitSequences/lfsr.md#function-connectionpolynomial-seqenum)
  - [`CharacteristicPolynomial(S): SeqEnum → RngUPolElt, RngIntElt`](https://docs.magma-maths.org/CodingTheory/PseudoRandomBitSequences/lfsr.md#function-characteristicpolynomial-seqenum)
  - [Example: Connection Polynomial via Berlekamp-Massey](https://docs.magma-maths.org/CodingTheory/PseudoRandomBitSequences/lfsr.md#example-ex-ad3ed3)
  - [`ShrinkingGenerator(C1, S1, C2, S2, t): RngUPolElt, SeqEnum, RngUPolElt, SeqEnum, RngIntElt → SeqEnum`](https://docs.magma-maths.org/CodingTheory/PseudoRandomBitSequences/lfsr.md#function-shrinkinggenerator-rngupolelt-seqenum-rngupolelt-seqenum-rngintelt)
- [Correlation Functions](https://docs.magma-maths.org/CodingTheory/PseudoRandomBitSequences/correlation.md)
  - [`AutoCorrelation(S, t): SeqEnum, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/PseudoRandomBitSequences/correlation.md#function-autocorrelation-seqenum-rngintelt)
  - [Example: Autocorrelation of an LFSR Sequence](https://docs.magma-maths.org/CodingTheory/PseudoRandomBitSequences/correlation.md#example-ex-e9917a)
  - [`CrossCorrelation(S1, S2, t): SeqEnum, SeqEnum, RngIntElt → RngIntElt`](https://docs.magma-maths.org/CodingTheory/PseudoRandomBitSequences/correlation.md#function-crosscorrelation-seqenum-seqenum-rngintelt)
- [Decimation](https://docs.magma-maths.org/CodingTheory/PseudoRandomBitSequences/misc.md)
  - [`Decimation(S, f, d): SeqEnum, RngIntElt, RngIntElt → SeqEnum`](https://docs.magma-maths.org/CodingTheory/PseudoRandomBitSequences/misc.md#function-decimation-seqenum-rngintelt-rngintelt)
  - [`Decimation(S, f, d, t): SeqEnum, RngIntElt, RngIntElt, RngIntElt → SeqEnum`](https://docs.magma-maths.org/CodingTheory/PseudoRandomBitSequences/misc.md#function-decimation-seqenum-rngintelt-rngintelt-rngintelt)
  - [Example: Decimating an LFSR Sequence](https://docs.magma-maths.org/CodingTheory/PseudoRandomBitSequences/misc.md#example-ex-29a760)
- [Hash Functions](https://docs.magma-maths.org/CodingTheory/PseudoRandomBitSequences/hash.md)
  - [`SHA1(S): SeqEnum → MonStgElt`](https://docs.magma-maths.org/CodingTheory/PseudoRandomBitSequences/hash.md#function-sha1-seqenum)
  - [`SHA1(s): MonStgElt → MonStgElt`](https://docs.magma-maths.org/CodingTheory/PseudoRandomBitSequences/hash.md#function-sha1-monstgelt)
  - [Example: Digest of a String and of Its Bytes](https://docs.magma-maths.org/CodingTheory/PseudoRandomBitSequences/hash.md#example-ex-d53a66)

### Introduction

Magma provides some tools for the creation and analysis of pseudo-random bit sequences. The universe of these sequences is generally ${\bf F}_{2}$. However, some functions, such as `BerlekampMassey`, may be applied to sequences defined over arbitrary finite fields. The chapter closes with the SHA-1 hash function, which maps a string or byte sequence of any length to a digest of fixed length.

### Linear Feedback Shift Registers

For a linear feedback shift register (LFSR) of length $L$, initial state $s_0, \ldots, s_{L-1} \in {\bf F}_{q}$, and connection polynomial $C(D) = 1 + c_1 D + c_2 D^2 + \ldots + c_L D^L$ (also over ${\bf F}_{q}$), the $j$’th element of the sequence is computed as $s_j = - \sum_{i=1}^L c_i s_{j-i}$ for $j \geq L$.

<a id="function-lfsrsequence-rngupolelt-seqenum-rngintelt"></a>
#### `LFSRSequence(C, S, t): RngUPolElt, SeqEnum, RngIntElt -> SeqEnum`

Computes the first $t$ sequence elements of the LFSR with connection polynomial $C$ and initial state the sequence $S$ (thus, the length of the LFSR is assumed to be the length of $S$). $C$ must be at least degree 1, its coefficients must come from the same finite field as the universe of $S$, and its constant coefficient must be $1$. Also, the sequence $S$ must have at least as many terms as the degree of $C$.

<a id="function-lfsrstep-rngupolelt-seqenum"></a>
#### `LFSRStep(C, S): RngUPolElt, SeqEnum -> SeqEnum`

Computes the next state of the LFSR having connection polynomial $C$ and current state the sequence $S$ (thus, the length of the LFSR is assumed to be the length of $S$). $C$ must be at least degree 1, its coefficients must come from the same finite field as the universe of $S$, and its constant coefficient must be $1$. Also, the sequence $S$ must have at least as many terms as the degree of $C$.

<a id="function-berlekampmassey-seqenum"></a>
#### `BerlekampMassey(S): SeqEnum -> RngUPolElt, RngIntElt`

<a id="function-connectionpolynomial-seqenum"></a>
#### `ConnectionPolynomial(S): SeqEnum -> RngUPolElt, RngIntElt`

<a id="function-characteristicpolynomial-seqenum"></a>
#### `CharacteristicPolynomial(S): SeqEnum -> RngUPolElt, RngIntElt`

Given a sequence S of elements from ${\bf F}_{q}$, return the connection polynomial $C(D)$ and the length $L$ of a LFSR that generates the sequence S.

Note that it is possible that the `BerlekampMassey` will return a singular LFSR (i.e. the degree of $C(D)$ is less than $L$), and therefore one must be sure to use the first $L$ elements of $S$ to regenerate the sequence.

<a id="example-ex-ad3ed3"></a>
#### `Example: Connection Polynomial via Berlekamp-Massey (ex-ad3ed3)`

We first create a sequence and then use `BerlekampMassey` to get the connection polynomial and its length:

```magma
> S:= [GF(2)| 1,1,0,1,0,1,1,1,0,0,1,0];
> C<D>, L := BerlekampMassey(S);
> C;
D^3 + D^2 + 1
> L;
5
```

Now create a new sequence $T$ containing the first $L$ elements of $S$, and reconstruct the sequence from $C(D)$ and $T$.

```magma
> T := S[1..L];
> LFSRSequence(C, T, #S);
[ 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0 ]
```

<a id="function-shrinkinggenerator-rngupolelt-seqenum-rngupolelt-seqenum-rngintelt"></a>
#### `ShrinkingGenerator(C1, S1, C2, S2, t): RngUPolElt, SeqEnum, RngUPolElt, SeqEnum, RngIntElt -> SeqEnum`

Outputs a sequence of $t$ bits from the shrinking generator having connection polynomials $C_1$ and $C_2$ and initial states sequences $S_1$ and $S_2$ (thus, the lengths of the LFSRs are assumed to be the lengths of $S_1$ and $S_2$). Bits are represented as elements from ${\bf F}_{2}$. Polynomial coefficients and sequence elements must be from ${\bf F}_{2}$. The degrees of the connection polynomials must be at least $1$ and their trailing coefficients must be $1$. The number of elements in the initial states must be at least as large as the degrees of the corresponding connection polynomials.

### Correlation Functions

<a id="function-autocorrelation-seqenum-rngintelt"></a>
#### `AutoCorrelation(S, t): SeqEnum, RngIntElt -> RngIntElt`

Computes the autocorrelation of a sequence $S$, where $S$ must have universe ${\bf F}_{2}$. The autocorrelation is defined to be

$$
C(t) = \sum_{i=1}^{L}  (-1)^{ S[i] + S[i+t] }
$$

where $L$ is the length of the sequence, and the values of $S[i+t]$ wrap around to the beginning of the sequence when $i+t > L$.

<a id="example-ex-e9917a"></a>
#### `Example: Autocorrelation of an LFSR Sequence (ex-e9917a)`

It is well known that the LFSR’s with maximal periods have nice autocorrelation properties. This is illustrated below.

```magma
> C<D> := PrimitivePolynomial (GF(2), 5);
> C;
D^5 + D^2 + 1
> s := [GF(2)|1,1,1,1,1];
> t := LFSRSequence(C, s, 31);
> t;
[ 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0,
1, 1, 0, 0, 0 ]
> AutoCorrelation (t, 2);
-1
```

<a id="function-crosscorrelation-seqenum-seqenum-rngintelt"></a>
#### `CrossCorrelation(S1, S2, t): SeqEnum, SeqEnum, RngIntElt -> RngIntElt`

Computes the crosscorrelation of two binary sequences $S_1$ and $S_2$, where $S_1$ and $S_2$ must each have universe ${\bf F}_{2}$, and they must have the same length $L$. The crosscorrelation is defined to be:

$$
C(t) = \sum_{i=1}^{L} (-1)^{ S_1[i] + S_2[i+t] }
$$

and the values of $S_2[i+t]$ wrap around to the beginning of the sequence when $i+t > L$.

### Decimation

<a id="function-decimation-seqenum-rngintelt-rngintelt"></a>
#### `Decimation(S, f, d): SeqEnum, RngIntElt, RngIntElt -> SeqEnum`

Given a binary sequence $S$, and integers $f$ and $d$, return the decimation of $S$. This is the sequence containing elements $S[f]$, $S[f+d]$, $S[f+2d]$, … where the indices in $S$ are interpreted with wrap-around as integers between $1$ and $\#S$.

<a id="function-decimation-seqenum-rngintelt-rngintelt-rngintelt"></a>
#### `Decimation(S, f, d, t): SeqEnum, RngIntElt, RngIntElt, RngIntElt -> SeqEnum`

Decimation of the sequence $S$. Returns a new sequence containing the first $t$ elements of $S[f]$, $S[f+d]$, $S[f+2d]$, … where the indices in $S$ are interpreted with wrap-around as integers between $1$ and #$S$.

<a id="example-ex-29a760"></a>
#### `Example: Decimating an LFSR Sequence (ex-29a760)`

Given a primitive polynomial over ${\bf F}_{q}$, one can obtain another primitive polynomial by decimating an LFSR sequence obtained from the initial polynomial. This is demonstrated in the code below.

```magma
> K := GF(7);
> C<D> := PrimitivePolynomial(K, 2);
> C;
D^2 + 6*D + 3
```

In order to generate an LFSR sequence, we must first multiply this polynomial by a suitable constant so that the trailing coefficient becomes $1$.

```magma
> C := C * Coefficient(C,0)^-1;
> C;
5*D^2 + 2*D + 1
```

We are now able to generate an LFSR sequence of length $7^2 - 1$. The initial state can be anything other than $[0, 0]$.

```magma
> t := LFSRSequence (C, [K| 1,1], 48);
> t;
[ 1, 1, 0, 2, 3, 5, 3, 4, 5, 5, 0, 3, 1, 4, 1, 6, 4, 4, 0, 1, 5, 6, 5, 2, 6, 6,
0, 5, 4, 2, 4, 3, 2, 2, 0, 4, 6, 3, 6, 1, 3, 3, 0, 6, 2, 1, 2, 5 ]
```

We decimate the sequence by a value $d$ having the property $\gcd(d,48)=1$.

```magma
> t := Decimation(t, 1, 5);
> t;
[ 1, 5, 0, 6, 5, 6, 4, 4, 3, 1, 0, 4, 1, 4, 5, 5, 2, 3, 0, 5, 3, 5, 1, 1, 6, 2,
0, 1, 2, 1, 3, 3, 4, 6, 0, 3, 6, 3, 2, 2, 5, 4, 0, 2, 4, 2, 6, 6 ]
> B := BerlekampMassey(t);
> B;
3*D^2 + 5*D + 1
```

To get the corresponding primitive polynomial, we multiply by a constant to make it monic.

```magma
> B := B * Coefficient(B, 2)^-1;
> B;
D^2 + 4*D + 5
> IsPrimitive(B);
true
```

### Hash Functions

A hash function maps a string of bytes of arbitrary length to a bit string of fixed length, called the digest of the input, in such a way that the digests of distinct inputs are spread uniformly over the range. Magma provides the SHA-1 function specified in FIPS PUB 180-1 (1995), whose digest has 160 bits. SHA-1 is no longer considered collision resistant, so it should not be relied on where an adversary may choose the input; its digests remain useful as fixed-length fingerprints of data, for instance to detect a change in a file or to index a table by the contents of a long string.

<a id="function-sha1-seqenum"></a>
#### `SHA1(S): SeqEnum -> MonStgElt`

<a id="function-sha1-monstgelt"></a>
#### `SHA1(s): MonStgElt -> MonStgElt`

Given a sequence $S$ of integers in the range $[0, 255]$, regarded as a sequence of bytes, or a string $s$, regarded as the sequence of its bytes, return the SHA-1 digest of the input as a string of 40 lowercase hexadecimal digits.

<a id="example-ex-d53a66"></a>
#### `Example: Digest of a String and of Its Bytes (ex-d53a66)`

The digest of a string agrees with that of the sequence of its byte values, and matches the test vector published for the message `"abc"`.

```magma
> SHA1("abc");
a9993e364706816aba3e25717850c26c9cd0d89d
> S := [StringToCode(c) : c in Eltseq("abc")]; S;
[ 97, 98, 99 ]
> SHA1(S);
a9993e364706816aba3e25717850c26c9cd0d89d
> SHA1("abd") eq SHA1("abc");
false
```
