示例#1
0
/*
   -----------------------------------------------------------------
   sort the entries in ivec1[] and ivec2[] into lexicographic order,
   then compress out the duplicates

   return value -- # of compressed entries

   created -- 97dec18, cca
   -----------------------------------------------------------------
*/
int
IV2sortUpAndCompress (
   int   n,
   int   ivec1[],
   int   ivec2[]
) {
int   first, ierr, ii, key, length, start ;
/*
   ---------------
   check the input
   ---------------
*/
if ( n < 0 || ivec1 == NULL || ivec2 == NULL) {
   fprintf(stderr, 
           "\n fatal error in IV2sortAndCompress(%d,%p,%p)"
           "\n bad input, n = %d, ivec1 = %p, ivec2 = %p",
           n, ivec1, ivec2, n, ivec1, ivec2) ;
   spoolesFatal();
}
if ( n == 0 ) {
   return(0) ;
}
/*
   ------------------------------------------------------------------
   sort ivec1[] in ascending order with ivec2[] as a companion vector
   ------------------------------------------------------------------
*/
IV2qsortUp(n, ivec1, ivec2) ;
#if MYDEBUG > 0
fprintf(stdout, "\n ivec1[] after sort up") ;
IVfp80(stdout, n, ivec1, 80, &ierr) ;
fprintf(stdout, "\n ivec2[] after sort up") ;
IVfp80(stdout, n, ivec2, 80, &ierr) ;
#endif
first = start = 0 ;
key   = ivec1[0] ;
for ( ii = 1 ; ii < n ; ii++ ) {
   if ( key != ivec1[ii] ) {
      length = IVsortUpAndCompress(ii - start, ivec2 + start) ;
      IVfill(length, ivec1 + first, key) ;
      IVcopy(length, ivec2 + first, ivec2 + start) ;
      start = ii ;
      first += length ;
      key = ivec1[ii] ;
   }
}
length = IVsortUpAndCompress(n - start, ivec2 + start) ;
IVfill(length, ivec1 + first, key) ;
IVcopy(length, ivec2 + first, ivec2 + start) ;
first += length ;

return(first) ; }
示例#2
0
文件: IO.c 项目: fransklaver/SPOOLES
/*
   -------------------------------------------------------
   purpose -- to read in a Graph object from a CHACO file
 
   input --
 
      fn -- filename
 
   return value -- 1 if success, 0 if failure
 
   created -- 98sep20, jjs
   --------------------------------------------------------
*/
int
Graph_readFromChacoFile (
   Graph   *graph,
   char    *fn
) {
char    *rc ;
FILE    *fp;
int     nvtx, nedges, format;
char    string[BUFLEN], *s1, *s2;
int     k, v, vsize, w, vwghts, ewghts;
int     *adjncy, *weights, *vwghtsINT;
IVL     *adjIVL, *ewghtIVL;
/*
   ---------------
   check the input
   ---------------
*/
if ((graph == NULL) || (fn == NULL)) {
   fprintf(stderr, "\n error in Graph_readFromFile(%p,%s)"
           "\n bad input\n", graph, fn);
   return(0);
}
/*
   ---------------------
   clear the data fields
   ---------------------
*/
Graph_clearData(graph);
/*
   ----------------------------------------------
   open file and read in nvtx, nedges, and format
   ----------------------------------------------
*/
if ((fp = fopen(fn, "r")) == (FILE*)NULL) {
   fprintf(stderr, "\n error in Graph_readFromChacoFile(%p,%s)"
           "\n unable to open file %s", graph, fn, fn);
   return(0);
}
/*
   -------------
   skip comments
   -------------
*/
do {
   rc = fgets(string, BUFLEN, fp) ;
   if ( rc == NULL ) {
      fprintf(stderr, "\n error in Graph_readFromChacoFile()"
             "\n error skipping comments in file %s\n", fn) ;
      return(0) ;
   }
} while ( string[0] == '%');
/*
   -------------------------------------------------
   read in # vertices, # edges and (optional) format
   -------------------------------------------------
*/
format = 0;
if (sscanf(string, "%d %d %d", &nvtx, &nedges, &format) < 2) {
   fprintf(stderr, "\n error in Graph_readFromChacoFile(%p,%s)"
           "\n unable to read header of file %s", graph, fn, fn);
   return(0);
}
ewghts = ((format % 10) > 0);
vwghts = (((format / 10) % 10) > 0);
if (format >= 100) {
   fprintf(stderr, "\n error in Graph_readFromChacoFile(%p,%s)"
           "\n unknown format", graph, fn);
   return(0);
}
/*
   ------------------------------------------------------------------
   initialize vector(s) to hold adjacency and (optional) edge weights
   ------------------------------------------------------------------
*/
adjncy = IVinit(nvtx, -1) ;
if ( ewghts ) {
   weights = IVinit(nvtx, -1) ;
} else {
   weights = NULL ;
}
/*
   ---------------------------
   initialize the Graph object
   ---------------------------
*/
nedges *= 2;
nedges += nvtx;
Graph_init1(graph, 2*ewghts+vwghts, nvtx, 0, nedges, 
            IVL_CHUNKED, IVL_CHUNKED);
adjIVL = graph->adjIVL;
if (ewghts) {
   ewghtIVL = graph->ewghtIVL;
   weights[0] = 0;                 /* self loops have no weight */
}
if (vwghts) vwghtsINT = graph->vwghts;
/*
   ---------------------------
   read in all adjacency lists
   ---------------------------
*/
k = 0;
for (v = 0; v < nvtx; v++) {
/*
   -------------
   skip comments
   -------------
*/
   do {
      rc = fgets(string, BUFLEN, fp);
      if ( rc == NULL ) {
         fprintf(stderr, "\n error in Graph_readFromChacoFile()"
                "\n error reading adjacency for vertex %d in file %s\n",
                v, fn) ;
         IVfree(adjncy) ;
         if ( weights != NULL ) {
            IVfree(weights) ;
         }
         return(0) ;
      }
   } while ( string[0] == '%');
/*
   -------------------------
   check for buffer overflow
   -------------------------
*/
   if (strlen(string) == BUFLEN-1) {
      fprintf(stderr, "\n error in Graph_readFromChacoFile(%p,%s)"
              "\n unable to read adjacency lists of file %s (line "
              "buffer too small)\n", graph, fn, fn);
      IVfree(adjncy) ;
      if ( weights != NULL ) {
         IVfree(weights) ;
      }
      return(0);
   }
/*
   ----------------------------------------------
   read in (optional) vertex weight, 
   adjacent vertices, and (optional) edge weights
   ----------------------------------------------
*/ 
   s1 = string;
   if (vwghts) vwghtsINT[v] = (int)strtol(string, &s1, 10);
   adjncy[0] = v;              /* insert self loop needed by spooles */
   if ( ewghts ) {
      weights[0] = 0;
   }
   vsize = 1;
   while ((w = (int)strtol(s1, &s2, 10)) > 0) {
      adjncy[vsize] = --w;     /* node numbering starts with 0 */
      s1 = s2;
      if (ewghts)
       { weights[vsize] = (int)strtol(s1, &s2, 10);
         s1 = s2;
       }
      vsize++;
   }
/*
   ---------------------------------
   sort the lists in ascending order
   ---------------------------------
*/
   if ( ewghts ) {
      IV2qsortUp(vsize, adjncy, weights) ;
   } else {
      IVqsortUp(vsize, adjncy) ;
   }
/*
   --------------------------------
   set the lists in the IVL objects
   --------------------------------
*/
   IVL_setList(adjIVL, v, vsize, adjncy);
   if (ewghts) IVL_setList(ewghtIVL, v, vsize, weights);
   k += vsize;
}
/*
   -----------------------------------
   close the file and do a final check
   -----------------------------------
*/
fclose(fp);
/*
   ------------------------
   free the working storage
   ------------------------
*/
IVfree(adjncy) ;
if ( weights != NULL ) {
   IVfree(weights) ;
}
/*
   ----------------
   check for errors
   ----------------
*/
if ((k != nedges) || (v != nvtx)) {
   fprintf(stderr, "\n error in Graph_readFromChacoFile()"
           "\n number of nodes/edges does not match with header of %s"
           "\n k %d, nedges %d, v %d, nvtx %d\n", 
           fn, k, nedges, v, nvtx);
   return(0);
}
return(1); }
示例#3
0
文件: sort.c 项目: bialk/SPOOLES
/*
   ----------------------------------------------
   sort the rows of the matrix in ascending order
   of the rowids[] vector. on return, rowids is
   in asending order. return value is the number
   of row swaps made.

   created -- 98apr15, cca
   ----------------------------------------------
*/
int
A2_sortRowsUp (
   A2    *mtx,
   int   nrow,
   int   rowids[]
) {
int   ii, minrow, minrowid, nswap, target ;
/*
   ---------------
   check the input
   ---------------
*/
if ( mtx == NULL || mtx->n1 < nrow || nrow < 0 || rowids == NULL ) {
   fprintf(stderr, "\n fatal error in A2_sortRowsUp(%p,%d,%p)"
           "\n bad input\n", mtx, nrow, rowids) ;
   if ( mtx != NULL ) {
      A2_writeStats(mtx, stderr) ;
   }
   exit(-1) ;
}
if ( ! (A2_IS_REAL(mtx) || A2_IS_COMPLEX(mtx)) ) {
   fprintf(stderr, "\n fatal error in A2_sortRowsUp(%p,%d,%p)"
           "\n bad type %d, must be SPOOLES_REAL or SPOOLES_COMPLEX\n", 
           mtx, nrow, rowids, mtx->type) ;
   exit(-1) ;
}
nswap = 0 ;
if ( mtx->inc1 == 1 ) {
   double   *dvtmp ;
   int      jcol, ncol ;
   int      *ivtmp ;
/*
   ---------------------------------------------------
   matrix is stored by columns, so permute each column
   ---------------------------------------------------
*/
   ivtmp = IVinit(nrow, -1) ;
   if ( A2_IS_REAL(mtx) ) {
      dvtmp = DVinit(nrow, 0.0) ;
   } else if ( A2_IS_COMPLEX(mtx) ) {
      dvtmp = DVinit(2*nrow, 0.0) ;
   }
   IVramp(nrow, ivtmp, 0, 1) ;
   IV2qsortUp(nrow, rowids, ivtmp) ;
   ncol = mtx->n2 ;
   for ( jcol = 0 ; jcol < ncol ; jcol++ ) {
      if ( A2_IS_REAL(mtx) ) {
         DVcopy(nrow, dvtmp, A2_column(mtx, jcol)) ;
         DVgather(nrow, A2_column(mtx, jcol), dvtmp, ivtmp) ;
      } else if ( A2_IS_COMPLEX(mtx) ) {
         ZVcopy(nrow, dvtmp, A2_column(mtx, jcol)) ;
         ZVgather(nrow, A2_column(mtx, jcol), dvtmp, ivtmp) ;
      }
   }
   IVfree(ivtmp) ;
   DVfree(dvtmp) ;
} else {
/*
   ----------------------------------------
   use a simple insertion sort to swap rows
   ----------------------------------------
*/
   for ( target = 0 ; target < nrow ; target++ ) {
      minrow   = target ;
      minrowid = rowids[target] ;
      for ( ii = target + 1 ; ii < nrow ; ii++ ) {
         if ( minrowid > rowids[ii] ) {
            minrow   = ii ;
            minrowid = rowids[ii] ;
         }
      }
      if ( minrow != target ) {
         rowids[minrow] = rowids[target] ;
         rowids[target] = minrowid ;
         A2_swapRows(mtx, target, minrow) ;
         nswap++ ;
      }
   }
}

return(nswap) ; }
示例#4
0
文件: sort.c 项目: bialk/SPOOLES
/*
   -------------------------------------------------
   sort the columns of the matrix in ascending order
   of the colids[] vector. on return, colids is
   in asending order. return value is the number
   of column swaps made.

   created -- 98apr15, cca
   -------------------------------------------------
*/
int
A2_sortColumnsUp (
   A2   *mtx,
   int   ncol,
   int   colids[]
) {
int   ii, mincol, mincolid, nswap, target ;
/*
   ---------------
   check the input
   ---------------
*/
if ( mtx == NULL || mtx->n2 < ncol || ncol < 0 || colids == NULL ) {
   fprintf(stderr, "\n fatal error in A2_sortColumnsUp(%p,%d,%p)"
           "\n bad input\n", mtx, ncol, colids) ;
   if ( mtx != NULL ) {
      A2_writeStats(mtx, stderr) ;
   }
   exit(-1) ;
}
if ( ! (A2_IS_REAL(mtx) || A2_IS_COMPLEX(mtx)) ) {
   fprintf(stderr, "\n fatal error in A2_sortColumnsUp(%p,%d,%p)"
           "\n bad type %d, must be SPOOLES_REAL or SPOOLES_COMPLEX\n", 
           mtx, ncol, colids, mtx->type) ;
   exit(-1) ;
}
nswap = 0 ;
if ( mtx->inc2 == 1 ) {
   double   *dvtmp ;
   int      irow, nrow ;
   int      *ivtmp ;
/*
   ---------------------------------------------------
   matrix is stored by rows, so permute each row
   ---------------------------------------------------
*/
   ivtmp = IVinit(ncol, -1) ;
   if ( A2_IS_REAL(mtx) ) {
      dvtmp = DVinit(ncol, 0.0) ;
   } else if ( A2_IS_COMPLEX(mtx) ) {
      dvtmp = DVinit(2*ncol, 0.0) ;
   }
   IVramp(ncol, ivtmp, 0, 1) ;
   IV2qsortUp(ncol, colids, ivtmp) ;
   nrow = mtx->n1 ;
   for ( irow = 0 ; irow < nrow ; irow++ ) {
      if ( A2_IS_REAL(mtx) ) {
         DVcopy(ncol, dvtmp, A2_row(mtx, irow)) ;
         DVgather(ncol, A2_row(mtx, irow), dvtmp, ivtmp) ;
      } else if ( A2_IS_COMPLEX(mtx) ) {
         ZVcopy(ncol, dvtmp, A2_row(mtx, irow)) ;
         ZVgather(ncol, A2_row(mtx, irow), dvtmp, ivtmp) ;
      }
   }
   IVfree(ivtmp) ;
   DVfree(dvtmp) ;
} else {
/*
   ----------------------------------------
   use a simple insertion sort to swap cols
   ----------------------------------------
*/
   for ( target = 0 ; target < ncol ; target++ ) {
      mincol   = target ;
      mincolid = colids[target] ;
      for ( ii = target + 1 ; ii < ncol ; ii++ ) {
         if ( mincolid > colids[ii] ) {
            mincol   = ii ;
            mincolid = colids[ii] ;
         }
      }
      if ( mincol != target ) {
         colids[mincol] = colids[target] ;
         colids[target] = mincolid ;
         A2_swapColumns(mtx, target, mincol) ;
         nswap++ ;
      }
   }
}
return(nswap) ; }
示例#5
0
文件: QRutil.c 项目: damiannz/spooles
/*
   --------------------------------------------------------------
   purpose -- create and return an A2 object that contains rows
              of A and rows from update matrices of the children.
              the matrix may not be in staircase form

   created -- 98may25, cca
   --------------------------------------------------------------
*/
A2 *
FrontMtx_QR_assembleFront (
   FrontMtx   *frontmtx,
   int        J,
   InpMtx     *mtxA,
   IVL        *rowsIVL,
   int        firstnz[],
   int        colmap[],
   Chv        *firstchild,
   DV         *workDV,
   int        msglvl,
   FILE       *msgFile
) {
A2       *frontJ ;
Chv      *chvI ;
double   *rowI, *rowJ, *rowentA ;
int      ii, irow, irowA, irowI, jcol, jj, jrow, ncolI, ncolJ, 
         nentA, nrowI, nrowJ, nrowFromA ;
int      *colindA, *colindI, *colindJ, *map, *rowids, *rowsFromA ;
/*
   ---------------
   check the input
   ---------------
*/
if ( frontmtx == NULL || mtxA == NULL || rowsIVL == NULL
   || (msglvl > 0 && msgFile == NULL) ) {
   fprintf(stderr, "\n fatal error in FrontMtx_QR_assembleFront()"
           "\n bad input\n") ;
   exit(-1) ;
}
if ( msglvl > 3 ) {
   fprintf(msgFile, "\n\n inside FrontMtx_QR_assembleFront(%d)", J) ;
   fflush(msgFile) ;
}
/*
   --------------------------------------------------
   set up the map from global to local column indices
   --------------------------------------------------
*/
FrontMtx_columnIndices(frontmtx, J, &ncolJ, &colindJ) ;
for ( jcol = 0 ; jcol < ncolJ ; jcol++ ) {
   colmap[colindJ[jcol]] = jcol ;
}
if ( msglvl > 3 ) {
   fprintf(msgFile, "\n front %d's column indices", J) ;
   IVfprintf(msgFile, ncolJ, colindJ) ;
   fflush(msgFile) ;
}
/*
   -------------------------------------------------
   compute the size of the front and map the global 
   indices of the update matrices into local indices
   -------------------------------------------------
*/
IVL_listAndSize(rowsIVL, J, &nrowFromA, &rowsFromA) ;
nrowJ = nrowFromA ;
if ( msglvl > 3 ) {
   fprintf(msgFile, "\n %d rows from A", nrowFromA) ;
   fflush(msgFile) ;
}
for ( chvI = firstchild ; chvI != NULL ; chvI = chvI->next ) {
   nrowJ += chvI->nD ;
   Chv_columnIndices(chvI, &ncolI, &colindI) ;
   for ( jcol = 0 ; jcol < ncolI ; jcol++ ) {
      colindI[jcol] = colmap[colindI[jcol]] ;
   }
   if ( msglvl > 3 ) {
      fprintf(msgFile, "\n %d rows from child %d", chvI->nD, chvI->id) ;
      fflush(msgFile) ;
   }
}
/*
   ----------------------------------------------------------
   get workspace for the rowids[nrowJ] and map[nrowJ] vectors
   ----------------------------------------------------------
*/
if ( sizeof(int) == sizeof(double) ) {
   DV_setSize(workDV, 2*nrowJ) ;
} else if ( 2*sizeof(int) == sizeof(double) ) {
   DV_setSize(workDV, nrowJ) ;
}
rowids = (int *) DV_entries(workDV) ;
map    = rowids + nrowJ ;
IVramp(nrowJ, rowids, 0, 1) ;
IVfill(nrowJ, map, -1) ;
/*
   -----------------------------------------------------------------
   get the map from incoming rows to their place in the front matrix
   -----------------------------------------------------------------
*/
for ( irow = jrow = 0 ; irow < nrowFromA ; irow++, jrow++ ) {
   irowA = rowsFromA[irow] ;
   map[jrow] = colmap[firstnz[irowA]] ;
}
for ( chvI = firstchild ; chvI != NULL ; chvI = chvI->next ) {
   nrowI = chvI->nD ;
   Chv_columnIndices(chvI, &ncolI, &colindI) ;
   for ( irow = 0 ; irow < nrowI ; irow++, jrow++ ) {
      map[jrow] = colindI[irow] ;
   }
}
IV2qsortUp(nrowJ, map, rowids) ;
for ( irow = 0 ; irow < nrowJ ; irow++ ) {
   map[rowids[irow]] = irow ;
}
/*
   ----------------------------
   allocate the A2 front object
   ----------------------------
*/
frontJ = A2_new() ;
A2_init(frontJ, frontmtx->type, nrowJ, ncolJ, ncolJ, 1, NULL) ;
A2_zero(frontJ) ;
/*
   ------------------------------------
   load the original rows of the matrix
   ------------------------------------
*/
for ( jrow = 0 ; jrow < nrowFromA ; jrow++ ) {
   irowA = rowsFromA[jrow] ;
   rowJ  = A2_row(frontJ, map[jrow]) ;
   if ( A2_IS_REAL(frontJ) ) {
      InpMtx_realVector(mtxA, irowA, &nentA, &colindA, &rowentA) ;
   } else if ( A2_IS_COMPLEX(frontJ) ) {
      InpMtx_complexVector(mtxA, irowA, &nentA, &colindA, &rowentA) ;
   }
   if ( msglvl > 3 ) {
      fprintf(msgFile, "\n loading row %d", irowA) ;
      fprintf(msgFile, "\n global indices") ;
      IVfprintf(msgFile, nentA, colindA) ;
      fflush(msgFile) ;
   }
   if ( A2_IS_REAL(frontJ) ) {
      for ( ii = 0 ; ii < nentA ; ii++ ) {
         jj = colmap[colindA[ii]] ;
         rowJ[jj] = rowentA[ii] ;
      }
   } else if ( A2_IS_COMPLEX(frontJ) ) {
      for ( ii = 0 ; ii < nentA ; ii++ ) {
         jj = colmap[colindA[ii]] ;
         rowJ[2*jj]   = rowentA[2*ii]   ;
         rowJ[2*jj+1] = rowentA[2*ii+1] ;
      }
   }
}
if ( msglvl > 3 ) {
   fprintf(msgFile, "\n after assembling rows of A") ;
   A2_writeForHumanEye(frontJ, msgFile) ;
   fflush(msgFile) ;
}
/*
   ----------------------------------
   load the updates from the children 
   ----------------------------------
*/
for ( chvI = firstchild ; chvI != NULL ; chvI = chvI->next ) {
   nrowI = chvI->nD ;
   Chv_columnIndices(chvI, &ncolI, &colindI) ;
   if ( msglvl > 3 ) {
      fprintf(msgFile, "\n loading child %d", chvI->id) ;
      fprintf(msgFile, "\n child's column indices") ;
      IVfprintf(msgFile, ncolI, colindI) ;
      Chv_writeForHumanEye(chvI, msgFile) ;
      fflush(msgFile) ;
   }
   rowI = Chv_entries(chvI) ;
   for ( irowI = 0 ; irowI < nrowI ; irowI++, jrow++ ) {
      rowJ = A2_row(frontJ, map[jrow]) ;
      if ( A2_IS_REAL(frontJ) ) {
         for ( ii = irowI ; ii < ncolI ; ii++ ) {
            jj = colindI[ii] ;
            rowJ[jj] = rowI[ii] ;
         }
         rowI += ncolI - irowI - 1 ;
      } else if ( A2_IS_COMPLEX(frontJ) ) {
         for ( ii = irowI ; ii < ncolI ; ii++ ) {
            jj = colindI[ii] ;
            rowJ[2*jj]   = rowI[2*ii]   ;
            rowJ[2*jj+1] = rowI[2*ii+1] ;
         }
         rowI += 2*(ncolI - irowI - 1) ;
      }
   }
   if ( msglvl > 3 ) {
      fprintf(msgFile, "\n after assembling child %d", chvI->id) ;
      A2_writeForHumanEye(frontJ, msgFile) ;
      fflush(msgFile) ;
   }
}
return(frontJ) ; }
示例#6
0
/*
   ------------------------------------------------------------------
   purpose -- to find indistinguishable nodes in the reach set

   flag = 0 --> return
   flag = 1 --> check out nodes that are 2-adj
   flag = 2 --> check out nodes that are both 2-adj and not

   note: the reach set is not changed.

   created -- 96feb15, cca
   modified -- 97feb07, cca
      very tricky "bug"
      was : sum += ip->val for subtrees
            sum += IVsum(nvedge, vedges) for uncovered edges
      now : sum += ip->val + 1 for subtrees
            sum += IVsum(nvedge, vedges) + nvedge for uncovered edges
      checksums were "wrong" due to vertex 0 adding nothing
      to the checksum. beware 0-indexing.
   ------------------------------------------------------------------
*/
void
MSMD_findInodes ( 
   MSMD       *msmd,
   MSMDinfo   *info
) {
int             first, flag, i, ierr, iv, iw, j, k, keepon, nlist, 
                nreach, nvedge, sum, vid, vchk, vcount, wid ;
int             *chk, *list, *reach, *vedges, *wedges ;
IP              *ip, *ipv, *ipw, *vsubtrees ;
MSMDvtx         *v, *w ;
/*
   ---------------
   check the input
   ---------------
*/
if ( msmd == NULL || info == NULL ) {
   fprintf(stderr, "\n fatal error in MSMD_findInodes(%p,%p)"
           "\n bad input\n", msmd, info) ;
   exit(-1) ;
}
if ( (flag = info->compressFlag % 4) == 0 ) {
/*
   ---------------------------------------
   no compression requested, simple return
   ---------------------------------------
*/
   return ;
}
/*
   ---------------------------------
   if the reach set is empty, return
   ---------------------------------
*/
if ( (nreach = IV_size(&msmd->reachIV)) == 0 ) {
   return ; 
}
/*
reach = msmd->reach ;
*/
reach = IV_entries(&msmd->reachIV) ;
if ( info->msglvl > 3 ) {
   fprintf(info->msgFile, "\n inside MSMD_findInodes(%p)"
           "\n reach(%d) :", msmd, nreach) ;
   IVfp80(info->msgFile, nreach, reach, 10, &ierr);
   fflush(info->msgFile) ;
}
/*
   -------------------------------------------------------
   load the front of the reach set with nodes to be tested
   -------------------------------------------------------
*/
chk = IV_entries(&msmd->ivtmpIV) ;
list = reach ;
if ( flag == 1 ) {
/*
   -------------------------------------------
   work only with nodes adjacent to 2 subtrees
   -------------------------------------------
*/
   i = 0 ; j = nreach - 1 ;
   while ( i <= j ) {
      vid = list[i] ;
      v = msmd->vertices + vid ;
      if (  v->nadj != 0 || (ip = v->subtrees) == NULL
        || (ip = ip->next) == NULL || ip->next != NULL ) {
/*
         --------------------------------
         vertex is not 2-adj, swap to end
         --------------------------------
*/
         list[i] = list[j] ;
         list[j] = vid     ;
         j-- ;
      } else {
/*
         --------------------------
         vertex is 2-adj, keep here
         --------------------------
*/
         i++ ;
      }
   }
   nlist = j + 1 ;
} else {
/*
   ---------------------------------
   put all reached nodes in the list
   ---------------------------------
*/
   nlist = nreach ;
}
if ( nlist == 0 ) {
   return ; 
}
/*
   -----------------------------------------------------
   compute the the checksums and count adjacent subtrees
   for all vertices in the list
   -----------------------------------------------------
*/
for ( k = 0 ; k < nlist ; k++ ) {
   vid    = list[k] ;
   v      = msmd->vertices + vid ;
   vcount = 0 ;
   sum    = 0 ;
   if ( info->msglvl > 4 ) {
      fprintf(info->msgFile, "\n vertex %d", vid) ;
      fflush(info->msgFile) ;
   }
   for ( ipv = v->subtrees ; ipv != NULL ; ipv = ipv->next ) {
/*
      ------------------------------------
      add adjacent subtree to the checksum
      ------------------------------------
*/
      sum += ipv->val + 1 ;
      if ( info->msglvl > 4 ) {
         fprintf(info->msgFile, "\n    adjacent subtree %d, sum = %d",
                 ipv->val, sum) ;
         fflush(info->msgFile) ;
      }
      vcount++ ;
   }
   if ( (nvedge = v->nadj) > 0 && (vedges = v->adj) != NULL ) {
      sum += IVsum(nvedge, vedges) + nvedge ;
      if ( info->msglvl > 4 ) {
         fprintf(info->msgFile, "\n    %d adjacent edges :",
                 nvedge) ;
         IVfp80(info->msgFile, nvedge, vedges, 20, &ierr) ;
         fprintf(info->msgFile, " : sum = %d", sum) ;
         fflush(info->msgFile) ;
      }
      IVqsortUp(nvedge, vedges) ;
   }
/*
   -----------------
   save the checksum
   -----------------
*/
   chk[k] = sum ;
}
if ( info->msglvl > 3 ) {
   fprintf(info->msgFile, "\n before sort, list array") ;
   fflush(info->msgFile) ;
   IVfp80(info->msgFile, nlist, list, 80, &ierr) ;
   fflush(info->msgFile) ;
   fprintf(info->msgFile, "\n chk array") ;
   fflush(info->msgFile) ;
   IVfp80(info->msgFile, nlist, chk, 80, &ierr) ;
   fflush(info->msgFile) ;
}
/*
   -----------------------------------------------------
   sort the vertices in the reach set by their checksums
   -----------------------------------------------------
*/
IV2qsortUp(nlist, chk, list) ;
if ( info->msglvl > 3 ) {
   fprintf(info->msgFile, "\n after sort, reach array") ;
   IVfp80(info->msgFile, nlist, list, 80, &ierr) ;
   fprintf(info->msgFile, "\n chk array") ;
   IVfp80(info->msgFile, nlist, chk, 80, &ierr) ;
   fflush(info->msgFile) ;
}
/*
   ----------------------------------------
   detect and purge indistinguishable nodes
   ----------------------------------------
*/
for ( iv = 0 ; iv < nlist ; iv++ ) {
   vid = list[iv] ;
   v   = msmd->vertices + vid ;
   if ( v->status == 'I' ) {
/*
      -----------------------------------------------------
      vertex has been found indistinguishable, skip to next
      -----------------------------------------------------
*/
      continue ;
   }
/*
   ---------------------------
   test against other vertices
   ---------------------------
*/
   vchk      = chk[iv]     ;
   nvedge    = v->nadj     ;
   vedges    = v->adj      ;
   vsubtrees = v->subtrees ;
   if ( info->msglvl > 3 ) {
      fprintf(info->msgFile, 
              "\n checking out v = %d, vchk = %d, status = %c",
              v->id, vchk, v->status) ;
      fflush(info->msgFile) ;
   }
/*
   ---------------------------------------------------
   check v against all vertices with the same checksum
   ---------------------------------------------------
*/
   if ( info->msglvl > 3 ) {
      fprintf(info->msgFile, "\n checking out v = %d, status = %d",
              v->id, v->stage) ;
      fflush(info->msgFile) ;
   }
   first =  1 ;
   for ( iw = iv + 1 ; iw < nlist && chk[iw] == vchk ; iw++ ) {
      wid = reach[iw] ;
      w   = msmd->vertices + wid ;
      if ( info->msglvl > 3 ) {
         fprintf(info->msgFile, 
                 "\n     w = %d, status = %c, status = %d",
                 w->id, w->status, w->stage) ;
         fflush(info->msgFile) ;
      }
      if (  w->status == 'I' 
         || v->stage != w->stage
         || nvedge != w->nadj ) {
/*
         ------------------------------------
         w has been found indistinguishable
            or
         v and w do not lie on the same stage
            or
         edge counts are not the same
         ------------------------------------
*/
         continue ;
      }
/*
      ----------------------------------------
      w and v check out so far, check to see 
      if all vertices adjacent to w are marked
      ----------------------------------------
*/
      if ( info->msglvl > 3 ) {
         fprintf(info->msgFile, 
                 "\n    checking %d against %d", wid, vid) ;
         fflush(info->msgFile) ;
      }
/*
      ---------------------------------------------------------------
      check to see if the subtree lists and edge lists are indentical
      ---------------------------------------------------------------
*/
      info->stageInfo->ncheck++ ;
      keepon = 1 ;
      ipv = vsubtrees ;
      ipw = w->subtrees ;
      while ( ipv != NULL && ipw != NULL ) {
         if ( ipv->val != ipw->val ) {
            keepon = 0 ;
            break ;
         }
         ipv = ipv->next ;
         ipw = ipw->next ;
      }
      if ( keepon == 1 ) {
         wedges = w->adj ;
         for ( k = 0 ; k < nvedge ; k++ ) {
            if ( vedges[k] != wedges[k] ) {
               keepon = 0 ;
               break ;
            }
         }
      }
      if ( keepon == 1 ) {
/*
         ---------------------------------------------
         w and v are indistinguishable, merge w into v
         ---------------------------------------------
*/
         if ( info->msglvl > 1 ) {
            fprintf(info->msgFile, 
                    "\n %d absorbs %d, wght = %d, status[%d] = %c", 
                    v->id, w->id, w->wght, w->id, w->status) ;
            fflush(info->msgFile) ;
         }
         v->wght   += w->wght  ;
         w->wght   =  0 ;
         w->status =  'I' ;
         w->nadj   =  0 ;
         w->adj    = NULL ;
         w->par    =  v ;
         if ( (ipw = w->subtrees) != NULL ) {
            while ( ipw->next != NULL ) {
               ipw = ipw->next ;
            }
            ipw->next   = msmd->freeIP ;
            msmd->freeIP = ipw ;
            w->subtrees = NULL ;
         }
         info->stageInfo->nindst++ ;
      }
   }
}
if ( info->msglvl > 4 ) {
   fprintf(info->msgFile, 
         "\n MSMD_findInodes(%p), all done checking the nodes", msmd) ;
   fflush(info->msgFile) ;
}

return ; }
示例#7
0
/*
   ------------------------------------------------
   given a permutation and a vector to map vertices 
   into compressed vertices, create and return a 
   permutation object for the compressed vertices.

   created -- 96may02, cca
   ------------------------------------------------
*/
Perm *
Perm_compress (
   Perm   *perm,
   IV     *eqmapIV
) {
int    n, N, v, vcomp, vnew ;
int    *eqmap, *head, *link, *newToOld, *oldToNew, *vals ; 
Perm   *perm2 ;
/*
   ---------------
   check the input
   ---------------
*/
if (  perm == NULL 
   || (n = perm->size) <= 0
   || eqmapIV == NULL 
   || n != IV_size(eqmapIV)
   || (eqmap = IV_entries(eqmapIV)) == NULL ) {
   fprintf(stderr, "\n fatal error in Perm_compress(%p,%p)"
           "\n bad input\n", perm, eqmapIV) ;
   if ( perm != NULL ) {
      Perm_writeStats(perm, stderr) ;
   }
   if ( eqmapIV != NULL ) {
      IV_writeStats(eqmapIV, stderr) ;
   }
   spoolesFatal();
}
n = perm->size ;
if ( (oldToNew = perm->oldToNew) == NULL ) {
   Perm_fillOldToNew(perm) ;
   oldToNew = perm->oldToNew ;
}
if ( (newToOld = perm->newToOld) == NULL ) {
   Perm_fillNewToOld(perm) ;
   newToOld = perm->newToOld ;
}
/*
   ---------------------------------
   create the new permutation object
   ---------------------------------
*/
N = 1 + IVmax(n, eqmap, &v) ;
perm2 = Perm_new() ;
Perm_initWithTypeAndSize(perm2, 3, N) ;
/*
   --------------------------------------------
   get the head/link structure for the vertices
   --------------------------------------------
*/
head = IVinit(N, -1) ;
link = IVinit(n, -1) ;
for ( v = 0 ; v < n ; v++ ) {
   vcomp = eqmap[v] ;
   link[v] = head[vcomp] ;
   head[vcomp] = v ;
}
/*
   ---------------------------
   get the two vectors to sort
   ---------------------------
*/
IVramp(N, perm2->newToOld, 0, 1) ;
vals = IVinit(N, -1) ;
for ( vcomp = 0 ; vcomp < N ; vcomp++ ) {
   v = head[vcomp] ;
   vnew = perm->oldToNew[v] ;
   for ( v = link[v] ; v != -1 ; v = link[v] ) {
      if ( vnew > perm->oldToNew[v] ) {
         vnew = perm->oldToNew[v] ;
      }
   }
   vals[vcomp] = vnew ;
}
IV2qsortUp(N, vals, perm2->newToOld) ;
for ( vcomp = 0 ; vcomp < N ; vcomp++ ) {
   perm2->oldToNew[perm2->newToOld[vcomp]] = vcomp ;
}
/*
   ---------------------
   free the working data
   ---------------------
*/
IVfree(head) ;
IVfree(link) ;
IVfree(vals) ;

return(perm2) ; }