Esempio n. 1
0
/*
   -----------------------------------------
   purpose -- eliminate vertex v
      1) create v's boundary list
      2) merge boundary list onto reach list
      3) for each vertex in the boundary
         3.1) add v to the subtree list

   created -- 96feb25, cca
   -----------------------------------------
*/
void 
MSMD_eliminateVtx ( 
   MSMD       *msmd,
   MSMDvtx    *v,
   MSMDinfo   *info 
) {
int       i, ierr, j, nadj, nbnd, nedge, uid, wid, wght ;
int       *adj, *bnd, *edges ;
IP        *ip, *ip2, *prev ;
IV        *reachIV ;
MSMDvtx   *u, *w ;
/*
   ---------------
   check the input
   ---------------
*/
if ( msmd == NULL || v == NULL || info == NULL ) {
   fprintf(stderr, "\n fatal error in MSMD_eliminateVtx(%p,%p,%p)"
           "\n bad input\n", msmd, v, info) ;
   exit(-1) ;
}
adj     = IV_entries(&msmd->ivtmpIV) ;
reachIV = &msmd->reachIV ;
/*
   -----------------------------
   create the boundary set for v
   -----------------------------
*/
v->mark = 'X' ;
if ( v->subtrees == NULL ) {
/*
   --------------------------------------------------------
   v is a leaf, look at its uncovered edge list, move v and 
   any indistinguishable vertices to the end of the list
   --------------------------------------------------------
*/
   if ( info->msglvl > 3 ) {
      fprintf(info->msgFile, "\n vertex %d is a leaf", v->id) ;
      fflush(info->msgFile) ;
   }
   v->status = 'L' ;
   nedge = v->nadj ;
   edges = v->adj  ;
   i = 0 ; j = nedge - 1 ;
   while ( i <= j ) {
      wid = edges[i] ;
      w   = msmd->vertices + wid ;
      if ( w == v || w->status == 'I' ) {
         edges[i] = edges[j] ;
         edges[j] = wid      ;
         j-- ;
      } else {
         w->mark = 'X' ;
         i++ ;
      }
   }
   v->nadj = j + 1 ;
} else {
/*
   ----------------------------------------------------
   v is not a leaf, merge its subtrees' boundaries
   with its uncovered edge list to get the new boundary
   ----------------------------------------------------
*/
   if ( info->msglvl > 3 ) {
      fprintf(info->msgFile, "\n vertex %d is not a leaf", v->id) ;
      fprintf(info->msgFile, "\n  vertex %d, subtrees :", v->id) ;
      IP_fp80(info->msgFile, v->subtrees, 20) ;
      fflush(info->msgFile) ;
   }
   v->status = 'E' ;
   nadj = 0 ;
   while ( (ip = v->subtrees) != NULL ) {
      if ( info->msglvl > 3 ) {
         fprintf(info->msgFile, "\n    subtree %d, ip(%p)<%d,%p>",
                 ip->val, ip, ip->val, ip->next) ;
         fflush(info->msgFile) ;
      }
      uid    = ip->val ;
      u      = msmd->vertices + uid ;
      u->par = v ;
      nbnd   = u->nadj ;
      bnd    = u->adj  ;
      if ( info->msglvl > 3 ) {
         fprintf(info->msgFile, "\n    bnd of adj subtree %d :", u->id) ;
         IVfp80(info->msgFile, nbnd, bnd, 25, &ierr) ;
         fflush(info->msgFile) ;
      }
      for ( i = 0 ; i < nbnd ; i++ ) {
         wid = bnd[i] ;
         w   = msmd->vertices + wid ;
         if ( w->mark == 'O' && w->status != 'I' ) {
            w->mark = 'X' ;
            adj[nadj++] = wid ;
         }
      }
      if ( u->status == 'E' ) {
/*
         ------------------------------------------
         u is not a leaf, free its boundary storage
         ------------------------------------------
*/
         IVfree(u->adj) ;
         info->nbytes -= u->nadj * sizeof(int) ;
      }
      u->adj  = NULL ;
      u->nadj =   0  ;
/*
      --------------------------------------
      put this IP structure on the free list
      --------------------------------------
*/
      v->subtrees = ip->next    ;
      ip->val     = -1          ;
      ip->next    = msmd->freeIP ;
      msmd->freeIP = ip          ;
      if ( info->msglvl > 3 ) {
         fprintf(info->msgFile, 
                 "\n   v->subtrees = %p, msmd->freeIP = %p",
                 v->subtrees, msmd->freeIP) ;
         fflush(info->msgFile) ;
      }
   }
/*
   ------------------------------------------------
   merge all uncovered edges into the boundary list
   ------------------------------------------------
*/
   nedge = v->nadj ;
   edges = v->adj  ;
   for ( i = 0 ; i < nedge ; i++ ) {
      wid = edges[i] ;
      w   = msmd->vertices + wid ;
      if ( w->mark == 'O' && w->status != 'I' ) {
         w->mark     = 'X' ;
         adj[nadj++] = wid ;
      }
   }
/*
   ----------------------------------------------------------
   if boundary is not empty, allocate new storage for entries
   ----------------------------------------------------------
*/
   v->nadj = nadj ;
   if ( nadj > 0 ) {
      v->adj = IVinit(nadj, -1) ;
      IVcopy(nadj, v->adj, adj) ;
      info->nbytes += nadj*sizeof(int) ;
      if ( info->maxnbytes < info->nbytes ) {
         info->maxnbytes = info->nbytes ;
      }
   } else {
      v->adj = NULL ;
   }
}
if ( info->msglvl > 3 ) {
   fprintf(info->msgFile, "\n    bnd(%d) :", v->id) ;
   if ( v->nadj > 0 ) {
      IVfp80(info->msgFile, v->nadj, v->adj, 17, &ierr) ;
   }
   fflush(info->msgFile) ;
}
/*
   ----------------------------------------------
   for each boundary vertex
      1. add v to subtree list
      2. put v on reach set if not already there
      3. unmark and add weight to boundary weight
   ----------------------------------------------
*/
nbnd = v->nadj ;
bnd  = v->adj  ;
if ( info->msglvl > 3 ) {
   fprintf(info->msgFile, "\n %d's bnd :", v->id) ;
   IVfp80(info->msgFile, nbnd, bnd, 12, &ierr) ;
   fflush(info->msgFile) ;
}
wght = 0 ;
for ( i = 0 ; i < nbnd ; i++ ) {
   wid = bnd[i] ;
   w   = msmd->vertices + wid ;
   if ( info->msglvl > 4 ) {
      fprintf(info->msgFile, "\n   adjacent vertex %d", w->id) ;
      fflush(info->msgFile) ;
   }
/*
   -------------------------------
   add v to the subtree list for w
   -------------------------------
*/
   if ( (ip = msmd->freeIP) == NULL ) {
      if ( info->msglvl > 2 ) {
         fprintf(info->msgFile, "\n   need to get more IP objects") ;
         fflush(info->msgFile) ;
      }
/*
      -------------------------------------------------
      no more free IP structures, allocate more storage
      -------------------------------------------------
*/
      if ( (ip = IP_init(msmd->incrIP, IP_FORWARD)) == NULL ) {
         fprintf(stderr, "\n fatal error in MSMD_eliminateVtx%p,%p,%p)"
                 "\n unable to allocate more IP objects",
                 msmd, v, info) ;
         exit(-1) ;
      }
      if ( info->msglvl > 4 ) {
         fprintf(info->msgFile, "\n   old baseIP = %p", msmd->baseIP) ;
         fprintf(info->msgFile, "\n   new baseIP = %p", ip) ;
         fflush(info->msgFile) ;
      }
      ip->next = msmd->baseIP ;
      msmd->baseIP = ip ;
      info->nbytes += msmd->incrIP*sizeof(struct _IP) ;
      if ( info->maxnbytes < info->nbytes ) {
         info->maxnbytes = info->nbytes ;
      }
      ip = msmd->freeIP = msmd->baseIP + 1 ;
      if ( info->msglvl > 2 ) {
         fprintf(info->msgFile, "\n   all set") ;
         fflush(info->msgFile) ;
      }
   }
   msmd->freeIP = ip->next ;
   ip->val     = v->id    ;
   ip->next    = NULL     ;
   for ( ip2 = w->subtrees, prev = NULL ; 
         ip2 != NULL && ip2->val > ip->val ;
         ip2 = ip2->next ) {
      prev = ip2 ;
   }
   if ( prev == NULL ) {
      w->subtrees = ip ;
   } else {
      prev->next = ip ;
   }
   ip->next = ip2 ;
   if ( info->msglvl > 3 ) {
      fprintf(info->msgFile, "\n %d's subtrees :", w->id) ;
      IP_fp80(info->msgFile, w->subtrees, 15) ;
      fflush(info->msgFile) ;
   }
/*
   --------------------------------
   add w to reach list if necessary
   --------------------------------
*/
   if ( info->msglvl > 4 ) {
      fprintf(info->msgFile, "\n    status[%d] = %c", wid, w->status) ;
      fflush(info->msgFile) ;
   }
   switch ( w->status ) {
   case 'D' :
      if ( info->msglvl > 4 ) {
         fprintf(info->msgFile, ", remove from heap") ;
         fflush(info->msgFile) ;
      }
      IIheap_remove(msmd->heap, wid) ;
   case 'O' :
   case 'B' :
      if ( info->msglvl > 4 ) {
         fprintf(info->msgFile, ", add to reach set, nreach = %d",
                 IV_size(reachIV) + 1) ;
         fflush(info->msgFile) ;
      }
      IV_push(reachIV, wid) ;
      w->status = 'R' ;
   case 'R' :
      break ;
   case 'I' :
      break ;
   default :
      fprintf(stderr, "\n error in MSMD_eliminateVtx(%p,%p,%p)"
              "\n status[%d] = '%c'\n",
              msmd, v, info, wid, w->status) ;
      fprintf(stderr, "\n msmd->nvtx = %d", msmd->nvtx) ;
      exit(-1) ;
   }
/*
   --------------------------------
   unmark the boundary vertices and
   store the weight of the boundary
   --------------------------------
*/
   w->mark = 'O' ;
   wght += w->wght ;
}
/*
   ------------------------------------
   unmark v and set its boundary weight
   ------------------------------------
*/
v->mark    = 'O'  ;
v->bndwght = wght ;

return ; }
Esempio n. 2
0
File: init.c Progetto: bialk/SPOOLES
/*
   ------------------------------------------------------------------
   purpose -- to initialize the semi-implicit matrix using as input a
              FrontMtx and a map from fronts to domains (map[J] != 0)
              or the schur complement (map[J] = 0)

   return value --
      1 -- normal return
     -1 -- semimtx is NULL
     -2 -- frontmtx is NULL
     -3 -- inpmtx is NULL
     -4 -- frontmapIV is NULL
     -5 -- frontmapIV is invalid
     -6 -- unable to create domains' front matrix
     -7 -- unable to create schur complement front matrix

   created -- 98oct17, cca
   ------------------------------------------------------------------
*/
int
SemiImplMtx_initFromFrontMtx (
   SemiImplMtx   *semimtx,
   FrontMtx      *frontmtx,
   InpMtx        *inpmtx,
   IV            *frontmapIV,
   int           msglvl,
   FILE          *msgFile
) {
FrontMtx   *domMtx, *schurMtx ;
InpMtx     *A12, *A21 ;
int        ii, J, ncol, nfront, nrow, rc, size ;
int        *cols, *frontmap, *rows ;
IV         *domColsIV, *domidsIV, *domRowsIV, 
           *schurColsIV, *schuridsIV, *schurRowsIV ;
/*
   --------------
   check the data
   --------------
*/
if ( semimtx == NULL ) {
   fprintf(stderr, "\n error in SemiImplMtx_initFromFrontMtx()"
           "\n semimtx is NULL\n") ;
   return(-1) ;
}
if ( frontmtx == NULL ) {
   fprintf(stderr, "\n error in SemiImplMtx_initFromFrontMtx()"
           "\n frontmtx is NULL\n") ;
   return(-2) ;
}
if ( inpmtx == NULL ) {
   fprintf(stderr, "\n error in SemiImplMtx_initFromFrontMtx()"
           "\n inpmtx is NULL\n") ;
   return(-3) ;
}
if ( frontmapIV == NULL ) {
   fprintf(stderr, "\n error in SemiImplMtx_initFromFrontMtx()"
           "\n frontmapIV is NULL\n") ;
   return(-4) ;
}
nfront = FrontMtx_nfront(frontmtx) ;
IV_sizeAndEntries(frontmapIV, &size, &frontmap) ;
if ( nfront != size ) {
   fprintf(stderr, "\n error in SemiImplMtx_initFromFrontMtx()"
           "\n nfront %d, size of front map %d\n", nfront, size) ;
   return(-5) ;
}
domidsIV   = IV_new() ;
schuridsIV = IV_new() ;
for ( J = 0 ; J < nfront ; J++ ) {
   if ( frontmap[J] == 0 ) {
      IV_push(schuridsIV, J) ;
   } else if ( frontmap[J] > 0 ) {
      IV_push(domidsIV, J) ;
   } else {
      fprintf(stderr, "\n error in SemiImplMtx_initFromFrontMtx()"
              "\n frontmap[%d] = %d, invalid\n", J, frontmap[J]) ;
      IV_free(domidsIV) ;
      IV_free(schuridsIV) ;
      return(-5) ;
   }
}
/*
   -----------------------------------------------------------
   clear the data for the semi-implicit matrix and set scalars
   -----------------------------------------------------------
*/
SemiImplMtx_clearData(semimtx) ;
semimtx->neqns = frontmtx->neqns ;
semimtx->type  = frontmtx->type  ;
semimtx->symmetryflag = frontmtx->symmetryflag ;
/*
   ----------------------------------------------
   get the front matrix that contains the domains
   ----------------------------------------------
*/
if ( msglvl > 4 ) {
   fprintf(msgFile, "\n\n working on domain front matrix") ;
   fflush(msgFile) ;
}
domMtx = semimtx->domainMtx = FrontMtx_new() ;
domRowsIV = semimtx->domRowsIV = IV_new() ;
domColsIV = semimtx->domColsIV = IV_new() ;
rc = FrontMtx_initFromSubmatrix(domMtx, frontmtx, domidsIV, 
                                domRowsIV, domColsIV, msglvl, msgFile) ;
if ( rc != 1 ) {
   fprintf(stderr, "\n error in SemiImplMtx_initFromFrontMtx()"
           "\n unable to initialize the domains' front matrix"
           "\n error return = %d\n", rc) ;
   return(-6) ;
}
semimtx->ndomeqns = IV_size(domRowsIV) ;
if ( msglvl > 4 ) {
   fprintf(msgFile, "\n\n---------------------------------------- ") ;
   fprintf(msgFile, "\n\n submatrix for domains") ;
   FrontMtx_writeForHumanEye(domMtx, msgFile) ;
   fflush(msgFile) ;
}
if ( msglvl > 4 ) {
   FrontMtx_writeForMatlab(domMtx, "L11", "D11", "U11", msgFile) ;
   IV_writeForMatlab(domRowsIV, "domrows", msgFile) ;
   IV_writeForMatlab(domColsIV, "domcols", msgFile) ;
   fflush(msgFile) ;
}
/*
   -------------------------------------------------------
   get the front matrix that contains the schur complement
   -------------------------------------------------------
*/
if ( msglvl > 4 ) {
   fprintf(msgFile, "\n\n working on domain front matrix") ;
   fflush(msgFile) ;
}
schurMtx = semimtx->schurMtx = FrontMtx_new() ;
schurRowsIV = semimtx->schurRowsIV = IV_new() ;
schurColsIV = semimtx->schurColsIV = IV_new() ;
rc = FrontMtx_initFromSubmatrix(schurMtx, frontmtx, schuridsIV, 
                            schurRowsIV, schurColsIV, msglvl, msgFile) ;
if ( rc != 1 ) {
   fprintf(stderr, "\n error in SemiImplMtx_initFromFrontMtx()"
           "\n unable to initialize the schur complement front matrix"
           "\n error return = %d\n", rc) ;
   return(-6) ;
}
semimtx->nschureqns = IV_size(schurRowsIV) ;
if ( msglvl > 4 ) {
   fprintf(msgFile, "\n\n---------------------------------------- ") ;
   fprintf(msgFile, "\n\n submatrix for schur complement") ;
   FrontMtx_writeForHumanEye(schurMtx, msgFile) ;
   fflush(msgFile) ;
}
if ( msglvl > 4 ) {
   FrontMtx_writeForMatlab(schurMtx, "L22", "D22", "U22", msgFile) ;
   IV_writeForMatlab(schurRowsIV, "schurrows", msgFile) ;
   IV_writeForMatlab(schurColsIV, "schurcols", msgFile) ;
   fflush(msgFile) ;
}
/*
   -------------------------
   get the A12 InpMtx object
   -------------------------
*/
A12 = semimtx->A12 = InpMtx_new() ;
rc = InpMtx_initFromSubmatrix(A12, inpmtx, domRowsIV, schurColsIV,
                              semimtx->symmetryflag, msglvl, msgFile) ;
if ( rc != 1 ) {
   fprintf(stderr, "\n error in SemiImplMtx_initFromFrontMtx()"
           "\n unable to create A21 matrix"
           "\n error return = %d\n", rc) ;
   return(-6) ;
}
InpMtx_changeCoordType(A12, INPMTX_BY_ROWS) ;
InpMtx_changeStorageMode(A12, INPMTX_BY_VECTORS) ;
if ( msglvl > 4 ) {
   fprintf(msgFile, "\n\n---------------------------------------- ") ;
   fprintf(msgFile, "\n\n domRowsIV ") ;
   IV_writeForHumanEye(domRowsIV, msgFile) ;
   fprintf(msgFile, "\n\n schurColsIV ") ;
   IV_writeForHumanEye(schurColsIV, msgFile) ;
   fprintf(msgFile, "\n\n A12 matrix") ;
   InpMtx_writeForHumanEye(A12, msgFile) ;
   fflush(msgFile) ;
}
if ( msglvl > 4 ) {
   fprintf(msgFile, "\n\n A12 = zeros(%d,%d) ;",
           IV_size(domRowsIV), IV_size(schurColsIV)) ;
   InpMtx_writeForMatlab(A12, "A12", msgFile) ;
   fflush(msgFile) ;
}
if ( FRONTMTX_IS_NONSYMMETRIC(frontmtx) ) {
/*
   -------------------------
   get the A21 InpMtx object
   -------------------------
*/
   A21 = semimtx->A21 = InpMtx_new() ;
   rc = InpMtx_initFromSubmatrix(A21, inpmtx, schurRowsIV, domColsIV,
                              semimtx->symmetryflag, msglvl, msgFile) ;
   if ( rc != 1 ) {
      fprintf(stderr, "\n error in SemiImplMtx_initFromFrontMtx()"
              "\n unable to create A21 matrix"
              "\n error return = %d\n", rc) ;
      return(-6) ;
   }
   InpMtx_changeCoordType(A21, INPMTX_BY_COLUMNS) ;
   InpMtx_changeStorageMode(A21, INPMTX_BY_VECTORS) ;
   if ( msglvl > 4 ) {
      fprintf(msgFile, "\n\n--------------------------------------- ") ;
      fprintf(msgFile, "\n\n schurRowsIV ") ;
      IV_writeForHumanEye(schurRowsIV, msgFile) ;
      fprintf(msgFile, "\n\n domColsIV ") ;
      IV_writeForHumanEye(domColsIV, msgFile) ;
      fprintf(msgFile, "\n\n A21 matrix") ;
      InpMtx_writeForHumanEye(A21, msgFile) ;
      fflush(msgFile) ;
   }
   if ( msglvl > 4 ) {
      fprintf(msgFile, "\n\n A21 = zeros(%d,%d) ;",
              IV_size(schurRowsIV), IV_size(domColsIV)) ;
      InpMtx_writeForMatlab(A21, "A21", msgFile) ;
      fflush(msgFile) ;
   }
}
/*
   ------------------------
   free the working storage
   ------------------------
*/
IV_free(domidsIV) ;
IV_free(schuridsIV) ;

return(1) ; }
Esempio n. 3
0
/*
   ---------------------------------------------------------------------
   eliminate all nodes in a stage

   created -- 96feb25, cca
   ---------------------------------------------------------------------
*/
void
MSMD_eliminateStage ( 
   MSMD       *msmd,
   MSMDinfo   *info
) {
int       ierr, ii, jj, iv, nelim, nreach, stage, step ;
int       *reach ;
IV        *reachIV ;
MSMDvtx   *v ;
/*
   ---------------
   check the input
   ---------------
*/
if (  msmd == NULL || info == NULL ) {
   fprintf(stderr, "\n fatal error in MSMD_eliminateStage(%p,%p)"
           "\n bad input\n", msmd, info) ;
   exit(-1) ;
}
stage = info->istage ;
/*
   -----------------------------------------------
   load the reach set with all nodes in this stage
   -----------------------------------------------
*/
reachIV = &msmd->reachIV ;
IV_setSize(reachIV, 0) ;
for ( iv = 0, v = msmd->vertices ; iv < msmd->nvtx ; iv++, v++ ) {
   if ( v->status != 'I' ) {
      if ( v->stage == stage ) {
         IV_push(reachIV, v->id) ;
         v->status = 'R' ;
      } else if ( v->stage > stage || v->stage < 0 ) {
         v->status = 'B' ;
      }
   }
}
if ( info->msglvl > 3 ) {
   fprintf(info->msgFile, "\n after loading reach set") ;
   IV_fp80(reachIV, info->msgFile, 80, &ierr) ;
   fflush(info->msgFile) ;
}
if ( info->seed > 0 ) {
   IV_shuffle(reachIV, info->seed) ;
}
if ( info->msglvl > 3 ) {
   fprintf(info->msgFile, "\n reach set at stage %d", stage) ;
   IV_fp80(reachIV, info->msgFile, 80, &ierr) ;
   fflush(info->msgFile) ;
}
/*
   ------------------------------------
   do an initial update of the vertices
   ------------------------------------
*/
MSMD_update(msmd, info) ;
if ( info->msglvl > 4 ) {
   fprintf(info->msgFile, "\n\n after initial update") ;
   fflush(info->msgFile) ;
}
IV_setSize(reachIV, 0) ;
/*
   -----------
   elimination
   -----------
*/
step = 0 ; 
while ( 1 ) {
   if ( info->msglvl > 1 ) {
      fprintf(info->msgFile, "\n\n ##### stage %d, elimination step %d",
              stage, step) ;
      fflush(info->msgFile) ;
   }
   nelim = MSMD_eliminateStep(msmd, info) ;
   if ( nelim == 0 ) {
      break ;
   }
/*
   -----------------------------------------
   for each node in the reach set, clean its 
   subtree list and list of uncovered edges
   -----------------------------------------
*/
   if ( info->msglvl > 3 ) {
      fprintf(info->msgFile, "\n calling MSMD_cleanReachSet()") ;
      fprintf(info->msgFile, "\n reach set") ;
      IV_fp80(reachIV, info->msgFile, 80, &ierr) ;
      fflush(info->msgFile) ;
   }
   MSMD_cleanReachSet(msmd, info) ;
   if ( info->msglvl > 3 ) {
      fprintf(info->msgFile, "\n return from MSMD_cleanReachSet()") ;
      fflush(info->msgFile) ;
   }
/*
   ------------------
   compress the graph
   ------------------
*/
   MSMD_findInodes(msmd, info) ;
/*
   ----------------------------------------------
   clean the reach set of indistinguishable nodes
   and any nodes not on the present stage
   ----------------------------------------------
*/
   nreach = IV_size(reachIV) ;
   reach  = IV_entries(reachIV) ;
   for ( ii = jj = 0 ; ii < nreach ; ii++ ) {
      if ( reach[ii] < 0 || reach[ii] >= msmd->nvtx ) {
         fprintf(stderr, "\n fatal error in MSMD_eliminateStage()"
                 "\n reach[%d] = %d", ii, reach[ii]) ;
         exit(-1) ;
      }
      v = msmd->vertices + reach[ii] ;
      if ( v->status == 'I' ) {
         continue ;
      } else if ( v->stage != stage ) {
         v->status = 'B' ;
      } else {
         reach[jj++] = v->id ;
      }
   }
   IV_setSize(reachIV, jj) ;
   if ( info->msglvl > 2 ) {
      fprintf(info->msgFile, 
              "\n\n after cleaning reach set, nreach = %d",
              IV_size(reachIV)) ;
      fprintf(info->msgFile, "\n reach :") ;
      IV_fp80(reachIV, info->msgFile, 8, &ierr) ;
      fflush(info->msgFile) ;
   }
/*
   ----------------------------------
   update the nodes on the reach set
   ----------------------------------
*/
   MSMD_update(msmd, info) ;
   if ( info->msglvl > 2 ) {
      fprintf(info->msgFile, "\n\n return from update") ;
      fflush(info->msgFile) ;
   }
   IV_setSize(reachIV, 0) ;
/*
   ------------------------------
   increment the elimination step
   ------------------------------
*/
   step++ ;
}
if ( info->msglvl > 2 ) {
   fprintf(info->msgFile, "\n stage %d over, %d steps",
           stage, step) ;
   fflush(info->msgFile) ;
}
/*
   --------------------------------------
   set the number of steps for this stage
   --------------------------------------
*/
info->stageInfo->nstep = step ;

return ; }
Esempio n. 4
0
/*
   ---------------------------------------------------------------------
   purpose -- to order the graph using multi-stage minimum degree

   g      -- Graph object
   stages -- stage vector for vertices, 
      if NULL then
         all vertices on stage zero.
      otherwise 
         vertices with stage istage are eliminated 
         before any vertices with stage > istage

   working storage is free'd,
   statistics can be accessed through their variables or printed
   via the void MSMD_printStats(MSMD*,FILE*) method.

   created -- 96feb25, cca
   ---------------------------------------------------------------------
*/
void
MSMD_order ( 
   MSMD       *msmd,
   Graph      *g, 
   int        stages[],
   MSMDinfo   *info
) {
double          t0, t1, t2, t3 ;
int             istage, iv, nstage, nvtx ;
IP              *ip ;
MSMDstageInfo   *now, *total ;
MSMDvtx         *v ;
/*
   ---------------
   check the input
   ---------------
*/
MARKTIME(t0) ;
if (  msmd == NULL || g == NULL || info == NULL ) {
   fprintf(stderr, "\n fatal error in MSMD_order(%p,%p,%p,%p)"
           "\n bad input\n", msmd, g, stages, info) ;
   exit(-1) ;
}
if ( info->msglvl > 2 ) {
   fprintf(info->msgFile, "\n\n inside MSMD_order()") ;
   if ( stages != NULL ) {
      int ierr ;
      fprintf(info->msgFile, "\n stages[%d]", g->nvtx) ;
      IVfp80(info->msgFile, g->nvtx, stages, 80, &ierr) ;
   }
   fflush(info->msgFile) ;
}
/*
   -------------------------------
   check the information structure
   -------------------------------
*/
if ( MSMDinfo_isValid(info) != 1 ) {
   fprintf(stderr, "\n fatal error in MSMD_order(%p,%p,%p,%p)"
           "\n bad MSMDinfo object\n", msmd, g, stages, info) ;
   exit(-1) ;
}
/*
   ---------------------
   initialize the object
   ---------------------
*/
if ( info->msglvl > 3 ) {
   fprintf(info->msgFile, "\n\n trying to initialize MSMD object ") ;
   Graph_writeForHumanEye(g, info->msgFile) ;
   fflush(info->msgFile) ;
}
MSMD_init(msmd, g, stages, info) ;
nvtx   = g->nvtx ;
nstage = info->nstage ;
if ( info->msglvl > 2 ) {
   fprintf(info->msgFile, 
           "\n\n MSMD object initialized, %d stages", nstage) ;
   fflush(info->msgFile) ;
}
/*
   ------------------------------------
   load the reach set with all vertices
   ------------------------------------
*/
if ( info->compressFlag / 4 >= 1 ) {
/*
   ------------------
   compress the graph
   ------------------
*/
   if ( info->msglvl > 2 ) {
      fprintf(info->msgFile, "\n\n initial compression") ;
      fflush(info->msgFile) ;
   }
   IV_setSize(&msmd->reachIV, nvtx) ;
   IV_ramp(&msmd->reachIV, 0, 1) ;
   MSMD_findInodes(msmd, info) ;
   if ( info->msglvl > 2 ) {
      fprintf(info->msgFile, 
              "\n\n %d checked, %d found indistinguishable",
              info->stageInfo->ncheck, info->stageInfo->nindst) ;
      fflush(info->msgFile) ;
   }
   MSMD_cleanReachSet(msmd, info) ;
/*
   for ( iv = 0, v = msmd->vertices ; iv < nvtx ; iv++, v++ ) {
      MSMD_cleanEdgeList(msmd, v, info) ;
   }
*/
}
IV_setSize(&msmd->reachIV, 0) ;
/*
   --------------------
   loop over the stages
   --------------------
*/
for ( info->istage = 0 ; info->istage <= nstage ; info->istage++ ) {
   if ( info->msglvl > 2 ) {
      fprintf(info->msgFile, 
              "\n\n ##### elimination stage %d", info->istage) ;
      fflush(info->msgFile) ;
   }
/*
   if ( info->istage == nstage ) {
      info->msglvl = 5 ;
   }
*/
   MARKTIME(t1) ;
   MSMD_eliminateStage(msmd, info) ;
   MARKTIME(t2) ;
   info->stageInfo->cpu = t2 - t1 ;
   info->stageInfo++ ;
}
/*
   -------------
   final cleanup 
   -------------
*/
{
MSMDvtx   *first, *last, *v ;

IV_setSize(&msmd->reachIV, 0) ;
first = msmd->vertices ;
last  = first + nvtx - 1 ;
for ( v = first ; v <= last ; v++ ) {
   switch ( v->status ) {
   case 'E' :
   case 'L' :
   case 'I' :
      break ;
   default :
      IV_push(&msmd->reachIV, v->id) ;
      break ;
   }
}
/*
fprintf(stdout, "\n reach set, %d entries", IV_size(&msmd->reachIV)) ;
IV_writeForHumanEye(&msmd->reachIV, stdout) ;
*/
MSMD_findInodes(msmd, info) ;
}
/*
   ---------------------------------------------------------
   make info->stagInfo point back to beginning of the stages
   ---------------------------------------------------------
*/
info->stageInfo -= nstage + 1 ;
/*
   ------------------------
   get the total statistics
   ------------------------
*/
for ( istage = 0, now = info->stageInfo,
      total = info->stageInfo + nstage + 1 ; 
      istage <= nstage ; 
      istage++, now++ ) {
   total->nstep    += now->nstep    ;
   total->nfront   += now->nfront   ;
   total->welim    += now->welim    ;
   total->nfind    += now->nfind    ;
   total->nzf      += now->nzf      ;
   total->ops      += now->ops      ;
   total->nexact2  += now->nexact2  ;
   total->nexact3  += now->nexact3  ;
   total->napprox  += now->napprox  ;
   total->ncheck   += now->ncheck   ;
   total->nindst   += now->nindst   ;
   total->noutmtch += now->noutmtch ;
}
/*
   -----------------------------------------------------
   free some working storage (leave the MSMDvtx objects
   so the user can extract the permutations and/or ETree
   -----------------------------------------------------
*/
IIheap_free(msmd->heap) ;
msmd->heap = NULL ;
IV_clearData(&msmd->ivtmpIV) ;
IV_clearData(&msmd->reachIV) ;
/*
while ( (ip = msmd->baseIP) != NULL ) {
   msmd->baseIP = ip->next ;
   IP_free(ip) ;
}
*/
MARKTIME(t3) ;
info->totalCPU = t3 - t0 ;

return ; }