/* * Nonsymmetric elimination tree */ int sp_coletree( int *acolst, int *acolend, /* column start and end past 1 */ int *arow, /* row indices of A */ int nr, int nc, /* dimension of A */ int *parent /* parent in elim tree */ ) { int *root; /* root of subtee of etree */ int *firstcol; /* first nonzero col in each row*/ int rset, cset; int row, col; int rroot; int p; int *pp; root = mxCallocInt (nc); initialize_disjoint_sets (nc, &pp); /* Compute firstcol[row] = first nonzero column in row */ firstcol = mxCallocInt (nr); for (row = 0; row < nr; firstcol[row++] = nc); for (col = 0; col < nc; col++) for (p = acolst[col]; p < acolend[col]; p++) { row = arow[p]; firstcol[row] = SUPERLU_MIN(firstcol[row], col); } /* Compute etree by Liu's algorithm for symmetric matrices, except use (firstcol[r],c) in place of an edge (r,c) of A. Thus each row clique in A'*A is replaced by a star centered at its first vertex, which has the same fill. */ for (col = 0; col < nc; col++) { cset = make_set (col, pp); root[cset] = col; parent[col] = nc; /* Matlab */ for (p = acolst[col]; p < acolend[col]; p++) { row = firstcol[arow[p]]; if (row >= col) continue; rset = find (row, pp); rroot = root[rset]; if (rroot != col) { parent[rroot] = col; cset = link (cset, rset, pp); root[cset] = col; } } } SUPERLU_FREE (root); SUPERLU_FREE (firstcol); finalize_disjoint_sets (pp); return 0; }
/*! \brief Symmetric elimination tree * * <pre> * p = spsymetree (A); * * Find the elimination tree for symmetric matrix A. * This uses Liu's algorithm, and runs in time O(nz*log n). * * Input: * Square sparse matrix A. No check is made for symmetry; * elements below and on the diagonal are ignored. * Numeric values are ignored, so any explicit zeros are * treated as nonzero. * Output: * Integer array of parents representing the etree, with n * meaning a root of the elimination forest. * Note: * This routine uses only the upper triangle, while sparse * Cholesky (as in spchol.c) uses only the lower. Matlab's * dense Cholesky uses only the upper. This routine could * be modified to use the lower triangle either by transposing * the matrix or by traversing it by rows with auxiliary * pointer and link arrays. * * John R. Gilbert, Xerox, 10 Dec 1990 * Based on code by JRG dated 1987, 1988, and 1990. * Modified by X.S. Li, November 1999. * </pre> */ int sp_symetree_dist( int_t *acolst, int_t *acolend, /* column starts and ends past 1 */ int_t *arow, /* row indices of A */ int_t n, /* dimension of A */ int_t *parent /* parent in elim tree */ ) { int_t *root; /* root of subtee of etree */ int_t rset, cset; int_t row, col; int_t rroot; int_t p; int_t *pp; #if ( DEBUGlevel>=1 ) CHECK_MALLOC(0, "Enter sp_symetree()"); #endif root = mxCallocInt (n); initialize_disjoint_sets (n, &pp); for (col = 0; col < n; col++) { cset = make_set (col, pp); root[cset] = col; parent[col] = n; /* Matlab */ for (p = acolst[col]; p < acolend[col]; p++) { row = arow[p]; if (row >= col) continue; rset = find (row, pp); rroot = root[rset]; if (rroot != col) { parent[rroot] = col; cset = link (cset, rset, pp); root[cset] = col; } } } SUPERLU_FREE (root); finalize_disjoint_sets (pp); #if ( DEBUGlevel>=1 ) CHECK_MALLOC(0, "Exit sp_symetree()"); #endif return 0; } /* SP_SYMETREE_DIST */
/* * Symmetric elimination tree */ int sp_symetree( int *acolst, int *acolend, /* column starts and ends past 1 */ int *arow, /* row indices of A */ int n, /* dimension of A */ int *parent /* parent in elim tree */ ) { int *root; /* root of subtree of etree */ int rset, cset; int row, col; int rroot; int p; root = mxCallocInt (n); initialize_disjoint_sets (n); for (col = 0; col < n; col++) { cset = make_set (col); root[cset] = col; parent[col] = n; /* Matlab */ for (p = acolst[col]; p < acolend[col]; p++) { row = arow[p]; if (row >= col) continue; rset = find (row); rroot = root[rset]; if (rroot != col) { parent[rroot] = col; cset = link (cset, rset); root[cset] = col; } } } SUPERLU_FREE (root); finalize_disjoint_sets (); return 0; } /* SP_SYMETREE */