home *** CD-ROM | disk | FTP | other *** search
- sprow_xpd(r_out,0,type);
- len_out = r_out->maxlen;
- elt_out = &(r_out->elt[idx_out]);
- }
- if ( idx2 >= len2 || (idx1 < len1 && elt1->col <= elt2->col) )
- {
- elt_out->col = elt1->col;
- elt_out->val = elt1->val;
- if ( idx2 < len2 && elt1->col == elt2->col )
- {
- elt_out->val += elt2->val;
- elt2++; idx2++;
- }
- elt1++; idx1++;
- }
- else
- {
- elt_out->col = elt2->col;
- elt_out->val = elt2->val;
- elt2++; idx2++;
- }
- elt_out++; idx_out++;
- }
- r_out->len = idx_out;
-
- return r_out;
- }
-
- /* sprow_sub -- sets r_out <- r1 - r2
- -- cannot be in situ
- -- only for columns j0, j0+1, ...
- -- type must be SPMAT or SPROW depending on
- whether r_out is a row of a SPMAT structure
- or a SPROW variable
- -- returns r_out */
- SPROW *sprow_sub(r1,r2,j0,r_out,type)
- SPROW *r1, *r2, *r_out;
- int j0, type;
- {
- int idx1, idx2, idx_out, len1, len2, len_out;
- row_elt *elt1, *elt2, *elt_out;
-
- if ( ! r1 || ! r2 )
- error(E_NULL,"sprow_sub");
- if ( r1 == r_out || r2 == r_out )
- error(E_INSITU,"sprow_sub");
- if ( j0 < 0 )
- error(E_BOUNDS,"sprow_sub");
- if ( ! r_out )
- r_out = sprow_get(MINROWLEN);
-
- /* Initialise */
- len1 = r1->len; len2 = r2->len; len_out = r_out->maxlen;
- /* idx1 = idx2 = idx_out = 0; */
- idx1 = sprow_idx(r1,j0);
- idx2 = sprow_idx(r2,j0);
- idx_out = sprow_idx(r_out,j0);
- idx1 = (idx1 < 0) ? -(idx1+2) : idx1;
- idx2 = (idx2 < 0) ? -(idx2+2) : idx2;
- idx_out = (idx_out < 0) ? -(idx_out+2) : idx_out;
- elt1 = &(r1->elt[idx1]);
- elt2 = &(r2->elt[idx2]);
- elt_out = &(r_out->elt[idx_out]);
-
- while ( idx1 < len1 || idx2 < len2 )
- {
- if ( idx_out >= len_out )
- { /* r_out is too small */
- r_out->len = idx_out;
- r_out = sprow_xpd(r_out,0,type);
- len_out = r_out->maxlen;
- elt_out = &(r_out->elt[idx_out]);
- }
- if ( idx2 >= len2 || (idx1 < len1 && elt1->col <= elt2->col) )
- {
- elt_out->col = elt1->col;
- elt_out->val = elt1->val;
- if ( idx2 < len2 && elt1->col == elt2->col )
- {
- elt_out->val -= elt2->val;
- elt2++; idx2++;
- }
- elt1++; idx1++;
- }
- else
- {
- elt_out->col = elt2->col;
- elt_out->val = -elt2->val;
- elt2++; idx2++;
- }
- elt_out++; idx_out++;
- }
- r_out->len = idx_out;
-
- return r_out;
- }
-
-
- /* sprow_smlt -- sets r_out <- alpha*r1
- -- can be in situ
- -- only for columns j0, j0+1, ...
- -- returns r_out */
- SPROW *sprow_smlt(r1,alpha,j0,r_out,type)
- SPROW *r1, *r_out;
- double alpha;
- int j0, type;
- {
- int idx1, idx_out, len1;
- row_elt *elt1, *elt_out;
-
- if ( ! r1 )
- error(E_NULL,"sprow_smlt");
- if ( j0 < 0 )
- error(E_BOUNDS,"sprow_smlt");
- if ( ! r_out )
- r_out = sprow_get(MINROWLEN);
-
- /* Initialise */
- len1 = r1->len;
- idx1 = sprow_idx(r1,j0);
- idx_out = sprow_idx(r_out,j0);
- idx1 = (idx1 < 0) ? -(idx1+2) : idx1;
- idx_out = (idx_out < 0) ? -(idx_out+2) : idx_out;
- elt1 = &(r1->elt[idx1]);
-
- r_out = sprow_resize(r_out,idx_out+len1-idx1,type);
- elt_out = &(r_out->elt[idx_out]);
-
- for ( ; idx1 < len1; elt1++,elt_out++,idx1++,idx_out++ )
- {
- elt_out->col = elt1->col;
- elt_out->val = alpha*elt1->val;
- }
-
- r_out->len = idx_out;
-
- return r_out;
- }
-
-
- /* sprow_foutput -- print a representation of r on stream fp */
- void sprow_foutput(fp,r)
- FILE *fp;
- SPROW *r;
- {
- int i, len;
- row_elt *e;
-
- if ( ! r )
- {
- fprintf(fp,"SparseRow: **** NULL ****\n");
- return;
- }
- len = r->len;
- fprintf(fp,"SparseRow: length: %d\n",len);
- for ( i = 0, e = r->elt; i < len; i++, e++ )
- fprintf(fp,"Column %d: %g, next row: %d, next index %d\n",
- e->col, e->val, e->nxt_row, e->nxt_idx);
- }
-
-
- /* sprow_set_val -- sets the j-th column entry of the sparse row r
- -- Note: destroys the usual column & row access paths */
- double sprow_set_val(r,j,val)
- SPROW *r;
- int j;
- double val;
- {
- int idx, idx2, new_len;
-
- if ( ! r )
- error(E_NULL,"sprow_set_val");
-
- idx = sprow_idx(r,j);
- if ( idx >= 0 )
- { r->elt[idx].val = val; return val; }
- /* else */ if ( idx < -1 )
- {
- /* shift & insert new value */
- idx = -(idx+2); /* this is the intended insertion index */
- if ( r->len >= r->maxlen )
- {
- r->len = r->maxlen;
- new_len = max(2*r->maxlen+1,5);
- if (mem_info_is_on()) {
- mem_bytes(TYPE_SPROW,r->maxlen*sizeof(row_elt),
- new_len*sizeof(row_elt));
- }
-
- r->elt = RENEW(r->elt,new_len,row_elt);
- if ( ! r->elt ) /* can't allocate = 0 i < m; i++ )
- {
- r = A->row+i;
- max_idx = r->len;
- elts = r->elt;
- tmp = x_ve[i];
- for ( j_idx = 0; j_idx < max_idx; j_idx++, elts++ )
- out_ve[elts->col] += elts->val*tmp;
- }
-
- return out;
- of
-
- /* sp_ge;
- /*******matr**
- -- len is number of elements available for each row without
- allocating further memory */
- SPMAT *sp_get(m,n,maxlen)
- int m, n, maxlen;
- {
- SPMAT *A;
- SPROW *rows;
- int i;
-
- if ( m < 0 || n < 0 )
- error(E_NEG,"sp_get");
-
- maxlen = max(maxlen,1);
-
- A = NEW(SPMAT);
- if ( ! A ) /* can't allocate */
- error(E_MEM,"sp_get");
- else if (mem_info_is_on()) {
- mem_bytes(TYPE_SPMAT,0,sizeof(SPMAT));
- mem_numvar(TYPE_SPMAT,1);
- }
- /* fprintf(stderr,"Have SPMAT structure\n"); */
-
- A->row = rows = NEW_A(m,SPROW);
- if ( ! A->row ) /* can't allocate */
- error(E_MEM,"sp_get");
- else if (mem_info_is_on()) {
- mem_bytes(TYPE_SPMAT,0,m*sizeof(SPROW));
- }
- /* fprintf(stderr,"Have row structure array\n"); */
-
- A->start_row = NEW_A(n,int);
- A->start_idx = NEW_A(n,int);
- if ( ! A->start_row || ! A->start_idx ) /* can't allocate */
- error(E_MEM,"sp_get");
- else if (mem_info_is_on()) {
- mem_bytes(TYPE_SPMAT,0,2*n*sizeof(int));
- }
- for ( i = 0; i < n; i++ )
- A->start_row[i] = A->start_idx[i] = -1;
- /* fprintf(stderr,"Have start_row array\n"); */
-
- A->m = A->max_m = m;
- A->n = A->max_n = n;
-
- for ( i = 0; i < m; i++, rows++ )
- {
- rows->elt = NEW_A(maxlen,row_elt);
- if ( ! rows->elt )
- error(E_MEM,"sp_get");
- else if (mem_info_is_on()) {
- mem_bytes(TYPE_SPMAT,0,maxlen*sizeof(row_elt));
- }
- /* fprintf(stderr,"Have row %d element array\n",i); */
- rows->len = 0;
- s a
- ** distribution fee considered a charge.
- **
- ***************************************************************************/
-
-
- /*
- Sparse matrix swap and permutation routines
- Modified Mon 09th Nov 1992, 08:50:54 PM
- to use Karen George's suggestion to use unordered rows
- */
-
- static char rcsid[] = "$Id: spswap.c,v 1.3 1994/01/13 05:44:43 des Exp $";
-
- #include <stdio.h>
- #include <math.h>
- #include "matrix.h"
- #include "sparse.h"
- #include "sparse2.h"
-
-
- #define btos(x) ((x) ? "TRUE" : "FALSE")
-
- /* scan_to -- updates scan (int) vectors to point to the last row in each
- column with row # <= max_row, if any */
- void scan_to(A, scan_row, scan_idx, col_list, max_row)
- SPMAT *A;
- IVEC *scan_row, *scan_idx, *col_list;
- int max_row;
- {
- int col, idx, j_idx, row_num;
- SPROW *r;
- row_elt *e;
-
- if ( ! A || ! scan_row || ! scan_idx || ! col_list )
- error(E_NULL,"scan_to");
- if ( scan_row->dim != scan_idx->dim || scan_idx->dim != col_list->dim )
- error(E_SIZES,"scan_to");
-
- if ( max_row < 0 )
- return;
-
- if ( ! A->flag_col )
- sp_col_access(A);
-
- for ( j_idx = 0; j_idx < scan_row->dim; j_idx++ )
- {
- row_num = scan_row->ive[j_idx];
- idx = scan_idx->ive[j_idx];
- col = col_list->ive[j_idx];
-
- if ( col < 0 || col >= A->n )
- error(E_BOUNDS,"scan_to");
- if ( row_num < 0 )
- {
- idx = col;
- continue;
- }
- r = &(A->row[row_num]);
- if ( idx < 0 )
- error(E_INTERN,"scan_to");
- e = &(r->elt[idx]);
- if ( e->col != col )
- error(E_INTERN,"scan_to");
- if ( idx < 0 )
- {
- printf("scan_to: row_num = %d, idx = %d, col = %d\n",
- row_num, idx, col);
- error(E_INTERN,"scan_to");
- }
- /* if ( e->nxt_row <= max_row )
- chase_col(A, col, &row_num, &idx, max_row); */
- while ( e->nxt_row >= 0 && e->nxt_row <= max_row )
- {
- row_num = e->nxt_row;
- idx = e->nxt_idx;
- e = &(A->row[row_num].elt[idx]);
- }
-
- /* printf("scan_to: computed j_idx = %d, row_num = %d, idx = %d\n",
- j_idx, row_num, idx); */
- scan_row->ive[j_idx] = row_num;
- scan_idx->ive[j_idx] = idx;
- }
- }
-
- /* patch_col -- patches column access paths for fill-in */
- void patch_col(A, col, old_row, old_idx, row_num, idx)
- SPMAT *A;
- int col, old_row, old_idx, row_num, idx;
- {
- SPROW *r;
- row_elt *e;
-
- if ( old_row >= 0 )
- {
- r = &(A->row[old_row]);
- old_idx = sprow_idx2(r,col,old_idx);
- e = &(r->elt[old_idx]);
- e->nxt_row = row_num;
- e->nxt_idx = idx;
- }
- else
- {
- A->start_row[col] = row_num;
- A->start_idx[col] = idx;
- }
- }
-
- /* chase_col -- chases column access path in column col, starting with
- row_num and idx, to find last row # in this column <= max_row
- -- row_num is returned; idx is also set by this routine
- -- assumes that the column access paths (possibly without the
- nxt_idx fields) are set up */
- row_elt *chase_col(A, col, row_num, idx, max_row)
- SPMAT *A;
- int col, *row_num, *idx, max_row;
- {
- int old_idx, old_row, tmp_idx, tmp_row;
- SPROW *r;
- row_elt *e;
-
- if ( col < 0 || col >= A->n )
- error(E_BOUNDS,"chase_col");
- tmp_row = *row_num;
- if ( tmp_row < 0 )
- {
- if ( A->start_row[col] > max_row )
- {
- tmp_row = -1;
- tmp_idx = col;
- return (row_elt *)NULL;
- }
- else
- {
- tmp_row = A->start_row[col];
- tmp_idx = A->start_idx[col];
- }
- }
- else
- tmp_idx = *idx;
-
- old_row = tmp_row;
- old_idx = tmp_idx;
- while ( tmp_row >= 0 && tmp_row < max_row )
- {
- r = &(A->row[tmp_row]);
- /* tmp_idx = sprow_idx2(r,col,tmp_idx); */
- if ( tmp_idx < 0 || tmp_idx >= r->len ||
- r->elt[tmp_idx].col != col )
- {
- #ifdef DEBUG
- printf("chase_col:error: col = %d, row # = %d, idx = %d\n",
- col, tmp_row, tmp_idx);
- printf("chase_col:error: old_row = %d, old_idx = %d\n",
- old_row, old_idx);
- printf("chase_col:error: A =\n");
- sp_dump(stdout,A);
- #endif
- error(E_INTERN,"chase_col");
- }
- e = &(r->elt[tmp_idx]);
- old_row = tmp_row;
- old_idx = tmp_idx;
- tmp_row = e->nxt_row;
- tmp_idx = e->nxt_idx;
- }
- A == SMNULL )
- error(E_NULL,"sp_diag_access");
-
- m = A->m;
-
- row = A->row;
- for ( i = 0; i < m; i++, row++ )
- row->diag = sprow_idx(row,i);
-
- A->flag_diag = TRUE;
-
- return A;
- }
-
- /* sp_m2dense -- convert a sparse matrix to a dense one */
- MAT *sp_m2dense(A,out)
- SPMAT *A;
- MAT *out;
- {
- int i, j_idx;
- SPROW *row;
- row_elt *elt;
-
- if ( ! A )
- error(E_NULL,"sp_m2dense");
- if ( ! out || out->m < A->m || out->n < A->n )
- out = m_get(A->m,A->n);
-
- m_zero(out);
- for ( i = 0; i < A->m; i++ )
- {
- row = &(A->row[i]);
- elt = row->elt;
- for ( j_idx = 0; j_idx < row->len; j_idx++, elt++ )
- out->me[i][elt->col] = elt->val;
- }
-
- return out;
- }
-
-
- /* C = A+B, can be in situ */
- SPMAT *sp_add(A,B,C)
- SPMAT *A, *B, *C;
- {
- int i, in_situ;
- SPROW *rc;
- static SPROW *tmp;
-
- if ( ! A || ! B )
- error(E_NULL,"sp_add");
- if ( A->m != B->m || A->n != B->n )
- error(E_SIZES,"sp_add");
- if (C == A || C == B)
- in_situ = TRUE;
- else in_situ = FALSE;
-
- if ( ! C )
- C = sp_get(A->m,A->n,5);
- else {
- if ( C->m != A->m || C->n != A->n )
- error(E_SIZES,"sp_add");
- if (!in_situ) sp_zero(C);
- }
-
- if (tmp == (SPROW *)NULL && in_situ) {
- tmp = sprow_get(MINROWLEN);
- MEM_STAT_REG(tmp,TYPE_SPROW);
- }
-
- if (in_situ)
- for (i=0; i < A->m; i++) {
- rc = &(C->row[i]);
- sprow_add(&(A->row[i]),&(B->row[i]),0,tmp,TYPE_SPROW);
- sprow_resize(rc,tmp->len,TYPE_SPMAT);
- MEM_COPY(tmp->elt,rc->elt,tmp->len*sizeof(row_elt));
- rc->len = tmp->len;
- }
- else
- for (i=0; i < A->m; i++) {
- sprow_add(&(A->row[i]),&(B->row[i]),0,&(C->row[i]),TYPE_SPMAT);
- }
-
- C->flag_col = C->flag_diag = FALSE;
-
- return C;
- }
-
- /* C = A-B, cannot be in situ */
- SPMAT *sp_sub(A,B,C)
- SPMAT *A, *B, *C;
- {
- int i, in_situ;
- SPROW *rc;
- static SPROW *tmp;
-
- if ( ! A || ! B )
- error(E_NULL,"sp_sub");
- if ( A->m != B->m || A->n != B->n )
- error(E_SIZES,"sp_sub");
- if (C == A || C == B)
- in_situ = TRUE;
- else in_situ = FALSE;
-
- if ( ! C )
- C = sp_get(A->m,A->n,5);
- else {
- if ( C->m != A->m || C->n != A->n )
- error(E_SIZES,"sp_sub");
- if (!in_situ) sp_zero(C);
- }
-
- if (tmp == (SPROW *)NULL && in_situ) {
- tmp = sprow_get(MINROWLEN);
- MEM_STAT_REG(tmp,TYPE_SPROW);
- }
-
- if (in_situ)
- for (i=0; i < A->m; i++) {
- rc = &(C->row[i]);
- sprow_sub(&(A->row[i]),&(B->row[i]),0,tmp,TYPE_SPROW);
- sprow_resize(rc,tmp->len,TYPE_SPMAT);
- MEM_COPY(tmp->elt,rc->elt,tmp->len*sizeof(row_elt));
- rc->len = tmp->len;
- }
- else
- for (i=0; i < A->m; i++) {
- sprow_sub(&(A->row[i]),&(B->row[i]),0,&(C->row[i]),TYPE_SPMAT);
- }
-
- C->flag_col = C->flag_diag = FALSE;
-
- return C;
- }
-
- /* C = A+alpha*B, cannot be in situ */
- SPMAT *sp_mltadd(A,B,alpha,C)
- SPMAT *A, *B, *C;
- double alpha;
- {
- int i, in_situ;
- SPROW *rc;
- static SPROW *tmp;
-
- if ( ! A || ! B )
- error(E_NULL,"sp_mltadd");
- if ( A->m != B->m || A->n != B->n )
- error(E_SIZES,"sp_mltadd");
- if (C == A || C == B)
- in_situ = TRUE;
- else in_situ = FALSE;
-
- if ( ! C )
- C = sp_get(A->m,A->n,5);
- else {
- if ( C->m != A->m || C->n != A->n )
- error(E_SIZES,"sp_mltadd");
- if (!in_situ) sp_zero(C);
- }
-
- if (tmp == (SPROW *)NULL && in_situ) {
- tmp = sprow_get(MINROWLEN);
- MEM_STAT_REG(tmp,TYPE_SPROW);
- }
-
- if (in_situ)
- for (i=0; i < A->m; i++) {
- rc = &(C->row[i]);
- sprow_mltadd(&(A->row[i]),&(B->row[i]),alpha,0,tmp,TYPE_SPROW);
- sprow_resize(rc,tmp->len,TYPE_SPMAT);
- MEM_COPY(tmp->elt,rc->elt,tmp->len*sizeof(row_elt));
- rc->len = tmp->len;
- }
- else
- for (i=0; i < A->m; i++) {
- sprow_mltadd(&(A->row[i]),&(B->row[i]),alpha,0,
- &(C->row[i]),TYPE_SPMAT);
- }
-
- C->flag_col = C->flag_diag = FALSE;
-
- return C;
- }
-
-
-
- /* B = alpha*A, can be in situ */
- SPMAT *sp_smlt(A,alpha,B)
- SPMAT *A, *B;
- double alpha;
- {
- int i;
-
- if ( ! A )
- error(E_NULL,"sp_smlt");
- if ( ! B )
- B = sp_get(A->m,A->n,5);
- else
- if ( A->m != B->m || A->n != B->n )
- error(E_SIZES,"sp_smlt");
-
- for (i=0; i < A->m; i++) {
- sprow_smlt(&(A->row[i]),alpha,0,&(B->row[i]),TYPE_SPMAT);
- }
- return B;
- }
-
-
-
- /* sp_zero -- zero all the (represented) elements of a sparse matrix */
- SPMAT *sp_zero(A)
- SPMAT *A;
- {
- int i, idx, len;
- row_elt *elt;
-
- if ( ! A )
- error(E_NULL,"sp_zero");
-
- for ( i = 0; i < A->m; i++ )
- {
- elt = A->row[i].elt;
- len = A->row[i].len;
- for ( idx = 0; idx < len; idx++ )
- (*elt++).val = 0.0;
- }
-
- return A;
- }
-
- /* sp_copy2 -- copy sparse matrix (type 2)
- -- keeps structure of the OUT matrix */
- SPMAT *sp_copy2(A,OUT)
- SPMAT *A, *OUT;
- {
- int i /* , idx, len1, len2 */;
- SPROW *r1, *r2;
- static SPROW *scratch = (SPROW *)NULL;
- /* row_elt *e1, *e2; */
-
- if ( ! A )
- error(E_NULL,"sp_copy2");
- if ( ! OUT )
- OUT = sp_get(A->m,A->n,10);
- if ( ! scratch ) {
- scratch = sprow_xpd(scratch,MINROWLEN,TYPE_SPROW);
- MEM_STAT_REG(scratch,TYPE_SPROW);
- }
-
- if ( OUT->m < A->m )
- {
- if (mem_info_is_on()) {
- mem_bytes(TYPE_SPMAT,A->max_m*sizeof(SPROW),
- A->m*sizeof(SPROW));
- }
-
- OUT->row = RENEW(OUT->row,A->m,SPROW);
- if ( ! OUT->row )
- error(E_MEM,"sp_copy2");
-
- for ( i = OUT->m; i < A->m; i++ )
- {
- OUT->row[i].elt = NEW_A(MINROWLEN,row_elt);
- if ( ! OUT->row[i].elt )
- error(E_MEM,"sp_copy2");
- else if (mem_info_is_on()) {
- mem_bytes(TYPE_SPMAT,0,MINROWLEN*sizeof(row_elt));
- }
-
- OUT->row[i].maxlen = MINROWLEN;
- OUT->row[i].len = 0;
- }
- OUT->m = A->m;
- }
-
- OUT->flag_col = OUT->flag_diag = FALSE;
- /* sp_zero(OUT); */
-
- for ( i = 0; i < A->m; i++ )
- {
- r1 = &(A->row[i]); r2 = &(OUT->row[i]);
- sprow_copy(r1,r2,scratch,TYPE_SPROW);
- if ( r2->maxlen < scratch->len )
- sprow_xpd(r2,scratch->len,TYPE_SPMAT);
- MEM_COPY((char *)(scratch->elt),(char *)(r2->elt),
- scratch->len*sizeof(row_elt));
- r2->len = scratch->len;
- /*******************************************************
- e1 = r1->elt; e2 = r2->elt;
- len1 = r1->len; len2 = r2->len;
- for ( idx = 0; idx < len2; idx++, e2++ )
- e2->val = 0.0;
- for ( idx = 0; idx < len1; idx++, e1++ )
- sprow_set_val(r2,e1->col,e1->val);
- *******************************************************/
- }
-
- sp_col_access(OUT);
- return OUT;
- }
-
- /* sp_resize -- resize a sparse matrix
- -- don't destroying any contents if possible
- -- returns resized matrix */
- SPMAT *sp_resize(A,m,n)
- SPMAT *A;
- int m, n;
- {
- int i, len;
- SPROW *r;
-
- if (m < 0 || n < 0)
- error(E_NEG,"sp_resize");
-
- if ( ! A )
- return sp_get(m,n,10);
-
- if (m == A->m && n == A->n)
- return A;
-
- if ( m <= A->max_m )
- {
- for ( i = A->m; i < m; i++ )
- A->row[i].len = 0;
- A->m = m;
- }
- else
- {
- if (mem_info_is_on()) {
- mem_bytes(TYPE_SPMAT,A->max_m*sizeof(SPROW),
- m*sizeof(SPROW));
- }
-
- A->row = RENEW(A->row,(unsigned)m,SPROW);
- if ( ! A->row )
- error(E_MEM,"sp_resize");
- for ( i = A->m; i < m; i++ )
- {
- if ( ! (A->row[i].elt = NEW_A(MINROWLEN,row_elt)) )
- error(E_MEM,"sp_resize");
- else if (mem_info_is_on()) {
- mem_bytes(TYPE_SPMAT,0,MINROWLEN*sizeof(row_elt)