---
abstract: 'Regenerating codes allow distributed storage systems to recover from the loss of a storage node while transmitting the minimum possible amount of data across the network. We present a systematic computer search for optimal systematic regenerating codes. To search the space of potential codes, we reduce the potential search space in several ways. We impose an additional symmetry condition on codes that we consider. We specify codes in a simple alternative way, using additional recovered coefficients rather than transmission coefficients and place codes into equivalence classes to avoid redundant checking. Our main finding is a few optimal systematic minimum storage regenerating codes for $n=5$ and $k=3$, over several finite fields. No such codes were previously known and the matching of the information theoretic cut-set bound was an open problem.'
author:
- 
- 
- 
bibliography:
- 'thesisbib.bib'
title: Searching for Minimum Storage Regenerating Codes
---

Introduction
============

Erasure codes can be used in storage systems to efficiently store data while protecting against failures much more efficiently than replication. We can divide a file of size ${\mathcal{M}}$ into $k$ pieces, each of size ${\mathcal{M}}/k$, encode them into $n$ coded pieces using an $(n,k)$ maximum distance separable (MDS) code, and store them at $n$ nodes. Then, the original file can be recovered from any set of $k$ coded pieces. This is optimal in terms of the redundancy–reliability tradeoff because $k$ pieces, each of size ${\mathcal{M}}/k$, provide the minimum data for recovering the file, which is of size ${\mathcal{M}}$.

In practical distributed storage systems based on $(n,k)$ MDS codes, we are often faced with the *repair problem* [@DGWR_Infocom07]: If a node storing a encoded piece fails or leaves the system, in order to maintain the same level of reliability, we need to create a new encoded piece and store it at a new node, but we can only access other encoded blocks. One straightforward way to do so is to let the new node download $k$ encoded pieces from a subset of the surviving nodes, reconstruct the original file, and compute the needed new coded piece. In this process, the new node incurred a total network traffic of $\gamma_{naive}=k\times {\mathcal{M}}/k={\mathcal{M}}$.

Recent prior work [@DGWR_Infocom07] showed that it is possible to reduce this repair bandwidth below ${\mathcal{M}}$ and developed information theoretic lower bounds and achievable schemes. At this point, need to distinguish between two different repair problems: In this paper we consider the problem of *systematic repair* [@Wu09] (also called *exact repair* [@Rashmi09]) where we require that it is exactly the same block that is reconstructed after a failure. This is in sharp contrast to *functional repair* i.e. only requiring that the new block is linearly independent and hence forms a good erasure code jointly with the other existing blocks [@DGWR_Infocom07]. Systematic repair is a strictly harder problem, which however is of great practical interest since in most practical storage systems reading parts of the data is the most common operation and it should not require decoding of blocks if no failures have occurred (see also [@ICDCS09] for a practical analysis).

\[fig:53repair\] ![An optimal (5,3) systematic MSR code over GF(3). We show the repair of the first node. The key property is that in the last two packets communicated, the coefficients of $(a_3, b_3)$ are aligned (both are $(1,0)$) and *at the same time*, the coefficients of $(a_2,b_2)$ are aligned (since $(2,1)=2 \times (1,2) \,\text{mod}\, 3$. This allows for only two extra blocks $(2a_2+b_2)$ and $(a_3)$ to suffice for four linear equations that can be solved in the desired variables $(a_1,b_1)$. The rotational symmetry of the code allows all node failures to be recovered similarly](allerton_graphic.pdf "fig:"){width="13cm"}

As was shown in [@DGWR_Infocom07], the functional repair problem is equivalent to a multicasting problem on an information flow graph that adds all reconstruction points as virtual data collectors who demand all the data. Using cut-set arguments (which are achievable for multicasting [@Ahlswede00; @RLNC]) we can determine the minimum repair bandwidth for MDS codes (codes matching this bound are called Minimum Storage Regenerating codes [@DGWR_Infocom07]): $$\label{cutset}
\gamma_{MSR}=\frac{{\mathcal{M}}}{k} \frac{n-1}{n-k},$$ if the new node is allowed to connect to $d=n-1$ surviving nodes, after one failure. Note that throughout this paper, we are only considering the minimum storage point and we do not address other points in the storage-repair tradeoff curve of [@DGWR_Infocom07].

The systematic repair problem, however, is equivalent to a network coding problem where there are receivers who want all the data (the data collectors) and receivers who want subsets of the data (the nodes who will replace the failed ones are now also sinks with a demand of the lost blocks). This reduction shows exactly why systematic repair is a much harder problem and careful coefficient selections are required. Further, the cut-set bound \[cutset\] is no longer necessarily tight and the optimal systematic repair rates are unknown for general $(n,k)$. Recent work [@Wu09] has developed an achievable scheme that is based on aligning the undesired subspaces, similarly to recent ideas for the interference channel (see e.g.  [@CadambeJ:08]) that have an achievable repair rate of $$\label{IR_rate}
\gamma_{IA}=\frac{{\mathcal{M}}}{k} \frac{(k-1)(n-k)+1}{n-k},$$ achieved by sub-packetizing each packet into $q=n-k$ blocks of size ${\mathcal{M}}/kq$ and communicating a total of $(k-1)q+1$ blocks from $d=n-1$ surviving nodes.

It is easy to verify that the achievable rate (\[IR\_rate\]) is matching the cut-set lower bound (\[cutset\]) for $k=2$ and $k=n-1$ but the other cases remain unknown. In this paper we present a searching approach to find systematic MSR codes that match the information theoretic lower bound (\[cutset\]). Our search found some optimal systematic $(5,3)$ MSR codes (the existence of which was previously unknown), the simplest of which is shown in figure \[fig:53repair\]. The key property that allows optimality is that when one of the undesired subspaces is aligned (as done in the scheme of [@Wu09]), the other is also aligned because of the selection of coefficients of the code. This remarkable property is only possible if the code coefficients are carefully chosen and is closely linked to the size of the finite field.

To search the space of potential codes in feasible amounts of time, we reduce the search space in several ways. We impose an additional condition that restricts the type of codes that we consider. This allows us to consider only highly symmetric codes that can be more concisely specified. We specify a code in a simple alternative way, using additional recovered coefficients rather than transmission coefficients. The space of codes can be searched more easily and efficiently when codes are specified this way. Finally, we use linear transformations to relate codes to each other and place them into equivalence classes. This allows us to check only one code from each equivalence class.

Definitions and Notation
========================

The storage networks that we are concerned with contain $n$ equivalent storage nodes. We wish to store $\mathcal{M}$ bits of data in the network, where $\mathcal{M}$ is $k$ times the size of one of the storage nodes. Because of this, we say that the network has $k$ source nodes.

Lower bound on recovery bandwidth
---------------------------------

During the recovery process, $\frac{\mathcal{M}d}{k(d-k+1)}$ bits of data must be transmitted, where $d$ is the number of nodes providing data [@DGWR_Infocom07]. We are interested in the case where $d=n-1$, so this bound becomes $\frac{\mathcal{M}(n-1)}{k(n-k)}$. There are $n-1$ nodes that each contain $\frac{\mathcal{M}}{k}$, so each node is transmitting $\frac{1}{n-k}$ of its contents. Because of this, we store $n-k$ packets of data in each storage node. We break the source data up into packets of the same size and each storage packet will be some linear combination of the $k(n-k)$ packets of source data.

Notation
--------

We use several matrices to represent the data and coefficients used in an MSR code.

  ${\mathbf{A}_i}$        $(n-k)$    $\times$   $k(n-k)$  matrix of storage coefficients
  ---------------------- ---------- ---------- ---------- -----------------------------------------
  ${\mathbf{B}_{i,j}}$      $1$      $\times$   $(n-k)$   row vector of transmission coefficients
  ${\mathbf{C}_i}$        $(n-k)$    $\times$   $(n-1)$   matrix used to rebuild storage node $i$
  $\mathbf{D}$            $k(n-k)$   $\times$     $x$     matrix of source data

The $i$th storage node contains ${\mathbf{A}_i}\mathbf{D}$, the original data multiplied by the storage coefficients for that node.

Independence
------------

The storage nodes of the code are independent if any $k$ nodes can reproduce the original data. That is, for all combinations of $k$ storage nodes, there is a matrix $\mathbf{M}$ such that\
$$\begin{aligned}
    \mathbf{D} &=& 
    \mathbf{M}
    {\left(\begin{array}{c}{\mathbf{A}}_{c(1)}\\#2\\#3\\#4\\\end{array}\right)}
    \mathbf{D}
    \end{aligned}$$

for any value of D. An equivalent condition is that for each combination of k nodes, the matrix of storage coefficients must have full rank, i.e. a nonzero determinant.

Recovery
--------

When node $j$ fails, the $i$th node transmits ${\mathbf{B}_{i,j}}{\mathbf{A}_i}\mathbf{D}$. The code allows the recovery of node $j$ if there is a matrix ${\mathbf{C}}_j$ that recreates the lost node from the transmitted vectors: $$\begin{aligned}
    {\mathbf{A}}_{j}\mathbf{D} &=& 
    {\mathbf{C}}_j
    {\left(\begin{array}{c}{\mathbf{B}}_{1,j}{\mathbf{A}}_{1}\\#2\\#3\\#4\\#5\\#6\\\end{array}\right)}
    \mathbf{D}
    \end{aligned}$$

for any value of $\mathbf{D}$. Therefore, $\mathbf{D}$ drops out of both the independent and recovery conditions, and we can focus on the coding coefficients only. We can also ignore the ${\mathbf{C}}_i$ matrices because from the recovery condition we can see that in a working code the ${\mathbf{C}_i}$ matrices are fully specified by the ${\mathbf{A}_i}$ and ${\mathbf{B}_{i,j}}$ matrices. With these two conditions, we can determine whether a set of ${\mathbf{A}_i}$ and ${\mathbf{B}_{i,j}}$ matrices form a code.

Rotationally Symmetric Codes
============================

To reduce the total number of coefficients, we consider codes whose ${\mathbf{A}_i}$ matrices are related to each other by a simple transformation.\
Let ${\mathbf{R}}$ be an $k(n-k)\times k(n-k)$ matrix such that $$\begin{aligned}
    {\mathbf{R}}^{n}={\mathbf{I}},
    \end{aligned}$$ and let $$\begin{aligned}
    {\mathbf{A}_i}={\mathbf{A}}{\mathbf{R}}^{i}.
    \end{aligned}$$\
A discussion of the ${\mathbf{R}}$ matrices themselves can be found in [@DanThesis]. This reduces the number of storage coefficients needed to specify a code by a factor of $n$, reducing the search space exponentially.

Recovery Condition
------------------

This makes the recovery condition\
$$\begin{aligned}
    {\mathbf{A}}{\mathbf{R}}^{j} &=& 
      {\mathbf{C}}_{j}
      {\left(\begin{array}{c}{\mathbf{B}}_{1,j}{\mathbf{A}}{\mathbf{R}}^{1}\\#2\\#3\\#4\\#5\\#6\\\end{array}\right)}
            \\
        {\mathbf{A}}&=& 
        \begin{comment}
      {\mathbf{C}}_{j}
      {\left(\begin{array}{c}{\mathbf{B}}_{1,j}{\mathbf{A}}{\mathbf{R}}^{1}\\#2\\#3\\#4\\#5\\#6\\\end{array}\right)}
        {\mathbf{R}}^{n-j}\\
    &=& 
        \end{comment}
      {\mathbf{C}}_{j}
      {\left(\begin{array}{c}{\mathbf{B}}_{1,j}{\mathbf{A}}{\mathbf{R}}^{n-j+1}\\#2\\#3\\#4\\#5\\#6\\\end{array}\right)}.
        \end{aligned}$$ We can replace ${\mathbf{B}_{i,j}}$ with ${\mathbf{B}}_{i-j}$, reorder the rows of the transmitted coefficient matrix, and replace ${\mathbf{C}}_{j}$ with ${\mathbf{C}}$. Now there is only one recovery condition.\
$$\begin{aligned}
        {\mathbf{A}}&=&
      {\mathbf{C}}{\left(\begin{array}{c}{\mathbf{B}}_{1}{\mathbf{A}}{\mathbf{R}}^{1}\\#2\\#3\\\end{array}\right)}
        \end{aligned}$$ This is an improvement of a factor of $n$.

Independence Condition
----------------------

Similarly, when checking independence, we only need to check combinations that include the first node. $$\begin{aligned}
      \det{\left(\begin{array}{c}{\mathbf{A}}{\mathbf{R}}^{c(1)}\\#2\\#3\\#4\\\end{array}\right)}
        &=&
        \det{\left(\begin{array}{c}{\mathbf{A}}{\mathbf{R}}^1\\#2\\#3\\#4\\\end{array}\right)}
        \det{\mathbf{R}}^{c(1)}
        \end{aligned}$$

This reduces the number of conditions from ${\left(\begin{array}{c}n\\#2\\\end{array}\right)}$ to ${\left(\begin{array}{c}n-1\\#2\\\end{array}\right)}$. This is an improvement of a factor of $\frac{n}{k}$.\

Example
-------

$$\begin{aligned}
        {\mathbf{R}}&=& \left(\begin{array}{cccc}0&1&0&0\\0&0&1&0\\0&0&0&1\\1&0&0&0\\\end{array}\right)\\
        {\mathbf{A}}_1 &=& {\left(\begin{array}{cccc}1&0&0&0\\#5&1&1&0\\\end{array}\right)}                \end{aligned}$$

The ${\mathbf{B}}_{i}$ matrices gives us the transmitted vectors. $$\begin{aligned}
        {\mathbf{B}}_{1}{\mathbf{A}}_2 &=& 
        {\left(\begin{array}{cc}1&0\\\end{array}\right)}{\left(\begin{array}{cccc}0&1&0&0\\#5&0&1&1\\\end{array}\right)}\\
        &=& {\left(\begin{array}{cccc}0&1&0&0\\\end{array}\right)}
    \end{aligned}$$ $$\begin{aligned}
        {\mathbf{B}}_{2}{\mathbf{A}}_3 &=& 
        {\left(\begin{array}{cc}1&0\\\end{array}\right)}{\left(\begin{array}{cccc}0&0&1&0\\#5&0&0&1\\\end{array}\right)}\\
        &=& {\left(\begin{array}{cccc}0&0&1&0\\\end{array}\right)}
    \end{aligned}$$ $$\begin{aligned}
        {\mathbf{B}}_{3}{\mathbf{A}}_4 &=& 
        {\left(\begin{array}{cc}0&1\\\end{array}\right)}{\left(\begin{array}{cccc}0&0&0&1\\#5&1&0&0\\\end{array}\right)}\\
        &=& {\left(\begin{array}{cccc}1&1&0&0\\\end{array}\right)}
    \end{aligned}$$ From these we can complete the code by calculating ${\mathbf{C}}$. $$\begin{aligned}
        {\mathbf{A}}_1 &=& {\mathbf{C}}{\left(\begin{array}{c}{\mathbf{B}}_{1}{\mathbf{A}}_2\\#2\\#3\\\end{array}\right)}
            \\
            {\left(\begin{array}{cccc}1&0&0&0\\#5&1&1&0\\\end{array}\right)} &=& 
            {\mathbf{C}}\left(\begin{array}{cccc}0&1&0&0\\0&0&1&0\\1&1&0&0\\\end{array}\right)
            \\
            {\mathbf{C}}&=& {\left(\begin{array}{ccc}-1&0&1\\#4&1&0\\\end{array}\right)}
    \end{aligned}$$

Additional Recovered Coefficients
=================================

The ${\mathbf{B}_{i,j}}$ matrices cannot be eliminated in a similarly simple manner, but their contribution to the code to be represented in alternative way. During recovery $n-1$ vectors are transmitted to the lost node, but the original ${\mathbf{A}_i}$ matrix has only $n-k$ rows. Thus $k-1$ additional vectors of coefficients are recovered. Specifying these vectors allows the ${\mathbf{B}_{i,j}}$ matrices to be determined.

Let ${\mathbf{Z}}_j$ be the $k-1 \times k(n-k)$ matrix that contains the additional rows recovered when node $j$ is lost. Let $$\begin{aligned}
{\mathbf{X}_j}={\left(\begin{array}{c}{\mathbf{Z}}_j\\#2\\\end{array}\right)}\end{aligned}$$ be the $n-1 \times k(n-k)$ matrix that contains all of the rows recovered when node $j$ is lost. Then ${\mathbf{X}_j}^{T}({\mathbf{X}_j}{\mathbf{X}_j}^{T})^{-1}{\mathbf{X}_j}$ projects vectors into $\operatorname{span}{\mathbf{X}_j}$. A row vector $\mathbf{v}$ is in $\operatorname{span}{{\mathbf{X}_j}}$ if the projection does not change the vector, or $$\begin{aligned}
\mathbf{v}({\mathbf{X}_j}^{T}({\mathbf{X}_j}{\mathbf{X}_j}^{T})^{-1}{\mathbf{X}_j})=\mathbf{v}
.\end{aligned}$$ This can be rewritten as $$\begin{aligned}
\mathbf{v}({\mathbf{I}}-{\mathbf{X}_j}^{T}({\mathbf{X}_j}{\mathbf{X}_j}^{T})^{-1}{\mathbf{X}_j})=\mathbf{0}.\end{aligned}$$

${\mathbf{I}}-{\mathbf{X}_j}^{T}({\mathbf{X}_j}{\mathbf{X}_j}^{T})^{-1}{\mathbf{X}_j}$ gives the difference between the original vector and the projection. This is a projection to the $(k-1)(n-k-1)$-dimensional space $\mathbb{F}^n/\operatorname{span}{{\mathbf{X}_j}}$. The only potentially useful vectors to transmit during recovery are those in $\operatorname{span}{\mathbf{X}_j}$, so we need to ensure that the transmitted vector ${\mathbf{B}_{i,j}}{\mathbf{A}_i}$ must satisfy $$\begin{aligned}
{\mathbf{B}_{i,j}}{\mathbf{A}_i}({\mathbf{I}}-{\mathbf{X}_j}^{T}({\mathbf{X}_j}{\mathbf{X}_j}^{T})^{-1}{\mathbf{X}_j})=\mathbf{0}.  \end{aligned}$$ Thus the choices for ${\mathbf{B}_{i,j}}$ are the vectors in the nullspace of ${\mathbf{A}_i}({\mathbf{I}}-{\mathbf{X}_j}^{T}({\mathbf{X}_j}{\mathbf{X}_j}^{T})^{-1}{\mathbf{X}_j})$.

Unrecovered Coefficients
------------------------

Let ${\mathbf{Y}_j}$ refer to a basis that spans $\mathbb{F}^n/\operatorname{span}{{\mathbf{X}_j}}$. Now we can rewrite the projection as ${\mathbf{I}}-{\mathbf{X}_j}^{T}({\mathbf{X}_j}{\mathbf{X}_j}^{T})^{-1}{\mathbf{X}_j}={\mathbf{Y}_j}^{T}({\mathbf{Y}_j}{\mathbf{Y}_j}^{T})^{-1}{\mathbf{Y}_j}$. Now we can say ${\mathbf{B}_{i,j}}{\mathbf{A}_i}$ must satisfy ${\mathbf{B}_{i,j}}{\mathbf{A}_i}{\mathbf{Y}_j}^{T}({\mathbf{Y}_j}{\mathbf{Y}_j}^{T})^{-1}{\mathbf{Y}_j}=\mathbf{0}$, which reduces to ${\mathbf{B}_{i,j}}{\mathbf{A}_i}{\mathbf{Y}_j}^{T}=0$. Thus the null space of ${\mathbf{A}_i}({\mathbf{I}}-{\mathbf{X}_j}^{T}({\mathbf{X}_j}{\mathbf{X}_j}^{T})^{-1}{\mathbf{X}_j})$ is the same as the nullspace of ${\mathbf{A}_i}{\mathbf{Y}_j}^{T}$. ${\mathbf{A}_i}{\mathbf{Y}_j}^{T}$ is a $(n-k)\times(k-1)(n-k-1)$ matrix, so its nullity is at least $(n-k)-(k-1)(n-k-1)$ or $1+(n-k-1)(2-k)$. However, if $2<k<n-1$, this bound does not force the nullity to be positive. This bound does explain why it is so easy to find codes when $k=2$.

Example: Obtaining ${\mathbf{B}}$ from $\mathbf{Y}$
---------------------------------------------------

Now we can see how the ${\mathbf{B}_{i,j}}$ vectors were discovered in the previous example. Let $\mathbf{Y}_1 = (\begin{array}{cccc} 0&0&0&1\\ \end{array})$. Note that ${\mathbf{A}}_1\mathbf{Y}_1^T=0$ as required. We apply $\mathbf{Y}_1^T$ to the other ${\mathbf{A}_i}$ matrices and find the ${\mathbf{B}_{i,j}}$ vectors that satisfy ${\mathbf{B}_{i,j}}{\mathbf{A}_i}{\mathbf{Y}_j}^{T}=0$. $$\begin{aligned}
    {\mathbf{A}}_2\mathbf{Y}_1^T &=& {\left(\begin{array}{c}0\\#2\\\end{array}\right)} \\ 
    {\mathbf{B}}_{1} &=& {\left(\begin{array}{cc}1&0\\\end{array}\right)}
    \end{aligned}$$ $$\begin{aligned}
    {\mathbf{A}}_3\mathbf{Y}_1^T &=& {\left(\begin{array}{c}0\\#2\\\end{array}\right)} \\ 
    {\mathbf{B}}_{2} &=& {\left(\begin{array}{cc}1&0\\\end{array}\right)}
    \end{aligned}$$ $$\begin{aligned}
    {\mathbf{A}}_4\mathbf{Y}_1^T &=& {\left(\begin{array}{c}1\\#2\\\end{array}\right)} \\ 
    {\mathbf{B}}_{3} &=& {\left(\begin{array}{cc}0&1\\\end{array}\right)}
    \end{aligned}$$

For the $n=4$, $k=2$ case, nearly all choices for ${\mathbf{Y}_j}$ produce a working code. This is not the case for larger coefficients.

Transformations of codes and equivalence classes
================================================

Row transformations
-------------------

Suppose we have an invertible $(n-k)\times(n-k)$ matrix ${\mathbf{T}}$ and a working code defined by ${\mathbf{A}_i}$ and ${\mathbf{B}_{i,j}}$ matrices. Then the matrices ${\mathbf{T}}{\mathbf{A}_i}$ and ${\mathbf{B}_{i,j}}{\mathbf{T}}^{-1}$ also define a working code. For recoverability we have $$\begin{aligned}
    {\mathbf{T}}{\mathbf{A}}_{j} &=& 
      {\mathbf{T}}{\mathbf{C}}_{j}
      {\left(\begin{array}{c}{\mathbf{B}}_{1,j}{\mathbf{T}}^{-1}{\mathbf{T}}{\mathbf{A}}_{1}\\#2\\#3\\#4\\#5\\#6\\\end{array}\right)}
        \\
        &=&{\mathbf{T}}{\mathbf{C}}_{j}
      {\left(\begin{array}{c}{\mathbf{B}}_{1,j}{\mathbf{A}}_{1}\\#2\\#3\\#4\\#5\\#6\\\end{array}\right)},
        \end{aligned}$$ and for independence we have $$\begin{aligned}
      \det{\left(\begin{array}{c}{\mathbf{T}}{\mathbf{A}}_{c(1)}\\#2\\#3\\#4\\\end{array}\right)}
        &=&
        \det\left(\begin{array}{cccc}
            {\mathbf{T}}& 0 & \hdots & 0\\
            0 & {\mathbf{T}}& \ddots & \vdots\\
            \vdots & \ddots & \ddots & 0\\
            0 & \hdots & 0 & {\mathbf{T}}\\
        \end{array} \right)
        \det{\left(\begin{array}{c}{\mathbf{A}}_{c(1)}\\#2\\#3\\#4\\\end{array}\right)}
        \\
        &=&(\det{\mathbf{T}})^{k}\det{\left(\begin{array}{c}{\mathbf{A}}_{c(1)}\\#2\\#3\\#4\\\end{array}\right)}
        \\
        &\neq&0.
        \end{aligned}$$ The row transformation is applied to the ${\mathbf{A}}$ matrices from the left and the rotation matrix in a rotationally symmetric code is applied from the right. Thus, applying the transformation to a rotationally symmetric code results in another rotationally symmetric code that uses the same rotation matrix. We can define codes to be equivalent if they are related by a row transformation. Testing only one code from each equivalence class reduces the search space by $k^2$ dimensions.

Column transformations
----------------------

The same technique can be applied to the columns. If we have an invertible $k(n-k)\times k(n-k)$ matrix ${\mathbf{T}}$ and a working code defined by ${\mathbf{A}_i}$ and ${\mathbf{B}_{i,j}}$ matrices, then the matrices ${\mathbf{A}_i}{\mathbf{T}}$ and ${\mathbf{B}_{i,j}}$ also define a working code. For recoverability we have $$\begin{aligned}
    {\mathbf{A}}_{j}{\mathbf{T}}&=& 
      {\mathbf{C}}_{j}
      {\left(\begin{array}{c}{\mathbf{B}}_{1,j}{\mathbf{A}}_{1}{\mathbf{T}}\\#2\\#3\\#4\\#5\\#6\\\end{array}\right)}
        \\
        &=&{\mathbf{C}}_{j}
      {\left(\begin{array}{c}{\mathbf{B}}_{1,j}{\mathbf{A}}_{1}\\#2\\#3\\#4\\#5\\#6\\\end{array}\right)}
        {\mathbf{T}},
    \end{aligned}$$ and for independence we have $$\begin{aligned}
\det{\left(\begin{array}{c}{\mathbf{A}}_{c(1)}{\mathbf{T}}\\#2\\#3\\#4\\\end{array}\right)}
        &=& \det{\left(\begin{array}{c}{\mathbf{A}}_{c(1)}\\#2\\#3\\#4\\\end{array}\right)}
        \det{\mathbf{T}}\\
        &\neq&0.
        \end{aligned}$$ In a rotationally symmetric code, the column transformation and the rotation are both applied from the right, so they interact. $$\begin{aligned}
        {\mathbf{A}_i}{\mathbf{T}}&=& {\mathbf{A}}{\mathbf{R}}^{i}{\mathbf{T}}\\
        &=& {\mathbf{A}}{\mathbf{T}}{\mathbf{T}}^{-1}{\mathbf{R}}^{i}{\mathbf{T}}\\
        &=& {\mathbf{A}}{\mathbf{T}}({\mathbf{T}}^{-1}{\mathbf{R}}{\mathbf{T}})^{i} 
        \end{aligned}$$ So the new code is rotationally symmetric with a different rotation matrix, ${\mathbf{T}}^{-1}{\mathbf{R}}{\mathbf{T}}$. This means that we can use a simple rotation matrix when searching for codes and simultaneously check all rotationally symmetric codes that use similar rotation matrices.

This also makes it possible to put any rotationally symmetric code into systematic form. When a code is in systematic form, the first $k$ storage matrices can be stacked to form an identity matrix. $$\begin{aligned}
            {\left(\begin{array}{c}{\mathbf{A}}_1{\mathbf{T}}\\#2\\#3\\\end{array}\right)}
        &=& {\mathbf{I}}\end{aligned}$$ Finding the transformation that puts a code into systematic form is simple. It is simply the inverse of the stack of first $k$ storage matrices.

$$\begin{aligned}
    {\mathbf{T}}&=&
    {\left(\begin{array}{c}{\mathbf{A}}_1\\#2\\#3\\\end{array}\right)}
    ^{-1}\end{aligned}$$

Example: Systematic Form
------------------------

$$\begin{aligned}
{\left(\begin{array}{c}{\mathbf{A}}_1\\#2\\\end{array}\right)} &=& 
    \left(\begin{array}{cccc}
        1&0&0&0\\
        0&1&1&0\\
        0&1&0&0\\
        0&0&1&1\\
    \end{array} \right)
\\
{\mathbf{T}}&=& {\left(\begin{array}{c}{\mathbf{A}}_1\\#2\\\end{array}\right)}^{-1}
\\
&=&
    \left(\begin{array}{cccc}
        1&0&0&0\\
        0&0&1&0\\
        0&1&-1&0\\
        0&-1&1&1\\
    \end{array} \right)\end{aligned}$$

The same ${\mathbf{B}}$ vectors as before will work for recovery. $$\begin{aligned}
    {\mathbf{B}}_{1}{\mathbf{A}}_2{\mathbf{T}}&=& 
    {\left(\begin{array}{cc}1&0\\\end{array}\right)}{\left(\begin{array}{cccc}0&0&1&0\\#5&0&0&1\\\end{array}\right)}\\
    &=& {\left(\begin{array}{cccc}0&0&1&0\\\end{array}\right)}\end{aligned}$$ $$\begin{aligned}
    {\mathbf{B}}_{2}{\mathbf{A}}_3{\mathbf{T}}&=& 
    {\left(\begin{array}{cc}1&0\\\end{array}\right)}{\left(\begin{array}{cccc}0&1&-1&0\\#5&-1&1&1\\\end{array}\right)}\\
    &=& {\left(\begin{array}{cccc}0&1&-1&0\\\end{array}\right)}\end{aligned}$$ $$\begin{aligned}
    {\mathbf{B}}_{3}{\mathbf{A}}_4{\mathbf{T}}&=& 
    {\left(\begin{array}{cc}0&1\\\end{array}\right)}{\left(\begin{array}{cccc}0&-1&1&1\\#5&0&1&0\\\end{array}\right)}\\
    &=& {\left(\begin{array}{cccc}1&0&1&0\\\end{array}\right)}\end{aligned}$$

The same ${\mathbf{C}}$ matrix as before will also work. $$\begin{aligned}
    {\mathbf{A}}_1{\mathbf{T}}&=& {\mathbf{C}}{\left(\begin{array}{c}{\mathbf{B}}_{1}{\mathbf{A}}_2\\#2\\#3\\\end{array}\right)}
            {\mathbf{T}}\\
    &=& {\left(\begin{array}{ccc}-1&0&1\\#4&1&0\\\end{array}\right)}
    \left(\begin{array}{cccc}0&0&1&0\\0&1&-1&0\\1&0&1&0\\\end{array}\right)
    \\
    &=& {\left(\begin{array}{cccc}1&0&0&0\\#5&1&0&0\\\end{array}\right)} \end{aligned}$$

Search Procedure
================

When searching for codes of a given $n$ and $k$ over a finite field, this procedure was used. Iterate over ${\mathbf{A}}$ matrices in a way that ensures that exactly one matrix from each row transformation equivalence class is produced. For each ${\mathbf{A}}$ matrix, produce the collection of $n$ ${\mathbf{A}_i}$ matrices using a single simple column rotation matrix. Then test the independence condition. Test it before the recovery condition because it requires only ${\mathbf{A}_i}$ matrices. If the independence condition is met, iterate over the space of potential additional recovered coefficients. For each ${\mathbf{X}_j}$ matrix produced by this process, check the recovery condition. If the condition is met, this is a code.

Search results
==============

$n=4$, $k=2$
------------

These coefficients are small enough to all several fields to be searched exhaustively. We have searched the prime fields up to $GF(13)$. There are no rotationally symmetric codes in $GF(2)$, but in all larger fields codes are extremely easy to find. In all of these fields, nearly all of the potential codes that satisfy the independence condition also satisfy the recovery condition. As the field size increases, larger and larger fractions of the potential codes satisfy the independence condition. In $GF(3)$, $22\%$ of potential codes satisfy the independence condition, and of these all satisfy the recovery condition. In $GF(13)$, $78\%$ of potential codes satisfy the independence condition and of these $92\%$ also satisfy the recovery condition.

$n=5$, $k=3$
------------

For these coefficients, codes were not previously known. We have exhaustively searched $GF(2)$, $GF(3)$, $GF(4)$, and $GF(5)$ and randomly searched in larger fields for rotationally symmetric codes. We found codes in $GF(3)$, $GF(4)$, $GF(7)$, and larger fields, but none in $GF(2)$ or $GF(5)$. While the codes we have found in smaller fields are not composed of vectors in general position, we found a code in $GF(17)$ that is. Several of these codes are given in the appendix. The full descriptions can be found in [@DanThesis].

$n=6$, $k=3$
------------

For these coefficients, We have yet to find any codes. In $GF(3)$, only about $1\%$ of potential codes satisfy the independence condition. In $GF(4)$ this number is about $14\%$ and in $GF(5)$ it is about $30\%$.

Appendix
========

$(5,3)$ code over $GF(3)$ in systematic form
--------------------------------------------

$$\begin{aligned}
    {\mathbf{B}}_{2,1}{\mathbf{A}}_2 &=& 
    \left(\begin{array}{cc} 2&1\\ \end{array}\right)
    \left(\begin{array}{cccccc} 0&0&1&0&0&0\\0&0&0&1&0&0\\ \end{array}\right)
    $$

$$\begin{aligned}
    {\mathbf{B}}_{3,1}{\mathbf{A}}_3 &=& 
    \left(\begin{array}{cc} 1&0\\ \end{array}\right)
    \left(\begin{array}{cccccc} 0&0&0&0&1&0\\0&0&0&0&0&1\\ \end{array}\right)
    $$

$$\begin{aligned}
    {\mathbf{B}}_{4,1}{\mathbf{A}}_4 &=& 
    \left(\begin{array}{cc} 0&1\\ \end{array}\right)
    \left(\begin{array}{cccccc} 1&1&2&0&1&2\\1&2&1&2&1&0\\ \end{array}\right)
    $$

$$\begin{aligned}
    {\mathbf{B}}_{5,1}{\mathbf{A}}_5 &=& 
    \left(\begin{array}{cc} 1&1\\ \end{array}\right)
    \left(\begin{array}{cccccc} 0&2&2&2&2&2\\1&1&0&2&2&1\\ \end{array}\right)
    $$

$$\begin{aligned}
    {\mathbf{A}}_1 &=& {\mathbf{C}}\left(\begin{array}{c} 
            {\mathbf{B}}_{2,1}{\mathbf{A}}_2\\
            {\mathbf{B}}_{3,1}{\mathbf{A}}_3\\
            {\mathbf{B}}_{4,1}{\mathbf{A}}_4\\
            {\mathbf{B}}_{5,1}{\mathbf{A}}_5\\
        \end{array}\right)
    \\
                &=& 
        \left(\begin{array}{cccc} 2&2&0&1\\1&0&2&1\\ \end{array}\right)
        \left(\begin{array}{cccccc} 0&0&2&1&0&0\\0&0&0&0&1&0\\1&2&1&2&1&0\\1&0&2&1&1&0\\ \end{array}\right)
        $$

$(5,3)$ code over $GF(7)$ in systematic form
--------------------------------------------

$$\begin{aligned}
    {\mathbf{B}}_{2,1}{\mathbf{A}}_2 &=& 
    \left(\begin{array}{cc} 0&1\\ \end{array}\right)
    \left(\begin{array}{cccccc} 0&0&1&0&0&0\\0&0&0&1&0&0\\ \end{array}\right)
    $$

$$\begin{aligned}
    {\mathbf{B}}_{3,1}{\mathbf{A}}_3 &=& 
    \left(\begin{array}{cc} 2&1\\ \end{array}\right)
    \left(\begin{array}{cccccc} 0&0&0&0&1&0\\0&0&0&0&0&1\\ \end{array}\right)
    $$

$$\begin{aligned}
    {\mathbf{B}}_{4,1}{\mathbf{A}}_4 &=& 
    \left(\begin{array}{cc} 5&1\\ \end{array}\right)
    \left(\begin{array}{cccccc} 2&0&5&6&1&1\\6&4&3&4&5&0\\ \end{array}\right)
    $$

$$\begin{aligned}
    {\mathbf{B}}_{5,1}{\mathbf{A}}_5 &=& 
    \left(\begin{array}{cc} 6&1\\ \end{array}\right)
    \left(\begin{array}{cccccc} 1&4&3&3&4&0\\3&0&3&6&1&2\\ \end{array}\right)
    $$

$$\begin{aligned}
    {\mathbf{A}}_1 &=& {\mathbf{C}}_1
        \left(\begin{array}{c} 
            {\mathbf{B}}_{2,1}{\mathbf{A}}_2\\
            {\mathbf{B}}_{3,1}{\mathbf{A}}_3\\
            {\mathbf{B}}_{4,1}{\mathbf{A}}_4\\
            {\mathbf{B}}_{5,1}{\mathbf{A}}_5\\
        \end{array}\right)
        \\
                &=& 
        \left(\begin{array}{cccc} 3&0&2&2\\4&4&1&6\\ \end{array}\right)
        \left(\begin{array}{cccccc} 0&0&0&1&0&0\\0&0&0&0&2&1\\2&4&0&6&3&5\\2&3&0&3&4&2\\ \end{array}\right) 
        $$
