# Constructions for ${\mathbb{Z}}_4$ Codes

## 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 [[Wan, 1997](../../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).

### `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.

### `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.

### `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$.

### `Example: Gray Map (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 [[Wan, 1997](../../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

```

## 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.

### `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$.

### `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$.

### `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$.

### `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$.

### `DelsarteGoethalsCode(m, delta): RngIntElt, RngIntElt -> Code`

Return the Delsarte-Goethals Code of length $2^m$.

### `GoethalsDelsarteCode(m, delta): RngIntElt, RngIntElt -> Code`

Return the Goethals-Delsarte code of length $2^m$

### `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$.

### `GolayCodeZ4(e): BoolElt -> Code`

Return the Golay Code over ${\mathbb{Z}}_4$. If $e$ is `true` then return the extended Golay Code

### `SimplexAlphaCodeZ4(k): RngIntElt -> Code`

Return the simplex alpha code over ${\mathbb{Z}}_4$ of degree $k$.

### `SimplexBetaCodeZ4(k): RngIntElt -> Code`

Return the simplex beta code over ${\mathbb{Z}}_4$ of degree $k$.

### `Example: Kerdock (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

```

### `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](#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}$.

### `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](#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}$.

### `Example: Spain Z4 1 (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

```

### `ReedMullerCodeZ4(r, m): RngIntElt, RngIntElt -> CodeLinRng`

### `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.

### `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.

### `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$.

### `Example: Spain Z4 2 (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 [Example: Spain Z4 1](#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

```

### `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)$

### `Example: Spain Z4 3 (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](#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.

### `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$.

### `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$.

### `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$.

### `Example: Derived Binary (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

```

## 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$.

### `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).
$$

### `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.

### `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).
$$

### `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.

### `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.

### `BQPlotkinSum(D, E, F): Code, Code, Code -> Code`

Given three codes $D$, $E$ and $F$ over ${\mathbb{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 ${\mathbb{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 ${\mathbb{Z}}_4$ is obtained from $E$ removing the $\gamma$ rows of order two of $Ge$.

The BQ Plotkin sum is a code over ${\mathbb{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 ${\mathbb{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 [Example: Spain Z4 4](#example-ex-b631eb).

### `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).
$$

### `DoublePlotkinSum(E, F, G, H): Code, Code, Code, Code -> Code`

Given four codes $E$, $F$, $G$ and $H$ over ${\mathbb{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 ${\mathbb{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 ${\mathbb{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.

### `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.

### `Example: Spain Z4 4 (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

```

### `Example: Spain Z4 4a (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

```
