Beispiel #1
0
/*
   ---------------------------------------------------------------
   purpose --  fill dvec[J] with the stack storage to solve for J
               in a forward solve

   created -- 97nov30, cca
   ---------------------------------------------------------------
*/
void
ETree_forwSolveProfile (
   ETree    *etree,
   double   dvec[]
) {
int    I, J, maxstack, nDJ, nfront, nUJ, stack ;
int    *bndwghts, *fch, *nodwghts, *sib ;
Tree   *tree ;
/*
   ---------------
   check the input
   ---------------
*/
if ( etree == NULL || dvec == NULL ) {
   fprintf(stderr, 
           "\n fatal error in ETree_forwSolveProfile(%p,%p)"
           "\n bad input\n", etree, dvec) ;
   exit(-1) ;
}
tree       = ETree_tree(etree) ;
nodwghts   = ETree_nodwghts(etree) ;
bndwghts   = ETree_bndwghts(etree) ;
nfront     = ETree_nfront(etree) ;
fch        = ETree_fch(etree) ;
sib        = ETree_sib(etree) ;
/*
   ---------------------------------------------
   loop over the nodes in a post-order traversal
   ---------------------------------------------
*/
maxstack = stack = 0 ;
for ( J = Tree_postOTfirst(tree) ;
      J != -1 ;
      J = Tree_postOTnext(tree, J) ) {
   nDJ = nodwghts[J] ;
   nUJ = bndwghts[J] ;
   stack += nDJ + nUJ ;
   dvec[J] = stack ;
   if ( maxstack < stack ) {
      maxstack = stack ;
   }
#if MYDEBUG > 0
   fprintf(stdout, 
           "\n working on front %d, nD = %d, nU = %d, stack = %d",
           J, nDJ, nUJ, stack) ;
#endif
   for ( I = fch[J] ; I != -1 ; I = sib[I] ) {
      stack -= bndwghts[I] ;
   }
   stack -= nDJ ;
}
#if MYDEBUG >= 0
fprintf(stdout, 
        "\n    forward solve : final stack = %d, max stack = %d", 
        stack, maxstack) ;
#endif

return ; }
/*
   ------------------------------------------------------------
   purpose -- compute the maximum number of indices and entries
              in a front

   symflag = SPOOLES_SYMMETRIC or SPOOLES_HERMITIAN -->
      count only column indices
      count upper entries in (1,1) block and (1,2) block
   symflag = SPOOLES_NONSYMMETRIC -->
      count row and column indices
      count entries in (1,1), (1,2) and (2,1) blocks

   created -- 97may23, cca
   ------------------------------------------------------------
*/
void
ETree_maxNindAndNent (
    ETree   *etree,
    int     symflag,
    int     *pmaxnind,
    int     *pmaxnent
) {
    int   J, maxnent, maxnind, nDJ, nent, nfront, nind, nUJ ;
    int   *nodwghts, *bndwghts ;
    /*
       ---------------
       check the input
       ---------------
    */
    if ( etree == NULL ) {
        fprintf(stderr, "\n fatal error in ETree_maxNindAndNent(%p,%d)"
                "\n bad input\n", etree, symflag) ;
        exit(-1) ;
    }
    nfront   = etree->nfront ;
    nodwghts = ETree_nodwghts(etree) ;
    bndwghts = ETree_bndwghts(etree) ;
    for ( J = 0, maxnent = maxnind = 0 ; J < nfront ; J++ ) {
        nDJ = nodwghts[J] ;
        nUJ = bndwghts[J] ;
        switch ( symflag ) {
        case SPOOLES_SYMMETRIC :
        case SPOOLES_HERMITIAN :
            nind = nDJ + nUJ ;
            nent = (nDJ*(nDJ+1))/2 + nDJ*nUJ ;
            break ;
        case SPOOLES_NONSYMMETRIC :
            nind = 2*(nDJ + nUJ) ;
            nent = nDJ*(nDJ + 2*nUJ) ;
            break ;
        default :
            fprintf(stderr, "\n fatal error in ETree_maxNindAndNent(%p,%d)"
                    "\n bad symflag\n", etree, symflag) ;
            exit(-1) ;
            break ;
        }
        if ( maxnind < nind ) {
            maxnind = nind ;
        }
        if ( maxnent < nent ) {
            maxnent = nent ;
        }
    }
    *pmaxnind = maxnind ;
    *pmaxnent = maxnent ;

    return ;
}
Beispiel #3
0
/*
   ---------------------------------------------
   purpose -- to broadcast a front tree object 
              from one process to all the others

   created -- 98may21, cca
   ---------------------------------------------
*/
ETree *
ETree_MPI_Bcast (
   ETree      *etree,
   int        root,
   int        msglvl,
   FILE       *msgFile,
   MPI_Comm   comm
) {
int   myid, nvtx, nfront, nint ;
int   *buffer ;
/*
   -------------
   find identity
   -------------
*/
MPI_Comm_rank(comm, &myid) ;
if ( myid == root ) {
/*
   --------------------------------------------
   this process owns the front tree, allocate a
   continuous buffer and load the data into it.
   --------------------------------------------
*/
   nfront = ETree_nfront(etree) ;
   nvtx   = ETree_nvtx(etree) ;
   nint   = 3 + 5*nfront + nvtx ;
   buffer = IVinit(nint, -1) ;
   buffer[0] = nfront ;
   buffer[1] = nvtx  ;
   buffer[2] = ETree_root(etree) ;
   IVcopy(nfront, buffer + 3,            ETree_par(etree)) ;
   IVcopy(nfront, buffer + 3 +   nfront, ETree_fch(etree)) ;
   IVcopy(nfront, buffer + 3 + 2*nfront, ETree_sib(etree)) ;
   IVcopy(nfront, buffer + 3 + 3*nfront, ETree_nodwghts(etree)) ;
   IVcopy(nfront, buffer + 3 + 4*nfront, ETree_bndwghts(etree)) ;
   IVcopy(nvtx,   buffer + 3 + 5*nfront, ETree_vtxToFront(etree)) ;
/*
   ------------------------------------
   send the size of the buffer and then 
   the buffer to the other processors
   ------------------------------------
*/
   MPI_Bcast(&nint,     1, MPI_INT, root, comm) ;
   MPI_Bcast(buffer, nint, MPI_INT, root, comm) ;
} else {
/*
   --------------------------------------------
   this process will receive the front tree.
   clear its data, receive the number of int's,
   then receive the buffer
   --------------------------------------------
*/
   if ( etree != NULL ) {
      ETree_free(etree) ;
   }
   MPI_Bcast(&nint, 1, MPI_INT, root, comm) ;
   buffer = IVinit(nint, -1) ;
   MPI_Bcast(buffer, nint, MPI_INT, root, comm) ;
/*
   ----------------------------------------
   create an ETree object and fill its data
   ----------------------------------------
*/
   etree  = ETree_new() ;
   nfront = buffer[0] ;
   nvtx   = buffer[1] ;
   ETree_init1(etree, nfront, nvtx) ;
   etree->tree->n    = nfront ;
   etree->tree->root = buffer[2] ;
   IVcopy(nfront, ETree_par(etree),        buffer + 3) ;
   IVcopy(nfront, ETree_fch(etree),        buffer + 3 +   nfront) ;
   IVcopy(nfront, ETree_sib(etree),        buffer + 3 + 2*nfront) ;
   IVcopy(nfront, ETree_nodwghts(etree),   buffer + 3 + 3*nfront) ;
   IVcopy(nfront, ETree_bndwghts(etree),   buffer + 3 + 4*nfront) ;
   IVcopy(nvtx,   ETree_vtxToFront(etree), buffer + 3 + 5*nfront) ;
}
/*
   ---------------
   free the buffer
   ---------------
*/
IVfree(buffer) ;

return(etree) ; }
Beispiel #4
0
/*
   ---------------------------------------------------------------
   purpose --  fill dvec[J] with the active storage to eliminate J
               using the right-looking general sparse method

   symflag -- symmetry flag, one of SPOOLES_SYMMETRIC,
              SPOOLES_HERMITIAN or SPOOLES_NONSYMMETRIC

   created -- 98dec19, cca
   ---------------------------------------------------------------
*/
void
ETree_FSstorageProfile (
   ETree    *etree,
   int      symflag,
   IVL      *symbfacIVL,
   double   dvec[]
) {
char   *incore ;
int    ii, J, K, nDJ, nfront, nUJ, sizeJ, storage ;
int    *bndwghts, *indJ, *mark, *nodwghts, *stor, *vtxToFront ;
Tree   *tree ;
/*
   ---------------
   check the input
   ---------------
*/
if ( etree == NULL || symbfacIVL == NULL || dvec == NULL ) {
   fprintf(stderr, 
           "\n fatal error in ETree_FSstorageProfile(%p,%p,%p)"
           "\n bad input\n", etree, symbfacIVL, dvec) ;
   exit(-1) ;
}
tree       = ETree_tree(etree) ;
nodwghts   = ETree_nodwghts(etree) ;
bndwghts   = ETree_bndwghts(etree) ;
vtxToFront = ETree_vtxToFront(etree) ;
nfront     = ETree_nfront(etree) ;
incore     = CVinit(nfront, 'F') ;
stor       = IVinit(nfront, 0) ;
mark       = IVinit(nfront, -1) ;
/*
   --------------------------------------------
   compute the storage for each front's chevron
   --------------------------------------------
*/
if ( symflag == SPOOLES_SYMMETRIC || symflag == SPOOLES_HERMITIAN ) {
   for ( J = 0 ; J < nfront ; J++ ) {
      nDJ = nodwghts[J] ;
      nUJ = bndwghts[J] ;
      stor[J] = (nDJ*(nDJ+1))/2 + nDJ*nUJ ;
   }
} else {
   for ( J = 0 ; J < nfront ; J++ ) {
      nDJ = nodwghts[J] ;
      nUJ = bndwghts[J] ;
      stor[J] = nDJ*nDJ + 2*nDJ*nUJ ;
   }
}
/*
   ---------------------------------------------
   loop over the nodes in a post-order traversal
   ---------------------------------------------
*/
storage = 0 ;
for ( J = Tree_postOTfirst(tree) ;
      J != -1 ;
      J = Tree_postOTnext(tree, J) ) {
   if ( incore[J] == 'F' ) {
      storage += stor[J] ;
      incore[J] = 'T' ;
   }
   IVL_listAndSize(symbfacIVL, J, &sizeJ, &indJ) ;
   mark[J] = J ;
   for ( ii = 0 ; ii < sizeJ ; ii++ ) {
      K = vtxToFront[indJ[ii]] ;
      if ( mark[K] != J ) {
         mark[K] = J ;
         if ( incore[K] == 'F' ) {
            storage += stor[K] ;
            incore[K] = 'T' ;
         }
      }
   }
   dvec[J] = storage ;
   storage -= stor[J] ;
}
IVfree(mark) ;
IVfree(stor) ;
CVfree(incore) ;

return ; }
Beispiel #5
0
/*
   ---------------------------------------------------------------
   purpose --  fill dvec[J] with the active storage to eliminate J
               using the multifrontal method

   symflag -- symmetry flag, one of SPOOLES_SYMMETRIC,
              SPOOLES_HERMITIAN or SPOOLES_NONSYMMETRIC

   created -- 97may21, cca
   ---------------------------------------------------------------
*/
void
ETree_MFstackProfile (
   ETree    *etree,
   int      symflag,
   double   dvec[]
) {
int    I, J, nDJ, nUI, nUJ, stack ;
int    *bndwghts, *fch, *nodwghts, *sib ;
Tree   *tree ;
/*
   ---------------
   check the input
   ---------------
*/
if ( etree == NULL || dvec == NULL ) {
   fprintf(stderr, "\n fatal error in ETree_MFstackProfile(%p,%p)"
           "\n bad input\n", etree, dvec) ;
   exit(-1) ;
}
tree     = ETree_tree(etree) ;
nodwghts = ETree_nodwghts(etree) ;
bndwghts = ETree_bndwghts(etree) ;
fch      = ETree_fch(etree) ;
sib      = ETree_sib(etree) ;
/*
   ---------------------------------------------
   loop over the nodes in a post-order traversal
   ---------------------------------------------
*/
stack = 0 ;
for ( J = Tree_postOTfirst(tree) ;
      J != -1 ;
      J = Tree_postOTnext(tree, J) ) {
   nDJ = nodwghts[J] ;
   nUJ = bndwghts[J] ;
#if MYDEBUG > 0
   fprintf(stdout, 
           "\n working on front %d, nD = %d, nU = %d, stack = %d",
           J, nDJ, nUJ, stack) ;
#endif
   if ( (I = fch[J]) != -1 ) {
/*
      --------------------------------
      remove last child from the stack
      --------------------------------
*/
      while ( sib[I] != -1 ) {
         I = sib[I] ;
      }
      nUI = bndwghts[I] ;
      if ( symflag == SPOOLES_SYMMETRIC 
        || symflag == SPOOLES_HERMITIAN ) {
         stack -= (nUI*(nUI+1))/2 ;
      } else if ( symflag == SPOOLES_NONSYMMETRIC ) {
         stack -= nUI*nUI ;
      }
#if MYDEBUG > 0
      fprintf(stdout, 
           "\n    removing last child %d, stack = %d", I, stack) ;
#endif
   }
/*
   ---------------------------------
   add frontal matrix for J to stack
   and store as the storage for J
   ---------------------------------
*/
   dvec[J] = stack + (nDJ + nUJ)*(nDJ + nUJ) ;
   if ( symflag == SPOOLES_SYMMETRIC || symflag == SPOOLES_HERMITIAN ) {
      dvec[J] = stack + ((nDJ + nUJ)*(nDJ + nUJ+1))/2 ;
   } else if ( symflag == SPOOLES_NONSYMMETRIC ) {
      dvec[J] = stack + (nDJ + nUJ)*(nDJ + nUJ) ;
   }
#if MYDEBUG > 0
      fprintf(stdout, 
           "\n    working storage = %.0f", dvec[J]) ;
#endif
   if ( (I = fch[J]) != -1 ) {
/*
      ------------------------------------
      remove other children from the stack
      ------------------------------------
*/
      while ( sib[I] != -1 ) {
         nUI = bndwghts[I] ;
         if ( symflag == SPOOLES_SYMMETRIC 
           || symflag == SPOOLES_HERMITIAN ) {
            stack -= (nUI*(nUI+1))/2 ;
         } else if ( symflag == SPOOLES_NONSYMMETRIC ) {
            stack -= nUI*nUI ;
         }
#if MYDEBUG > 0
      fprintf(stdout, 
           "\n    removing child %d, stack = %d", I, stack) ;
#endif
         I = sib[I] ;
      }
   }
/*
   --------------------------------
   add update matrix for J to stack
   --------------------------------
*/
   if ( symflag == SPOOLES_SYMMETRIC || symflag == SPOOLES_HERMITIAN ) {
      stack += (nUJ*(nUJ+1))/2 ;
   } else if ( symflag == SPOOLES_NONSYMMETRIC ) {
      stack += nUJ*nUJ ;
   }
#if MYDEBUG > 0
      fprintf(stdout, 
           "\n    adding update matrix, stack = %d", stack) ;
#endif
}
#if MYDEBUG >= 0
fprintf(stdout, "\n    MF: final stack = %d", stack) ;
#endif
return ; }
Beispiel #6
0
/*
   ---------------------------------------------------------------
   purpose --  fill dvec[J] with the active storage to eliminate J
               using the left-looking general sparse method

   symflag -- symmetry flag, one of SPOOLES_SYMMETRIC,
              SPOOLES_HERMITIAN or SPOOLES_NONSYMMETRIC

   created -- 97may21, cca
   ---------------------------------------------------------------
*/
void
ETree_GSstorageProfile (
   ETree    *etree,
   int      symflag,
   IVL      *symbfacIVL,
   int      *vwghts,
   double   dvec[]
) {
int    count, ii, I, J, K, nDJ, nfront, nUJ, sizeI, sizeJ, storage, v ;
int    *bndwghts, *head, *indI, *indJ, 
       *link, *nodwghts, *offsets, *vtxToFront ;
Tree   *tree ;
/*
   ---------------
   check the input
   ---------------
*/
if ( etree == NULL || symbfacIVL == NULL || dvec == NULL ) {
   fprintf(stderr, 
           "\n fatal error in ETree_GSstorageProfile(%p,%p,%p,%p)"
           "\n bad input\n", etree, symbfacIVL, vwghts, dvec) ;
   exit(-1) ;
}
tree       = ETree_tree(etree) ;
nodwghts   = ETree_nodwghts(etree) ;
bndwghts   = ETree_bndwghts(etree) ;
vtxToFront = ETree_vtxToFront(etree) ;
nfront     = ETree_nfront(etree) ;
head       = IVinit(nfront, -1) ;
link       = IVinit(nfront, -1) ;
offsets    = IVinit(nfront,  0) ;
/*
   ---------------------------------------------
   loop over the nodes in a post-order traversal
   ---------------------------------------------
*/
storage = 0 ;
for ( J = Tree_postOTfirst(tree) ;
      J != -1 ;
      J = Tree_postOTnext(tree, J) ) {
   nDJ = nodwghts[J] ;
   nUJ = bndwghts[J] ;
   if ( symflag == SPOOLES_SYMMETRIC || symflag == SPOOLES_HERMITIAN ) {
      storage += (nDJ*(nDJ + 1))/2 + nDJ*nUJ ;
   } else if ( symflag == SPOOLES_NONSYMMETRIC ) {
      storage += nDJ*nDJ + 2*nDJ*nUJ ;
   }
   dvec[J] = storage ;
#if MYDEBUG > 0
   fprintf(stdout, 
           "\n working on front %d, nD = %d, nU = %d, storage = %d",
           J, nDJ, nUJ, storage) ;
#endif
/*
   -----------------------------
   loop over the updating fronts
   -----------------------------
*/
   while ( (I = head[J]) != -1 ) {
      head[J] = link[I] ;
      IVL_listAndSize(symbfacIVL, I, &sizeI, &indI) ;
#if MYDEBUG > 0
      fprintf(stdout, 
              "\n    updating front %d, offset = %d, sizeI = %d", 
              I, offsets[I], sizeI) ;
      IVfprintf(stdout, sizeI, indI) ;
#endif
      for ( ii = offsets[I], count = 0, K = -1 ; ii < sizeI ; ii++ ) {
         v = indI[ii] ;
#if MYDEBUG > 0
         fprintf(stdout, "\n       ii = %d, v = %d, K = %d",
                 ii, v, vtxToFront[v]) ;
         fflush(stdout) ;
#endif
         K = vtxToFront[v] ;
         if ( K < 0 || K >= nfront ) {
            fprintf(stderr, "\n\n fatal error"
                    "\n ii = %d, v = %d, K = %d", ii, v, K) ;
            exit(-1) ;
         }
         if ( (K = vtxToFront[v]) != J ) {
#if MYDEBUG > 0
            fprintf(stdout, "\n       linking to next ancestor %d", K) ;
#endif
            link[I] = head[K] ;
            head[K] = I ;
            offsets[I] = ii ;
            break ;
         }
         count += (vwghts == NULL) ? 1 : vwghts[v] ;
#if MYDEBUG > 0
         fprintf(stdout, "\n       count = %d", count) ;
         fflush(stdout) ;
#endif
      }
      if ( symflag == SPOOLES_SYMMETRIC 
        || symflag == SPOOLES_HERMITIAN ) {
         storage -= count*nodwghts[I] ;
      } else if ( symflag == SPOOLES_NONSYMMETRIC ) {
         storage -= 2*count*nodwghts[I] ;
      }
   }
   if ( symflag == SPOOLES_SYMMETRIC || symflag == SPOOLES_HERMITIAN ) {
      storage -= (nDJ*(nDJ+1))/2 ;
   } else if ( symflag == SPOOLES_NONSYMMETRIC ) {
      storage -= nDJ*nDJ ;
   }
   if ( nUJ > 0 ) {
      IVL_listAndSize(symbfacIVL, J, &sizeJ, &indJ) ;
      for ( ii = 0 ; ii < sizeJ ; ii++ ) {
         v = indJ[ii] ;
         if ( (K = vtxToFront[v]) != J ) {
            break ;
         }
      }
      offsets[J] = ii ;
#if MYDEBUG > 0
      fprintf(stdout, "\n    linking to next ancestor %d", K) ;
#endif
      IVL_listAndSize(symbfacIVL, J, &sizeJ, &indJ) ;
      link[J] = head[K] ;
      head[K] = J ;
   }
#if MYDEBUG > 0
   fprintf(stdout, "\n    at end of step %d, storage = %d", 
           J, storage) ;
#endif
}
#if MYDEBUG >= 0
fprintf(stdout, "\n    GS: final storage = %d", storage) ;
#endif
IVfree(head) ;
IVfree(link) ;
IVfree(offsets) ;

return ; }
Beispiel #7
0
/*
   -----------------------------------------------------------
   purpose -- to initialize subtree with the subtree 
              of the front tree using nodes in nodeidsIV.
              vtxIV is filled with the vertices in the subtree
 
   return values ---
      1 -- normal return
     -1 -- subtree is NULL
     -2 -- nodeidsIV is NULL
     -3 -- etree is NULL
     -4 -- nodeidsIV is invalid
     -5 -- vtxIV is NULL
 
   created -- 98oct15, cca
   -----------------------------------------------------------
*/
int
ETree_initFromSubtree (
   ETree   *subtree,
   IV      *nodeidsIV,
   ETree   *etree,
   IV      *vtxIV
) {
int   J, Jsub, nfrontInETree, nfrontInSubtree, 
      nvtxInETree, nvtxInSubtree, v, vSub ;
int   *bndwghts, *bndwghtsSub, *localmap, *nodwghts, *nodwghtsSub,
      *subtreeNodes, *vtxInSubtree, *vtxToFront, *vtxToFrontSub ;
/*
   ---------------
   check the input
   ---------------
*/
if ( subtree == NULL ) {
   fprintf(stderr, "\n\n error in ETree_initFromSubtree()"
           "\n subtree is NULL\n") ;
   return(-1) ;
}
if ( nodeidsIV == NULL ) {
   fprintf(stderr, "\n\n error in ETree_initFromSubtree()"
           "\n nodeidsIV is NULL\n") ;
   return(-2) ;
}
if ( etree == NULL ) {
   fprintf(stderr, "\n\n error in ETree_initFromSubtree()"
           "\n etree is NULL\n") ;
   return(-3) ;
}
nfrontInETree = ETree_nfront(etree) ;
IV_sizeAndEntries(nodeidsIV, &nfrontInSubtree, &subtreeNodes) ;
if ( nfrontInSubtree < 0 || nfrontInSubtree >= nfrontInETree ) {
   fprintf(stderr, "\n\n error in ETree_initFromSubtree()"
           "\n nfrontInETree = %d, nfrontInSubtree = %d\n",
           nfrontInETree, nfrontInSubtree) ;
   return(-4) ;
}
for ( Jsub = 0 ; Jsub < nfrontInSubtree ; Jsub++ ) {
   J = subtreeNodes[Jsub] ;
   if ( J < 0 || J >= nfrontInETree ) {
      fprintf(stderr, "\n\n error in ETree_initFromSubtree()"
              "\n nfrontInETree = %d, subtreeNodes[%d] = %d\n",
              nfrontInETree, Jsub, subtreeNodes[Jsub]) ;
      return(-4) ;
   }
}
if ( vtxIV == NULL ) {
   fprintf(stderr, "\n\n error in ETree_initFromSubtree()"
           "\n vtxIV is NULL\n") ;
   return(-5) ;
}
nvtxInETree = ETree_nvtx(etree) ;
vtxToFront  = ETree_vtxToFront(etree) ;
/*
   ----------------------------
   create a global-to-local map
   ----------------------------
*/
localmap = IVinit(nfrontInETree, -1) ;
for ( Jsub = 0 ; Jsub < nfrontInSubtree ; Jsub++ ) {
   J = subtreeNodes[Jsub] ;
   localmap[J] = Jsub ;
}
/*
   ---------------------------------------------
   compute the number of vertices in the subtree
   ---------------------------------------------
*/
nvtxInSubtree = 0 ;
for ( v = 0 ; v < nvtxInETree ; v++ ) {
   J = vtxToFront[v] ;
   if ( (Jsub = localmap[J]) != -1 ) {
      nvtxInSubtree++ ;
   }
}
/*
   ----------------------
   initialize the subtree
   ----------------------
*/
ETree_init1(subtree, nfrontInSubtree, nvtxInSubtree) ;
/*
   -----------------------------
   initialize the subtree's tree
   -----------------------------
*/
Tree_initFromSubtree(subtree->tree, nodeidsIV, etree->tree) ;
/*
   -----------------------------------
   set the nodwght and bndwght vectors
   -----------------------------------
*/
nodwghts    = ETree_nodwghts(etree) ;
bndwghts    = ETree_bndwghts(etree) ;
nodwghtsSub = ETree_nodwghts(subtree) ;
bndwghtsSub = ETree_bndwghts(subtree) ;
for ( Jsub = 0 ; Jsub < nfrontInSubtree ; Jsub++ ) {
   J = subtreeNodes[Jsub] ;
   nodwghtsSub[Jsub] = nodwghts[J] ;
   bndwghtsSub[Jsub] = bndwghts[J] ;
}
/*
   -------------------------------------
   set the subtree's vtxToFront[] vector
   and fill vtxIV with the vertices
   -------------------------------------
*/
IV_init(vtxIV, nvtxInSubtree, NULL) ;
vtxInSubtree  = IV_entries(vtxIV) ;
vtxToFrontSub = ETree_vtxToFront(subtree) ;
for ( v = vSub = 0 ; v < nvtxInETree ; v++ ) {
   J = vtxToFront[v] ;
   if ( (Jsub = localmap[J]) != -1 ) {
      vtxInSubtree[vSub] = v ;
      vtxToFrontSub[vSub] = Jsub ;
      vSub++ ;
   }
}
/*
   ------------------------
   free the working storage
   ------------------------
*/
IVfree(localmap) ;

return(1) ; }
Beispiel #8
0
/*--------------------------------------------------------------------*/
int
main ( int argc, char *argv[] )
/*
   ---------------------------------------------------------------
   read in a ETree object, create an IV object with the same size,
   mark the vertices in the top level separator(s), write the IV
   object to a file

   created -- 96may02, cca
   ---------------------------------------------------------------
*/
{
char     *inETreeFileName, *outIVfileName ;
double   t1, t2 ;
int      msglvl, rc, J, K, ncomp, nfront, nvtx, v ;
int      *bndwghts, *compids, *fch, *map, *nodwghts, 
         *par, *sib, *vtxToFront ;
IV       *compidsIV, *mapIV ;
ETree    *etree ;
FILE     *msgFile ;
Tree     *tree ;

if ( argc != 5 ) {
   fprintf(stdout, 
      "\n\n usage : %s msglvl msgFile inETreeFile outIVfile"
      "\n    msglvl      -- message level"
      "\n    msgFile     -- message file"
      "\n    inETreeFile -- input file, must be *.etreef or *.etreeb"
      "\n    outIVfile   -- output file, must be *.ivf or *.ivb"
      "\n", argv[0]) ;
   return(0) ;
}
msglvl = atoi(argv[1]) ;
if ( strcmp(argv[2], "stdout") == 0 ) {
   msgFile = stdout ;
} else if ( (msgFile = fopen(argv[2], "a")) == NULL ) {
   fprintf(stderr, "\n fatal error in %s"
           "\n unable to open file %s\n",
           argv[0], argv[2]) ;
   return(-1) ;
}
inETreeFileName = argv[3] ;
outIVfileName   = argv[4] ;
fprintf(msgFile, 
        "\n %s "
        "\n msglvl      -- %d" 
        "\n msgFile     -- %s" 
        "\n inETreeFile -- %s" 
        "\n outIVfile   -- %s" 
        "\n",
        argv[0], msglvl, argv[2], inETreeFileName, outIVfileName) ;
fflush(msgFile) ;
/*
   ------------------------
   read in the ETree object
   ------------------------
*/
if ( strcmp(inETreeFileName, "none") == 0 ) {
   fprintf(msgFile, "\n no file to read from") ;
   exit(0) ;
}
etree = ETree_new() ;
MARKTIME(t1) ;
rc = ETree_readFromFile(etree, inETreeFileName) ;
MARKTIME(t2) ;
fprintf(msgFile, "\n CPU %9.5f : read in etree from file %s",
        t2 - t1, inETreeFileName) ;
if ( rc != 1 ) {
   fprintf(msgFile, "\n return value %d from ETree_readFromFile(%p,%s)",
           rc, etree, inETreeFileName) ;
   exit(-1) ;
}
fprintf(msgFile, "\n\n after reading ETree object from file %s",
        inETreeFileName) ;
if ( msglvl > 2 ) {
   ETree_writeForHumanEye(etree, msgFile) ;
} else {
   ETree_writeStats(etree, msgFile) ;
}
fflush(msgFile) ;
nfront     = ETree_nfront(etree) ;
nvtx       = ETree_nvtx(etree) ;
bndwghts   = ETree_bndwghts(etree) ;
vtxToFront = ETree_vtxToFront(etree) ;
nodwghts   = ETree_nodwghts(etree) ;
par        = ETree_par(etree) ;
fch        = ETree_fch(etree) ;
sib        = ETree_sib(etree) ;
tree       = ETree_tree(etree) ;
/*
   -----------------------------------------
   create the map from fronts to components,
   top level separator(s) are component zero
   -----------------------------------------
*/
mapIV = IV_new() ;
IV_init(mapIV, nfront, NULL) ;
map = IV_entries(mapIV) ;
ncomp = 0 ;
for ( J = Tree_preOTfirst(tree) ;
      J != -1 ;
      J = Tree_preOTnext(tree, J) ) { 
   if ( (K = par[J]) == -1 ) {
      map[J] = 0 ;
   } else if ( map[K] != 0 ) {
      map[J] = map[K] ;
   } else if ( J == fch[K] && sib[J] == -1 
            && bndwghts[J] == nodwghts[K] + bndwghts[K] ) {
      map[J] = 0 ;
   } else {
      map[J] = ++ncomp ;
   }
}
fprintf(msgFile, "\n\n mapIV object") ;
if ( msglvl > 2 ) {
   IV_writeForHumanEye(mapIV, msgFile) ;
} else {
   IV_writeStats(mapIV, msgFile) ;
}
/*
   ----------------------------------------
   fill the map from vertices to components
   ----------------------------------------
*/
compidsIV = IV_new() ;
IV_init(compidsIV, nvtx, NULL) ;
compids = IV_entries(compidsIV) ;
for ( v = 0 ; v < nvtx ; v++ ) {
   compids[v] = map[vtxToFront[v]] ;
}
fprintf(msgFile, "\n\n compidsIV object") ;
if ( msglvl > 2 ) {
   IV_writeForHumanEye(compidsIV, msgFile) ;
} else {
   IV_writeStats(compidsIV, msgFile) ;
}
fflush(msgFile) ;
/*
   -----------------------
   write out the IV object
   -----------------------
*/
if ( strcmp(outIVfileName, "none") != 0 ) {
   MARKTIME(t1) ;
   rc = IV_writeToFile(compidsIV, outIVfileName) ;
   MARKTIME(t2) ;
   fprintf(msgFile, "\n CPU %9.5f : write etree to file %s",
           t2 - t1, outIVfileName) ;
}
if ( rc != 1 ) {
   fprintf(msgFile, "\n return value %d from IV_writeToFile(%p,%s)",
           rc, compidsIV, outIVfileName) ;
}
/*
   ----------------
   free the objects
   ----------------
*/
ETree_free(etree) ;
IV_free(mapIV) ;
IV_free(compidsIV) ;

fprintf(msgFile, "\n") ;
fclose(msgFile) ;

return(1) ; }
Beispiel #9
0
/*
   --------------------------------------------------------------------
   purpose -- to fill submtx with a submatrix of the front matrix.
      the fronts that form the submatrix are found in frontidsIV.

      all information in submtx is local, front #'s are from 0 to
      one less than the number of fronts in the submatrix, equation
      #'s are from 0 to one less than the number of rows and columns
      in the submatrix. the global row and column ids for the submatrix
      are stored in rowsIV and colsIV on return.

   return values ---
      1 -- normal return
     -1 -- submtx is NULL
     -2 -- frontmtx is NULL
     -3 -- frontmtx is not in 2-D mode
     -4 -- frontidsIV is NULL
     -5 -- frontidsIV is invalid
     -6 -- rowsIV is NULL
     -7 -- colsIV is NULL
     -8 -- unable to create front tree
     -9 -- unable to create symbfacIVL
    -10 -- unable to create coladjIVL
    -11 -- unable to create rowadjIVL
    -12 -- unable to create upperblockIVL
    -13 -- unable to create lowerblockIVL

   created -- 98oct17, cca
   --------------------------------------------------------------------
*/
int
FrontMtx_initFromSubmatrix (
   FrontMtx   *submtx,
   FrontMtx   *frontmtx,
   IV         *frontidsIV,
   IV         *rowsIV,
   IV         *colsIV,
   int        msglvl,
   FILE       *msgFile
) {
ETree    *etreeSub ;
int      ii, J, Jsub, K, Ksub, ncol, nfront, nfrontSub, neqnSub, nJ,
         nrow, offset, rc, size, vSub ;
int      *bndwghts, *colind, *colmap, *cols, *frontSubIds, 
         *list, *nodwghts, *rowind, *rowmap, *rows ;
IV       *frontsizesIVsub, *vtxIV ;
IVL      *coladjIVLsub, *lowerblockIVLsub, *rowadjIVLsub, 
         *symbfacIVLsub, *upperblockIVLsub ;
SubMtx   *mtx ;
/*
   ---------------
   check the input
   ---------------
*/
if ( submtx == NULL ) {
   fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
           "\n submtx is NULL\n") ;
   return(-1) ;
}
if ( frontmtx == NULL ) {
   fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
           "\n frontmtx is NULL\n") ;
   return(-2) ;
}
if ( ! FRONTMTX_IS_2D_MODE(frontmtx) ) {
   fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
           "\n frontmtx mode is not 2D\n") ;
   return(-3) ;
}
if ( frontidsIV == NULL ) {
   fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
           "\n frontidsIV is NULL\n") ;
   return(-4) ;
}
nfront = FrontMtx_nfront(frontmtx) ;
IV_sizeAndEntries(frontidsIV, &nfrontSub, &frontSubIds) ;
if ( nfrontSub < 0 || nfrontSub > nfront ) {
   fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
           "\n invalid frontidsIV"
           "\n nfrontSub = %d, nfront %d\n", nfrontSub, nfront) ;
   return(-5) ;
}
for ( ii = 0 ; ii < nfrontSub ; ii++ ) {
   if ( (J = frontSubIds[ii]) < 0 || J >= nfront ) {
      fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
              "\n invalid frontidsIV"
              "\n frontSubIds[%d] = %d, nfront = %d\n",
              ii, J, nfront) ;
      return(-5) ;
   }
}
if ( rowsIV == NULL ) {
   fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
           "\n rowsIV is NULL\n") ;
   return(-6) ;
}
if ( colsIV == NULL ) {
   fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
           "\n colsIV is NULL\n") ;
   return(-7) ;
}
/*--------------------------------------------------------------------*/
/*
   -----------------------------------------------------
   clear the data for the submatrix and set the 
   scalar values (some inherited from the global matrix)
   -----------------------------------------------------
*/
FrontMtx_clearData(submtx) ;
submtx->nfront       = nfrontSub ;
submtx->type         = frontmtx->type ;
submtx->symmetryflag = frontmtx->symmetryflag ;
submtx->sparsityflag = frontmtx->sparsityflag ;
submtx->pivotingflag = frontmtx->pivotingflag ;
submtx->dataMode     = FRONTMTX_2D_MODE ;
/*
   ---------------------------------------------------------------
   initialize the front tree for the submatrix.

   note: on return, vtxIV is filled with the vertices originally
   in the submatrix, (pivoting may change this), needed to find
   symbolic factorization IVL object

   note: at return, the boundary weights are likely to be invalid,
   since we have no way of knowing what boundary indices for a
   front are really in the domain. this will be changed after we
   have the symbolic factorization.
   ---------------------------------------------------------------
*/
etreeSub = submtx->frontETree = ETree_new() ;
vtxIV = IV_new() ;
rc = ETree_initFromSubtree(etreeSub, frontidsIV, 
                           frontmtx->frontETree, vtxIV) ;
if ( rc != 1 ) {
   fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
         "\n unable to create submatrix's front ETree, rc = %d\n", rc) ;
   return(-8) ;
}
if ( msglvl > 4 ) {
   fprintf(msgFile, "\n\n submatrix ETree") ;
   ETree_writeForHumanEye(etreeSub, msgFile) ;
   fprintf(msgFile, "\n\n submatrix original equations") ;
   IV_writeForHumanEye(vtxIV, msgFile) ;
   fflush(msgFile) ;
}
/*
   ------------------------------------------------------
   set the # of equations (perhap temporarily if pivoting 
   has delayed some rows and columns), and the tree.
   ------------------------------------------------------
*/
submtx->neqns = neqnSub = IV_size(vtxIV) ;
submtx->tree  = etreeSub->tree ;
/*
   -----------------------------------------------------
   initialize the symbolic factorization for the subtree
   -----------------------------------------------------
*/
symbfacIVLsub = submtx->symbfacIVL = IVL_new() ;
rc = IVL_initFromSubIVL(symbfacIVLsub, frontmtx->symbfacIVL,
                        frontidsIV, vtxIV) ;
if ( rc != 1 ) {
   fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
         "\n unable to create submatrix's symbfac, rc = %d\n", rc) ;
   return(-9) ;
}
if ( msglvl > 4 ) {
   fprintf(msgFile, "\n\n submatrix symbolic factorizatio") ;
   IVL_writeForHumanEye(symbfacIVLsub, msgFile) ;
   fflush(msgFile) ;
}
/*
   ---------------------------------------------
   adjust the boundary weights of the front tree
   ---------------------------------------------
*/
nodwghts = ETree_nodwghts(etreeSub) ;
bndwghts = ETree_bndwghts(etreeSub) ;
for ( J = 0 ; J < nfrontSub ; J++ ) {
   IVL_listAndSize(symbfacIVLsub, J, &size, &list) ;
   bndwghts[J] = size - nodwghts[J] ;
}
if ( msglvl > 4 ) {
   fprintf(msgFile, "\n\n submatrix ETree after bndweight adjustment") ;
   ETree_writeForHumanEye(etreeSub, msgFile) ;
   fflush(msgFile) ;
}
/*
   -------------------------------------
   set the front sizes for the submatrix
   -------------------------------------
*/
frontsizesIVsub = submtx->frontsizesIV = IV_new() ;
IV_init(frontsizesIVsub, nfrontSub, NULL) ;
IVgather(nfrontSub, IV_entries(frontsizesIVsub), 
         IV_entries(frontmtx->frontsizesIV),
         IV_entries(frontidsIV)) ;
neqnSub = submtx->neqns = IV_sum(frontsizesIVsub) ;
if ( msglvl > 4 ) {
   fprintf(msgFile, "\n\n %d equations in submatrix", neqnSub) ;
   fprintf(msgFile, "\n\n front sizes for submatrix") ;
   IV_writeForHumanEye(frontsizesIVsub, msgFile) ;
   fflush(msgFile) ;
}
/*
   -------------------------------------------------------------------
   fill rowsIV and colsIV with the row and column ids of the submatrix
   -------------------------------------------------------------------
*/
IV_setSize(rowsIV, neqnSub) ;
IV_setSize(colsIV, neqnSub) ;
rows = IV_entries(rowsIV) ;
cols = IV_entries(colsIV) ;
for ( Jsub = offset = 0 ; Jsub < nfrontSub ; Jsub++ ) {
   if ( (nJ = FrontMtx_frontSize(submtx, Jsub)) > 0 ) {
      J = frontSubIds[Jsub] ;
      FrontMtx_columnIndices(frontmtx, J, &size, &list) ;
      IVcopy(nJ, cols + offset, list) ;
      FrontMtx_rowIndices(frontmtx, J, &size, &list) ;
      IVcopy(nJ, rows + offset, list) ;
      offset += nJ ;
   }
}
if ( msglvl > 4 ) {
   fprintf(msgFile, "\n\n row ids for submatrix") ;
   IV_writeForHumanEye(rowsIV, msgFile) ;
   fprintf(msgFile, "\n\n column ids for submatrix") ;
   IV_writeForHumanEye(colsIV, msgFile) ;
   fflush(msgFile) ;
}
/*
   ----------------------------------
   get the row and column adjacencies
   ----------------------------------
*/
if ( FRONTMTX_IS_PIVOTING(frontmtx) ) {
   submtx->neqns = neqnSub ;
   coladjIVLsub  = submtx->coladjIVL = IVL_new() ;
   rc = IVL_initFromSubIVL(coladjIVLsub, frontmtx->coladjIVL,
                           frontidsIV, colsIV) ;
   if ( rc != 1 ) {
      fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
           "\n unable to create submatrix's coladjIVL, rc = %d\n", rc) ;
      return(-10) ;
   }
   if ( msglvl > 4 ) {
      fprintf(msgFile, "\n\n submatrix col adjacency") ;
      IVL_writeForHumanEye(coladjIVLsub, msgFile) ;
      fflush(msgFile) ;
   }
   if ( FRONTMTX_IS_NONSYMMETRIC(frontmtx) ) {
      rowadjIVLsub = submtx->rowadjIVL = IVL_new() ;
      rc = IVL_initFromSubIVL(rowadjIVLsub, frontmtx->rowadjIVL,
                              frontidsIV, rowsIV) ;
      if ( rc != 1 ) {
         fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
           "\n unable to create submatrix's rowadjIVL, rc = %d\n", rc) ;
         return(-11) ;
      }
      if ( msglvl > 4 ) {
         fprintf(msgFile, "\n\n submatrix row adjacency") ;
         IVL_writeForHumanEye(rowadjIVLsub, msgFile) ;
         fflush(msgFile) ;
      }
   }
}
IV_free(vtxIV) ;
/*
   ----------------------------------------------
   get the rowmap[] and colmap[] vectors,
   needed to translate indices in the submatrices
   ----------------------------------------------
*/
colmap = IVinit(frontmtx->neqns, -1) ;
for ( ii = 0 ; ii < neqnSub ; ii++ ) {
   colmap[cols[ii]] = ii ;
}
if ( FRONTMTX_IS_NONSYMMETRIC(frontmtx) ) {
   rowmap = IVinit(frontmtx->neqns, -1) ;
   for ( ii = 0 ; ii < neqnSub ; ii++ ) {
      rowmap[rows[ii]] = ii ;
   }
} else {
   rowmap = colmap ;
}
/*
   -----------------------------------------------------------
   get the upper and lower block IVL objects for the submatrix
   -----------------------------------------------------------
*/
upperblockIVLsub = submtx->upperblockIVL = IVL_new() ;
rc = IVL_initFromSubIVL(upperblockIVLsub, frontmtx->upperblockIVL,
                        frontidsIV, frontidsIV) ;
if ( rc != 1 ) {
   fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
        "\n unable to create upperblockIVL, rc = %d\n", rc) ;
   return(-12) ;
}
if ( msglvl > 4 ) {
   fprintf(msgFile, "\n\n upper block adjacency IVL object") ;
   IVL_writeForHumanEye(upperblockIVLsub, msgFile) ;
   fflush(msgFile) ;
}
if ( FRONTMTX_IS_NONSYMMETRIC(frontmtx) ) {
   lowerblockIVLsub = submtx->lowerblockIVL = IVL_new() ;
   rc = IVL_initFromSubIVL(lowerblockIVLsub, frontmtx->lowerblockIVL,
                           frontidsIV, frontidsIV) ;
   if ( rc != 1 ) {
      fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
           "\n unable to create lowerblockIVL, rc = %d\n", rc) ;
      return(-13) ;
   }
   if ( msglvl > 4 ) {
      fprintf(msgFile, "\n\n lower block adjacency IVL object") ;
      IVL_writeForHumanEye(lowerblockIVLsub, msgFile) ;
      fflush(msgFile) ;
   }
}
/*
   ----------------------------------------------------------------
   allocate the vector and hash table(s) for the factor submatrices
   ----------------------------------------------------------------
*/
ALLOCATE(submtx->p_mtxDJJ, struct _SubMtx *, nfrontSub) ;
for ( J = 0 ; J < nfrontSub ; J++ ) {
   submtx->p_mtxDJJ[J] = NULL ;
}
submtx->upperhash = I2Ohash_new() ;
I2Ohash_init(submtx->upperhash, nfrontSub, nfrontSub, nfrontSub) ;
if ( FRONTMTX_IS_NONSYMMETRIC(frontmtx) ) {
   submtx->lowerhash = I2Ohash_new() ;
   I2Ohash_init(submtx->lowerhash, nfrontSub, nfrontSub, nfrontSub) ;
}
/*
   -----------------------------------------------------------------
   remove the diagonal submatrices from the factor matrix
   and insert into the submatrix object. note: front row and column
   ids must be changed to their local values, and the row and column
   indices must be mapped to local indices.
   -----------------------------------------------------------------
*/
for ( Jsub = 0 ; Jsub < nfrontSub ; Jsub++ ) {
   J = frontSubIds[Jsub] ;
   if ( (mtx = frontmtx->p_mtxDJJ[J]) != NULL ) {
      SubMtx_setIds(mtx, Jsub, Jsub) ;
      SubMtx_columnIndices(mtx, &ncol, &colind) ;
      IVgather(ncol, colind, colmap, colind) ;
      SubMtx_rowIndices(mtx, &nrow, &rowind) ;
      IVgather(nrow, rowind, rowmap, rowind) ;
      submtx->p_mtxDJJ[Jsub] = mtx ;
      frontmtx->p_mtxDJJ[J]  = NULL ;
      submtx->nentD += mtx->nent ;
   }
}
/*
   ----------------------------------------------------------------
   remove the upper triangular submatrices from the factor matrix
   and insert into the submatrix object. note: front row and column
   ids must be changed to their local values. if the matrix is on
   the diagonal, i.e., U(J,J), its row and column indices must be 
   mapped to local indices.
   ----------------------------------------------------------------
*/
for ( Jsub = 0 ; Jsub < nfrontSub ; Jsub++ ) {
   J = frontSubIds[Jsub] ;
   FrontMtx_upperAdjFronts(submtx, Jsub, &size, &list) ;
   for ( ii = 0 ; ii < size ; ii++ ) {
      Ksub = list[ii] ;
      K = frontSubIds[Ksub] ;
      if ( 1 == I2Ohash_remove(frontmtx->upperhash, 
                               J, K, (void *) &mtx) ) {
         SubMtx_setIds(mtx, Jsub, Ksub) ;
         if ( K == J ) {
            SubMtx_columnIndices(mtx, &ncol, &colind) ;
            IVgather(ncol, colind, colmap, colind) ;
            SubMtx_rowIndices(mtx, &nrow, &rowind) ;
            IVgather(nrow, rowind, rowmap, rowind) ;
         }
         I2Ohash_insert(submtx->upperhash, Jsub, Ksub, (void *) mtx) ;
         submtx->nentU += mtx->nent ;
      }
   }
}
if ( FRONTMTX_IS_NONSYMMETRIC(frontmtx) ) {
/*
   ----------------------------------------------------------------
   remove the lower triangular submatrices from the factor matrix
   and insert into the submatrix object. note: front row and column
   ids must be changed to their local values. if the matrix is on
   the diagonal, i.e., L(J,J), its row and column indices must be 
   mapped to local indices.
   ----------------------------------------------------------------
*/
   for ( Jsub = 0 ; Jsub < nfrontSub ; Jsub++ ) {
      J = frontSubIds[Jsub] ;
      FrontMtx_lowerAdjFronts(submtx, Jsub, &size, &list) ;
      for ( ii = 0 ; ii < size ; ii++ ) {
         Ksub = list[ii] ;
         K = frontSubIds[Ksub] ;
         if ( 1 == I2Ohash_remove(frontmtx->lowerhash, 
                                  K, J, (void *) &mtx) ) {
            SubMtx_setIds(mtx, Ksub, Jsub) ;
            if ( K == J ) {
               SubMtx_columnIndices(mtx, &ncol, &colind) ;
               IVgather(ncol, colind, colmap, colind) ;
               SubMtx_rowIndices(mtx, &nrow, &rowind) ;
               IVgather(nrow, rowind, rowmap, rowind) ;
            }
            I2Ohash_insert(submtx->lowerhash, Ksub, Jsub, (void *) mtx);
            submtx->nentL += mtx->nent ;
         }
      }
   }
}
/*
   ------------------------
   free the working storage
   ------------------------
*/
IVfree(colmap) ;
if ( FRONTMTX_IS_NONSYMMETRIC(frontmtx) ) {
   IVfree(rowmap) ;
}
return(1) ; }
Beispiel #10
0
/*
   -------------------------------------------------------
   purpose -- merge the front tree allowing a parent 
              to absorb all children when that creates 
              at most maxzeros zero entries inside a front

   return -- 
      IV object that has the old front to new front map

   created -- 98jan29, cca
   -------------------------------------------------------
*/
ETree *
ETree_mergeFrontsAll (
   ETree   *etree,
   int     maxzeros,
   IV      *nzerosIV
) {
ETree   *etree2 ;
int     cost, J, Jall, K, KandBnd, nfront, nvtx, nnew ;
int     *bndwghts, *fch, *map, *nodwghts, *nzeros, *rep, *sib, *temp ;
IV      *mapIV ;
Tree    *tree ;
/*
   ---------------
   check the input
   ---------------
*/
if (  etree == NULL || nzerosIV == NULL
   || (nfront = etree->nfront) <= 0
   || (nvtx = etree->nvtx) <= 0 ) {
   fprintf(stderr, "\n fatal error in ETree_mergeFrontsAll(%p,%d,%p)"
           "\n bad input\n", etree, maxzeros, nzerosIV) ;
   if ( etree != NULL ) {
      fprintf(stderr, "\n nfront = %d, nvtx = %d",
              etree->nfront, etree->nvtx) ;
   }
   spoolesFatal();
}
if ( IV_size(nzerosIV) != nfront ) {
   fprintf(stderr, "\n fatal error in ETree_mergeFrontsAll(%p,%d,%p)"
           "\n size(nzerosIV) = %d, nfront = %d\n", 
           etree, maxzeros, nzerosIV, IV_size(nzerosIV), nfront) ;
   spoolesFatal();
}
nzeros = IV_entries(nzerosIV) ;
/*
   ----------------------
   set up working storage
   ----------------------
*/
tree     = etree->tree ;
fch      = ETree_fch(etree) ;
sib      = ETree_sib(etree) ;
nodwghts = IVinit(nfront, 0) ;
IVcopy(nfront, nodwghts, ETree_nodwghts(etree)) ;
bndwghts = ETree_bndwghts(etree) ;
rep = IVinit(nfront, -1) ;
IVramp(nfront, rep, 0, 1) ;
/*
   ------------------------------------------
   perform a post-order traversal of the tree
   ------------------------------------------
*/
for ( K = Tree_postOTfirst(tree) ;
      K != -1 ;
      K = Tree_postOTnext(tree, K) ) {
#if MYDEBUG > 0
   fprintf(stdout, "\n\n ##### visiting front %d", K) ;
   fflush(stdout) ;
#endif
   if ( (J = fch[K]) != -1 ) {
      KandBnd = nodwghts[K] + bndwghts[K] ;
      Jall = 0 ;
      cost = 2*nzeros[K] ;
      for ( J = fch[K] ; J != -1 ; J = sib[J] ) {
         Jall += nodwghts[J] ;
         cost -= nodwghts[J]*nodwghts[J] ;
         cost += 2*nodwghts[J]*(KandBnd - bndwghts[J]) ;
         cost += 2*nzeros[J] ;
      }
      cost += Jall*Jall ;
      cost = cost/2 ;
#if MYDEBUG > 0
      fprintf(stdout, "\n cost = %d", cost) ;
      fflush(stdout) ;
#endif
      if ( cost <= maxzeros ) {
         for ( J = fch[K] ; J != -1 ; J = sib[J] ) {
#if MYDEBUG > 0
            fprintf(stdout, "\n merging %d into %d", J, K) ;
            fflush(stdout) ;
#endif
            rep[J] = K ;
            nodwghts[K] += nodwghts[J] ;
         }
         nzeros[K] = cost ;
      }
   }
}
#if MYDEBUG > 0
   fprintf(stdout, "\n\n whoa, finished") ;
   fflush(stdout) ;
#endif
/*
   -------------------------------------------------
   take the map from fronts to representative fronts
   and make the map from old fronts to new fronts
   -------------------------------------------------
*/
mapIV = IV_new() ;
IV_init(mapIV, nfront, NULL) ;
map   = IV_entries(mapIV) ;
for ( J = 0, nnew = 0 ; J < nfront ; J++ ) {
   if ( rep[J] == J ) {
      map[J] = nnew++ ;
   } else {
      K = J ;
      while ( rep[K] != K ) {
         K = rep[K] ;
      }
      rep[J] = K ;
   }
}
for ( J = 0 ; J < nfront ; J++ ) {
   if ( (K = rep[J]) != J ) {
      map[J] = map[K] ;
   }
}
/*
   -------------------------------
   get the compressed ETree object
   -------------------------------
*/
etree2 = ETree_compress(etree, mapIV) ;
/*
   -------------------------
   remap the nzeros[] vector
   -------------------------
*/
temp = IVinit(nfront, 0) ;
IVcopy(nfront, temp, nzeros) ;
IV_setSize(nzerosIV, nnew) ;
nzeros = IV_entries(nzerosIV) ;
for ( J = 0 ; J < nfront ; J++ ) {
   if ( rep[J] == J ) {
      nzeros[map[J]] = temp[J] ;
   }
}
IVfree(temp) ;
/*
   ------------------------
   free the working storage
   ------------------------
*/
IVfree(nodwghts) ;
IVfree(rep)      ;
IV_free(mapIV)   ;

return(etree2) ; }