/*
 * Revision Control Information
 *
 * $Source$
 * $Author$
 * $Revision$
 * $Date$
 *
 */
//#include "port.h"
#include "sparse_int.h"

ABC_NAMESPACE_IMPL_START


/*
 *  free-lists are only used if 'FAST_AND_LOOSE' is set; this is because
 *  we lose the debugging capability of libmm_t which trashes objects when
 *  they are free'd.  However, FAST_AND_LOOSE is much faster if matrices
 *  are created and freed frequently.
 */

#ifdef FAST_AND_LOOSE
sm_element *sm_element_freelist;
sm_row *sm_row_freelist;
sm_col *sm_col_freelist;
#endif


sm_matrix *
sm_alloc()
{
    register sm_matrix *A;

    A = ALLOC(sm_matrix, 1);
    A->rows = NIL(sm_row *);
    A->cols = NIL(sm_col *);
    A->nrows = A->ncols = 0;
    A->rows_size = A->cols_size = 0;
    A->first_row = A->last_row = NIL(sm_row);
    A->first_col = A->last_col = NIL(sm_col);
    A->user_word = NIL(char);        /* for our user ... */
    return A;
}


sm_matrix *
sm_alloc_size(row, col)
int row, col;
{
    register sm_matrix *A;

    A = sm_alloc();
    sm_resize(A, row, col);
    return A;
}


void
sm_free(A)
sm_matrix *A;
{
#ifdef FAST_AND_LOOSE
    register sm_row *prow;

    if (A->first_row != 0) {
    for(prow = A->first_row; prow != 0; prow = prow->next_row) {
        /* add the elements to the free list of elements */
        prow->last_col->next_col = sm_element_freelist;
        sm_element_freelist = prow->first_col;
    }

    /* Add the linked list of rows to the row-free-list */
    A->last_row->next_row = sm_row_freelist;
    sm_row_freelist = A->first_row;

    /* Add the linked list of cols to the col-free-list */
    A->last_col->next_col = sm_col_freelist;
    sm_col_freelist = A->first_col;
    }
#else
    register sm_row *prow, *pnext_row;
    register sm_col *pcol, *pnext_col;

    for(prow = A->first_row; prow != 0; prow = pnext_row) {
    pnext_row = prow->next_row;
    sm_row_free(prow);
    }
    for(pcol = A->first_col; pcol != 0; pcol = pnext_col) {
    pnext_col = pcol->next_col;
    pcol->first_row = pcol->last_row = NIL(sm_element);
    sm_col_free(pcol);
    }
#endif

    /* Free the arrays to map row/col numbers into pointers */
    FREE(A->rows);
    FREE(A->cols);
    FREE(A);
}


sm_matrix *
sm_dup(A)
sm_matrix *A; 
{
    register sm_row *prow;
    register sm_element *p;
    register sm_matrix *B;

    B = sm_alloc();
    if (A->last_row != 0) {
    sm_resize(B, A->last_row->row_num, A->last_col->col_num);
    for(prow = A->first_row; prow != 0; prow = prow->next_row) {
        for(p = prow->first_col; p != 0; p = p->next_col) {
        (void) sm_insert(B, p->row_num, p->col_num);
        }
    }
    }
    return B;
}


void 
sm_resize(A, row, col)
register sm_matrix *A;
int row, col;
{
    register int i, new_size;

    if (row >= A->rows_size) {
    new_size = MAX(A->rows_size*2, row+1);
    A->rows = REALLOC(sm_row *, A->rows, new_size);
    for(i = A->rows_size; i < new_size; i++) {
        A->rows[i] = NIL(sm_row);
    }
    A->rows_size = new_size;
    }

    if (col >= A->cols_size) {
    new_size = MAX(A->cols_size*2, col+1);
    A->cols = REALLOC(sm_col *, A->cols, new_size);
    for(i = A->cols_size; i < new_size; i++) {
        A->cols[i] = NIL(sm_col);
    }
    A->cols_size = new_size;
    }
}


/*  
 *  insert -- insert a value into the matrix
 */
sm_element *
sm_insert(A, row, col)
register sm_matrix *A;
register int row, col;
{
    register sm_row *prow;
    register sm_col *pcol;
    register sm_element *element;
    sm_element *save_element;

    if (row >= A->rows_size || col >= A->cols_size) {
    sm_resize(A, row, col);
    }

    prow = A->rows[row];
    if (prow == NIL(sm_row)) {
    prow = A->rows[row] = sm_row_alloc();
    prow->row_num = row;
    sorted_insert(sm_row, A->first_row, A->last_row, A->nrows, 
            next_row, prev_row, row_num, row, prow);
    }

    pcol = A->cols[col];
    if (pcol == NIL(sm_col)) {
    pcol = A->cols[col] = sm_col_alloc();
    pcol->col_num = col;
    sorted_insert(sm_col, A->first_col, A->last_col, A->ncols, 
            next_col, prev_col, col_num, col, pcol);
    }

    /* get a new item, save its address */
    sm_element_alloc(element);
    save_element = element;

    /* insert it into the row list */
    sorted_insert(sm_element, prow->first_col, prow->last_col, 
        prow->length, next_col, prev_col, col_num, col, element);

    /* if it was used, also insert it into the column list */
    if (element == save_element) {
    sorted_insert(sm_element, pcol->first_row, pcol->last_row, 
        pcol->length, next_row, prev_row, row_num, row, element);
    } else {
    /* otherwise, it was already in matrix -- free element we allocated */
    sm_element_free(save_element);
    }
    return element;
}


sm_element *
sm_find(A, rownum, colnum)
sm_matrix *A;
int rownum, colnum;
{
    sm_row *prow;
    sm_col *pcol;

    prow = sm_get_row(A, rownum);
    if (prow == NIL(sm_row)) {
    return NIL(sm_element);
    } else {
    pcol = sm_get_col(A, colnum);
    if (pcol == NIL(sm_col)) {
        return NIL(sm_element);
    }
    if (prow->length < pcol->length) {
        return sm_row_find(prow, colnum);
    } else {
        return sm_col_find(pcol, rownum);
    }
    }
}


void
sm_remove(A, rownum, colnum)
sm_matrix *A;
int rownum, colnum;
{
    sm_remove_element(A, sm_find(A, rownum, colnum));
}



void
sm_remove_element(A, p)
register sm_matrix *A; 
register sm_element *p;
{
    register sm_row *prow;
    register sm_col *pcol;

    if (p == 0) return;

    /* Unlink the element from its row */
    prow = sm_get_row(A, p->row_num);
    dll_unlink(p, prow->first_col, prow->last_col, 
            next_col, prev_col, prow->length);

    /* if no more elements in the row, discard the row header */
    if (prow->first_col == NIL(sm_element)) {
    sm_delrow(A, p->row_num);
    }

    /* Unlink the element from its column */
    pcol = sm_get_col(A, p->col_num);
    dll_unlink(p, pcol->first_row, pcol->last_row, 
            next_row, prev_row, pcol->length);

    /* if no more elements in the column, discard the column header */
    if (pcol->first_row == NIL(sm_element)) {
    sm_delcol(A, p->col_num);
    }

    sm_element_free(p);
}

void 
sm_delrow(A, i)
sm_matrix *A;
int i;
{
    register sm_element *p, *pnext;
    sm_col *pcol;
    sm_row *prow;

    prow = sm_get_row(A, i);
    if (prow != NIL(sm_row)) {
    /* walk across the row */
    for(p = prow->first_col; p != 0; p = pnext) {
        pnext = p->next_col;

        /* unlink the item from the column (and delete it) */
        pcol = sm_get_col(A, p->col_num);
        sm_col_remove_element(pcol, p);

        /* discard the column if it is now empty */
        if (pcol->first_row == NIL(sm_element)) {
        sm_delcol(A, pcol->col_num);
        }
    }

    /* discard the row -- we already threw away the elements */ 
    A->rows[i] = NIL(sm_row);
    dll_unlink(prow, A->first_row, A->last_row, 
                next_row, prev_row, A->nrows);
    prow->first_col = prow->last_col = NIL(sm_element);
    sm_row_free(prow);
    }
}

void 
sm_delcol(A, i)
sm_matrix *A;
int i;
{
    register sm_element *p, *pnext;
    sm_row *prow;
    sm_col *pcol;

    pcol = sm_get_col(A, i);
    if (pcol != NIL(sm_col)) {
    /* walk down the column */
    for(p = pcol->first_row; p != 0; p = pnext) {
        pnext = p->next_row;

        /* unlink the element from the row (and delete it) */
        prow = sm_get_row(A, p->row_num);
        sm_row_remove_element(prow, p);

        /* discard the row if it is now empty */
        if (prow->first_col == NIL(sm_element)) {
        sm_delrow(A, prow->row_num);
        }
    }

    /* discard the column -- we already threw away the elements */ 
    A->cols[i] = NIL(sm_col);
    dll_unlink(pcol, A->first_col, A->last_col, 
                next_col, prev_col, A->ncols);
    pcol->first_row = pcol->last_row = NIL(sm_element);
    sm_col_free(pcol);
    }
}

void
sm_copy_row(dest, dest_row, prow)
register sm_matrix *dest;
int dest_row;
sm_row *prow;
{
    register sm_element *p;

    for(p = prow->first_col; p != 0; p = p->next_col) {
    (void) sm_insert(dest, dest_row, p->col_num);
    }
}


void
sm_copy_col(dest, dest_col, pcol)
register sm_matrix *dest;
int dest_col;
sm_col *pcol;
{
    register sm_element *p;

    for(p = pcol->first_row; p != 0; p = p->next_row) {
    (void) sm_insert(dest, dest_col, p->row_num);
    }
}


sm_row *
sm_longest_row(A)
sm_matrix *A;
{
    register sm_row *large_row, *prow;
    register int max_length;

    max_length = 0;
    large_row = NIL(sm_row);
    for(prow = A->first_row; prow != 0; prow = prow->next_row) {
    if (prow->length > max_length) {
        max_length = prow->length;
        large_row = prow;
    }
    }
    return large_row;
}


sm_col *
sm_longest_col(A)
sm_matrix *A;
{
    register sm_col *large_col, *pcol;
    register int max_length;

    max_length = 0;
    large_col = NIL(sm_col);
    for(pcol = A->first_col; pcol != 0; pcol = pcol->next_col) {
    if (pcol->length > max_length) {
        max_length = pcol->length;
        large_col = pcol;
    }
    }
    return large_col;
}

int
sm_num_elements(A)
sm_matrix *A;
{
    register sm_row *prow;
    register int num;

    num = 0;
    sm_foreach_row(A, prow) {
    num += prow->length;
    }
    return num;
}

int 
sm_read(fp, A)
FILE *fp;
sm_matrix **A;
{
    int i, j, err;

    *A = sm_alloc();
    while (! feof(fp)) {
    err = fscanf(fp, "%d %d", &i, &j);
    if (err == EOF) {
        return 1;
    } else if (err != 2) {
        return 0;
    }
    (void) sm_insert(*A, i, j);
    }
    return 1;
}


int 
sm_read_compressed(fp, A)
FILE *fp;
sm_matrix **A;
{
    int i, j, k, nrows, ncols;
    unsigned long x;

    *A = sm_alloc();
    if (fscanf(fp, "%d %d", &nrows, &ncols) != 2) {
    return 0;
    }
    sm_resize(*A, nrows, ncols);

    for(i = 0; i < nrows; i++) {
    if (fscanf(fp, "%lx", &x) != 1) {
        return 0;
    }
    for(j = 0; j < ncols; j += 32) {
        if (fscanf(fp, "%lx", &x) != 1) {
        return 0;
        }
        for(k = j; x != 0; x >>= 1, k++) {
        if (x & 1) {
            (void) sm_insert(*A, i, k);
        }
        }
    }
    }
    return 1;
}


void 
sm_write(fp, A)
FILE *fp;
sm_matrix *A;
{
    register sm_row *prow;
    register sm_element *p;

    for(prow = A->first_row; prow != 0; prow = prow->next_row) {
    for(p = prow->first_col; p != 0; p = p->next_col) {
        (void) fprintf(fp, "%d %d\n", p->row_num, p->col_num);
    }
    }
}

void 
sm_print(fp, A)
FILE *fp;
sm_matrix *A;
{
    register sm_row *prow;
    register sm_col *pcol;
    int c;

    if (A->last_col->col_num >= 100) {
    (void) fprintf(fp, "    ");
    for(pcol = A->first_col; pcol != 0; pcol = pcol->next_col) {
        (void) fprintf(fp, "%d", (pcol->col_num / 100)%10);
    }
    putc('\n', fp);
    }

    if (A->last_col->col_num >= 10) {
    (void) fprintf(fp, "    ");
    for(pcol = A->first_col; pcol != 0; pcol = pcol->next_col) {
        (void) fprintf(fp, "%d", (pcol->col_num / 10)%10);
    }
    putc('\n', fp);
    }

    (void) fprintf(fp, "    ");
    for(pcol = A->first_col; pcol != 0; pcol = pcol->next_col) {
    (void) fprintf(fp, "%d", pcol->col_num % 10);
    }
    putc('\n', fp);

    (void) fprintf(fp, "    ");
    for(pcol = A->first_col; pcol != 0; pcol = pcol->next_col) {
    (void) fprintf(fp, "-");
    }
    putc('\n', fp);

    for(prow = A->first_row; prow != 0; prow = prow->next_row) {
    (void) fprintf(fp, "%3d:", prow->row_num);

    for(pcol = A->first_col; pcol != 0; pcol = pcol->next_col) {
        c = sm_row_find(prow, pcol->col_num) ? '1' : '.';
        putc(c, fp);
    }
    putc('\n', fp);
    }
}


void 
sm_dump(A, s, max)
sm_matrix *A;
char *s;
int max;
{
    FILE *fp = stdout;

    (void) fprintf(fp, "%s %d rows by %d cols\n", s, A->nrows, A->ncols);
    if (A->nrows < max) {
    sm_print(fp, A);
    }
}

void
sm_cleanup()
{
#ifdef FAST_AND_LOOSE
    register sm_element *p, *pnext;
    register sm_row *prow, *pnextrow;
    register sm_col *pcol, *pnextcol;

    for(p = sm_element_freelist; p != 0; p = pnext) {
    pnext = p->next_col;
    FREE(p);
    }
    sm_element_freelist = 0;

    for(prow = sm_row_freelist; prow != 0; prow = pnextrow) {
    pnextrow = prow->next_row;
    FREE(prow);
    }
    sm_row_freelist = 0;

    for(pcol = sm_col_freelist; pcol != 0; pcol = pnextcol) {
    pnextcol = pcol->next_col;
    FREE(pcol);
    }
    sm_col_freelist = 0;
#endif
}
ABC_NAMESPACE_IMPL_END

