Skip to content

Commit aa8ca6c

Browse files
committed
Sparse Matrices in C
0 parents  commit aa8ca6c

25 files changed

+2420
-0
lines changed

Makefile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Makefile
2+
3+
matrix: matrix.o coo.o csr.o
4+
gcc -o matrix matrix.o coo.o csr.o
5+
6+
matrix.o: matrix.c
7+
gcc -O1 -c matrix.c
8+
9+
coo.o: coo.c coo.h
10+
gcc -O1 -c coo.c
11+
12+
csr.o: csr.c csr.h coo.c coo.h
13+
gcc -O1 -c csr.c coo.c

coo.c

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* coo.c
3+
* 21103CW2
4+
*
5+
* Created by Matthew Livingston on 23/01/2012.
6+
* Copyright 2012 University of Bristol. All rights reserved.
7+
*
8+
*/
9+
10+
#include "coo.h"
11+
12+
// Allocate memory for a new Node struct
13+
Node * insertNode(int row, int col, int val, Node * nextNode) {
14+
Node * newNode = calloc(1, sizeof(Node));
15+
newNode->row = row;
16+
newNode->col = col;
17+
newNode->val = val;
18+
newNode->next = nextNode;
19+
20+
return newNode;
21+
}
22+
23+
// Add a new node to the List
24+
List * add(List * list, int row, int col, int val) {
25+
if (list->head == NULL) list->head = list->tail = insertNode(row, col, val, NULL);
26+
else list->tail = list->tail->next = insertNode(row, col, val, NULL);
27+
list->size++;
28+
return list;
29+
}
30+
31+
// Add a new node to the List in ascending row order
32+
List * addRowOrdered(List * list, int row, int col, int val) {
33+
if (list->head == NULL) list->head = list->tail = insertNode(row, col, val, NULL);
34+
else if (row <= list->head->row) list->head = insertNode(row, col, val, list->head);
35+
else if (row >= list->tail->row) list->tail = list->tail->next = insertNode(row, col, val, NULL);
36+
else {
37+
Node * prev = searchList(list->head, row);
38+
if (prev != NULL) prev->next = insertNode(row, col, val, prev->next);
39+
else list->tail = insertNode(row, col, val, NULL);
40+
}
41+
list->size++;
42+
return list;
43+
}
44+
45+
// Search a List sequentially
46+
Node * searchList(Node * node, int row) {
47+
while (node->next != NULL) {
48+
if (node->next->row > row) return node;
49+
else node = node->next;
50+
}
51+
return NULL;
52+
}
53+
54+
// Search a List for a specific element
55+
int searchElement(Node * node, int row, int col) {
56+
while (node != NULL) {
57+
if ((node->row == row) && (node->col == col)) return node->val;
58+
else node = node->next;
59+
}
60+
return -1;
61+
}
62+
63+
// Transpose a COO matrix
64+
List * transpose(List * list) {
65+
Node * node = list->head;
66+
int temp;
67+
while (node != NULL) {
68+
temp = node->row;
69+
node->row = node->col;
70+
node->col = temp;
71+
node = node->next;
72+
}
73+
temp = list->rows;
74+
list->rows = list->cols;
75+
list->cols = temp;
76+
return list;
77+
}
78+
79+
// Return pointer to an empty list
80+
List * freeList(List * list) {
81+
Node * temp;
82+
while ((temp = list->head) != NULL) {
83+
list->head = list->head->next;
84+
free(temp);
85+
}
86+
list->rows = 0;
87+
list->cols = 0;
88+
list->size = 0;
89+
return list;
90+
}
91+
92+
// Print a List
93+
void printList(Node * node) {
94+
while (node != NULL)
95+
{
96+
printf("%d %d %d", node->row, node->col, node->val);
97+
printf("\n");
98+
node = node->next;
99+
}
100+
}

coo.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* coo.h
3+
* 21103CW2
4+
*
5+
* Created by Matthew Livingston on 23/01/2012.
6+
* Copyright 2012 University of Bristol. All rights reserved.
7+
*
8+
*/
9+
10+
#ifndef coo_h
11+
#define coo_h
12+
13+
#include <stdio.h>
14+
#include <string.h>
15+
#include <stdlib.h>
16+
17+
typedef struct node {
18+
int row, col, val;
19+
struct node * next;
20+
} Node;
21+
22+
typedef struct {
23+
Node * head;
24+
Node * tail;
25+
int rows;
26+
int cols;
27+
int size;
28+
} List;
29+
30+
Node * insertNode(int row, int col, int val, Node * nextNode);
31+
List * add(List * list, int row, int col, int val);
32+
List * addRowOrdered(List * list, int row, int col, int val);
33+
Node * searchList(Node * node, int row);
34+
int searchElement(Node * node, int row, int col);
35+
List * transpose(List * list);
36+
List * freeList(List * list);
37+
void printList(Node * node);
38+
39+
#endif

csr.c

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/*
2+
* csr.c
3+
* 21103CW2
4+
*
5+
* Created by Matthew Livingston on 23/01/2012.
6+
* Copyright 2012 University of Bristol. All rights reserved.
7+
*
8+
*/
9+
10+
#include "csr.h"
11+
12+
// Add two CSR matrices together and return a COO matrix
13+
List * addCSR(CSR * A, CSR * B, List * M) {
14+
M->rows = A->rows;
15+
M->cols = A->cols;
16+
int total, i, j, k = 0;
17+
for (i = 0; i < M->rows; i++) {
18+
for (j = 0; j < M->cols; j++) {
19+
total = findVal(A, i, j) + findVal(B, i, j);
20+
if (total != 0) { M = add(M, i, j, total); k++; }
21+
}
22+
}
23+
M->size = k;
24+
return M;
25+
}
26+
27+
// Find a column value in a particular row of a CSR matrix
28+
int findVal(CSR * csr, int row, int col) {
29+
int i;
30+
for (i = csr->row_ptr[row]; i < csr->row_ptr[row+1]; i++) {
31+
if (csr->col_ind[i] == col) return csr->val[i];
32+
}
33+
return 0;
34+
}
35+
36+
// Multiply two CSR matrices together and return a COO matrix
37+
List * multiplyCSR(CSR * A, CSR * B, List * M) {
38+
M->rows = A->rows;
39+
M->cols = B->cols;
40+
int size = 0, total, MRow, MCol, ARow, BCol;
41+
for (MRow = 0; MRow < M->rows; MRow++) {
42+
for (MCol = 0; MCol < M->cols; MCol++) {
43+
total = 0;
44+
for (ARow = A->row_ptr[MRow]; ARow < A->row_ptr[MRow+1]; ARow++) {
45+
for (BCol = B->row_ptr[A->col_ind[ARow]]; BCol < B->row_ptr[A->col_ind[ARow]+1]; BCol++) {
46+
if (B->col_ind[BCol] == MCol) total += A->val[ARow] * B->val[BCol];
47+
}
48+
}
49+
if (total != 0) { M = add(M, MRow, MCol, total); size++; }
50+
}
51+
}
52+
M->size = size;
53+
return M;
54+
}
55+
56+
// Allocate space for and initialise a CSR matrix
57+
CSR * initCSR(CSR * csr, int size, int rows) {
58+
csr->val = calloc(size, sizeof(int));
59+
csr->col_ind = calloc(size, sizeof(int));
60+
csr->row_ptr = calloc(rows+1, sizeof(int));
61+
csr->val_length = size;
62+
csr->row_ptr_length = rows+1;
63+
int i;
64+
for (i = 0; i < csr->row_ptr_length; i++) csr->row_ptr[i] = -1;
65+
66+
return csr;
67+
}
68+
69+
// Return pointer to empty CSR matrix
70+
CSR * freeCSR(CSR * csr) {
71+
free(csr->val);
72+
free(csr->col_ind);
73+
free(csr->row_ptr);
74+
return csr;
75+
}
76+
77+
// Print a particular column of a CSR matrix
78+
void printCol(CSR * csr, int col) {
79+
int * A = calloc(csr->cols, sizeof(int));
80+
int i, j;
81+
for (i = 0; i < csr->row_ptr_length-1; i++) {
82+
for (j = csr->row_ptr[i]; j < csr->row_ptr[i+1]; j++) if (csr->col_ind[j] == col) A[i] = csr->val[j];
83+
}
84+
for (i = 0; i < csr->cols; i++) {
85+
if (i < csr->cols-1) printf("%d,", A[i]);
86+
else printf("%d", A[i]);
87+
}
88+
printf("\n");
89+
free(A);
90+
}
91+
92+
// Print a particular row of a CSR matrix
93+
void printRow(CSR * csr, int row) {
94+
int * A = calloc(csr->rows, sizeof(int));
95+
int i;
96+
for (i = csr->row_ptr[row]; i < csr->row_ptr[row+1]; i++) A[csr->col_ind[i]] = csr->val[i];
97+
for (i = 0; i < csr->rows; i++) {
98+
if (i < csr->rows-1) printf("%d,", A[i]);
99+
else printf("%d", A[i]);
100+
}
101+
printf("\n");
102+
free(A);
103+
}
104+
105+
// Print out the three arrays that make up the CSR matrix
106+
void printCSR(CSR * csr) {
107+
int i;
108+
for (i = 0; i < csr->val_length; i++) {
109+
printf("%d ", csr->val[i]);
110+
}
111+
printf("\n\n");
112+
for (i = 0; i < csr->val_length; i++) {
113+
printf("%d ", csr->col_ind[i]);
114+
}
115+
printf("\n\n");
116+
for (i = 0; i < csr->row_ptr_length; i++) {
117+
printf("%d ", csr->row_ptr[i]);
118+
}
119+
printf("\n");
120+
}

csr.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* csr.h
3+
* 21103CW2
4+
*
5+
* Created by Matthew Livingston on 23/01/2012.
6+
* Copyright 2012 University of Bristol. All rights reserved.
7+
*
8+
*/
9+
10+
#ifndef csr_h
11+
#define csr_h
12+
13+
#include <stdio.h>
14+
#include <string.h>
15+
#include <stdlib.h>
16+
#include "coo.h"
17+
18+
typedef struct {
19+
int * val;
20+
int * col_ind;
21+
int * row_ptr;
22+
int val_length;
23+
int row_ptr_length;
24+
int rows;
25+
int cols;
26+
} CSR;
27+
28+
List * addCSR(CSR * A, CSR * B, List * M);
29+
List * multiplyCSR(CSR * A, CSR * B, List * M);
30+
int findVal(CSR * csr, int row, int col);
31+
CSR * initCSR(CSR * csr, int size, int rows);
32+
CSR * freeCSR(CSR * csr);
33+
void printCSR(CSR * csr);
34+
void printCol(CSR * csr, int col);
35+
void printRow(CSR * csr, int row);
36+
37+
#endif

input/.DS_Store

6 KB
Binary file not shown.

input/stage1.input

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
5,5
2+
0,0,-1
3+
0,4,2
4+
1,1,5
5+
1,3,6
6+
2,2,7
7+
3,1,8
8+
3,3,9
9+
4,0,3
10+
4,4,-4

0 commit comments

Comments
 (0)