src/sparse/matrix.c File Reference

#include <stdio.h>
#include "sparse_int.h"
Include dependency graph for matrix.c:

Go to the source code of this file.

Functions

sm_matrixsm_allocate (void)
sm_matrixsm_alloc_size (int row, int col)
void sm_free_space (sm_matrix *A)
sm_matrixsm_dup (sm_matrix *A)
void sm_resize (sm_matrix *A, int row, int col)
sm_elementsm_insert (sm_matrix *A, int row, int col)
sm_elementsm_find (sm_matrix *A, int rownum, int colnum)
void sm_remove (sm_matrix *A, int rownum, int colnum)
void sm_remove_element (sm_matrix *A, sm_element *p)
void sm_delrow (sm_matrix *A, int i)
void sm_delcol (sm_matrix *A, int i)
void sm_copy_row (sm_matrix *dest, int dest_row, sm_row *prow)
void sm_copy_col (sm_matrix *dest, int dest_col, sm_col *pcol)
sm_rowsm_longest_row (sm_matrix *A)
sm_colsm_longest_col (sm_matrix *A)
int sm_num_elements (sm_matrix *A)
int sm_read (FILE *fp, sm_matrix **A)
int sm_read_compressed (FILE *fp, sm_matrix **A)
void sm_write (FILE *fp, sm_matrix *A)
void sm_print (FILE *fp, sm_matrix *A)
void sm_dump (sm_matrix *A, char *s, int max)
void sm_cleanup (void)

Function Documentation

sm_matrix* sm_alloc_size ( int  row,
int  col 
)

Definition at line 41 of file matrix.c.

00042 {
00043     register sm_matrix *A;
00044 
00045     A = sm_alloc();
00046     sm_resize(A, row, col);
00047     return A;
00048 }

sm_matrix* sm_allocate ( void   ) 

Definition at line 24 of file matrix.c.

00025 {
00026     register sm_matrix *A;
00027 
00028     A = ALLOC(sm_matrix, 1);
00029     A->rows = NIL(sm_row *);
00030     A->cols = NIL(sm_col *);
00031     A->nrows = A->ncols = 0;
00032     A->rows_size = A->cols_size = 0;
00033     A->first_row = A->last_row = NIL(sm_row);
00034     A->first_col = A->last_col = NIL(sm_col);
00035     A->user_word = NIL(char);           /* for our user ... */
00036     return A;
00037 }

void sm_cleanup ( void   ) 

Definition at line 508 of file matrix.c.

00509 {
00510 #ifdef FAST_AND_LOOSE
00511     register sm_element *p, *pnext;
00512     register sm_row *prow, *pnextrow;
00513     register sm_col *pcol, *pnextcol;
00514 
00515     for(p = sm_element_freelist; p != 0; p = pnext) {
00516         pnext = p->next_col;
00517         FREE(p);
00518     }
00519     sm_element_freelist = 0;
00520 
00521     for(prow = sm_row_freelist; prow != 0; prow = pnextrow) {
00522         pnextrow = prow->next_row;
00523         FREE(prow);
00524     }
00525     sm_row_freelist = 0;
00526 
00527     for(pcol = sm_col_freelist; pcol != 0; pcol = pnextcol) {
00528         pnextcol = pcol->next_col;
00529         FREE(pcol);
00530     }
00531     sm_col_freelist = 0;
00532 #endif
00533 }

void sm_copy_col ( sm_matrix dest,
int  dest_col,
sm_col pcol 
)

Definition at line 328 of file matrix.c.

00329 {
00330     register sm_element *p;
00331 
00332     for(p = pcol->first_row; p != 0; p = p->next_row) {
00333         (void) sm_insert(dest, dest_col, p->row_num);
00334     }
00335 }

void sm_copy_row ( sm_matrix dest,
int  dest_row,
sm_row prow 
)

Definition at line 317 of file matrix.c.

00318 {
00319     register sm_element *p;
00320 
00321     for(p = prow->first_col; p != 0; p = p->next_col) {
00322         (void) sm_insert(dest, dest_row, p->col_num);
00323     }
00324 }

void sm_delcol ( sm_matrix A,
int  i 
)

Definition at line 285 of file matrix.c.

00286 {
00287     register sm_element *p, *pnext;
00288     sm_row *prow;
00289     sm_col *pcol;
00290 
00291     pcol = sm_get_col(A, i);
00292     if (pcol != NIL(sm_col)) {
00293         /* walk down the column */
00294         for(p = pcol->first_row; p != 0; p = pnext) {
00295             pnext = p->next_row;
00296 
00297             /* unlink the element from the row (and delete it) */
00298             prow = sm_get_row(A, p->row_num);
00299             sm_row_remove_element(prow, p);
00300 
00301             /* discard the row if it is now empty */
00302             if (prow->first_col == NIL(sm_element)) {
00303                 sm_delrow(A, prow->row_num);
00304             }
00305         }
00306 
00307         /* discard the column -- we already threw away the elements */ 
00308         A->cols[i] = NIL(sm_col);
00309         dll_unlink(pcol, A->first_col, A->last_col, 
00310                             next_col, prev_col, A->ncols);
00311         pcol->first_row = pcol->last_row = NIL(sm_element);
00312         sm_col_free(pcol);
00313     }
00314 }

void sm_delrow ( sm_matrix A,
int  i 
)

Definition at line 253 of file matrix.c.

00254 {
00255     register sm_element *p, *pnext;
00256     sm_col *pcol;
00257     sm_row *prow;
00258 
00259     prow = sm_get_row(A, i);
00260     if (prow != NIL(sm_row)) {
00261         /* walk across the row */
00262         for(p = prow->first_col; p != 0; p = pnext) {
00263             pnext = p->next_col;
00264 
00265             /* unlink the item from the column (and delete it) */
00266             pcol = sm_get_col(A, p->col_num);
00267             sm_col_remove_element(pcol, p);
00268 
00269             /* discard the column if it is now empty */
00270             if (pcol->first_row == NIL(sm_element)) {
00271                 sm_delcol(A, pcol->col_num);
00272             }
00273         }
00274 
00275         /* discard the row -- we already threw away the elements */ 
00276         A->rows[i] = NIL(sm_row);
00277         dll_unlink(prow, A->first_row, A->last_row, 
00278                                 next_row, prev_row, A->nrows);
00279         prow->first_col = prow->last_col = NIL(sm_element);
00280         sm_row_free(prow);
00281     }
00282 }

void sm_dump ( sm_matrix A,
char *  s,
int  max 
)

Definition at line 497 of file matrix.c.

00498 {
00499     FILE *fp = stdout;
00500 
00501     (void) fprintf(fp, "%s %d rows by %d cols\n", s, A->nrows, A->ncols);
00502     if (A->nrows < max) {
00503         sm_print(fp, A);
00504     }
00505 }

sm_matrix* sm_dup ( sm_matrix A  ) 

Definition at line 95 of file matrix.c.

00096 {
00097     register sm_row *prow;
00098     register sm_element *p;
00099     register sm_matrix *B;
00100 
00101     B = sm_alloc();
00102     if (A->last_row != 0) {
00103         sm_resize(B, A->last_row->row_num, A->last_col->col_num);
00104         for(prow = A->first_row; prow != 0; prow = prow->next_row) {
00105             for(p = prow->first_col; p != 0; p = p->next_col) {
00106                 (void) sm_insert(B, p->row_num, p->col_num);
00107             }
00108         }
00109     }
00110     return B;
00111 }

sm_element* sm_find ( sm_matrix A,
int  rownum,
int  colnum 
)

Definition at line 191 of file matrix.c.

00192 {
00193     sm_row *prow;
00194     sm_col *pcol;
00195 
00196     prow = sm_get_row(A, rownum);
00197     if (prow == NIL(sm_row)) {
00198         return NIL(sm_element);
00199     } else {
00200         pcol = sm_get_col(A, colnum);
00201         if (pcol == NIL(sm_col)) {
00202             return NIL(sm_element);
00203         }
00204         if (prow->length < pcol->length) {
00205             return sm_row_find(prow, colnum);
00206         } else {
00207             return sm_col_find(pcol, rownum);
00208         }
00209     }
00210 }

void sm_free_space ( sm_matrix A  ) 

Definition at line 52 of file matrix.c.

00053 {
00054 #ifdef FAST_AND_LOOSE
00055     register sm_row *prow;
00056 
00057     if (A->first_row != 0) {
00058         for(prow = A->first_row; prow != 0; prow = prow->next_row) {
00059             /* add the elements to the free list of elements */
00060             prow->last_col->next_col = sm_element_freelist;
00061             sm_element_freelist = prow->first_col;
00062         }
00063 
00064         /* Add the linked list of rows to the row-free-list */
00065         A->last_row->next_row = sm_row_freelist;
00066         sm_row_freelist = A->first_row;
00067 
00068         /* Add the linked list of cols to the col-free-list */
00069         A->last_col->next_col = sm_col_freelist;
00070         sm_col_freelist = A->first_col;
00071     }
00072 #else
00073     register sm_row *prow, *pnext_row;
00074     register sm_col *pcol, *pnext_col;
00075 
00076     for(prow = A->first_row; prow != 0; prow = pnext_row) {
00077         pnext_row = prow->next_row;
00078         sm_row_free(prow);
00079     }
00080     for(pcol = A->first_col; pcol != 0; pcol = pnext_col) {
00081         pnext_col = pcol->next_col;
00082         pcol->first_row = pcol->last_row = NIL(sm_element);
00083         sm_col_free(pcol);
00084     }
00085 #endif
00086 
00087     /* Free the arrays to map row/col numbers into pointers */
00088     FREE(A->rows);
00089     FREE(A->cols);
00090     FREE(A);
00091 }

sm_element* sm_insert ( sm_matrix A,
int  row,
int  col 
)

Definition at line 143 of file matrix.c.

00144 {
00145     register sm_row *prow;
00146     register sm_col *pcol;
00147     register sm_element *element;
00148     sm_element *save_element;
00149 
00150     if (row >= A->rows_size || col >= A->cols_size) {
00151         sm_resize(A, row, col);
00152     }
00153 
00154     prow = A->rows[row];
00155     if (prow == NIL(sm_row)) {
00156         prow = A->rows[row] = sm_row_alloc();
00157         prow->row_num = row;
00158         sorted_insert(sm_row, A->first_row, A->last_row, A->nrows, 
00159                         next_row, prev_row, row_num, row, prow);
00160     }
00161 
00162     pcol = A->cols[col];
00163     if (pcol == NIL(sm_col)) {
00164         pcol = A->cols[col] = sm_col_alloc();
00165         pcol->col_num = col;
00166         sorted_insert(sm_col, A->first_col, A->last_col, A->ncols, 
00167                         next_col, prev_col, col_num, col, pcol);
00168     }
00169 
00170     /* get a new item, save its address */
00171     sm_element_alloc(element);
00172     save_element = element;
00173 
00174     /* insert it into the row list */
00175     sorted_insert(sm_element, prow->first_col, prow->last_col, 
00176                 prow->length, next_col, prev_col, col_num, col, element);
00177 
00178     /* if it was used, also insert it into the column list */
00179     if (element == save_element) {
00180         sorted_insert(sm_element, pcol->first_row, pcol->last_row, 
00181                 pcol->length, next_row, prev_row, row_num, row, element);
00182     } else {
00183         /* otherwise, it was already in matrix -- free element we allocated */
00184         sm_element_free(save_element);
00185     }
00186     return element;
00187 }

sm_col* sm_longest_col ( sm_matrix A  ) 

Definition at line 357 of file matrix.c.

00358 {
00359     register sm_col *large_col, *pcol;
00360     register int max_length;
00361 
00362     max_length = 0;
00363     large_col = NIL(sm_col);
00364     for(pcol = A->first_col; pcol != 0; pcol = pcol->next_col) {
00365         if (pcol->length > max_length) {
00366             max_length = pcol->length;
00367             large_col = pcol;
00368         }
00369     }
00370     return large_col;
00371 }

sm_row* sm_longest_row ( sm_matrix A  ) 

Definition at line 339 of file matrix.c.

00340 {
00341     register sm_row *large_row, *prow;
00342     register int max_length;
00343 
00344     max_length = 0;
00345     large_row = NIL(sm_row);
00346     for(prow = A->first_row; prow != 0; prow = prow->next_row) {
00347         if (prow->length > max_length) {
00348             max_length = prow->length;
00349             large_row = prow;
00350         }
00351     }
00352     return large_row;
00353 }

int sm_num_elements ( sm_matrix A  ) 

Definition at line 374 of file matrix.c.

00375 {
00376     register sm_row *prow;
00377     register int num;
00378 
00379     num = 0;
00380     sm_foreach_row(A, prow) {
00381         num += prow->length;
00382     }
00383     return num;
00384 }

void sm_print ( FILE *  fp,
sm_matrix A 
)

Definition at line 450 of file matrix.c.

00451 {
00452     register sm_row *prow;
00453     register sm_col *pcol;
00454     int c;
00455 
00456     if (A->last_col->col_num >= 100) {
00457         (void) fprintf(fp, "    ");
00458         for(pcol = A->first_col; pcol != 0; pcol = pcol->next_col) {
00459             (void) fprintf(fp, "%d", (pcol->col_num / 100)%10);
00460         }
00461         putc('\n', fp);
00462     }
00463 
00464     if (A->last_col->col_num >= 10) {
00465         (void) fprintf(fp, "    ");
00466         for(pcol = A->first_col; pcol != 0; pcol = pcol->next_col) {
00467             (void) fprintf(fp, "%d", (pcol->col_num / 10)%10);
00468         }
00469         putc('\n', fp);
00470     }
00471 
00472     (void) fprintf(fp, "    ");
00473     for(pcol = A->first_col; pcol != 0; pcol = pcol->next_col) {
00474         (void) fprintf(fp, "%d", pcol->col_num % 10);
00475     }
00476     putc('\n', fp);
00477 
00478     (void) fprintf(fp, "    ");
00479     for(pcol = A->first_col; pcol != 0; pcol = pcol->next_col) {
00480         (void) fprintf(fp, "-");
00481     }
00482     putc('\n', fp);
00483 
00484     for(prow = A->first_row; prow != 0; prow = prow->next_row) {
00485         (void) fprintf(fp, "%3d:", prow->row_num);
00486 
00487         for(pcol = A->first_col; pcol != 0; pcol = pcol->next_col) {
00488             c = sm_row_find(prow, pcol->col_num) ? '1' : '.';
00489             putc(c, fp);
00490         }
00491         putc('\n', fp);
00492     }
00493 }

int sm_read ( FILE *  fp,
sm_matrix **  A 
)

Definition at line 387 of file matrix.c.

00388 {
00389     int i, j, err;
00390 
00391     *A = sm_alloc();
00392     while (! feof(fp)) {
00393         err = fscanf(fp, "%d %d", &i, &j);
00394         if (err == EOF) {
00395             return 1;
00396         } else if (err != 2) {
00397             return 0;
00398         }
00399         (void) sm_insert(*A, i, j);
00400     }
00401     return 1;
00402 }

int sm_read_compressed ( FILE *  fp,
sm_matrix **  A 
)

Definition at line 406 of file matrix.c.

00407 {
00408     int i, j, k, nrows, ncols;
00409     unsigned long x;
00410 
00411     *A = sm_alloc();
00412     if (fscanf(fp, "%d %d", &nrows, &ncols) != 2) {
00413         return 0;
00414     }
00415     sm_resize(*A, nrows, ncols);
00416 
00417     for(i = 0; i < nrows; i++) {
00418         if (fscanf(fp, "%lx", &x) != 1) {
00419             return 0;
00420         }
00421         for(j = 0; j < ncols; j += 32) {
00422             if (fscanf(fp, "%lx", &x) != 1) {
00423                 return 0;
00424             }
00425             for(k = j; x != 0; x >>= 1, k++) {
00426                 if (x & 1) {
00427                     (void) sm_insert(*A, i, k);
00428                 }
00429             }
00430         }
00431     }
00432     return 1;
00433 }

void sm_remove ( sm_matrix A,
int  rownum,
int  colnum 
)

Definition at line 214 of file matrix.c.

00215 {
00216     sm_remove_element(A, sm_find(A, rownum, colnum));
00217 }

void sm_remove_element ( sm_matrix A,
sm_element p 
)

Definition at line 222 of file matrix.c.

00223 {
00224     register sm_row *prow;
00225     register sm_col *pcol;
00226 
00227     if (p == 0) return;
00228 
00229     /* Unlink the element from its row */
00230     prow = sm_get_row(A, p->row_num);
00231     dll_unlink(p, prow->first_col, prow->last_col, 
00232                         next_col, prev_col, prow->length);
00233 
00234     /* if no more elements in the row, discard the row header */
00235     if (prow->first_col == NIL(sm_element)) {
00236         sm_delrow(A, p->row_num);
00237     }
00238 
00239     /* Unlink the element from its column */
00240     pcol = sm_get_col(A, p->col_num);
00241     dll_unlink(p, pcol->first_row, pcol->last_row, 
00242                         next_row, prev_row, pcol->length);
00243 
00244     /* if no more elements in the column, discard the column header */
00245     if (pcol->first_row == NIL(sm_element)) {
00246         sm_delcol(A, p->col_num);
00247     }
00248 
00249     sm_element_free(p);
00250 }

void sm_resize ( sm_matrix A,
int  row,
int  col 
)

Definition at line 115 of file matrix.c.

00116 {
00117     register int i, new_size;
00118 
00119     if (row >= A->rows_size) {
00120         new_size = MAX(A->rows_size*2, row+1);
00121         A->rows = REALLOC(sm_row *, A->rows, new_size);
00122         for(i = A->rows_size; i < new_size; i++) {
00123             A->rows[i] = NIL(sm_row);
00124         }
00125         A->rows_size = new_size;
00126     }
00127 
00128     if (col >= A->cols_size) {
00129         new_size = MAX(A->cols_size*2, col+1);
00130         A->cols = REALLOC(sm_col *, A->cols, new_size);
00131         for(i = A->cols_size; i < new_size; i++) {
00132             A->cols[i] = NIL(sm_col);
00133         }
00134         A->cols_size = new_size;
00135     }
00136 }

void sm_write ( FILE *  fp,
sm_matrix A 
)

Definition at line 437 of file matrix.c.

00438 {
00439     register sm_row *prow;
00440     register sm_element *p;
00441 
00442     for(prow = A->first_row; prow != 0; prow = prow->next_row) {
00443         for(p = prow->first_col; p != 0; p = p->next_col) {
00444             (void) fprintf(fp, "%d %d\n", p->row_num, p->col_num);
00445         }
00446     }
00447 }


Generated on Tue Jan 12 13:57:28 2010 for glu-2.2 by  doxygen 1.6.1