Sparse matrix

Een matrix wordt gewoonlijk opgeslagen als een tweedimensionale matrix. Elk element in de matrix staat voor een element ai,j van de matrix en wordt benaderd met de twee indexen i en j. Gewoonlijk is i de rij-index, genummerd van boven naar beneden, en j de kolom-index, genummerd van links naar rechts. Voor een m × n matrix is de hoeveelheid geheugen die nodig is om de matrix in dit formaat op te slaan evenredig met m × n (zonder rekening te houden met het feit dat de afmetingen van de matrix ook moeten worden opgeslagen).

In het geval van een sparse matrix kan een aanzienlijke vermindering van het geheugengebruik worden gerealiseerd door alleen de entries die niet nul zijn op te slaan. Afhankelijk van het aantal en de verdeling van de niet-nul-ingangen, kunnen verschillende gegevensstructuren worden gebruikt, die een enorme geheugenbesparing opleveren ten opzichte van de basisaanpak. Het nadeel is dat de toegang tot de afzonderlijke elementen ingewikkelder wordt en dat extra structuren nodig zijn om de oorspronkelijke matrix ondubbelzinnig te kunnen herstellen.

Formats kunnen in twee groepen worden verdeeld:

  • Die welke efficiënte wijziging ondersteunen, zoals DOK (Dictionary of keys), LIL (List of lists), of COO (Coordinate list). Deze worden gewoonlijk gebruikt om de matrices te construeren.
  • Die welke efficiënte toegang en matrixbewerkingen ondersteunen, zoals CSR (Compressed Sparse Row) of CSC (Compressed Sparse Column).

Dictionary of keys (DOK)Edit

DOK bestaat uit een woordenboek dat (rij, kolom)-paren aan de waarde van de elementen koppelt. Elementen die in het woordenboek ontbreken, worden als nul beschouwd. Het formaat is goed voor het incrementeel construeren van een sparse matrix in willekeurige volgorde, maar slecht voor het itereren over niet-nul waarden in lexicografische volgorde. Men construeert meestal een matrix in dit formaat en converteert dan naar een ander efficiënter formaat voor verwerking.

Lijst van lijsten (LIL)

LIL bewaart een lijst per rij, met elke entry de kolom index en de waarde. Typisch worden deze gegevens gesorteerd op kolomindex bewaard om sneller te kunnen zoeken. Dit is een ander formaat dat goed is voor incrementele matrixconstructie.

Coördinatenlijst (COO)bewerken

COO slaat een lijst van (rij, kolom, waarde) tupels op. Idealiter worden de items eerst gesorteerd op rij-index en dan op kolom-index, om willekeurige toegangstijden te verbeteren. Dit is een ander formaat dat goed is voor incrementele matrixconstructie.

Compressed sparse row (CSR, CRS of Yale formaat)

De compressed sparse row (CSR) of compressed row storage (CRS) of Yale formaat vertegenwoordigt een matrix M door drie (een-dimensionale) matrices, die respectievelijk niet-nul waarden, de extents van rijen, en kolom indexen bevatten. Het is vergelijkbaar met COO, maar comprimeert de rij-indices, vandaar de naam. Dit formaat maakt snelle rij-toegang en matrix-vector-vermenigvuldigingen (Mx) mogelijk. Het CSR formaat is in gebruik sinds tenminste het midden van de jaren zestig, met de eerste volledige beschrijving in 1967.

Het CSR formaat slaat een sparse m × n matrix M op in rij-vorm met behulp van drie (een-dimensionale) matrices (V, COL_INDEX, ROW_INDEX). Zij NNZ het aantal niet-nul-ingangen in M. (Merk op dat hier indexen op nulpunten worden gebruikt.)

  • De matrices V en COL_INDEX hebben een lengte van NNZ, en bevatten respectievelijk de niet-nul-waarden en de kolomindexen van die waarden.
  • De matrix ROW_INDEX heeft een lengte van m + 1 en codeert de index in V en COL_INDEX waar de gegeven rij begint. Het laatste element is NNZ , d.w.z, de fictieve index in V onmiddellijk na de laatste geldige index NNZ – 1.

Bijv. de matrix

( 5 0 0 0 8 0 0 0 3 0 0 6 0 0 ) {{pmatrix}}5&0&0&0&0&0&0&8&0&0&0&3&0&6&0&0&0&0&0&0&0&0&0&0&0&0&0&6&0&0&0&0}}}

{{begin{pmatrix}5000>0800>30&0600>eind{pmatrix}}

is een 4 × 4 matrix met 4 niet-nul elementen, dus

 V = COL_INDEX = ROW_INDEX = 

uitgaande van een nul-geïndexeerde taal.

Om een rij te extraheren, definiëren we eerst:

 row_start = ROW_INDEX row_end = ROW_INDEX

Dan nemen we schijven van V en COL_INDEX beginnend bij rij_begin en eindigend bij rij_einde.

Om rij 1 (de tweede rij) van deze matrix te extraheren, stellen we row_start=1 en row_end=2 in. Dan maken we de schijven V = en COL_INDEX = . We weten nu dat we in rij 1 een element hebben in kolom 1 met waarde 8.

In dit geval bevat de CSR representatie 13 entries, vergeleken met 16 in de originele matrix. Het CSR-formaat bespaart alleen geheugen als NNZ < (m (n – 1) – 1) / 2.Een ander voorbeeld, de matrix

( 10 20 0 0 0 0 30 0 40 0 0 0 0 50 60 70 0 0 0 0 0 0 80 ) {\displaystyle {\begin{pmatrix}10&20&0&0&0&0\\0&30&0&40&0&0\\0&0&50&60&70&0\\0&0&0&0&0&80\\\end{pmatrix}}}

{begin{pmatrix}1020000000030040000050607000000080%eind{pmatrix}}

is een 4 × 6 matrix (24 ingangen) met 8 niet-nul elementen, dus

 V = COL_INDEX = ROW_INDEX = 

Het geheel wordt opgeslagen als 21 ingangen.

  • ROW_INDEX verdeelt de matrix V in rijen: (10, 20) (30, 40) (50, 60, 70) (80);
  • COL_INDEX lijnt de waarden in kolommen uit: (10, 20, ...) (0, 30, 0, 40, ...)(0, 0, 50, 60, 70, 0) (0, 0, 0, 0, 0, 80).

Merk op dat in dit formaat de eerste waarde van ROW_INDEX altijd nul is en de laatste altijd NNZ, zodat ze in zekere zin overbodig zijn (hoewel in programmeertalen waar de array-lengte expliciet moet worden opgeslagen, NNZ niet overbodig zou zijn). Desalniettemin voorkomt dit de noodzaak om een uitzonderlijk geval te behandelen bij het berekenen van de lengte van elke rij, omdat het garandeert dat de formule ROW_INDEX – ROW_INDEX werkt voor elke rij i. Bovendien zijn de geheugenkosten van deze redundante opslag waarschijnlijk onbeduidend voor een voldoende grote matrix.

De (oude en nieuwe) Yale sparse matrix formaten zijn instanties van het CSR schema. Het oude Yale-formaat werkt precies zoals hierboven beschreven, met drie matrices; het nieuwe formaat combineert ROW_INDEX en COL_INDEX in een enkele matrix en behandelt de diagonaal van de matrix afzonderlijk.

Voor logische adjacency-matrices kan de data-matrix worden weggelaten, omdat het bestaan van een gegeven in de rij-matrix voldoende is om een binaire adjacency-relatie te modelleren.

Het staat waarschijnlijk bekend als het Yale-formaat, omdat het werd voorgesteld in het Yale Sparse Matrix Package-rapport uit 1977 van het Department of Computer Science van de Yale University.

Compressed sparse column (CSC of CCS)Edit

CSC is vergelijkbaar met CSR, behalve dat waarden eerst per kolom worden gelezen, dat voor elke waarde een rij-index wordt opgeslagen en dat kolom-aanwijzers worden opgeslagen. Bijvoorbeeld, CSC is (val, row_ind, col_ptr), waarbij val een array is van de (top-naar-bodem, dan links-naar-rechts) niet-nul waarden van de matrix; row_ind is de rij indexen die corresponderen met de waarden; en, col_ptr is de lijst van val indexen waar elke kolom begint. De naam is gebaseerd op het feit dat de kolomindex informatie gecomprimeerd is ten opzichte van het COO formaat. Men gebruikt gewoonlijk een ander formaat (LIL, DOK, COO) voor de constructie. Dit formaat is efficiënt voor rekenkundige bewerkingen, kolom-slicing, en matrix-vector producten. Zie scipy.sparse.csc_matrix.Dit is het traditionele formaat voor het specificeren van een sparse matrix in MATLAB (via de functie sparse).