# Compressed Row Storage

Compressed Row Storage (CRS) oder Compressed Sparse Row (CSR) ist ein häufig genutztes Verfahren zum Speichern dünnbesetzter Matrizen. In der numerischen Mathematik bezeichnet man damit eine Matrix, bei der so viele Einträge aus Nullen bestehen, dass es sich lohnt, dies auszunutzen.
Beim CRS-Verfahren werden nur die von Null verschiedenen Einträge einer $(m\times n)$-Matrix $A$ gespeichert: In Form eines Arrays $val$, also an aufeinanderfolgenden Stellen im Speicher. Die für die Abbildung zwischen Positionen in der Matrix und dem Array $val$ benötigten Informationen werden in zwei weiteren Arrays $rowPtr$ und $colInd$ gespeichert. In $colInd$ ist zu jedem Eintrag aus $val$ der Index seiner Spalte gespeichert. Er umfasst daher gleich viele Elemente wie $val$. Die Werte in $rowPtr$ legen fest, welche Werte von $val$ zu welcher Zeile gehören.
Der formale Zusammenhang zwischen der Matrix $A$ und ihrer Darstellung unter Verwendung von CRS lautet:
    $A_{i,j}=val[k]\iff (colInd[k]=j)\land (rowPtr[i]\leq k<rowPtr[i+1]).$
Beispiel: (Die blauen Zahlen geben die Zeilen und die grünen die Spalten der Matrix $A$ an. Die Indizes beginnen wie in vielen Computersprachen üblich mit 0.)
    $A={\begin{pmatrix}{\underset {({\color {Blue}0},{\color {Green}0})}{10}}&0&0&{\underset {({\color {Blue}0},{\color {Green}3})}{12}}&0\\0&0&{\underset {({\color {Blue}1},{\color {Green}2})}{11}}&0&{\underset {({\color {Blue}1},{\color {Green}4})}{13}}\\0&{\underset {({\color {Blue}2},{\color {Green}1})}{16}}&0&0&0\\0&0&{\underset {({\color {Blue}3},{\color {Green}2})}{11}}&0&{\underset {({\color {Blue}3},{\color {Green}4})}{13}}\\\end{pmatrix}}$
In diesem Beispiel sind in den drei Vektoren folgende Werte gespeichert:
    ${\begin{matrix}val&=&\left({\underset {({\color {Blue}0},{\color {Green}0})}{10}}\right.&{\underset {({\color {Blue}0},{\color {Green}3})}{12}}&{\underset {({\color {Blue}1},{\color {Green}2})}{11}}&{\underset {({\color {Blue}1},{\color {Green}4})}{13}}&{\underset {({\color {Blue}2},{\color {Green}1})}{16}}&{\underset {({\color {Blue}3},{\color {Green}2})}{11}}&\left.{\underset {({\color {Blue}3},{\color {Green}4})}{13}}\right)\\colInd&=&\left({\underset {({\color {Blue}0}\,}{\color {Green}0}}\right.&{\underset {\ \,)}{\color {Green}3}}&{\underset {({\color {Blue}1}\,}{\color {Green}2}}&{\underset {\ \,)}{\color {Green}4}}&{\underset {({\color {Blue}2})}{\color {Green}1}}&{\underset {({\color {Blue}3}\,}{\color {Green}2}}&\left.{\underset {\ \,)}{\color {Green}4}}\,\right)\\rowPtr&=&\left({\underset {({\color {Blue}0})}{0}}\right.&{\underset {({\color {Blue}1})}{2}}&{\underset {({\color {Blue}2})}{4}}&{\underset {({\color {Blue}3})}{5}}&\left.{\underset {({\color {Blue}4})}{7}}\right)&&\end{matrix}}$
Sowohl $val$ als auch $colInd$ enthalten 7 Elemente, dies entspricht immer der Anzahl der Nichtnullelemente in $A$. $rowPtr$ hat 5 Elemente; die Anzahl der Elemente ist immer um 1 größer als die Anzahl der Zeilen von $A$. Das Element 0 hat den Wert 0, das letzte Element gibt die Größe von $colInd$ an, in diesem Fall 7.
Die Rekonstruktion der Zeile 1 der Matrix aus der komprimierten Speicherform geschieht folgendermaßen: Die Elemente 1 und 2 des Vektors $rowPtr$ zeigen an, dass an der Stelle 2 der Vektoren $val$ und $colInd$ die Zeile 1 und an der Stelle 4 die folgende Zeile beginnt. Die Zeile 1 hat also zwei von 0 verschiedene Elemente. Ihre Spaltenindizes stehen an den Stellen 2 und 3 von $colInd$, ihre Werte an den entsprechenden Stellen in $val$: 11 in der Spalte 2 und 13 in der Spalte 4.