Effektiva Lagringsmetoder för Glesa Matriser

DEGREE PROJECT, IN COMPUTER SCIENCE , FIRST LEVEL
STOCKHOLM, SWEDEN 2015
Effektiva Lagringsmetoder för Glesa
Matriser
DANI POTRUS
KTH ROYAL INSTITUTE OF TECHNOLOGY
www.kth.se
Effektiva Lagringsmetoder för Glesa Matriser
En studie av glesa matrisers lagringsmetoder med fokus på en numerisk algoritm
DANI POTRUS
DD143X Examensarbete inom datalogi, grundnivå
Handledare: Michael Schliephake
Examinator: Örjan Ekeberg
CSC, KTH 2015-05
1
Referat
Glesa matriser är inom fokus för numeriska algoritmer som löser linjära ekvationssystem.
Många lagringsmetoder har under åren tagits fram för att lagra stora glesa matriser på ett
minneseffektivt och tidseffektivt sätt.
I denna rapport undersöks tillgängliga lagringsmetoder för glesa ostrukturerade matriser.
Formaten som undersöks och implementeras är COO, CRS och ELL formaten. Jämförelser
görs på totala lagringsminnet och lagringstiden vid lagrandet av glesa matriser med olika
fyllningsgrader, samt den totala beräkningstiden vid lösning med en numerisk algoritm.
Resultatet visar att CRS formatet är effektivast vid lagringen av en gles matris. Slutsatsen är
att det finns lagringsmetoder som lagrar en matris utan att ta upp onödigt minne och som
bevarar matrisstrukturen inom rimlig tid för processen.
2
Abstract
Sparse matrices are often used in numerical algorithms that solve linear equation systems.
Many methods for storing sparse matrices have been proposed and implemented during the
years. These methods focus primarily on minimizing the total memory consumption and the
time that it takes to store a sparse matrix. This report researches the available storage methods
for sparse unstructured matrices. The formats that are researched and implemented are COO,
CRS and ELL. The comparisons between the formats are made based on the storage memory
and time for the sparse matrices with different filling ratios. A numerical algorithm has also
been implemented to study the time it takes to solve a sparse matrix with one of the available
storage formats, ELL. The results show that the CRS format outperform the other formats in
the storage of a sparse matrix. It is concluded that there are storage methods for sparse
matrices that avoid taking up unnecessary memory space, simultaneously preserving the
matrix structure and doing so within a reasonable time.
3
4
Innehåll
Introduktion ............................................................................................................................................ 7
1.1 Syfte ............................................................................................................................................... 7
1.2 Studiens disposition ...................................................................................................................... 7
1.3 Frågeställning ................................................................................................................................ 7
Bakgrund ................................................................................................................................................. 9
2.1 Glesa matriser ............................................................................................................................... 9
2.2 Olika lagringsmetoder och datastrukturer .................................................................................. 10
2.2.1 Dictionary of Keys (DOK) .......................................................................................................... 11
2.2.2 List of lists (LIL) ......................................................................................................................... 11
2.2.3 Coordinate List (COO) ............................................................................................................... 12
2.2.4 Yale Sparse Matrix .................................................................................................................... 13
2.2.5 Compressed Row Storage ........................................................................................................ 13
2.2.6 Compressed Sparse Column ..................................................................................................... 14
2.2.7 ELL (Ellpack-ltpack) ................................................................................................................... 14
2.3 Gauss-Seidels metod ................................................................................................................... 15
Metod .................................................................................................................................................... 19
3.1 Jämförelse av lagringsmetoder ................................................................................................... 19
3.2 Datastrukturer ............................................................................................................................. 20
3.2.1 CRS ............................................................................................................................................ 20
3.2.2 COO .......................................................................................................................................... 20
3.2.3 ELL............................................................................................................................................. 21
3.3 Matriser ....................................................................................................................................... 21
3.4 Test miljö ..................................................................................................................................... 22
3.4.1 Hårdvara ................................................................................................................................... 22
3.4.2 Mjukvara................................................................................................................................... 22
Resultat ................................................................................................................................................. 24
4.1 Lagringstid ................................................................................................................................... 24
4.2 RAM-minne.................................................................................................................................. 27
4.3 Lösningstid med Gauss-Seidel ..................................................................................................... 30
5
4.4 Formatens effektivitet ................................................................................................................. 33
Diskussion ............................................................................................................................................. 35
5.1 Val av algoritm ............................................................................................................................. 35
5.2 Lagringsmetodernas effektivitet ................................................................................................. 35
5.2.1 Minneseffektivitet .................................................................................................................... 35
5.2.2 Tidseffektivitet.......................................................................................................................... 36
5.3 Implementeringarnas effektivitet ............................................................................................... 36
Slutsats .................................................................................................................................................. 39
6.1 Studiens slutsats .......................................................................................................................... 39
6.2 Framtida forskning ...................................................................................................................... 39
Appendix ............................................................................................................................................... 41
Appendix A: Kod för implementation av COO formatet ................................................................... 41
Appendix B: Kod för implementation av ELL formatet...................................................................... 43
Appendix C: Kod för implementation av CRS formatet ..................................................................... 45
Appendix D: Gauss Seidels metod ..................................................................................................... 48
Referenser ............................................................................................................................................. 50
6
Kapitel 1
Introduktion
Glesa matriser har länge varit inom fokus för algoritmer som löser linjära ekvationssystem.
En gles matris, som definieras av att den består av mer noll-element än andra element i
matrisen, kan ha många olika lagringsmetoder. Att lagra en gles matris naivt såsom alla andra
matriser i program har visat sig vara ineffektivt då detta tar upp onödigt minne och utför
överflödiga beräkningar under algoritmens körning. Därför är det både intressant och relevant
att fördjupa sig inom vilka lagringsmetoder som finns för glesa matriser för att undersöka
algoritmens tidseffektivitet för olika lagringsstrukturer och hur mycket minne som sparas.
1.1 Syfte
Denna studie har som syfte att undersöka olika lagringsmetoder som finns för glesa matriser,
där en fördjupning har gjorts i de lagringsmetoder som har visat sig vara mest effektiva avsett
på hur lång tid körningen tar och hur mycket minne som sparas för just dessa
lagringsmetoder. Lagringsmetoderna har implementerats i C++ och jämförelser har gjorts
mellan implementationerna för olika storlekar på kvadratiska glesa matriser, med hjälp av en
numerisk algoritm.
1.2 Studiens disposition
I kapitlet bakgrund beskrivs lagringsstrukturerna och hur effektiva de är för glesa matriser
med olika strukturer. I metodbeskrivningen har 3 lagringsstrukturer valts ut för att
implementeras i ett maskinnära programmeringsspråk, nämligen C++. Resultatdelen av denna
studie visar grafer på jämförelser för hur mycket minne som sparas och hur lång tid det tar att
lagra matrisen samt att beräkna det linjära ekvationssystemet Ax = b med en numerisk
algoritm. I slutsatsen diskuteras de olika lagringsstrukturernas effektivitet och vilka
optimeringar som kan göras.
1.3 Frågeställning
Vilka lagringsmetoder är mest minneseffektiva i lagrandet av en gles matris och hur
tidseffektivt blir lösningen av det linjära ekvationssystemet med en numerisk algoritm?
Hur beror dessa på matrisens storlek och fyllningsgrad?
7
8
Kapitel 2
Bakgrund
Detta kapitel ger en introduktion på vad glesa matriser är och hur de kan användas inom
verkliga situationer. Olika lagringsmetoder tas upp samt deras för-och nackdelar. Den
numeriska algoritmen som kommer att implementeras, nämligen Gauss-Seidels metod,
beskrivs i detalj.
2.1 Glesa matriser
Glesa matriser definieras i den numeriska analysen som matriser vars element består till
största delen av nollor. Har matrisen däremot fler nollskilda element så är matrisen tät.
Fyllningsgraden i en gles matris beskriver i procent hur många nollskilda element som
matrisen består av.
Glesheten korresponderar till system som har svaga länkar mellan varandra. Man kan tänka
sig att man har n bollar som är länkade tillsammans med en fjäder från varje boll till den
andra. Detta system beskrivs av en gles matris, då varje boll endast har en länk till endast en
annan boll. Om varje boll istället hade varit länkad till alla andra bollar hade systemet
beskrivits av en tät matris.
I figur 2.1.1 visas ett exempel på en gles matris av storlek 1000x1000 med 10 %
fyllningsgrad. Det vita området i grafen representerar nollor och det blåfärgade området
representerar nollskilda element.
9
Figur 2.1.1: Exempel på en gles matris med 10 % fyllningsgrad.
Stora glesa matriser dyker ofta upp inom vetenskapliga eller ingenjörsmässiga tillämpningar,
exempel på dessa är fackverkskonstruktioner och fouriertransformer.
Figur 2.1.2 beskriver en fackverkstakstol respektive ram. Denna struktur kan beskrivas med
hjälp av glesa matriser.
Figur 2.1.2: Fackverkskonstruktioner, som kan beskrivas av glesa matriser [1].
2.2 Olika lagringsmetoder och datastrukturer
Eftersom en gles matris element består till största delen av nollor så är det viktigt att smart
lagra dessa på ett sätt som inte tar upp onödigt minne. Lagrar man matrisen direkt så kommer
nollorna i matrisen att sparas i minnet och onödig minnesarea kommer att tas upp.
10
Olika lagringsmetoder har tagits fram för att lagra glesa matriser. Lagringsmetoderna har som
främsta uppgift att lagra matrisens nollskilda element utan att lagra matrisens nollor men som
bevarar varje elements position i matrisen indirekt. Vissa lagringsmetoder saknar potentialen
att utföra elementära matrisoperationer såsom matris-vektor multiplikation. Nedan presenteras
olika typer av lagringsmetoder, med unika lagringssätt.
2.2.1 Dictionary of Keys (DOK)
Istället för att spara matrisens nollor kan man istället använda sig av en Dictionary of Keys,
där man mappar en nyckel till ett värde. I detta fall kan man associera (rad, kolonn) till de
element som är nollskilda och på så sätt få en struktur som sparar värden på ett effektivt sätt.
Om gleshetens struktur på matrisen är okänd så är denna lagringsmetod effektiv för lagring
[2].
Med denna implementation får man dessvärre nackdelar såsom att man inte kan iterera
igenom elementen i lexikografisk ordning. Man konverterar därför matrisen till ett annat
format, såsom CRS eller CSC (se 2.2.5–2.2.6), för att kunna utföra aritmetiska operationer
[3].
Figur 2.2.1 är ett exempel på en gles 3x3 matris i DOK format. Matrisen innehåller rader och
kolonner, där rader representeras av r och kolonner representeras av c. Enbart nollskilda
element mappas på rad,kolonn som är nyckeln och det nollskilda elementet är värdet.
Figur 2.2.1: Exempel på en gles 3x3 matris i DOK format.
2.2.2 List of lists (LIL)
Sparar en lista per rad där varje lista innehåller kolumn index och värde. Dessa hålls sorterade
på kolumn index för snabbare åtkomst av värdet [4].
11
Denna lagringsmetod görs för konstruktion av matrisen och matrisen konverteras sedan till
CRS eller CSC format för att kunna utföra matris aritmetiska operationer. Lagringsmetoden är
effektiv vid t.ex. inläsning av matriser från fil [5].
I figur 2.2.2 visas ett exempel på en gles 4x5 matris i LIL format. Matrisen har rader och
kolonner som beskrivs av r respektive c. LIL strukturen har en lista som innehåller listor.
Listorna i listan innehåller kolonnindex för respektive nollskilt element. Varje lista i listan är
sorterat efter rad och kolonnindex, för snabbare åtkomst av element i matrisen. Den första
listan i listan (se höger figur i figur 2.2.2) är alltså den första raden med kolonnindex för
nollskilda element och den andra listan är den andra raden med kolonnindex för nollskilda
element.
Figur 2.2.2: Exempel på en gles 4x5 matris i LIL format.
2.2.3 Coordinate List (COO)
Sparar 3 olika listor som innehåller rad, kolonn och motsvarande nollskilda elements värde.
Mest effektivt blir det om man sorterar efter rad index och sen kolonn index för att förbättra
direktåtkomsttiden. Denna lagringsmetod används för konstruktion av matrisen, men kan inte
användas för aritmetiska operationer, då sökningen av ett element tar linjärtid och för stora
matriser tar detta för lång tid [6].
Figur 2.2.3 är ett exempel på en gles 4x4 matris i COO format. Matrisens nollskilda element
sparas på radindex, kolonnindex och det nollskilda elementet, där radindex läggs i radvektorn,
kolonnindex läggs i kolonnvektorn och elementet läggs i värdesvektorn.
12
Figur 2.2.3: Exempel på en gles 4x4 matris i COO format [7].
2.2.4 Yale Sparse Matrix
En matris, B, lagras i form av tre endimensionella vektorer, kallade A, IA och JA. Vektorn A
innehåller alla nollskilda element i B läst från vänster till höger, uppifrån och ner. Vektorn IA
är av storlek n+1 (där n är matrisstorleken) och innehåller indexet i A för det första elementet
i varje rad följt av det totala antalet nollskilda element. JA innehåller kolumnpositionerna för
talen i A, läst radvis från vänster till höger [8].
Figur 2.2.4 är ett exempel på en gles 4x4 matris i Yale Sparse Matrix format. Vektorn A
innehåller alla nollskilda element i matrisen B. IA[i] innehåller indexet i A för det första
nollskilda elementet i rad i. Rad i för matrisen förlängs från A[IA[i]] till A[IA[i+1]-1], alltså
börjar den från början av en rad tills det sista indexet i raden innan den börjar på nästa rad. JA
innehåller kolumnpositionerna för elementen i A.
Figur 2.2.4: Exempel på en 4x4 gles matris i Yale Sparse Matrix format.
2.2.5 Compressed Row Storage
Man sorterar matrisens element på rad (från toppen till botten) och kolonn (i raden – från
vänster till höger).
Figur 2.2.5 är ett exempel på en gles matris i CRS format. CRS formatet har en vektor för rad
offsets, en vektor för kolonnindex och en vektor för att spara de nollskilda elementen i
matrisen. Rad offset vektorn sparar indexet i värdesvektorn för det första nollskilda elementet
13
i varje rad och innehåller som sista element det totala antalet nollskilda element i matrisen.
Kolonnindex vektorn innehåller varje nollskilt elements kolonnindex och värdesvektorn
innehåller de nollskilda elementen sparade radvis från vänster till höger, uppifrån och ner.
Figur 2.2.5: Exempel på en gles 4x4 matris i CRS format [7].
Oavsett om matrisen är strukturerad eller ostrukturerad så är CRS den mest effektiva på
minneslagring. Det finns enstaka fall då andra lagringsmetoder är mer effektiva, men för stora
glesa matriser har det visat sig att CRS tar upp minst byte per nollskilda element [9]. Den
enda skillnaden mellan COO och CRS formatet är att COO har en radvektor istället för en
vektor med rad offsets, vilket gör det enkelt att konvertera mellan formaten.
CRS formatet är också ett effektivt format vid elementära matrisoperationer såsom matrisvektor produkt [10].
2.2.6 Compressed Sparse Column
CSC format är identiskt med CRS med undantaget att man har kolonn offsets istället för rad
offsets och en vektor med rad index istället för kolonn index.
2.2.7 ELL (Ellpack-ltpack)
ELL formatet sparar glesa matriser med två tvådimensionella vektorer, en för de nollskilda
elementen och en för varje elements kolumn index. Detta format är mest effektivt om varje
rad i matrisen har lika många nollskilda element och matrisens struktur har ett mönster som är
ostrukturerat [10].
Figur 2.2.7 är ett exempel på en gles 4x4 matris i ELL format. Matrisen har som mest 3
nollskilda element i en rad och därför blir längden för varje rad i de tvådimensionella
vektorerna 3. Kolonnindexet sparas i kolonnindex vektorn och om det finns ett mindre antal
nollskilda element på den specifika raden än den rad som innehåller mest nollskilda element
så läggs element till för att fylla ut raden. Detta kallas för utfyllning. Det nollskilda elementet
14
sparas i den tvådimensionella vektorn för värden och om raden inte är fylld så görs utfyllnings
här också. Varje rad representerar alltså varje rad i matrisen.
Figur 2.2.7: Exempel på en 4x4 gles matris i ELL format [7].
2.3 Gauss-Seidels metod
Gauss-Seidels metod är en iterativ metod för att lösa ett kvadratiskt linjärt ekvationssystem
bestående av n stycken ekvationer med okända variabler x, Ax = b.
Gauss-Seidels metod itererar, för begynnelse värden på x, tills den konvergerar mot en
lösning.
Metoden beskrivs av figur 2.3.1. Den okända variabeln i ekvationssystemet, xi(k+1), beräknas
genom att man tar högerledet bi i ekvationen och subtraherar med summan av elementen
multiplicerat med värdet för den specifika raden i, d.v.s. aij*xj(k+1) och summan av elementen
multiplicerat med det föregående värdet, d.v.s aij*xj(k), dividerat med elementet på diagonalen
aii.
Figur 2.3.1: Gauss-Seidels metod för en nxn matris [11].
Två viktiga egenskaper med Gauss-Seidels metod bör noteras. Det ena är att varje beräkning
görs i en följd. Eftersom varje komponent i den nya iterationen är beroende av de
komponenter som beräknats innan så kan ingen uppdatering ske samtidigt som beräkningen
görs såsom i Jacobis metod. Sedan är det så att den nya iterationen, xi(k+1), beror på ordningen
som ekvationerna undersöks i. Om ordningen ändras kommer de nya iterationernas
komponenter också att ändras.[12]
15
Figur 2.3.2 beskriver stop kriteriet för metoden. Normen för residual vektorn r, som är
ekvivalent med att man subtraherar högerledet b med ekvationssystemet Ax(k), divideras med
normen för högerledet. Detta används under beräkningen för att undersöka att felet i
beräkningen ligger under en viss tolerans ε.
Figur 2.3.2: Stop kriterium för Gauss-Seidels metod [11].
Gauss-Seidels metod är applicerbar på matriser som är strikt diagonalt dominerande eller
symmetrisk positivt definita.
Figur 2.2.3 visar ett exempel på Gauss-Seidels metod som är skriven i matlab kod. Detta
exempel kommer att översättas till programmeringsspråket C++ som kommer att användas
under implementationen av lagringsmetoderna. Det ska noteras att implementation av GaussSeidels metod som skrivs i C++ använder aritmetiska operationer med nollor även om den
implementerade datastrukturen inte innehåller nollor i minnet. Detta kommer att användas för
jämförelse under studien.
16
Figur 2.3.3: Gauss-Seidels metod skriven i MATLAB kod [13].
17
18
Kapitel 3
Metod
Detta kapitel beskriver metodiken och framtagningen av de lagringsmetoder som
implementeras i språket C++. I den första delen så görs en jämförelse av lagringsmetoderna
med hjälp av tidigare studier som gjorts inom området. Efter jämförelse så väljs 3
lagringsmetoder ut som kommer att implementeras. Det beskrivs sedan i detalj hur
datastrukturen kommer att se ut på lagringsmetoderna och hur implementationen går till, samt
i vilken miljö testning kommer att ske.
3.1 Jämförelse av lagringsmetoder
En jämförelse görs på tre olika lagringsmetoder som beskrivs i kapitel 2. Dessa
lagringsmetoder kommer sedan att implementeras i programmeringsspråket C++ för vidare
jämförelse på minneslagring och tidseffektivitet. En av implementationerna används sedan för
lösning av ett linjärt ekvationssystem Ax = b, med hjälp av Gauss-Seidels metod. Det görs
också ett test med C++ bibliotekets inbyggda matris representation, en tvådimensionell vektor
datastruktur. Matrisen sparas på ett naivt sätt, d.v.s. med nollor, och löses sedan med GaussSeidels metod.
Datastrukturerna representeras som klasser i C++. För att kunna implementera dessa
datastrukturer så har en litteraturstudie gjorts på tidigare arbeten inom samma område. Av
lagringsmetoderna som beskrivs i bakgrunden så är det inte alla som har kapaciteten att utföra
elementära matrisoperationer, såsom matris-vektor multiplikation. Dessa lagringsmetoder
kommer inte att användas under denna studie. Exempel på dessa är LIL och DOK, som
beskrivs i kapitel 2.
De lagringsmetoder som har valts för implementering är CRS, COO och ELL formaten. Dessa
lagringsmetoder har visat sig vara mest effektiva för glesa matriser som är ostrukturerade och
av godtycklig storlek, när det gäller minneseffektivitet [9]. CRS formatet föredras vid
lagrandet av glesa matriser, då det är användbart för elementära matrisoperationer. På grund
av COO formatets bekvämlighet så används det ofta vid inläsning av glesa matriser, dock så
konverteras formatet senare till ett annat för att kunna utföra matematiska beräkningar [14].
ELL formatet är en väldigt effektiv lagringsmetod då det gäller implementeringar av GPU
datastrukturer och har valts som en kontrast till CRS formatet som är extremt effektivt för
matris-vektor multiplikation [15].
19
3.2 Datastrukturer
Nedan följer datastrukturerna som kommer användas för lagring av de glesa matriserna. Dessa
datastrukturer skrivs i C++. C++ har valts eftersom att det har visat sig vara extremt
resursfullt när det gäller bibliotek med matrisimplementationer som innehåller
matrisoperationer och vektoroperationer. Språkets bibiliotek erbjuder bl.a. vector, en
lagringsstruktur som beskriver en vektor skriven i C++.
Varje datastruktur implementeras och testas med glesa matriser av kvadratisk storlek.
3.2.1 CRS
CRS sparar rad-offsets för antalet rader i matrisen + 1 i en vektor, alltså blir storleken på
vektorn n + 1. Kolonn index för varje nollskilt element i matrisen (läst från vänster till höger,
topp till botten på varje rad) sparas också i en vektor. De nollskilda elementen i matrisen
sparas sedan i en vektor, där varje värde sparas i ordning från rad till rad (vektor storleken är
densamma som kolonn vektorn).
En klass med metoder och attribut specifika för CRS formatet skapas. Datastrukturen beskrivs
genom följande:
•
•
•
En konstruktor där man anger storleken på matrisen och antalet nollskilda element.
En operator() metod som stoppar in ett värde på plats i, j där i är rad och j kolonn.
Denna metod stoppar in värdet i element vektorn beroende på vilket index i kolonn
vektorn som specificeras. Rad offset vektorn uppdateras.
En operator() metod som hämtar ett värde på plats i, j. Denna metod kommer att
utnyttja rad offset vektorn.
3.2.2 COO
COO sparar i en vektor indexet för raden där det nollskilda elementet finns, så storleken på
vektorn blir densamma som antalet nollskilda element i den glesa matrisen. Det sparas också i
en vektor indexet för kolonnen där det nollskilda elementet finns, storleken blir densamma
som rad vektorn. Det kommer också att sparas en vektor som innehåller värdena för varje
nollskilt element.
Datastrukturen består av följande:
•
•
En konstruktor där rad, kolonn och värdes vektorn skapas.
En operator() metod som stoppar in ett värde på plats i, j där i är rad och j kolonn.
Denna metod stoppar in värden i rad, kolonn samt element vektorn.
20
•
En operator() metod som hämtar ett värde på plats i, j. Denna metod kommer utnyttja
rad och kolonn vektorerna för att hämta värdet.
3.2.3 ELL
ELL sparar i en tvådimensionell vektor indexet för kolumnen där det första nollskilda
elementet finns och sedan resterande nollskilda element. Storleken på denna tvådimensionella
vektor blir n*nnz, där nnz är det största antalet nollskilda element som finns på varje rad i
matrisen och n är matrisstorleken. En tvådimensionell vektor av samma storlek används också
för att spara de nollskilda elementen. Om en rad innehåller mindre än det största antalet
nollskilda element, nnz, så kommer nollor att sparas i just den rad som sparas just nu. Det blir
alltså nollor i kolumn index och nollor som värde. Detta kallas för utfyllning.
Denna implementering innehåller följande:
•
•
•
En konstruktor där man anger storlek på matrisen och nnz, det största antalet
nollskilda element per rad. Fyra vektorer, en tvådimensionell vektor för nollskilda
element och en tvådimensionell vektor för kolonn index skapas samt en vektor för
element och en vektor för kolonn index.
En operator() metod som stoppar in ett värde på plats i, j där i är rad och j kolonn.
Denna metod stoppar in värdet i den tvådimensionella vektorn för nollskilda element
och kolumn indexet j stoppas in i den tvådimensionella vektorn för kolumn index.
En operator() metod som hämtar ett värde på plats i, j. Denna metod utnyttjar de
tvådimensionella vektorerna för att hämta ut det nollskilda elementet på plats i, j.
3.3 Matriser
Matriserna som används för testning är ostrukturerade glesa kvadratiska matriser av storlek
1000x1000, 2500x2500, 5000x5000 och 10000x10000. Testningen kommer att göras för
fyllningsgraderna 1 %, 25 %, 50 % och 75 %. Det finns 4 matriser för varje storlek, alltså 16
matriser totalt.
Matriser som har en fyllningsgrad >= 50 % räknas som täta. Dessa matriser finns med i
studien för att kunna undersöka lagringsmetodernas effektivitet på täta matriser jämfört med
en vanlig tvådimensionell vektor i C++ som sparar alla element, även nollor.
Framtagning av matriser har gjorts med hjälp av matlab. För att skapa en gles matris av
storlek n används funktionen zeros [16]. Matrisen fylls sedan in kontinuerligt tills en viss
fyllningsgrad nås. För att få fram en ostrukturerad matris har rand funktionen använts för att
stoppa in nollskilda element i matrisen på ett slumpmässigt sätt [17].
21
3.4 Test miljö
Nedan följer specifikationer för vilken testmiljö som används under studiens arbetsgång.
3.4.1 Hårdvara
CPU: Intel(R) Core(TM) i5-4210U CPU @ 1.70GHz 2.40 GHz
GPU: Intel(R) HD Graphics 4400
RAM-minne: SODIMM DDR3L 8 GB @ 1600 MHz
Lagring: 128 GB SSD @ 6GB/s
3.4.2 Mjukvara
Operativsystemet som har använts vid testning är Windows 8.1 för 64-bit.
22
23
Kapitel 4
Resultat
Detta kapitel presenterar de resultat som har fåtts fram vid lagring av de glesa matriserna med
de olika datastrukturerna. Resultatet visar lagringstid och det totala använda RAM minnet vid
lagringen samt den totala lösningstiden för det linjära ekvationssystemet med Gauss-Seidels
metod, som presenteras med grafer och tabeller.
4.1 Lagringstid
Graferna nedan visar den totala lagringstiden för matriserna med olika fyllningsgrader.
Figur 4.1.1 visar den beräknade lagringstiden, för matriser av olika storlekar och med 1 %
fyllningsgrad, för varje lagringsformat. Tiden är beräknad i sekunder. För matriser med 1 %
fyllningsgrad så lagrar COO och CRS formaten på ungefär samma tid, dock så är ELL lite
långsammare.
Figur 4.1.1: Totala lagringstiden för de olika lagringsformaten. Fyllningsgrad 1 %.
Figur 4.1.2 visar den beräknade lagringstiden, för matriser av olika storlekar och med 25 %
fyllningsgrad, för varje lagringsformat. För matriser med 25 % fyllningsgrad så lagrar COO
och ELL formaten på ungefär samma tid och CRS lagrar snabbast. Skillnaden är dock
minimal.
24
Figur 4.1.2: Totala lagringstiden för de olika lagringsformaten. Fyllningsgrad 25 %.
Figur 4.1.3 visar den beräknade lagringstiden, för matriser av olika storlekar och med 50 %
fyllningsgrad, för varje lagringsformat. För matriser med 50 % fyllningsgrad så är den totala
lagringstiden ungefär samma för alla format.
Figur 4.1.3: Totala lagringstiden för de olika lagringsformaten. Fyllningsgrad 50 %.
Figur 4.1.4 visar den beräknade lagringstiden, för matriser av olika storlekar och med 75 %
fyllningsgrad, för varje lagringsformat. För matriser med 75 % fyllningsgrad så är lagrar COO
och CRS på ungefär samma tid och ELL lagrar lite långsammare. Det ska dock noteras att
bara matriser av storlek 1000-5000 lagrades under denna körning, då större matrisstorlekar
inte kunde allokera nog med minne för vektorerna i CRS och COO formaten.
25
Figur 4.1.4: Totala lagringstiden för de olika lagringsformaten. Fyllningsgrad 75 %.
Figur 4.1.5 visar den totala lagringstiden för de olika lagringsformaten med en konstant
matrisstorlek 1000 och en varierande fyllningsgrad. Man ser att växande fyllningsgrad
innebär en förbättring av ELL formatet och försämring av COO formatet. CRS lagrar på den
snabbaste tiden.
Figur 4.1.5: Totala lagringstiden för de olika lagringsformaten med varierande fyllningsgrad,
matrisstorlek 1000.
Figur 4.1.6 visar den totala lagringstiden för de olika lagringsformaten med en konstant
matrisstorlek 5000 och en varierande fyllningsgrad. För denna matrisstorlek så lagrar COO
långsammast och CRS på den snabbaste tiden.
26
Figur 4.1.6: Totala lagringstiden för de olika lagringsformaten med varierande fyllningsgrad,
matrisstorlek 5000.
4.2 RAM-minne
För att kunna mäta hur effektivt minnet lagras med de olika lagringsformaten så används
glesa matriser av olika storlekar och fyllningsgrader.
Figur 4.2.1 visar det totala lagringsminnet för de olika lagringsformaten med 1 %
fyllningsgrad på matriserna. För matriser med 1 % fyllningsgrad så lagrar CRS det minsta
antalet bytes. ELL lagrar det största antalet bytes och COO lagrar lite mindre än ELL.
Figur 4.2.1: Totala lagringsminnet för de olika lagringsformaten. Fyllningsgrad 1 %.
Figur 4.2.2 visar det totala lagringsminnet för de olika lagringsformaten med 25 %
fyllningsgrad på matriserna. För matriser med 25 % fyllningsgrad så lagrar CRS det minsta
27
antalet bytes. ELL lagrar det största antalet bytes och COO lagrar lite mindre än ELL, dock så
är skillnaden relativt liten.
Figur 4.2.2: Totala lagringsminnet för de olika lagringsformaten. Fyllningsgrad 25 %.
Figur 4.2.3 visar det totala lagringsminnet för de olika lagringsformaten med 50 %
fyllningsgrad på matriserna. CRS lagrar fortfarande det minsta antalet bytes. COO lagrar det
största antalet bytes och ELL lagrar lite mindre än COO. Ju tätare matrisen blir ju sämre blir
effektiviten för COO formatet.
Figur 4.2.3: Totala lagringsminnet för de olika lagringsformaten. Fyllningsgrad 50 %.
Figur 4.2.4 visar det totala lagringsminnet för de olika lagringsformaten med 75 %
fyllningsgrad på matriserna. CRS lagrar det minsta antalet bytes. COO lagrar det största
antalet bytes och ELL lagrar lite mindre än COO. COO formatets effektivitet har blivit sämre.
28
Figur 4.2.4: Totala lagringsminnet för de olika lagringsformaten. Fyllningsgrad 75 %.
Figur 4.2.5 visar det totala lagringsminnet för de olika lagringsformaten med konstant
matrisstorlek 1000 och varierande fyllningsgrad. Precis som innan så dominerar CRS
formatet. COO formatet blir sämre ju tätare matrisen blir, som visat i figur 2.2.4.
Figur 4.2.5: Totala lagringsminnet för de olika lagringsformaten med varierande
fyllningsgrad, matrisstorlek 1000.
Figur 4.2.6 visar det totala lagringsminnet för de olika lagringsformaten med konstant
matrisstorlek 5000 och varierande fyllningsgrad. CRS formatet lagrar effektivast. I början
lagrar COO och ELL ungefär lika mycket minne, dock ju tätare matrisen blir så försämras
effektiviteten för COO som påståtts innan.
29
Figur 4.2.6: Totala lagringsminnet för de olika lagringsformaten med varierande
fyllningsgrad, matrisstorlek 5000.
4.3 Lösningstid med Gauss-Seidel
Lösningstiden för en numerisk algoritm har beräknats med formatet ELL. Detta format har
använts då det är det enda av de 3 lagringsformaten som kunde hantera en tät 10000x10000
matris, d.v.s. av fyllningsgrad >= 50 %. Lösningstiden beräknas också med en
tvådimensionell vektor från C++ biblioteket för jämförelse. I dessa tvådimensionella vektorer
sparas alla element, även nollor.
I figur 4.3.1 visas den totala tid det tar att lösa det linjära ekvationssystemet Ax = b med
Gauss-Seidels metod för matriser av olika storlekar och fyllningsgrader. Tidsskillnaden är
minimal i början men ökar ju tätare matrisen blir.
30
Figur 4.3.1: Totala tiden att lösa ett linjärt ekvationssystem med Gauss-Seidel för
matrisformatet ELL, olika matrisstorlekar.
I figur 4.3.2 visas den totala tid det tar att lösa det linjära ekvationssystemet Ax = b med
Gauss-Seidels metod för en konstant matrisstorlek 1000 med olika fyllningsgrader. Det tar
längre tid att lösa en matris av större fyllningsgrad. Eftersom implementationen inte är skapad
för täta matriser så är tidsskillnaden en naturlig konsekvens av detta.
Figur 4.3.2: Totala tiden att lösa ett linjärt ekvationssystem med Gauss-Seidel för
matrisformatet ELL, matrisstorlek 1000 med olika fyllningsgrader.
I figur 4.3.3 visas den totala tid det tar att lösa det linjära ekvationssystemet Ax = b med
Gauss-Seidels metod för en konstant matrisstorlek 5000 med olika fyllningsgrader. Ännu en
gång tar det längre tid att lösa en matris av större fyllningsgrad.
31
Figur 4.3.3: Totala tiden att lösa ett linjärt ekvationssystem med Gauss-Seidel för
matrisformatet ELL, matrisstorlek 5000 med olika fyllningsgrader.
Figur 4.3.4 visar en jämförelse mellan lösningstiden för det linjära ekvationssystemet Ax = b
med Gauss-Seidels metod för en konstant matrisstorlek 1000 med olika fyllningsgrader. ELL
formatet har jämförts med C++ inbyggda tvådimensionella vektor implementation. Vektor
implementationen har lagrat nollor i sin körning, vilket ELL formatet inte har. Eftersom
Gauss-Seidels metod inte har optimerats för just denna lagringsmetod, då lagringsmetoden
hämtar nollor och beräknar dessa under körningen, och ELL formatet inte är effektivt för täta
matriser (fyllningsgrad >= 50%) så löser vektor implementationen på en mycket kortare tid.
Figur 4.3.4: Totala tiden att lösa ett linjärt ekvationssystem med Gauss-Seidel för
matrisformatet ELL samt en vanlig vektor implementation, matrisstorlek 1000 med olika
fyllningsgrader.
32
4.4 Formatens effektivitet
Formatens effektivitet har jämförts på hur lång tid det tar att lagra ett nollskilt element och hur
mycket minne det tar. Medelvärdet har beräknats och jämförs i tabellform.
Tabell 4.3.1 representerar hur minneseffektiva implementationerna har varit under lagringen.
Eftersom det är nollskilda element som undersöks, och nollor inte sparas, mäts
minneseffektiviteten enligt det totala använda minnet dividerat med det totala antalet
nollskilda element för matrisen. Medelvärdet har beräknats för olika fyllningsgrader. CRS
formatet lagrar den minsta mängden bytes per nollskilt element och är alltså mest effektiv för
lagring.
Lagringsformat
Typ: Double
COO
CRS
ELL
16.0 Bytes/element
12.0 Bytes/element
15.4 Bytes/element
Tabell 4.3.1: Bytes per nollskilt element för varje
lagringsstruktur.
Tabell 4.3.2 representerar hur tidseffektiva implementationerna har varit under lagringen.
Tidseffektiviten har mäts genom att ta den totala lagringstiden dividerat med antalet nollskilda
element för matrisen. Medelvärdet har beräknats för olika fyllningsgrader. CRS lagrar på den
minsta tiden per nollskilt element men tidsskillnaden är minimal mellan lagringsformaten.
Lagringsformat
Tid i mikrosekunder
COO
CRS
ELL
3.82 µs/element
3.76 µs/element
3.80 µs/element
Tabell 4.3.2: Tiden det tar att lagra ett nollskilt element för varje
datastruktur.
33
34
Kapitel 5
Diskussion
Detta kapitel diskuterar resultaten som tagits fram under undersökningen.
Lagringsmetodernas minneslagring och lagringstid diskuteras samt deras effektivitet.
Implementationernas effektivitet diskuteras och nackdelar med användandet av Gauss-Seidels
metod för lösning av matrisernas linjära ekvationssystem tas fram.
5.1 Val av algoritm
Gauss-Seidels metod är iterativ och konvergerar inte alltid mot något värde, vilket kan leda
till att det uppstår fel inom lösningens tidsramar. För ostrukturerade matriser så ökar chansen
för detta då strukturen på matrisen påverkar lösningsmetoden.
Studien undersöker lagringseffektivitet på matriser som är ostrukturerade. Gauss-Seidels
metod konvergerar snabbare på matriser som är diagonalt strukturerade. Om matriserna
istället hade varit strukturerade på ett sådant sätt hade metoden konvergerat mot en lösning på
en kortare tid. Det finns metoder tillgängliga för omstrukturering av matrisen till ett enklare
format för beräkning, såsom Cholesky dekomposition [18].
ELL formatet, som användes vid undersökningen av metoden sparar inte nollor i minnet
(förutom de som används vid utfyllning). Dessa nollor finns virtuellt i programmet och
returneras i get metoden ifall inget annat värde hittas, detta leder till att vektorerna som
bygger upp datastrukturen först undersöks och om inget hittas så returneras en nolla, vilket tar
tid. Algoritmen har under studiens gång inte optimerats för någon specifik lagringsmetod utan
använts rakt av enligt definitionen. Nollor beräknas under körningen med ELL formatet och
effektiviteten på lagringsmetoden sjunker i detta avseende.
5.2 Lagringsmetodernas effektivitet
5.2.1 Minneseffektivitet
Lagringsmetoden CRS lagrar på det mest minneseffektiva sättet, för varierande
fyllningsgrader. Detta styrks i figurerna 4.2.1-4 där CRS formatet dominerar minneslagringen
35
och tar upp den minsta mängd bytes i RAM minnet för en gles eller tät matris av godtycklig
storlek n. Formatet lagrar också det minsta antalet bytes per nollskilt element.
COO formatet lagrar mindre än ELL formatet i figur 4.2.1-2. Efter att matrisen blir tätare,
d.v.s. fyllningsgraden stiger som i figur 4.2.3-4, så verkar COO formatets effektivitet
försämras och ELL formatet lagrar effektivare. Som beskrivs i bakgrunden så sparar ELL
formatet nollskilda element med två tvådimensionella vektorer. Storleken på varje vektor i
t.ex. den tvådimensionella kolonn vektorn bestäms av den rad som innehåller mest nollskilda
element. Denna storlek är konstant för alla vektorer i den tvådimensionella vektorn. COO
formatet lagrar i tre olika vektorer vars storlekar är densamma som antalet nollskilda element
i matrisen. Eftersom ELL formatets vektorer inte påverkas av matrisens täthet lika mycket
som COO formatet gör så försämras COO formatet och ELL formatet blir därför mer
användbar för matriser med större fyllningsgrad, detta styrks i figur 4.2.5-6 där
matrisstorleken är konstant men fyllningsgraden varierar i undersökningen.
5.2.2 Tidseffektivitet
Det finns ingen markant skillnad i lagringstid för de olika formaten. Den största skillnaden
som har observerats är den i figur 4.1.1 på ungefärligen en halv sekunds skillnad mellan ELL
formatet och COO-CRS. Detta beror till största delen på strukturen av ELL formatet som
använder sig av två tvådimensionella vektorer till skillnad från de andra formaten som
använder sig av tre endimensionella vektorer.
För en konstant matrisstorlek och varierande fyllningsgrad upptäcks heller inga större
skillnader i lagringstid. I figur 4.1.5 noteras enbart att COO formatets effektivitet sjunker med
en väldigt liten marginal ju tätare matrisen blir. CRS formatet, som också består av 3
endimensionella vektorer, påverkas inte av detta då rad offset vektorn inte växer lika mycket
som COO formatets radvektor.
5.3 Implementeringarnas effektivitet
Lagringsmetoderna som har implementerats har visat sig vara effektiva för glesa matriser av
godtycklig storlek och som är ostrukturerade. Eftersom det nu inte tas upp lika mycket RAMminne av en enskild process så kan man överväga att köra flera processer samtidigt, för att
kunna utnyttja effektiviten av lagringen.
Lagringsmetoderna har under undersökningens gång inte hunnit optimeras. För formatet COO
så tar det väldigt lång tid att plocka ut ett värde på plats i, j, eftersom att sökningen görs i
linjärtid. För att kunna optimera detta så kan man istället implementera en binärsökning, som
skulle kunna köras i mycket snabbare takt. Det nämns dock i bakgrunden att COO formatet är
ett format som oftast konverteras till ett annat och brukar användas i allmänhet för inläsning
36
av matrisen. COO formatet används inte heller i undersökningen med Gauss-Seidels metod på
grund av detta skäl.
Gauss-Seidels metod har skrivits enligt definitionen för täta matriser. Implementationen har
inte optimerats för lagringsmetoderna, vilket gör att onödiga beräkningar görs såsom
hämtning av nollor och beräkningar med dessa. I figur 4.3.4 noteras det att ELL formatet har
en sämre lösningstid än det vanliga formatet som C++ bibliotek erbjuder. Det huvudsakliga
skälet till detta nämns ovan då lösningsmetoden inte har optimerats för någon specifik
lagringsmetod och formatet används för lagring av glesa matriser. Problem uppstår också vid
lagring av större matriser i det vanliga formatet, då programmet inte kan allokera nog med
minne. Om lösningsmetoden hade optimerats för ELL formatet och enbart glesa matriser hade
undersöks så hade formatet funktionerat på ett betydligt bättre sätt än det vanliga formatet.
37
38
Kapitel 6
Slutsats
I detta kapitel presenteras studiens slutsats och diskussioner för framtida optimeringar av
lagringsmetoderna.
6.1 Studiens slutsats
I denna rapport har tre olika lagringsmetoder för glesa matriser implementerats och jämförts.
Metoderna som jämfördes används för minneseffektivisering och tidseffektivisering vid
lagring av glesa matriser. För att jämföra lagringsmetodernas effektivitet har glesa matriser av
olika storlekar och fyllningsgrader använts vid testning.
Resultatet visar att CRS formatet är det effektivaste formatet av formaten som har jämförts
vid minneslagring. Dock är skillnaden på lagringstiden för de olika formaten minimal. Det
implementerade ELL formatet är inte användbart vid lösning av ett linjärt ekvationssystem
med Gauss-Seidels metod då metoden inte är optimerats för detta format. Det finns
optimeringar att göra såsom att anpassa metoden för det specifika formatet, exempelvis
genom att eliminera beräkningar med nollor.
6.2 Framtida forskning
För framtida forskning bör man undersöka hur man effektivt kan kombinera olika
lagringsformat för att skapa nya. Det existerar forskning kring detta där man har kombinerat
exempelvis COO och ELL formatet för att skapa ett nytt format vid namnet HYB (Hybrid).
HYB formatet kombinerar ELL formatets tidseffektivitet vid beräkning med glesa matriser
samt COO formatets flexibilitet [9]. HEC är ett annat hybrid format som också är framtaget
genom en kombination tidigare existerande format, ELL och CSR [19]. Det ska dock noteras
att dessa format är framtagna för att effektivisera matris-vektor operationer för en
grafikprocessor (GPU).
39
40
Appendix
Appendix A: Kod för implementation av COO formatet
Detta är en implementation av COO formatet skrivet I programmeringsspråket C++.
class MatrixCOO{
public:
vector <int> rowArray;
vector <int> colArray;
vector <double> elemArray;
MatrixCOO(){};
double get(int i, int j) const{
for(int ri = 0; ri < rowArray.size(); ri++){
for(int ci = 0; ci < colArray.size(); ci++){
if(rowArray[ri] == i &&
colArray[ci] == j && ri == ci){
return elemArray[ri];
}
}
}
return 0;
}
double& operator() (int i, int j){
rowArray.push_back(i);
colArray.push_back(j);
elemArray.push_back(0);
return elemArray[elemArray.size() - 1];
}
double amountOfBytes(){
double fullAmount;
fullAmount = (rowArray.size()*4) + (colArray.size()*4) +
(elemArray.size()*8);
return fullAmount;
}
};
41
42
Appendix B: Kod för implementation av ELL formatet
Detta är en implementation av ELL formatet skrivet I programmeringsspråket C++.
class MatrixELL{
public:
int rowIndexSaver = 0;
int sizeOfMatrix;
int mostNNZ;
vector<int> tempVecCol;
vector<vector<int>> colArr;
vector<vector<double>> valArr;
vector<double> tempVecVal;
MatrixELL(int sizeOfMat, int moostNNZ){
mostNNZ = moostNNZ;
sizeOfMatrix = sizeOfMat;
};
double get(int i, int j) const{
for(int ci = 0; ci < mostNNZ; ci++){
if(colArr[i][ci] == j){
return valArr[i][ci];
}
}
return 0;
}
double& operator() (int i, int j){
if(rowIndexSaver == i){
tempVecCol.push_back(j);
tempVecVal.push_back(0);
return tempVecVal[tempVecVal.size() - 1];
}
else if(i > rowIndexSaver){
if(tempVecVal.size() < mostNNZ){
int q = mostNNZ tempVecVal.size();
for(int i = 0; i < q; i++){
tempVecVal.push_back(0);
tempVecCol.push_back(0);
}
colArr.push_back(tempVecCol);
43
valArr.push_back(tempVecVal);
tempVecCol.clear();
tempVecVal.clear();
rowIndexSaver++;
tempVecCol.push_back(j);
tempVecVal.push_back(0);
return tempVecVal[tempVecVal.size() - 1];
}
colArr.push_back(tempVecCol);
valArr.push_back(tempVecVal);
tempVecCol.clear();
tempVecVal.clear();
rowIndexSaver++;
tempVecCol.push_back(j);
tempVecVal.push_back(0);
return tempVecVal[tempVecVal.size() - 1];
}
}
void lastcheck(){
if(tempVecVal.size() < mostNNZ){
int q = mostNNZ - tempVecVal.size();
for(int i = 0; i < q; i++){
tempVecVal.push_back(0);
tempVecCol.push_back(0);
}
valArr.push_back(tempVecVal);
colArr.push_back(tempVecCol);
}
else{
valArr.push_back(tempVecVal);
colArr.push_back(tempVecCol);
}
}
double amountOfBytes(){
return (colArr.size()*tempVecCol.size()*4) +
(valArr.size()*tempVecVal.size()*8);
}
};
44
Appendix C: Kod för implementation av CRS formatet
Detta är en implementation av CRS formatet skrivet I programmeringsspråket C++.
class MatrixCSR{
public:
int offsetcounter = 0;
int indexSaver;
int nnz;
int sizeOfMatrix;
vector <int> offsetArray;
vector <int> colArray;
vector <double> elemArray;
MatrixCSR(int sizeOfMat, int numberofNonZero){
nnz = numberofNonZero;
sizeOfMatrix = sizeOfMat;
};
double get(int i, int j) const{
for(int ri = 1; ri < offsetArray.size(); ri++){
if(i == ri && colArray[offsetArray[i]] == j){
return elemArray[offsetArray[i]];
}
else if(i == ri && colArray[offsetArray[i-1]] != j){
int currentInd = offsetArray[i];
for(int q = i; q < sizeOfMatrix; q++){
if(colArray[currentInd + 1] == j){
return elemArray[currentInd + 1];
}
currentInd++;
}
}
}
if((i) == sizeOfMatrix && (j) == sizeOfMatrix){
return elemArray[nnz-1];
}
return 0;
}
double& operator() (int i, int j){
colArray.push_back(j);
elemArray.push_back(0);
if (offsetArray.size() == 0){
offsetArray.push_back(0);
offsetArray.push_back(offsetcounter);
indexSaver = i;
return elemArray[elemArray.size() - 1];
45
}
offsetcounter++;
if(elemArray.size() == nnz){
offsetArray.push_back(nnz);
}
else if(i > indexSaver){
offsetArray.push_back(offsetcounter);
indexSaver = i;
}
return elemArray[elemArray.size() - 1];
}
double amountOfBytes(){
return (offsetArray.size()*4 + colArray.size()*4 + elemArray.size()*8);
}
};
46
47
Appendix D: Gauss Seidels metod
Detta är en implementation av Gauss-Seidels metod skrivet I programmeringsspråket C++.
void GaussSeidel(MatrixCSR A, int sizeofMatrix, int numOfIter, double rightSide[],
double initGuess[], double saveVal[]){
while(numOfIter > 0)
{
for(int i = 0; i < sizeofMatrix; i++){
saveVal[i] = (rightSide[i] / A.get(i+1,i+1));
for(int j = 0; j < sizeofMatrix; j++){
if(j == i)
continue;
saveVal[i] = saveVal[i] - ((A.get(i+1,j+1)/A.get(i+1,i+1)) *
initGuess[j]);
initGuess[i] = saveVal[i];
}
printf("x%d = %f
", i + 1, saveVal[i]);
}
cout << "\n";
numOfIter--;
}
}
48
49
Referenser
[1] Lueger, O. (1904). Lexikon der gesamten Technik. 2nd ed. Deutsche Verlags-Anstalt. URL:
http://www.zeno.org/Lueger-1904/0/Suche?o=i [Hämtades 8 Maj 2015]
[2] Scipy-lectures.github.io, (2008). 2.5.2.2.3. Dictionary of Keys Format (DOK) — Scipy lecture notes.
URL: https://scipy-lectures.github.io/advanced/scipy_sparse/dok_matrix.html [Hämtades 8 Maj
2015]
[3] Docs.scipy.org, (2008). scipy.sparse.dok_matrix — SciPy v0.15.1 Reference Guide. URL:
http://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.dok_matrix.html [Hämtades 8 Maj
2015]
[4] Docs.scipy.org, (2008). scipy.sparse.lil_matrix — SciPy v0.15.1 Reference Guide. URL:
http://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.lil_matrix.html [Hämtades 8 Maj
2015]
[5] Scipy-lectures.github.io, (2008). 2.5.2.2.2. List of Lists Format (LIL) — Scipy lecture notes. URL:
https://scipy-lectures.github.io/advanced/scipy_sparse/lil_matrix.html [Hämtades 8 Maj 2015]
[6] Stanimirovic, I. and Tasic, M. (2009). PERFORMANCE COMPARISON OF STORAGE FORMATS FOR
SPARSE MATRICES. 1st ed. FACTA UNIVERSITATIS, s.2-3. URL:
http://facta.junis.ni.ac.rs/mai/mai24/fumi-24_39_51.pdf [Hämtades 8 Maj 2015]
[7] Golub, Gene H.; Van Loan, Charles F. (1996). Matrix Computations (3rd ed.), Baltimore: Johns
Hopkins, s.510. URL:
http://web.mit.edu/ehliu/Public/sclark/Golub%20G.H.,%20Van%20Loan%20C.F.%20Matrix%20Computations.pdf [Hämtades 8 Maj 2015]
[8] Eisenstat, S., Gursky, M., Schultz, M. och Sherman, A. (odaterat). Yale Sparse Matrix Package. 1st
ed. Yale, s.3-4. URL: http://cpsc.yale.edu/sites/default/files/files/tr112.pdf [Hämtades 8 Maj 2015]
[9] Bell, N. och Garland, M. (2009). Implementing Sparse Matrix-Vector Multiplication on ThroughputOriented Processors. 1st ed. NVIDIA, s.4, 10. URL: http://www.nvidia.com/docs/IO/77944/sc09-spmvthroughput.pdf [Hämtades 8 Maj 2015]
[10] Bell, N. and Garland, M. (2008). Efficient Sparse Matrix-Vector Multiplication on CUDA. 1st ed.
NVIDIA, s.6-7. URL: http://sbel.wisc.edu/Courses/ME964/Literature/techReportGarlandBell.pdf
[Hämtades 8 Maj 2015]
[11] Bell, N. (2011). Sparse Matrix Representations & Iterative Solvers. 1st ed. NVIDIA, s.10-12. URL:
http://www.bu.edu/pasi/files/2011/01/NathanBell1-10-1000.pdf [Hämtades 8 Maj 2015]
[12] Kahan, W. (1958). Gauss-Seidel Methods of Solving Large Systems of Linear Equations. Ph.D.
University of Toronto [Hämtades 8 Maj 2015]
50
[13] Saadeh, M. (2011). Gauss Seidel Method for a system of equations. URL:
http://www.mathworks.com/matlabcentral/fileexchange/32051-gauss-seidelmethod/content/Gauss_Seidel.m [Hämtades 8 Maj 2015]
[14] Saad, Y. (2003). Iterative Methods for Sparse Linear Systems. 2nd ed. Society for Industrial and
Applied Mathematics, s.113. URL: http://www-users.cs.umn.edu/~saad/IterMethBook_2ndEd.pdf
[Hämtades 8 Maj 2015]
[15] Antz, H., Tomov, S. och Dongarra, J. (2014). Implementing a Sparse Matrix Vector Product for the
SELL-C/SELL-C-σ formats on NVIDIA GPUs. 1st ed. University of Tennessee, Knoxville, USA: Innovative
Computing Lab, s.1 och s.3. URL: http://www.icl.utk.edu/sites/icl/files/publications/2014/icl-utk-7722014.pdf [Hämtades 8 Maj 2015]
[16] Se.mathworks.com, (2006). Create array of all zeros - MATLAB zeros. URL:
http://se.mathworks.com/help/matlab/ref/zeros.html [Hämtades 8 Maj 2015]
[17] Se.mathworks.com, (2006). Uniformly distributed random numbers - MATLAB rand. URL:
http://se.mathworks.com/help/matlab/ref/rand.html [Hämtades 8 MaJ 2015]
[18] Zubair, M. och Ghose, M. (1992). A PERFORMANCE STUDY OF SPARSE CHOLESKY
FACTORIZATION ON INTEL iPSC/860. 1st ed. Institute for Computer Applications in Science and
Engineering, s.8. URL: http://www.dtic.mil/dtic/tr/fulltext/u2/a251186.pdf [Hämtades 8 Maj 2015].
[19] Liu, H., Yu, S., Chen, Z., Hsieh, B. and Shao, L. (2012). SPARSE MATRIX-VECTOR MULTIPLICATION
ON NVIDIA GPU. 1st ed. Institute for Scientific Computing and Information, s.6. URL:
http://www.math.ualberta.ca/ijnamb/Volume-3-2012/No-2-12/2012-02-04.pdf [Hämtades 8 Maj
2015].
51