350 likes | 546 Views
Sparse Matrices. sparse … many elements are zero dense … few elements are zero. Example Of Sparse Matrices. diagonal tridiagonal lower triangular (?) These are structured sparse matrices. May be mapped into a 1D array so that a mapping function can be used to locate an element.
E N D
Sparse Matrices sparse … many elements are zero dense … few elements are zero
Example Of Sparse Matrices diagonal tridiagonal lower triangular (?) These are structured sparse matrices. May be mapped into a 1D array so that a mapping function can be used to locate an element.
Unstructured Sparse Matrices Airline flight matrix. airports are numbered 1 through n flight(i,j)= list of nonstop flights from airport i to airport j n = 1000 (say) n x n array of list references => 4 million bytes total number of flights = 20,000 (say) need at most 20,000 list references => at most 80,000 bytes
Unstructured Sparse Matrices Web page matrix. web pages are numbered 1 through n web(i,j)= number of links from page i to page j Web analysis. authority page … page that has many links to it hub page … links to many authority pages
Web Page Matrix n = 2 billion (and growing by 1 million a day) n x n array of ints => 16 * 1018 bytes (16 * 109 GB) each page links to 10 (say) other pages on average on average there are 10 nonzero entries per row space needed for nonzero elements is approximately 20 billion x 4 bytes = 80 billion bytes (80 GB)
Representation Of Unstructured Sparse Matrices Single linear list in row-major order. scan the nonzero elements of the sparse matrix in row-major order each nonzero element is represented by a triple (row, column, value) the list of triples may be an array list or a linked list (chain)
list = row 1 1 2 2 4 4 column 3 5 3 4 2 3 value 3 4 5 7 2 6 Single Linear List Example 0 0 3 0 4 0 0 5 7 0 0 0 0 0 0 0 2 6 0 0
element 0 1 2 3 4 5 row 1 1 2 2 4 4 column 3 5 3 4 2 3 value 3 4 5 7 2 6 Array Linear List Representation row 1 1 2 2 4 4 list = column 3 5 3 4 2 3 value 3 4 5 7 2 6
row col value next Chain Representation Node structure.
1 3 1 5 2 3 2 4 4 2 4 3 3 4 5 7 2 6 null firstNode Single Chain row 1 1 2 2 4 4 list = column 3 5 3 4 2 3 value 3 4 5 7 2 6
One Linear List Per Row row1 = [(3, 3), (5,4)] row2 = [(3,5), (4,7)] row3 = [] row4 = [(2,2), (3,6)] 0 0 3 0 4 0 0 5 7 0 0 0 0 0 0 0 2 6 0 0
next col value Array Of Row Chains Node structure.
null 3 3 5 4 null 3 5 4 7 null 2 2 3 6 row[] Array Of Row Chains 0 0 3 0 4 0 0 5 7 0 0 0 0 0 0 0 2 6 0 0 null
row col value down next Orthogonal List Representation Both row and column lists. Node structure. struct NodeS { int r; // row number int c; // column number struct NodeS *rptr; // row pointer struct NodeS *cptr; // column header int data; // actual data };typedef struct NodeS NodeS;
1 3 1 5 3 4 n 2 3 2 4 5 7 n null 4 2 4 3 2 6 n Row Lists 0 0 3 0 4 0 0 5 7 0 0 0 0 0 0 0 2 6 0 0
1 3 1 5 3 4 n 2 3 2 4 5 7 4 2 4 3 2 6 n n Column Lists 0 0 3 0 4 0 0 5 7 0 0 0 0 0 0 0 2 6 0 0
1 3 1 5 3 4 n n 2 3 2 4 5 7 n null 4 2 4 3 2 6 n n n row[] Orthogonal Lists 0 0 3 0 4 0 0 5 7 0 0 0 0 0 0 0 2 6 0 0
Variations May use circular lists instead of chains.
Sparse matrices • Represent each column of a sparse matrix as a circularly linked list with a head node. • A similar representation for each row of a sparse matrix. • Each node has a tag field that is used to distinguish between head nodes and entry nodes. • Each head node has three additional fields: down, right, and next. • down field: links into a column list • right field: links into a row list • next field: links the head nodes together • The head node for row i is also the head node for column i, and the total number of head nodes is max {number of rows, number of columns}.
Each entry node has six fields: tag, row, col, down, right, value. • down field: links to the next nonzero term in the same column • right field: links to the next nonzero term in the same row • A num_rows × num_cols matrix with num_terms nonzero terms needs max{num_rows, num_cols} + num_terms + 1 nodes. • Total storage will be less than num_rows × num_cols when num_terms is sufficiently small.
4 4 0 2 11 1 1 1 0 12 5 1 2 -4 3 3 -15
struct NodeS { int r; // row number int c; // column number struct NodeS *rptr; // row pointer struct NodeS *cptr; // column header int data; // actual data }; typedef struct NodeS NodeS;
NodeS* create(NodeS *h) { NodeS *ptr, *ptr1, *ptr2, *node; NodeS *row_ptr, *column_ptr, *row_header, *column_header; int i,j,d; int r, c; printf("\nEnter the no. of rows ::"); scanf("%d", &r); printf("Enter the no. of columns ::"); scanf("%d", &c); // create the head node h=(NodeS *)malloc(sizeof(NodeS)); h->r=r; h->c=c; h->rptr=h; h->cptr=h; h->data=0;
// create column headers ptr=h; for(i=1;i<=c;i++) { NodeS *node; node=(NodeS *)malloc(sizeof(NodeS)); node->r=0; node->c=i; node->data=0; node->rptr=h; node->cptr=node; ptr->rptr=node; ptr=node; }
// create row headers ptr=h; for(i=1;i<=r;i++) { NodeS *node; node=(NodeS *)malloc(sizeof(NodeS)); node->r=i; node->c=0; node->data=0; node->rptr=node; node->cptr=h; ptr->cptr=node; ptr=node; }
printf("\nNow enter the non zero elements one by one\n"); printf("\nEnter row number,column number, data\n"); printf("Enter (0 0 0) to stop ::"); scanf("%d%d%d",&i, &j, &d); if(i>r || j>c ||i<1 ||j<1) { printf("Error in input"); exit(1); }
while(i&&j&&d) { row_header=h->cptr; column_header=h->rptr; // find the correct row header and column header while(row_header->r<i) row_header=row_header->cptr; while(column_header->c<j) column_header=column_header->rptr;
// find the correct position to insert row_ptr=row_header; while((row_ptr->c)<j) { ptr1=row_ptr; row_ptr=row_ptr->rptr; if(row_ptr==row_header) break; }
column_ptr=column_header; while(column_ptr->r<i) { ptr2=column_ptr; column_ptr=column_ptr->cptr; if(column_ptr==column_header) break; }
node=(NodeS *)malloc(sizeof(NodeS)); node->r=i; node->c=j; node->data=d; ptr1->rptr=node; ptr2->cptr=node; node->rptr=row_ptr; node->cptr=column_ptr;
printf("\nEnter row number,column number,data\n"); printf("Enter (0 0 0) to stop ::"); scanf("%d%d%d", &i, &j, &d); if(i>r || j>c ) { printf(" error input"); exit(1); } } return h; }
void display(NodeS*h) { NodeS *right; right=h->cptr; while(right!=h) { NodeS *r=right; right=right->rptr; while(right!=r) { printf("%d\t%d\t%d\n", right->r, right->c, right->data); right=right->rptr; } right=right->cptr; } }
void add(NodeS*h1,NodeS*h2) { NodeS *r1, *r2, *p1, *p2; if(h1->r==h2->r && h1->c==h2->c) printf("The addition of the two given sparse matrices is ::\n"); else { printf("addition is not possible"); exit(1); } r1=h1->cptr; r2=h2->cptr;
while(r1!=h1) { p1=r1; r1=r1->rptr; p2=r2; r2=r2->rptr; while(r1!= p1 && r2!=p2) { if(r1->c==r2->c) { printf("%d\t%d\t%d\n", r1->r, r1->c, (r1->data+r2->data)); r1=r1->rptr; r2=r2->rptr; } else if(r1->c>r2->c) { printf("%d\t%d\t%d\n", r2->r, r2->c, r2->data); r2=r2->rptr; } else { printf("%d\t%d\t%d\n", r1->r, r1->c, r1->data); r1=r1->rptr; } }
while(r1!=p1) { printf("%d\t%d\t%d\n", r1->r, r1->c, r1->data); r1=r1->rptr; } while(r2!=p2) { printf("%d\t%d\t%d\n", r2->r, r2->c, r2->data); r2=r2->rptr; } r1=r1->cptr; r2=r2->cptr; } }