コード例 #1
0
ファイル: sortAndCompress.c プロジェクト: fransklaver/SPOOLES
/*
   ------------------------------------------------
   sort the entries in ivec[] into ascending order,
   then compress out the duplicates

   return value -- # of compressed entries

   created -- 97dec18, cca
   ------------------------------------------------
*/
int
IVsortUpAndCompress (
   int   n,
   int   ivec[]
) {
int   first, ierr, ii, key ;
/*
   ---------------
   check the input
   ---------------
*/
if ( n < 0 || ivec == NULL ) {
   fprintf(stderr, 
           "\n fatal error in IVsortAndCompress(%d,%p)"
           "\n bad input, n = %d, ivec = %p",
           n, ivec, n, ivec) ;
   spoolesFatal();
}
if ( n == 0 ) {
   return(0) ;
}
/*
   ----------------------------------
   sort the vector in ascending order
   ----------------------------------
*/
IVqsortUp(n, ivec) ;
#if MYDEBUG > 0
fprintf(stdout, "\n ivec[] after sort up") ;
IVfp80(stdout, n, ivec, 80, &ierr) ;
#endif
/*
   --------------------
   purge the duplicates
   --------------------
*/
first = 1 ;
key   = ivec[0] ;
#if MYDEBUG > 0
fprintf(stdout, "\n first = %d, key = %d, ivec[%d] = %d",
        first, key, 0, ivec[0]) ;
#endif
for ( ii = 1 ; ii < n ; ii++ ) {
#if MYDEBUG > 0
   fprintf(stdout, "\n first = %d, key = %d, ivec[%d] = %d",
           first, key, 0, ivec[0]) ;
#endif
   if ( key != ivec[ii] ) {
#if MYDEBUG > 0
      fprintf(stdout, "\n setting ivec[%d] = %d",
              first, ivec[ii]) ;
#endif
      ivec[first++] = key = ivec[ii] ;
   }
}
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
ファイル: colmapMPI.c プロジェクト: damiannz/spooles
/*
   -------------------------------------------------------------
   purpose -- after pivoting for a nonsymmetric factorization,
              some delayed columns may belong to a process other
              than its original owner. this method returns an
              IV object that maps columns to owning processes.

   created -- 98may22, cca
   -------------------------------------------------------------
*/
IV *
FrontMtx_MPI_colmapIV (
   FrontMtx   *frontmtx,
   IV         *frontOwnersIV,
   int        msglvl,
   FILE       *msgFile,
   MPI_Comm   comm
) {
int   buffersize, ii, iproc, J, myid, nDJ, neqns, nfront, nproc, 
      ncolJ, nToSend, v ;
int   *buffer, *counts, *frontOwners, *inbuffer, *outbuffer, 
      *colindJ, *colmap, *vtxToFront ;
IV    *colmapIV ;
/*
   -------------------------------------------
   get the process id and number of processors
   -------------------------------------------
*/
MPI_Comm_rank(comm, &myid) ;
MPI_Comm_size(comm, &nproc) ;
neqns      = frontmtx->neqns ;
vtxToFront = ETree_vtxToFront(frontmtx->frontETree) ;
IV_sizeAndEntries(frontOwnersIV, &nfront, &frontOwners) ;
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n\n inside FrontMtx_MPI_colmapIV()"
           "\n myid = %d, nproc = %d, nfront = %d, neqns = %d",
           myid, nproc, nfront, neqns) ;
   fflush(msgFile) ;
}
/*
   ----------------------------------------------------------
   loop through the owned fronts and store each column in an 
   owned front that was originally owned by another processor
   ----------------------------------------------------------
*/
outbuffer = IVinit(neqns, -1) ;
for ( J = nToSend = 0 ; J < nfront ; J++ ) {
   if (  frontOwners[J] == myid 
      && (nDJ = FrontMtx_frontSize(frontmtx, J)) > 0 ) {
      FrontMtx_columnIndices(frontmtx, J, &ncolJ, &colindJ) ;
      if ( msglvl > 2 ) {
         fprintf(msgFile, "\n front %d owned, nDJ = %d, ncolJ = %d",
                 J, nDJ, ncolJ) ;
         fflush(msgFile) ;
      }
      for ( ii = 0 ; ii < nDJ ; ii++ ) {
         v = colindJ[ii] ;
         if ( frontOwners[vtxToFront[v]] != myid ) {
            if ( msglvl > 2 ) {
               fprintf(msgFile, "\n column %d originally owned by %d",
                       v, frontOwners[vtxToFront[v]]) ;
               fflush(msgFile) ;
            }
            outbuffer[nToSend++] = v ;
         }
      }
   }
}
IVqsortUp(nToSend, outbuffer) ;
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n shifted vertices") ;
   IVfprintf(msgFile, nToSend, outbuffer) ;
   fflush(msgFile) ;
}
counts = IVinit(nproc, 0) ;
/*
   --------------------------------------------
   use an all-gather call to get the number of
   moved columns that are owned by each process
   --------------------------------------------
*/
MPI_Allgather((void *) &nToSend, 1, MPI_INT, counts, 1, MPI_INT, comm) ;
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n after the all-gather operation, counts") ;
   IVfprintf(msgFile, nproc, counts) ;
   fflush(msgFile) ;
}
buffersize = IVmax(nproc, counts, &iproc) ;
inbuffer   = IVinit(buffersize, -1) ;
/*
   -----------------------------------
   initialize the column map IV object
   -----------------------------------
*/
colmapIV = IV_new() ;
IV_init(colmapIV, neqns, NULL) ;
colmap = IV_entries(colmapIV) ;
IVgather(neqns, colmap, frontOwners, vtxToFront) ;
/*
   --------------------------------------------------------------
   loop over the other processes, receive vector of moved columns
   --------------------------------------------------------------
*/
for ( iproc = 0 ; iproc < nproc ; iproc++ ) {
   if ( counts[iproc] > 0 ) {
      if ( iproc == myid ) {
/*
        -------------------------------------
        send buffer vector to other processes
        -------------------------------------
*/
         if ( msglvl > 2 ) {
            fprintf(msgFile, "\n sending outbuffer to all processes") ;
            IVfprintf(msgFile, nToSend, outbuffer) ;
            fflush(msgFile) ;
         }
         MPI_Bcast(outbuffer, nToSend, MPI_INT, iproc, comm) ;
         buffer = outbuffer ;
      } else {
/*
        -----------------------------------------
        receive the vector from the other process
        -----------------------------------------
*/
         MPI_Bcast(inbuffer, counts[iproc], MPI_INT, iproc, comm) ;
         if ( msglvl > 2 ) {
            fprintf(msgFile, "\n received inbuffer from process %d",
                    iproc) ;
            IVfprintf(msgFile, counts[iproc], inbuffer) ;
            fflush(msgFile) ;
         }
         buffer = inbuffer ;
      }
/*
      -------------------------
      set the column map values
      -------------------------
*/
      for ( ii = 0 ; ii < counts[iproc] ; ii++ ) {
         v = buffer[ii] ;
         colmap[v] = iproc ;
      }
   }
}
/*
   ------------------------
   free the working storage
   ------------------------
*/
IVfree(inbuffer)  ;
IVfree(outbuffer) ;
IVfree(counts)    ;

return(colmapIV) ; }
コード例 #4
0
ファイル: misc.c プロジェクト: bialk/SPOOLES
/*
   -------------------------------------------------------------------
   make an element graph for a n1 x n2 x n3 grid with ncomp components

   created -- 95nov03, cca
   -------------------------------------------------------------------
*/
EGraph *
EGraph_make27P ( 
   int   n1, 
   int   n2, 
   int   n3, 
   int   ncomp 
) {
EGraph    *egraph ;
int       eid, icomp, ijk, ielem, jelem, kelem, m, nelem, nvtx ;
int       *list ;
/*
   ---------------
   check the input
   ---------------
*/
if ( n1 <= 0 || n2 <= 0 || n3 <= 0 || ncomp <= 0 ) {
   fprintf(stderr, "\n fatal error in EGraph_make27P(%d,%d,%d,%d)"
           "\n bad input\n", n1, n2, n3, ncomp) ;
   exit(-1) ;
}
#if MYDEBUG > 0
fprintf(stdout, "\n inside EGraph_make27P(%d,%d,%d,%d)", 
        n1, n2, n3, ncomp) ;
fflush(stdout) ;
#endif
/*
   -----------------
   create the object
   -----------------
*/
nelem = (n1 - 1)*(n2 - 1)*(n3 - 1) ;
nvtx  = n1*n2*n3*ncomp ;
egraph = EGraph_new() ;
if ( ncomp == 1 ) {
   EGraph_init(egraph, 0, nelem, nvtx, IVL_CHUNKED) ;
} else {
   EGraph_init(egraph, 1, nelem, nvtx, IVL_CHUNKED) ;
   IVfill(nvtx, egraph->vwghts, ncomp) ;
}
/*
   ----------------------------
   fill the adjacency structure
   ----------------------------
*/
list = IVinit(8*ncomp, -1) ;
for ( kelem = 0 ; kelem < n3 - 1 ; kelem++ ) {
   for ( jelem = 0 ; jelem < n2 - 1 ; jelem++ ) {
      for ( ielem = 0 ; ielem < n1 - 1 ; ielem++ ) {
         eid   = ielem + jelem*(n1-1) + kelem*(n1-1)*(n2-1);
         m   = 0 ;
         ijk = ncomp*(ielem + jelem*n1 + kelem*n1*n2) ;
         for ( icomp = 0 ; icomp < ncomp ; icomp++ ) {
            list[m++] = ijk++ ;
         }
         ijk = ncomp*(ielem + 1 + jelem*n1 + kelem*n1*n2) ;
         for ( icomp = 0 ; icomp < ncomp ; icomp++ ) {
            list[m++] = ijk++ ;
         }
         ijk = ncomp*(ielem + (jelem+1)*n1 + kelem*n1*n2) ;
         for ( icomp = 0 ; icomp < ncomp ; icomp++ ) {
            list[m++] = ijk++ ;
         }
         ijk = ncomp*(ielem + 1 + (jelem+1)*n1 + kelem*n1*n2) ;
         for ( icomp = 0 ; icomp < ncomp ; icomp++ ) {
            list[m++] = ijk++ ;
         }
         ijk = ncomp*(ielem + jelem*n1 + (kelem+1)*n1*n2) ;
         for ( icomp = 0 ; icomp < ncomp ; icomp++ ) {
            list[m++] = ijk++ ;
         }
         ijk = ncomp*(ielem + 1 + jelem*n1 + (kelem+1)*n1*n2) ;
         for ( icomp = 0 ; icomp < ncomp ; icomp++ ) {
            list[m++] = ijk++ ;
         }
         ijk = ncomp*(ielem + (jelem+1)*n1 + (kelem+1)*n1*n2) ;
         for ( icomp = 0 ; icomp < ncomp ; icomp++ ) {
            list[m++] = ijk++ ;
         }
         ijk = ncomp*(ielem + 1 + (jelem+1)*n1 + (kelem+1)*n1*n2) ;
         for ( icomp = 0 ; icomp < ncomp ; icomp++ ) {
            list[m++] = ijk++ ;
         }
         IVqsortUp(m, list) ;
         IVL_setList(egraph->adjIVL, eid, m, list) ;
      }
   }
}
IVfree(list) ;

return(egraph) ; }
コード例 #5
0
ファイル: testDrand.c プロジェクト: JuliaFEM/SPOOLES
/*--------------------------------------------------------------------*/
int
main ( int argc, char *argv[] )
/*
   ---------------------------------------------
   test the Drand random number generator object
   ---------------------------------------------
*/
{
double   ddot, dmean, param1, param2 ;
double   *dvec ;
Drand    drand ;
FILE     *msgFile ;
int      distribution, ierr, imean, msglvl, n, seed1, seed2 ;
int      *ivec ;

if ( argc != 9 ) {
   fprintf(stderr, 
"\n\n usage : testDrand msglvl msgFile "
"\n         distribution param1 param2 seed1 seed2 n"
"\n    msglvl       -- message level"
"\n    msgFile      -- message file"
"\n    distribution -- 1 for uniform(param1,param2)"
"\n                 -- 2 for normal(param1,param2)"
"\n    param1       -- first parameter"
"\n    param2       -- second parameter"
"\n    seed1        -- first random number seed"
"\n    seed2        -- second random number seed"
"\n    n            -- length of the vector"
"\n"
) ;
   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) ;
}
distribution = atoi(argv[3]) ;
if ( distribution < 1 || distribution > 2 ) {
   fprintf(stderr, "\n fatal error in testDrand"
           "\n distribution must be 1 (uniform) or 2 (normal)") ;
   exit(-1) ;
}
param1 = atof(argv[4]) ;
param2 = atof(argv[5]) ;
seed1  = atoi(argv[6]) ;
seed2  = atoi(argv[7]) ;
n      = atoi(argv[8]) ;

Drand_init(&drand) ;
Drand_setSeeds(&drand, seed1, seed2) ;
switch ( distribution ) {
case 1 : 
   fprintf(msgFile, "\n uniform in [%f,%f]", param1, param2) ;
   Drand_setUniform(&drand, param1, param2) ; 
   break ;
case 2 : 
   fprintf(msgFile, "\n normal(%f,%f)", param1, param2) ;
   Drand_setNormal(&drand, param1, param2) ; 
   break ;
}
/*
   ---------------------------------------------
   fill the integer and double precision vectors
   ---------------------------------------------
*/
dvec = DVinit(n, 0.0) ;
Drand_fillDvector(&drand, n, dvec) ;
dmean = DVsum(n, dvec)/n ;
ddot  = DVdot(n, dvec, dvec) ;
if ( msglvl > 0 ) {
   fprintf(msgFile, "\n dvec mean = %.4f, variance = %.4f",
           dmean, sqrt(fabs(ddot - n*dmean)/n)) ;
}
if ( msglvl > 1 ) {
   fprintf(msgFile, "\n dvec") ;
   DVfprintf(msgFile, n, dvec) ;
}
DVqsortUp(n, dvec) ;
if ( msglvl > 1 ) {
   fprintf(msgFile, "\n sorted dvec") ;
   DVfprintf(msgFile, n, dvec) ;
}
ivec = IVinit(n, 0) ;
Drand_fillIvector(&drand, n, ivec) ;
imean = IVsum(n, ivec)/n ;
if ( msglvl > 1 ) {
   fprintf(msgFile, "\n ivec") ;
   IVfp80(msgFile, n, ivec, 80, &ierr) ;
}
IVqsortUp(n, ivec) ;
if ( msglvl > 1 ) {
   fprintf(msgFile, "\n sorted ivec") ;
   IVfp80(msgFile, n, ivec, 80, &ierr) ;
}

fprintf(msgFile, "\n") ;

return(1) ; }
コード例 #6
0
ファイル: makeSchurComplement.c プロジェクト: bialk/SPOOLES
/*
   ----------------------------------------------------------------
   purpose -- 

   if the elimination has halted before all the stages have been 
   eliminated, then create the schur complement graph and the map 
   from the original vertices those in the schur complement graph.

   schurGraph -- Graph object to contain the schur complement graph
   VtoPhi     -- IV object to contain the map from vertices in V
                 to schur complement vertices in Phi

   created -- 97feb01, cca
   ----------------------------------------------------------------
*/
void
MSMD_makeSchurComplement (
   MSMD    *msmd,
   Graph   *schurGraph,
   IV      *VtoPhiIV
) {
int       nedge, nPhi, nvtx, totewght, totvwght ;
int       *mark, *rep, *VtoPhi, *vwghts ;
int       count, *list ;
int       ierr, ii, size, *adj ;
int       phi, psi, tag ;
IP        *ip ;
IVL       *adjIVL ;
MSMDvtx   *u, *v, *vertices, *vfirst, *vlast, *w ;
/*
   ---------------
   check the input
   ---------------
*/
if ( msmd == NULL || schurGraph == NULL || VtoPhiIV == NULL ) {
   fprintf(stderr, 
           "\n\n fatal error in MSMD_makeSchurComplement(%p,%p,%p)"
           "\n bad input\n", msmd, schurGraph, VtoPhiIV) ;
   exit(-1) ;
}
vertices = msmd->vertices ;
nvtx     = msmd->nvtx     ;
/*
   -------------------------------------
   initialize the V-to-Phi map IV object
   -------------------------------------
*/
IV_clearData(VtoPhiIV) ;
IV_setSize(VtoPhiIV, nvtx) ;
IV_fill(VtoPhiIV, -2) ;
VtoPhi = IV_entries(VtoPhiIV) ;
/*
   ---------------------------------------------
   count the number of Schur complement vertices
   ---------------------------------------------
*/
vfirst = vertices ;
vlast  = vfirst + nvtx - 1 ;
nPhi   = 0 ;
for ( v = vfirst ; v <= vlast ; v++ ) {
#if MYDEBUG > 0
   fprintf(stdout, "\n v->id = %d, v->status = %c", v->id, v->status) ;
   fflush(stdout) ;
#endif
   switch ( v->status ) {
   case 'L' :
   case 'E' :
   case 'I' :
      break ;
   case 'B' :
      VtoPhi[v->id] = nPhi++ ;
#if MYDEBUG > 0
      fprintf(stdout, ", VtoPhi[%d] = %d", v->id, VtoPhi[v->id]) ;
      fflush(stdout) ;
#endif
      break ;
   default :
      break ;
   }
}
#if MYDEBUG > 0
fprintf(stdout, "\n\n nPhi = %d", nPhi) ;
fflush(stdout) ;
#endif
/*
   ----------------------------------------------------
   get the representative vertex id for each Phi vertex
   ----------------------------------------------------
*/
rep = IVinit(nPhi, -1) ;
for ( v = vfirst ; v <= vlast ; v++ ) {
   if ( (phi = VtoPhi[v->id]) >= 0 ) {
#if MYDEBUG > 0
      fprintf(stdout, "\n rep[%d] = %d", phi, v->id) ;
      fflush(stdout) ;
#endif
      rep[phi] = v->id ;
   }
}
/*
   ------------------------------------------
   set the map for indistinguishable vertices
   ------------------------------------------
*/
for ( v = vfirst ; v <= vlast ; v++ ) {
   if ( v->status == 'I' ) {
      w = v ;
      while ( w->status == 'I' ) {
         w = w->par ;
      }
#if MYDEBUG > 0
      fprintf(stdout, "\n v = %d, status = %c, w = %d, status = %c", 
              v->id, v->status, w->id, w->status) ;
      fflush(stdout) ;
#endif
      VtoPhi[v->id] = VtoPhi[w->id] ;
   }
}
#if MYDEBUG > 0
fprintf(stdout, "\n\n VtoPhi") ;
IV_writeForHumanEye(VtoPhiIV, stdout) ;
fflush(stdout) ;
#endif
/*
   ---------------------------
   initialize the Graph object
   ---------------------------
*/
Graph_clearData(schurGraph) ;
Graph_init1(schurGraph, 1, nPhi, 0, 0, IVL_CHUNKED, IVL_CHUNKED) ;
adjIVL = schurGraph->adjIVL ;
vwghts = schurGraph->vwghts ;
#if MYDEBUG > 0
fprintf(stdout, "\n\n schurGraph initialized, nvtx = %d",
        schurGraph->nvtx) ;
fflush(stdout) ;
#endif
/*
   -------------------------------
   fill the vertex adjacency lists
   -------------------------------
*/
mark = IVinit(nPhi, -1) ;
list = IVinit(nPhi, -1) ;
nedge = totvwght = totewght = 0 ;
for ( phi = 0 ; phi < nPhi ; phi++ ) {
/*
   -----------------------------
   get the representative vertex
   -----------------------------
*/
   v = vfirst + rep[phi] ; 
#if MYDEBUG > 0
   fprintf(stdout, "\n phi = %d, v = %d", phi, v->id) ;
   fflush(stdout) ;
   MSMDvtx_print(v, stdout) ;
   fflush(stdout) ;
#endif
   count = 0 ;
   tag   = v->id ;
/*
   ---------------------------
   load self in adjacency list
   ---------------------------
*/
   mark[phi] = tag ;
   totewght += v->wght * v->wght ;
#if MYDEBUG > 0
   fprintf(stdout, "\n    mark[%d] = %d", phi, mark[phi]) ;
   fflush(stdout) ;
#endif
   list[count++] = phi ;
/*
   ----------------------------------------
   load boundary lists of adjacent subtrees 
   ----------------------------------------
*/
   for ( ip = v->subtrees ; ip != NULL ; ip = ip->next ) {
      u    = vertices + ip->val ;
      size = u->nadj ;
      adj  = u->adj  ;
#if MYDEBUG > 0
      fprintf(stdout, "\n    subtree %d :", u->id) ;
      IVfp80(stdout, size, adj, 15, &ierr) ;
      fflush(stdout) ;
#endif
      for ( ii = 0 ; ii < size ; ii++ ) {
         w = vertices + adj[ii] ;
#if MYDEBUG > 0
         fprintf(stdout, "\n       w %d, status %c, psi %d",
                 w->id, w->status, VtoPhi[w->id]) ;
         fflush(stdout) ;
#endif
         if ( (psi = VtoPhi[w->id]) != -2 && mark[psi] != tag ) {
            mark[psi] = tag ;
#if MYDEBUG > 0
            fprintf(stdout, ", mark[%d] = %d", psi, mark[psi]) ;
            fflush(stdout) ;
#endif
            list[count++] = psi ;
            totewght += v->wght * w->wght ;
         }
      }
   }
/*
   ----------------------
   load adjacent vertices 
   ----------------------
*/
   size = v->nadj ;
   adj  = v->adj  ;
   for ( ii = 0 ; ii < size ; ii++ ) {
      w = vertices + adj[ii] ;
      if ( (psi = VtoPhi[w->id]) != -2 && mark[psi] != tag ) {
         mark[psi] = tag ;
         list[count++] = psi ;
         totewght += v->wght * w->wght ;
      }
   }
/*
   ---------------------------------------------
   sort the list and inform adjacency IVL object
   ---------------------------------------------
*/
   IVqsortUp(count, list) ;
   IVL_setList(adjIVL, phi, count, list) ;
/*
   --------------------------------------
   set the vertex weight and increment 
   the total vertex weight and edge count
   --------------------------------------
*/
   vwghts[phi] =  v->wght ;
   totvwght    += v->wght ;
   nedge       += count   ;
}
schurGraph->totvwght = totvwght ;
schurGraph->nedges   = nedge    ;
schurGraph->totewght = totewght ;
/*
   ------------------------
   free the working storage
   ------------------------
*/
IVfree(list) ;
IVfree(mark) ;
IVfree(rep)  ;

return ; }
コード例 #7
0
ファイル: expand.c プロジェクト: fransklaver/SPOOLES
/*
   ---------------------------------------------------------------------
   purpose -- take a Graph object and a map to expand it, create and
              return a bigger unit weight Graph object. this is useful 
              for expanding a compressed graph into a unit weight graph.

   created -- 96mar02, cca
   ---------------------------------------------------------------------
*/
Graph *
Graph_expand (
   Graph   *g,
   int     nvtxbig,
   int     map[]
) {
Graph   *gbig ;
int     count, ii, nedge, nvtx, v, vbig, vsize, w ;
int     *head, *indices, *link, *mark, *vadj ;
IVL     *adjIVL, *adjbigIVL ;
/*
   ---------------
   check the input
   ---------------
*/
if ( g == NULL || nvtxbig <= 0 || map == NULL ) {
   fprintf(stderr, "\n fatal error in Graph_expand(%p,%d,%p)"
           "\n bad input\n", g, nvtxbig, map) ;
   spoolesFatal();
}
nvtx   = g->nvtx   ;
adjIVL = g->adjIVL ;
/*
   ----------------------------------------
   set up the linked lists for the vertices
   ----------------------------------------
*/
head = IVinit(nvtx,    -1) ;
link = IVinit(nvtxbig, -1) ;
for ( vbig = 0 ; vbig < nvtxbig ; vbig++ ) {
   v          = map[vbig] ;
   link[vbig] = head[v]   ;
   head[v]    = vbig      ;
}
/*
   --------------------------------
   create the expanded Graph object
   --------------------------------
*/
gbig = Graph_new() ;
Graph_init1(gbig, 0, nvtxbig, 0, 0, IVL_CHUNKED, IVL_CHUNKED) ;
adjbigIVL = gbig->adjIVL ;
/*
   -------------------------------------------
   fill the lists in the expanded Graph object
   -------------------------------------------
*/
indices = IVinit(nvtxbig, -1) ;
mark    = IVinit(nvtx,    -1) ;
nedge   = 0 ;
for ( v = 0 ; v < nvtx ; v++ ) {
   if ( head[v] != -1 ) {
/*
      ------------------------------
      load the indices that map to v
      ------------------------------
*/
      mark[v] = v ;
      count   = 0 ;
      for ( vbig = head[v] ; vbig != -1 ; vbig = link[vbig] ) {
         indices[count++] = vbig ;
      }
/*
      ---------------------------------------------------
      load the indices that map to vertices adjacent to v
      ---------------------------------------------------
*/
      IVL_listAndSize(adjIVL, v, &vsize, &vadj) ;
      for ( ii = 0 ; ii < vsize ; ii++ ) {
         w = vadj[ii] ;
         if ( w < nvtx && mark[w] != v ) {
            mark[w] = v ;
            for ( vbig = head[w] ; vbig != -1 ; vbig = link[vbig] ) {
               indices[count++] = vbig ;
            }
         }
      }
/*
      --------------------------------------
      sort the index list in ascending order
      --------------------------------------
*/
      IVqsortUp(count, indices) ;
/*
      -------------------------------------------------------
      each vertex in the big IVL object has its own list.
      -------------------------------------------------------
*/
      for ( vbig = head[v] ; vbig != -1 ; vbig = link[vbig] ) {
         IVL_setList(adjbigIVL, vbig, count, indices) ;
         nedge += count ;
      }
   }
}
gbig->nedges = nedge ;
/*
   ------------------------
   free the working storage
   ------------------------
*/
IVfree(head)    ;
IVfree(link)    ;
IVfree(indices) ;
IVfree(mark)    ;

return(gbig) ; }
コード例 #8
0
ファイル: fillFromOffsets.c プロジェクト: bialk/SPOOLES
/*
   -------------------------------------------------------------------
   purpose -- take an adjacency structure in the
              (offsets[neqns+1], adjncy[*]) form
              and load the Graph object

   g -- pointer to Graph object, must be initialized with nvtx = neqns
   neqns -- # of equations
   offsets -- offsets vector
   adjncy  -- big adjacency vector
      note, the adjacency for list v is found in
            adjncy[offsets[v]:offsets[v+1]-1]
      also note, offsets[] and adjncy[] must be zero based,
      if (offsets,adjncy) come from a harwell-boeing file, they use
      the fortran numbering, so each value must be decremented to
      conform with C's zero based numbering
   flag -- task flag
      flag = 0 --> just set the adjacency list for v to be that
                   found in adjncy[offsets[v]:offsets[v+1]-1]
      flag = 1 --> the input adjancency is just the upper triangle
                   (or strict upper triangle) as from a harwell-boeing
                   file. fill the Graph object with the full adjacency 
                   structure, including (v,v) edges

   created -- 96mar16, cca
   -------------------------------------------------------------------
*/
void
Graph_fillFromOffsets (
   Graph   *g,
   int     neqns,
   int     offsets[],
   int     adjncy[],
   int     flag
) {
IVL   *adjIVL ;
/*
   ---------------
   check the input
   ---------------
*/
if (  g == NULL 
   || neqns <= 0
   || offsets == NULL
   || adjncy == NULL
   || flag < 0
   || flag > 1 ) {
   fprintf(stderr, 
           "\n fatal error in Graph_fillFromOffsets(%p,%d,%p,%p,%d)"
           "\n bad input\n", g, neqns, offsets, adjncy, flag) ;
   exit(-1) ;
}
/*
   ---------------------------
   initialize the Graph object
   ---------------------------
*/
Graph_init1(g, 0, neqns, 0, 0, IVL_CHUNKED, IVL_CHUNKED) ;
adjIVL = g->adjIVL ;
if ( flag == 0 ) {
   int   count, ii, nedge, v, w ;
   int   *list, *mark ;
/*
   ----------------------------------------------
   simple map, do not enforce symmetric structure
   ----------------------------------------------
*/
   list = IVinit(neqns, -1) ;
   mark = IVinit(neqns, -1) ;
   for ( v = 0, nedge = 0 ; v < neqns ; v++ ) {
      count = 0 ;
      for ( ii = offsets[v] ; ii < offsets[v+1] ; ii++ ) {
         w = adjncy[ii] ;
if ( v == neqns ) {
   fprintf(stdout, "\n hey there!! (v,w) = (%d,%d)", v, w) ;
}
         if ( 0 <= w && w < neqns && mark[w] != v ) {
            list[count++] = w ;
            mark[w] = v ;
         }
      }
      if ( mark[v] != v ) {
         list[count++] = v ;
         mark[v] = v ;
      }
      IVqsortUp(count, list) ;
      IVL_setList(adjIVL, v, count, list) ;
      nedge += count ;
   }
   g->totvwght = neqns ;
   g->totewght = g->nedges = nedge ;
/*
   ----------------------------
   now free the working storage
   ----------------------------
*/
   IVfree(list) ;
   IVfree(mark) ;
} else {
   int   ii, jj, u, v, vsize, w ;
   int   *head, *link, *list, *sizes, *vadj ;
   int   **p_adj ;
/*
   -------------------------------------------
   enforce symmetric structure and (v,v) edges
   make a first pass to check the input
   -------------------------------------------
*/
fprintf(stdout, "\n offsets") ;
IVfprintf(stdout, neqns+1, offsets) ;
   for ( v = 0 ; v < neqns ; v++ ) {
fprintf(stdout, "\n v = %d", v) ;
      for ( ii = offsets[v] ; ii < offsets[v+1] ; ii++ ) {
fprintf(stdout, "\n    w = %d", adjncy[ii]) ;
         if ( (w = adjncy[ii]) < v || neqns <= w ) {
            fprintf(stderr, 
               "\n fatal error in Graph_fillFromOffsets(%p,%d,%p,%p,%d)"
               "\n list %d, entry %d\n", g, neqns, offsets, adjncy,
               flag, v, w) ;
            exit(-1) ;
         }
      }
   }
   head  = IVinit(neqns, -1) ;
   link  = IVinit(neqns, -1) ;
   list  = IVinit(neqns, -1) ;
   sizes = IVinit(neqns, 0) ;
   p_adj = PIVinit(neqns) ;
   for ( v = 0 ; v < neqns ; v++ ) {
      vsize = 0 ;
/*
      -------------------------
      add edges to vertices < v
      -------------------------
*/
      while ( (u = head[v]) != -1 ) {
         head[v] = link[u] ;
         list[vsize++] = u ;
         if ( --sizes[u] > 0 ) {
            w = *(++p_adj[u]) ;
            link[u] = head[w] ;
            head[w] = u ;
         }
      }
/*
      -----------------
      add in edge (v,v)
      -----------------
*/
      list[vsize++] = v ;
      jj = vsize ;
/*
      -------------------------
      add edges to vertices > v
      -------------------------
*/
      for ( ii = offsets[v] ; ii < offsets[v+1] ; ii++ ) {
         if ( (w = adjncy[ii]) != v ) {
            list[vsize++] = w ;
         }
      }
/*
      ---------------------
      sort and set the list
      ---------------------
*/
      IVqsortUp(vsize, list) ;
      IVL_setList(adjIVL, v, vsize, list) ;
/*
      --------------------------------------------------
      link v to first vertex in its lists greater than v
      --------------------------------------------------
*/
      if ( jj < vsize ) {
         IVL_listAndSize(adjIVL, v, &vsize, &vadj) ;
         w        = vadj[jj]   ;
         link[v]  = head[w]    ;
         head[w]  = v          ;
         sizes[v] = vsize - jj ;
         p_adj[v] = &vadj[jj]  ;
      }
      g->nedges += vsize ;
   }
   g->totvwght = neqns     ;
   g->totewght = g->nedges ;
/*
   ----------------------------
   now free the working storage
   ----------------------------
*/
   IVfree(head)   ;
   IVfree(link)   ;
   IVfree(list)   ;
   IVfree(sizes)  ;
   PIVfree(p_adj) ;
}
return ; }
コード例 #9
0
ファイル: identifyWideSep.c プロジェクト: bialk/SPOOLES
/*
   --------------------------------------------------------------
   identify the wide separator
 
   return -- IV object that holds the nodes in the wide separator

   created -- 96oct21, cca
   --------------------------------------------------------------
*/
IV *
GPart_identifyWideSep (
   GPart   *gpart,
   int     nlevel1,
   int     nlevel2
) {
FILE    *msgFile ;
Graph   *g ;
int     count, first, ierr, ii, ilevel, last, msglvl,
        nfirst, now, nsecond, nsep, nvtx, v, vsize, w ;
int     *compids, *list, *mark, *vadj ;
IV      *sepIV ;
/*
   ---------------
   check the input
   ---------------
*/
if (  gpart == NULL || (g = gpart->g) == NULL 
   || nlevel1 < 0 || nlevel2 < 0 ) {
  fprintf(stderr, "\n fatal error in GPart_identifyWideSep(%p,%d,%d)"
           "\n bad input\n", gpart, nlevel1, nlevel2) ;
   exit(-1) ;
}
g       = gpart->g ;
compids = IV_entries(&gpart->compidsIV) ;
nvtx    = g->nvtx ;
mark    = IVinit(nvtx, -1) ;
list    = IVinit(nvtx, -1) ;
msglvl  = gpart->msglvl ;
msgFile = gpart->msgFile ;
/*
   --------------------------------------
   load the separator nodes into the list
   --------------------------------------
*/
nsep = 0 ;
for ( v = 0 ; v < nvtx ; v++ ) {
   if ( compids[v] == 0 ) {
      list[nsep++] = v ;
      mark[v] = 0 ;
   }
}
count = nsep ;
if ( msglvl > 1 ) {
   fprintf(msgFile, 
           "\n GPart_identifyWideSep : %d separator nodes loaded", 
           count) ;
   fflush(msgFile) ;
}
if ( msglvl > 2 ) {
   IVfp80(msgFile, nsep, list, 80, &ierr) ;
   fflush(msgFile) ;
}
/*
   ----------------------------------------------
   loop over the number of levels out that form 
   the wide separator towards the first component
   ----------------------------------------------
*/
if ( nlevel1 >= 1 ) {
   first = count ;
   if ( msglvl > 2 ) {
      fprintf(msgFile, "\n\n level = %d, first = %d", 1, first) ;
      fflush(msgFile) ;
   }
   for ( now = 0 ; now < nsep ; now++ ) {
      v = list[now] ;
      Graph_adjAndSize(g, v, &vsize, &vadj) ;
      if ( msglvl > 2 ) {
         fprintf(msgFile, "\n %d : ", v) ;
         IVfp80(msgFile, vsize, vadj, 80, &ierr) ;
         fflush(msgFile) ;
      }
      for ( ii = 0 ; ii < vsize ; ii++ ) {
         w = vadj[ii] ;
         if ( w < nvtx && mark[w] == -1 && compids[w] == 1 ) {
            if ( msglvl > 2 ) {
               fprintf(msgFile, "\n    adding %d to list", w) ;
               fflush(msgFile) ;
            }
            list[count++] = w ;
            mark[w] = 1 ;
         }
      }
   }
   now = first ;
   for ( ilevel = 2 ; ilevel <= nlevel1 ; ilevel++ ) {
      if ( msglvl > 2 ) {
         fprintf(msgFile, "\n\n level = %d, first = %d", ilevel, first);
         fflush(msgFile) ;
      }
      last = count - 1 ;
      while ( now <= last ) {
         v = list[now++] ;
         Graph_adjAndSize(g, v, &vsize, &vadj) ;
         if ( msglvl > 2 ) {
            fprintf(msgFile, "\n %d : ", v) ;
            IVfp80(msgFile, vsize, vadj, 80, &ierr) ;
            fflush(msgFile) ;
         }
         for ( ii = 0 ; ii < vsize ; ii++ ) {
            w = vadj[ii] ;
            if ( w < nvtx && mark[w] == -1 && compids[w] == 1 ) {
               if ( msglvl > 2 ) {
                  fprintf(msgFile, "\n    adding %d to list", w) ;
                  fflush(msgFile) ;
               }
               mark[w] = 1 ;
               list[count++] = w ;
            }
         }
      }
   }
}
nfirst = count - nsep ;
if ( msglvl > 2 ) {
   fprintf(msgFile, 
           "\n %d nodes added from the first component", nfirst) ;
   fflush(msgFile) ;
}
if ( msglvl > 3 ) {
   IVfp80(msgFile, nfirst, &list[nsep], 80, &ierr) ;
   fflush(msgFile) ;
}
/*
   ----------------------------------------------
   loop over the number of levels out that form 
   the wide separator towards the second component
   ----------------------------------------------
*/
if ( nlevel2 >= 1 ) {
   first = count ;
   if ( msglvl > 2 ) {
      fprintf(msgFile, "\n\n level = %d, first = %d", 1, first) ;
      fflush(msgFile) ;
   }
   for ( now = 0 ; now < nsep ; now++ ) {
      v = list[now] ;
      Graph_adjAndSize(g, v, &vsize, &vadj) ;
      if ( msglvl > 2 ) {
         fprintf(msgFile, "\n %d : ", v) ;
         IVfp80(msgFile, vsize, vadj, 80, &ierr) ;
         fflush(msgFile) ;
      }
      for ( ii = 0 ; ii < vsize ; ii++ ) {
         w = vadj[ii] ;
         if ( w < nvtx && mark[w] == -1 && compids[w] == 2 ) {
            if ( msglvl > 2 ) {
               fprintf(msgFile, "\n    adding %d to list", w) ;
               fflush(msgFile) ;
            }
            list[count++] = w ;
            mark[w] = 2 ;
         }
      }
   }
   now = first ;
   for ( ilevel = 2 ; ilevel <= nlevel2 ; ilevel++ ) {
      if ( msglvl > 2 ) {
         fprintf(msgFile, "\n\n level = %d, first = %d", ilevel, first);
         fflush(msgFile) ;
      }
      last = count - 1 ;
      while ( now <= last ) {
         v = list[now++] ;
         Graph_adjAndSize(g, v, &vsize, &vadj) ;
         if ( msglvl > 2 ) {
            fprintf(msgFile, "\n %d : ", v) ;
            IVfp80(msgFile, vsize, vadj, 80, &ierr) ;
            fflush(msgFile) ;
         }
         for ( ii = 0 ; ii < vsize ; ii++ ) {
            w = vadj[ii] ;
            if ( w < nvtx && mark[w] == -1 && compids[w] == 2 ) {
               if ( msglvl > 2 ) {
                  fprintf(msgFile, "\n    adding %d to list", w) ;
                  fflush(msgFile) ;
               }
               mark[w] = 2 ;
               list[count++] = w ;
            }
         }
      }
   }
}
nsecond = count - nsep - nfirst ;
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n %d nodes added from the second component", 
           nsecond) ;
   fflush(msgFile) ;
}
if ( msglvl > 3 ) {
   IVfp80(msgFile, nsecond, &list[nsep + nfirst], 80, &ierr) ;
   fflush(msgFile) ;
}
IVqsortUp(count, list) ;
/*
   --------------------
   create the IV object
   --------------------
*/
sepIV = IV_new() ;
IV_init(sepIV, count, NULL) ;
IVcopy(count, IV_entries(sepIV), list) ;
if ( msglvl > 1 ) {
   fprintf(msgFile, "\n separator has %d nodes", IV_size(sepIV)) ;
   fflush(msgFile) ;
}
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n sepIV") ;
   IV_writeForHumanEye(sepIV, msgFile) ;
   fflush(msgFile) ;
}
/*
   ------------------------
   free the working storage
   ------------------------
*/
IVfree(mark) ;
IVfree(list) ;
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n return from GPart_identifyWideSep") ;
   fflush(msgFile) ;
}
 
return(sepIV) ; }
コード例 #10
0
ファイル: test_assmbChv.c プロジェクト: JuliaFEM/SPOOLES
/*--------------------------------------------------------------------*/
int
main ( int argc, char *argv[] )
/*
   ------------------------------------
   test the Chv_assembleChv() method.

   created -- 98apr18, cca
   ------------------------------------
*/
{
Chv     *chvI, *chvJ ;
double   imag, real, t1, t2 ;
double   *entriesI, *entriesJ ;
Drand    *drand ;
FILE     *msgFile ;
int      ierr, ii, irow, jcol,
         lastcol, msglvl, ncolI, ncolJ, nDI, nDJ, nentI, nentJ, 
         nrowI, nrowJ, nUI, nUJ, seed, symflag, type ;
int      *colindI, *colindJ, *rowindI, *rowindJ, *temp ;

if ( argc != 10 ) {
   fprintf(stdout, 
"\n\n usage : %s msglvl msgFile nDJ nUJ nDI nUI type symflag seed "
"\n    msglvl  -- message level"
"\n    msgFile -- message file"
"\n    nDJ     -- # of rows and columns in the (1,1) block"
"\n    nUJ     -- # of columns in the (1,2) block"
"\n    nDI     -- # of rows and columns in the (1,1) block"
"\n    nUI     -- # of columns in the (1,2) block"
"\n    type    -- entries type"
"\n       1 --> real"
"\n       2 --> complex"
"\n    symflag -- symmetry flag"
"\n       0 --> symmetric"
"\n       1 --> hermitian"
"\n       2 --> nonsymmetric"
"\n    seed    -- random number seed"
"\n", argv[0]) ;
   return(0) ;
}
if ( (msglvl = atoi(argv[1])) < 0 ) {
   fprintf(stderr, "\n message level must be positive\n") ;
   exit(-1) ;
}
if ( strcmp(argv[2], "stdout") == 0 ) {
   msgFile = stdout ;
} else if ( (msgFile = fopen(argv[2], "a")) == NULL ) {
   fprintf(stderr, "\n unable to open file %s\n", argv[2]) ;
   return(-1) ;
}
nDJ     = atoi(argv[3]) ;
nUJ     = atoi(argv[4]) ;
nDI     = atoi(argv[5]) ;
nUI     = atoi(argv[6]) ;
type    = atoi(argv[7]) ;
symflag = atoi(argv[8]) ;
seed    = atoi(argv[9]) ;
if (  nDJ <= 0 || nUJ < 0 
   || nDI <= 0 || nUI < 0 
   || nDI >= nDJ || (nDI + nUI) >= (nDJ + nUJ)
   || nUI >= (nDJ + nUJ - nDI)
   || (  symflag != SPOOLES_SYMMETRIC
      && symflag != SPOOLES_HERMITIAN
      && symflag != SPOOLES_NONSYMMETRIC) ) {
   fprintf(stderr, "\n invalid input"
      "\n nDJ = %d, nUJ = %d, nDI = %d, nUI = %d, symflag = %d\n",
           nDJ, nUJ, nDI, nUI, symflag) ;
   exit(-1) ;
}
/*
   --------------------------------------
   initialize the random number generator
   --------------------------------------
*/
drand = Drand_new() ;
Drand_init(drand) ;
Drand_setSeed(drand, seed) ;
Drand_setUniform(drand, -1.0, 1.0) ;
/*
   ----------------------------
   initialize the ChvJ object
   ----------------------------
*/
MARKTIME(t1) ;
chvJ = Chv_new() ;
Chv_init(chvJ, 0, nDJ, nUJ, nUJ, type, symflag) ;
MARKTIME(t2) ;
fprintf(msgFile, "\n %% CPU : %.3f to initialize chv object",
        t2 - t1) ;
fflush(msgFile) ;
Chv_columnIndices(chvJ, &ncolJ, &colindJ) ;
temp = IVinit(2*(nDJ+nUJ), -1) ;
IVramp(2*(nDJ+nUJ), temp, 0, 1) ;
IVshuffle(2*(nDJ+nUJ), temp, ++seed) ;
IVcopy(ncolJ, colindJ, temp) ;
IVfree(temp) ;
IVqsortUp(ncolJ, colindJ) ;
if ( CHV_IS_NONSYMMETRIC(chvJ) ) {
   Chv_rowIndices(chvJ, &nrowJ, &rowindJ) ;
   IVcopy(nrowJ, rowindJ, colindJ) ;
}
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n %% column indices") ;
   IVfprintf(msgFile, ncolJ, colindJ) ;
}
lastcol = colindJ[ncolJ-1] ;
nentJ = Chv_nent(chvJ) ;
entriesJ = Chv_entries(chvJ) ;
if ( CHV_IS_REAL(chvJ) ) {
   Drand_fillDvector(drand, nentJ, entriesJ) ;
} else if ( CHV_IS_COMPLEX(chvJ) ) {
   Drand_fillDvector(drand, 2*nentJ, entriesJ) ;
}
if ( CHV_IS_HERMITIAN(chvJ) ) {
/*
   ---------------------------------------------------------
   hermitian example, set imaginary part of diagonal to zero
   ---------------------------------------------------------
*/
   for ( irow = 0 ; irow < nDJ ; irow++ ) {
      Chv_complexEntry(chvJ, irow, irow, &real, &imag) ;
      Chv_setComplexEntry(chvJ, irow, irow, real, 0.0) ;
   }
}
/*
   ---------------------------
   initialize the ChvI object
   ---------------------------
*/
chvI = Chv_new() ;
Chv_init(chvI, 0, nDI, nUI, nUI, type, symflag) ;
Chv_columnIndices(chvI, &ncolI, &colindI) ;
temp = IVinit(ncolJ, -1) ;
IVramp(ncolJ, temp, 0, 1) ;
while ( 1 ) {
   IVshuffle(ncolJ, temp, ++seed) ;
   IVqsortUp(ncolI, temp) ;
   if ( temp[0] < nDJ ) {
      break ;
   }
}
for ( ii = 0 ; ii < ncolI ; ii++ ) {
   colindI[ii] = colindJ[temp[ii]] ;
}
IVfree(temp) ;
if ( CHV_IS_NONSYMMETRIC(chvI) ) {
   Chv_rowIndices(chvI, &nrowI, &rowindI) ;
   IVcopy(nrowI, rowindI, colindI) ;
}
nentI = Chv_nent(chvI) ;
entriesI = Chv_entries(chvI) ;
if ( CHV_IS_REAL(chvI) ) {
   Drand_fillDvector(drand, nentI, entriesI) ;
} else if ( CHV_IS_COMPLEX(chvI) ) {
   Drand_fillDvector(drand, 2*nentI, entriesI) ;
}
if ( CHV_IS_HERMITIAN(chvI) ) {
/*
   ---------------------------------------------------------
   hermitian example, set imaginary part of diagonal to zero
   ---------------------------------------------------------
*/
   for ( irow = 0 ; irow < nDI ; irow++ ) {
      Chv_complexEntry(chvI, irow, irow, &real, &imag) ;
      Chv_setComplexEntry(chvI, irow, irow, real, 0.0) ;
   }
}
/*
   --------------------------------------------------
   write out the two chevron objects to a matlab file
   --------------------------------------------------
*/
if ( msglvl > 1 ) {
   fprintf(msgFile, "\n a = zeros(%d,%d) ;", lastcol+1, lastcol+1) ;
   Chv_writeForMatlab(chvJ, "a", msgFile) ;
   fprintf(msgFile, "\n b = zeros(%d,%d) ;", lastcol+1, lastcol+1) ;
   Chv_writeForMatlab(chvI, "b", msgFile) ;
}
/*
   ---------------------------------------------
   assemble the chvI object into the chvJ object
   ---------------------------------------------
*/
Chv_assembleChv(chvJ, chvI) ;
if ( msglvl > 1 ) {
   fprintf(msgFile, "\n %% after assembly") ;
   fprintf(msgFile, "\n c = zeros(%d,%d) ;", lastcol+1, lastcol+1) ;
   Chv_writeForMatlab(chvJ, "c", msgFile) ;
}
/*
   -----------------
   compute the error
   -----------------
*/
fprintf(msgFile, "\n max(max(abs(c - (b + a))))") ;
/*
   ------------------------
   free the working storage
   ------------------------
*/
Chv_free(chvJ) ;
Chv_free(chvI) ;
Drand_free(drand) ;

fprintf(msgFile, "\n") ;

return(1) ; }
コード例 #11
0
ファイル: domSegMap.c プロジェクト: damiannz/spooles
/*
   --------------------------------------------------------------------
   fill *pndom with ndom, the number of domains.
   fill *pnseg with nseg, the number of segments.
   domains are numbered in [0, ndom), segments in [ndom,ndom+nseg).

   return -- an IV object that contains the map 
             from vertices to segments

   created -- 99feb29, cca
   --------------------------------------------------------------------
*/
IV *
GPart_domSegMap (
   GPart   *gpart,
   int     *pndom,
   int     *pnseg
) {
FILE    *msgFile ;
Graph   *g ;
int     adjdom, count, d, first, ierr, ii, jj1, jj2, last, ndom, 
        msglvl, nextphi, nPhi, nPsi, nV, phi, phi0, phi1, phi2, phi3, 
        psi, sigma, size, size0, size1, size2, v, vsize, w ;
int     *adj, *adj0, *adj1, *adj2, *compids, *dmark, *dsmap, *head, 
        *link, *list, *offsets, *PhiToPsi, *PhiToV, *PsiToSigma, 
        *vadj, *VtoPhi ;
IV      *dsmapIV ;
IVL     *PhiByPhi, *PhiByPowD, *PsiByPowD ;
/*
   --------------------
   set the initial time
   --------------------
*/
icputimes = 0 ;
MARKTIME(cputimes[icputimes]) ;
/*
   ---------------
   check the input
   ---------------
*/
if (  gpart == NULL 
   || (g = gpart->g) == NULL 
   || pndom == NULL
   || pnseg == NULL ) {
   fprintf(stderr, "\n fatal error in GPart_domSegMap(%p,%p,%p)"
           "\n bad input\n", gpart, pndom, pnseg) ;
   exit(-1) ;
}
compids = IV_entries(&gpart->compidsIV) ;
msglvl  = gpart->msglvl  ;
msgFile = gpart->msgFile ;
/*
   ------------------------
   create the map IV object
   ------------------------
*/
nV = g->nvtx ;
dsmapIV = IV_new() ;
IV_init(dsmapIV, nV, NULL) ;
dsmap = IV_entries(dsmapIV) ;
/*
   ----------------------------------
   check compids[] and get the number 
   of domains and interface vertices
   ----------------------------------
*/
icputimes++ ;
MARKTIME(cputimes[icputimes]) ;
ndom = nPhi = 0 ;
for ( v = 0 ; v < nV ; v++ ) {
   if ( (d = compids[v]) < 0 ) {
      fprintf(stderr, 
              "\n fatal error in GPart_domSegMap(%p,%p,%p)"
              "\n compids[%d] = %d\n", gpart, pndom, pnseg,
              v, compids[v]) ;
      exit(-1) ;
   } else if ( d == 0 ) {
      nPhi++ ;
   } else if ( ndom < d ) {
      ndom = d ;
   }
}
*pndom = ndom ;
if ( msglvl > 1 ) {
   fprintf(msgFile, "\n\n Inside GPart_domSegMap") ;
   fprintf(msgFile, "\n %d domains, %d Phi vertices", ndom, nPhi) ;
}
if ( ndom == 1 ) {
   IVfill(nV, dsmap, 0) ;
   *pndom = 1 ;
   *pnseg = 0 ;
   return(dsmapIV) ;
}
/*
   --------------------------------
   get the maps
   PhiToV : [0,nPhi) |---> [0,nV)
   VtoPhi : [0,nV)   |---> [0,nPhi)
   --------------------------------
*/
icputimes++ ;
MARKTIME(cputimes[icputimes]) ;
PhiToV = IVinit(nPhi, -1) ;
VtoPhi = IVinit(nV,   -1) ;
for ( v = 0, phi = 0 ; v < nV ; v++ ) {
   if ( (d = compids[v]) == 0 ) {
      PhiToV[phi] = v ;
      VtoPhi[v]   = phi++ ;
   }
}
if ( phi != nPhi ) {
   fprintf(stderr, 
           "\n fatal error in GPart_domSegMap(%p,%p,%p)"
           "\n phi = %d != %d = nPhi\n", 
           gpart, pndom, pnseg, phi, nPhi) ;
   exit(-1) ;
}
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n PhiToV(%d) :", nPhi) ;
   IVfp80(msgFile, nPhi, PhiToV, 15, &ierr) ;
   fflush(msgFile) ;
}
if ( msglvl > 3 ) {
   fprintf(msgFile, "\n VtoPhi(%d) :", nV) ;
   IVfp80(msgFile, nV, VtoPhi, 15, &ierr) ;
   fflush(msgFile) ;
}
/*
   ---------------------------------------------------
   create an IVL object, PhiByPowD, to hold lists from 
   the interface vertices to their adjacent domains
   ---------------------------------------------------
*/
icputimes++ ;
MARKTIME(cputimes[icputimes]) ;
dmark = IVinit(ndom+1, -1) ;
if ( nPhi >= ndom ) {
   list = IVinit(nPhi, -1) ;
} else {
   list = IVinit(ndom, -1) ;
}
PhiByPowD = IVL_new() ;
IVL_init1(PhiByPowD, IVL_CHUNKED, nPhi) ;
for ( phi = 0 ; phi < nPhi ; phi++ ) {
   v = PhiToV[phi] ;
   Graph_adjAndSize(g, v, &vsize, &vadj) ;
/*
if ( phi == 0 ) {
   int   ierr ;
   fprintf(msgFile, "\n adj(%d,%d) = ", v, phi) ;
   IVfp80(msgFile, vsize, vadj, 15, &ierr) ;
   fflush(msgFile) ;
}
*/
   count = 0 ;
   for ( ii = 0 ; ii < vsize ; ii++ ) {
      if ( (w = vadj[ii]) < nV  
        && (d = compids[w]) > 0 
        && dmark[d] != phi ) {
         dmark[d] = phi ;
         list[count++] = d ;
      }
   }
   if ( count > 0 ) {
      IVqsortUp(count, list) ;
      IVL_setList(PhiByPowD, phi, count, list) ;
   }
}
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n PhiByPowD : interface x adjacent domains") ;
   IVL_writeForHumanEye(PhiByPowD, msgFile) ;
   fflush(msgFile) ;
}
/*
   -------------------------------------------------------
   create an IVL object, PhiByPhi to hold lists
   from the interface vertices to interface vertices.
   (s,t) are in the list if (s,t) is an edge in the graph
   and s and t do not share an adjacent domain
   -------------------------------------------------------
*/
icputimes++ ;
MARKTIME(cputimes[icputimes]) ;
PhiByPhi = IVL_new() ;
IVL_init1(PhiByPhi, IVL_CHUNKED, nPhi) ;
offsets = IVinit(nPhi,  0)  ;
head    = IVinit(nPhi, -1) ;
link    = IVinit(nPhi, -1) ;
for ( phi1 = 0 ; phi1 < nPhi ; phi1++ ) {
   count = 0 ;
   if ( msglvl > 2 ) {
      v = PhiToV[phi1] ;
      Graph_adjAndSize(g, v, &vsize, &vadj) ;
      fprintf(msgFile, "\n checking out phi = %d, v = %d", phi1, v) ;
      fprintf(msgFile, "\n adj(%d) : ", v) ;
      IVfp80(msgFile, vsize, vadj, 10, &ierr) ;
   }
/*
   -------------------------------------------------------------
   get (phi1, phi0) edges that were previously put into the list
   -------------------------------------------------------------
*/
   if ( msglvl > 3 ) {
      if ( head[phi1] == -1 ) {
         fprintf(msgFile, "\n    no previous edges") ;
      } else {
         fprintf(msgFile, "\n    previous edges :") ;
      }
   }
   for ( phi0 = head[phi1] ; phi0 != -1 ; phi0 = nextphi ) {
      if ( msglvl > 3 ) {
         fprintf(msgFile, " %d", phi0) ;
      }
      nextphi = link[phi0] ;
      list[count++] = phi0 ;
      IVL_listAndSize(PhiByPhi, phi0, &size0, &adj0) ;
      if ( (ii = ++offsets[phi0]) < size0 ) {
/*
         ----------------------------
         link phi0 into the next list
         ----------------------------
*/
         phi2       = adj0[ii]   ;
         link[phi0] = head[phi2] ;
         head[phi2] = phi0       ;
      }
   }
/*
   --------------------------
   get new edges (phi1, phi2)
   --------------------------
*/
   IVL_listAndSize(PhiByPowD, phi1, &size1, &adj1) ;
   v = PhiToV[phi1] ;
   Graph_adjAndSize(g, v, &vsize, &vadj) ;
   for ( ii = 0 ; ii < vsize ; ii++ ) {
      if (  (w = vadj[ii]) < nV 
         && compids[w] == 0 
         && (phi2 = VtoPhi[w]) > phi1 ) {
         if ( msglvl > 3 ) {
            fprintf(msgFile, "\n    checking out phi2 = %d", phi2) ;
         }
/*
         --------------------------------------------------
         see if phi1 and phi2 have a common adjacent domain
         --------------------------------------------------
*/
         IVL_listAndSize(PhiByPowD, phi2, &size2, &adj2) ;
         adjdom = 0 ;
         jj1 = jj2 = 0 ;
         while ( jj1 < size1 && jj2 < size2 ) {
            if ( adj1[jj1] < adj2[jj2] ) {
               jj1++ ;
            } else if ( adj1[jj1] > adj2[jj2] ) {
               jj2++ ;
            } else {
               if ( msglvl > 3 ) {
                  fprintf(msgFile, ", common adj domain %d", adj1[jj1]) ;
               }
               adjdom = 1 ;
               break ;
            }
         }
         if ( adjdom == 0 ) {
            if ( msglvl > 3 ) {
               fprintf(msgFile, ", no adjacent domain") ;
            }
            list[count++] = phi2 ;
         }
      }
   }
   if ( count > 0 ) {
/*
      ---------------------
      set the list for phi1
      ---------------------
*/
      IVqsortUp(count, list) ;
      IVL_setList(PhiByPhi, phi1, count, list) ;
      if ( msglvl > 2 ) {
         fprintf(msgFile, "\n    edge list for %d :", phi1) ;
         IVfp80(msgFile, count, list, 15, &ierr) ;
      }
      for ( ii = 0, phi2 = -1 ; ii < count ; ii++ ) {
         if ( list[ii] > phi1 ) {
            offsets[phi1] = ii ;
            phi2 = list[ii] ;
            break ;
         }
      }
      if ( phi2 != -1 ) {
      if ( msglvl > 2 ) {
         fprintf(msgFile, 
                 "\n       linking %d into list for %d", phi1, phi2) ;
      }
         link[phi1] = head[phi2] ;
         head[phi2] = phi1       ;
      }
/*
      phi2 = list[0] ;
      link[phi1] = head[phi2] ;
      head[phi2] = phi1 ;
*/
   }
}
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n PhiByPhi : interface x interface") ;
   IVL_writeForHumanEye(PhiByPhi, msgFile) ;
   fflush(msgFile) ;
}
/*
   --------------------
   get the PhiToPsi map
   --------------------
*/
icputimes++ ;
MARKTIME(cputimes[icputimes]) ;
PhiToPsi = IVinit(nPhi, -1) ;
nPsi = 0 ;
for ( phi = 0 ; phi < nPhi ; phi++ ) {
   if ( PhiToPsi[phi] == -1 ) {
/*
      ---------------------------
      phi not yet mapped to a psi
      ---------------------------
*/
      first = last = 0 ;
      list[0] = phi ;
      PhiToPsi[phi] = nPsi ;
      while ( first <= last ) {
         phi2 = list[first++] ;
         IVL_listAndSize(PhiByPhi, phi2, &size, &adj) ;
         for ( ii = 0 ; ii < size ; ii++ ) {
            phi3 = adj[ii] ;
            if ( PhiToPsi[phi3] == -1 ) {
               PhiToPsi[phi3] = nPsi ;
               list[++last] = phi3 ; 
            }
         }
      }
      nPsi++ ;
   }
}
if ( msglvl > 1 ) {
   fprintf(msgFile, "\n nPsi = %d", nPsi) ;
   fflush(msgFile) ;
}
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n PhiToPsi(%d) :", nPhi) ;
   IVfp80(msgFile, nPhi, PhiToPsi, 15, &ierr) ;
   fflush(msgFile) ;
}
/*
   ---------------------------------
   create an IVL object, Psi --> 2^D
   ---------------------------------
*/
icputimes++ ;
MARKTIME(cputimes[icputimes]) ;
IVfill(nPsi, head, -1) ;
IVfill(nPhi, link, -1) ;
for ( phi = 0 ; phi < nPhi ; phi++ ) {
   psi = PhiToPsi[phi] ;
   link[phi] = head[psi] ;
   head[psi] =   phi     ;
}
PsiByPowD = IVL_new() ;
IVL_init1(PsiByPowD, IVL_CHUNKED, nPsi) ;
IVfill(ndom+1, dmark, -1) ;
for ( psi = 0 ; psi < nPsi ; psi++ ) {
   count = 0 ;
   for ( phi = head[psi] ; phi != -1 ; phi = link[phi] ) {
      v = PhiToV[phi] ;
      Graph_adjAndSize(g, v, &size, &adj) ;
      for ( ii = 0 ; ii < size ; ii++ ) {
         if (  (w = adj[ii]) < nV
            && (d = compids[w]) > 0 
            && dmark[d] != psi ) {
            dmark[d]      = psi ;
            list[count++] =  d  ;
         }
      }
   }
   if ( count > 0 ) {
      IVqsortUp(count, list) ;
      IVL_setList(PsiByPowD, psi, count, list) ;
   }
}
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n PsiByPowD(%d) :", nPhi) ;
   IVL_writeForHumanEye(PsiByPowD, msgFile) ;
   fflush(msgFile) ;
}
icputimes++ ;
MARKTIME(cputimes[icputimes]) ;
/*
   -------------------------------------
   now get the map Psi |---> Sigma that 
   is the equivalence map over PhiByPowD
   -------------------------------------
*/
icputimes++ ;
MARKTIME(cputimes[icputimes]) ;
PsiToSigma = IVL_equivMap1(PsiByPowD) ;
*pnseg = 1 + IVmax(nPsi, PsiToSigma, &ii) ;
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n nSigma = %d", *pnseg) ;
   fprintf(msgFile, "\n PsiToSigma(%d) :", nPhi) ;
   IVfp80(msgFile, nPsi, PsiToSigma, 15, &ierr) ;
   fflush(msgFile) ;
}
/*
   --------------------------------------------------------------
   now fill the map from the vertices to the domains and segments
   --------------------------------------------------------------
*/
icputimes++ ;
MARKTIME(cputimes[icputimes]) ;
for ( v = 0 ; v < nV ; v++ ) {
   if ( (d = compids[v]) > 0 ) {
      dsmap[v] = d - 1 ;
   } else {
      phi      = VtoPhi[v] ;
      psi      = PhiToPsi[phi] ;
      sigma    = PsiToSigma[psi] ;
      dsmap[v] = ndom + sigma ;
   }
}
/*
   ------------------------
   free the working storage
   ------------------------
*/
icputimes++ ;
MARKTIME(cputimes[icputimes]) ;
IVL_free(PhiByPhi)  ;
IVL_free(PhiByPowD) ;
IVL_free(PsiByPowD) ;
IVfree(PhiToV)      ;
IVfree(VtoPhi)      ;
IVfree(dmark)       ;
IVfree(list)        ;
IVfree(PhiToPsi)    ;
IVfree(head)        ;
IVfree(link)        ;
IVfree(offsets)     ;
IVfree(PsiToSigma)  ;
icputimes++ ;
MARKTIME(cputimes[icputimes]) ;
if ( msglvl > 1 ) {
   fprintf(msgFile, "\n domain/segment map timings split") ;
   fprintf(msgFile, 
   "\n %9.5f : create the DSmap object"
   "\n %9.5f : get numbers of domain and interface vertices"
   "\n %9.5f : generate PhiToV and VtoPhi"
   "\n %9.5f : generate PhiByPowD"
   "\n %9.5f : generate PhiByPhi"
   "\n %9.5f : generate PhiToPsi"
   "\n %9.5f : generate PsiByPowD"
   "\n %9.5f : generate PsiToSigma"
   "\n %9.5f : generate dsmap"
   "\n %9.5f : free working storage"
   "\n %9.5f : total time",
   cputimes[1] - cputimes[0],
   cputimes[2] - cputimes[1],
   cputimes[3] - cputimes[2],
   cputimes[4] - cputimes[3],
   cputimes[5] - cputimes[4],
   cputimes[6] - cputimes[5],
   cputimes[7] - cputimes[6],
   cputimes[8] - cputimes[7],
   cputimes[9] - cputimes[8],
   cputimes[10] - cputimes[9],
   cputimes[11] - cputimes[0]) ;
}

return(dsmapIV) ; }
コード例 #12
0
ファイル: makeGraphs.c プロジェクト: fransklaver/SPOOLES
/*
   -----------------------------------------------------------
   purpose -- return the Y by Y graph where (y1,y2) is an edge
              if there exists a x in X such that (x,y1) and
              (x,y2) are edges in the bipartite graph.

   created -- 95dec07, cca
   -----------------------------------------------------------
*/
Graph *
BPG_makeGraphYbyY (
   BPG   *bpg
) {
Graph   *graph, *gYbyY ;
int     count, ii, jj, nX, nY, x, xsize, y, ysize, z ;
int     *list, *mark, *xadj, *yadj ;
/*
   ---------------
   check the input
   ---------------
*/
if ( bpg == NULL ) {
   fprintf(stdout, "\n fatal error in BPG_makeGraphXbyX(%p)"
           "\n bad input\n", bpg) ;
   spoolesFatal();
}
/*
   ----------------------
   check for quick return
   ----------------------
*/
if ( (graph = bpg->graph) == NULL || (nY = bpg->nY) <= 0 ) {
   return(NULL) ;
}
nX = bpg->nX ;
/*
   --------------------
   initialize the graph
   --------------------
*/
gYbyY = Graph_new() ;
Graph_init1(gYbyY, graph->type, nY, 0, 0, IVL_CHUNKED, IVL_CHUNKED) ;
/*
   --------------
   fill the graph
   --------------
*/
mark = IVinit(nY, -1) ;
list = IVinit(nY, -1) ;
for ( y = 0 ; y < nY ; y++ ) {
   Graph_adjAndSize(graph, nX + y, &ysize, &yadj) ;
   mark[y] = y ;
   for ( ii = 0, count = 0 ; ii < ysize ; ii++ ) {
      x = yadj[ii] ;
      Graph_adjAndSize(graph, x, &xsize, &xadj) ;
      for ( jj = 0 ; jj < xsize ; jj++ ) {
         z = xadj[jj] ;
         if ( mark[z] != y ) {
            mark[z] = y ;
            list[count++] = z ;
         }
      }
   }
   if ( count > 0 ) {
      IVqsortUp(count, list) ;
      IVL_setList(gYbyY->adjIVL, nX + y, count, list) ;
   }
}
IVfree(list) ;
IVfree(mark) ;
/*
   ---------------------------------------
   set vertex weight vector if appropriate
   ---------------------------------------
*/
if ( graph->type % 2 == 1 ) {
   IVcopy(nY, gYbyY->vwghts, graph->vwghts + nX) ;
}

return(gYbyY) ; }
コード例 #13
0
ファイル: test_update.c プロジェクト: fransklaver/SPOOLES
/*--------------------------------------------------------------------*/
int
main ( int argc, char *argv[] )
/*
   -------------------------------------
   test the Chv_update{H,S,N}() methods.
   T := T - U^T * D * U
   T := T - U^H * D * U
   T := T - L   * D * U

   created -- 98apr23, cca
   -------------------------------------
*/
{
Chv     *chvT ;
SubMtx     *mtxD, *mtxL, *mtxU ;
double   imag, ops, real, t1, t2 ;
Drand    *drand ;
DV       *tempDV ;
FILE     *msgFile ;
int      irow, msglvl, ncolT, nDT, ncolU, nentT, nentU, nrowD, 
         nrowL, nrowT, offset, seed, size, sparsityflag, symflag, type ;
int      *colindT, *colindU, *ivec, *rowindL, *rowindT ;

if ( argc != 13 ) {
   fprintf(stdout, 
           "\n\n usage : %s msglvl msgFile type symflag sparsityflag"
           "\n         ncolT ncolU nrowD nentU offset seed"
           "\n    msglvl  -- message level"
           "\n    msgFile -- message file"
           "\n    type    -- entries type"
           "\n       1 -- real"
           "\n       2 -- complex"
           "\n    symflag -- type of matrix U"
           "\n       0 -- symmetric"
           "\n       1 -- hermitian"
           "\n       2 -- nonsymmetric"
           "\n    sparsityflag -- dense or sparse"
           "\n       0 -- dense"
           "\n       1 -- sparse"
           "\n    ncolT   -- # of rows and columns in matrix T"
           "\n    nDT     -- # of internal rows and columns in matrix T"
           "\n    ncolU   -- # of rows and columns in matrix U"
           "\n    nrowD   -- # of rows and columns in matrix D"
           "\n    nentU   -- # of entries in matrix U"
           "\n    offset  -- distance between D_I and T"
           "\n    seed    -- random number seed"
           "\n", argv[0]) ;
   return(0) ;
}
if ( (msglvl = atoi(argv[1])) < 0 ) {
   fprintf(stderr, "\n message level must be positive\n") ;
   spoolesFatal();
}
if ( strcmp(argv[2], "stdout") == 0 ) {
   msgFile = stdout ;
} else if ( (msgFile = fopen(argv[2], "a")) == NULL ) {
   fprintf(stderr, "\n unable to open file %s\n", argv[2]) ;
   return(-1) ;
}
type         = atoi(argv[3]) ;
symflag      = atoi(argv[4]) ;
sparsityflag = atoi(argv[5]) ;
ncolT        = atoi(argv[6]) ;
nDT          = atoi(argv[7]) ;
ncolU        = atoi(argv[8]) ;
nrowD        = atoi(argv[9]) ;
nentU        = atoi(argv[10]) ;
offset       = atoi(argv[11]) ;
seed         = atoi(argv[12]) ;
fprintf(msgFile, "\n %% %s:"
        "\n %% msglvl       = %d"
        "\n %% msgFile      = %s"
        "\n %% type         = %d"
        "\n %% symflag      = %d"
        "\n %% sparsityflag = %d"
        "\n %% ncolT        = %d"
        "\n %% nDT          = %d"
        "\n %% ncolU        = %d"
        "\n %% nrowD        = %d"
        "\n %% nentU        = %d"
        "\n %% offset       = %d"
        "\n %% seed         = %d",
        argv[0], msglvl, argv[2], type, symflag, sparsityflag, 
        ncolT, nDT, ncolU, nrowD, nentU, offset, seed) ;
/*
   -----------------------------
   check for errors in the input
   -----------------------------
*/
if (  (type != SPOOLES_REAL 
       && type != SPOOLES_COMPLEX) 
   || (symflag != SPOOLES_SYMMETRIC 
       && symflag != SPOOLES_HERMITIAN 
       && symflag != SPOOLES_NONSYMMETRIC) 
   || (sparsityflag < 0 || sparsityflag > 1)
   || ncolT <= 0 || ncolU > (ncolT + offset) || nrowD <= 0 ) {
   fprintf(stderr, "\n invalid input\n") ;
   spoolesFatal();
}
/*
   --------------------------------------
   initialize the random number generator
   --------------------------------------
*/
drand = Drand_new() ;
Drand_init(drand) ;
Drand_setSeed(drand, ++seed) ;
Drand_setNormal(drand, 0.0, 1.0) ;
/*
   -----------------------
   get a vector of indices
   -----------------------
*/
size = nrowD + offset + ncolT ;
ivec = IVinit(size, -1) ;
IVramp(size, ivec, 0, 1) ;
/*
   ----------------------------
   initialize the T Chv object
   ----------------------------
*/
fprintf(msgFile, "\n\n %% symflag = %d", symflag) ;
MARKTIME(t1) ;
chvT = Chv_new() ;
Chv_init(chvT, 0, nDT, ncolT - nDT, ncolT - nDT, type, symflag) ;
nentT = Chv_nent(chvT) ;
if ( CHV_IS_REAL(chvT) ) {
   Drand_fillDvector(drand, nentT, Chv_entries(chvT)) ;
} else if ( CHV_IS_COMPLEX(chvT) ) {
   Drand_fillDvector(drand, 2*nentT, Chv_entries(chvT)) ;
}
Chv_columnIndices(chvT, &ncolT, &colindT) ;
IVcopy(ncolT, colindT, ivec + nrowD + offset) ;
if ( CHV_IS_NONSYMMETRIC(chvT) ) {
   Chv_rowIndices(chvT, &nrowT, &rowindT) ;
   IVcopy(nrowT, rowindT, colindT) ;
}
IVfree(ivec) ;
if ( CHV_IS_HERMITIAN(chvT) ) {
   fprintf(msgFile, "\n\n %% hermitian\n") ;
/*
   ---------------------------------------------------------
   hermitian example, set imaginary part of diagonal to zero
   ---------------------------------------------------------
*/
   for ( irow = 0 ; irow < nDT ; irow++ ) {
      Chv_complexEntry(chvT, irow, irow, &real, &imag) ;
      Chv_setComplexEntry(chvT, irow, irow, real, 0.0) ;
   }
}
MARKTIME(t2) ;
fprintf(msgFile, "\n %% CPU : %.3f to initialize chvT Chv object",
        t2 - t1) ;
fprintf(msgFile, "\n T = zeros(%d,%d); ", size, size) ;
Chv_writeForMatlab(chvT, "T", msgFile) ;
/*
   ---------------------------
   initialize the D Mtx object
   ---------------------------
*/
MARKTIME(t1) ;
mtxD = SubMtx_new() ;
if ( CHV_IS_REAL(chvT) ) {
   if ( CHV_IS_SYMMETRIC(chvT) ) {
      SubMtx_initRandom(mtxD, SPOOLES_REAL, SUBMTX_BLOCK_DIAGONAL_SYM,
                      0, 0, nrowD, nrowD, nrowD*nrowD, ++seed) ;
   } else {
      SubMtx_initRandom(mtxD, SPOOLES_REAL, SUBMTX_DIAGONAL, 
                      0, 0, nrowD, nrowD, nrowD*nrowD, ++seed) ;
   }
} else if ( CHV_IS_COMPLEX(chvT) ) {
   if ( CHV_IS_HERMITIAN(chvT) ) {
      SubMtx_initRandom(mtxD,SPOOLES_COMPLEX,SUBMTX_BLOCK_DIAGONAL_HERM,
                      0, 0, nrowD, nrowD, nrowD*nrowD, ++seed) ;
   } else if ( CHV_IS_SYMMETRIC(chvT) ) {
      SubMtx_initRandom(mtxD,SPOOLES_COMPLEX, SUBMTX_BLOCK_DIAGONAL_SYM,
                      0, 0, nrowD, nrowD, nrowD*nrowD, ++seed) ;
   } else {
      SubMtx_initRandom(mtxD, SPOOLES_COMPLEX, SUBMTX_DIAGONAL, 
                      0, 0, nrowD, nrowD, nrowD*nrowD, ++seed) ;
   }
}
MARKTIME(t2) ;
fprintf(msgFile, "\n %% CPU : %.3f to initialize D SubMtx object",
        t2 - t1) ;
fprintf(msgFile, "\n D = zeros(%d,%d) ;", nrowD, nrowD) ;
SubMtx_writeForMatlab(mtxD, "D", msgFile) ;
/*
   ----------------------------
   initialize the U SubMtx object
   ----------------------------
*/
MARKTIME(t1) ;
mtxU = SubMtx_new() ;
if ( CHV_IS_REAL(chvT) ) {
   if ( sparsityflag == 0 ) {
      SubMtx_initRandom(mtxU, SPOOLES_REAL, SUBMTX_DENSE_COLUMNS, 
                      0, 0, nrowD, ncolU, nentU, ++seed) ;
   } else {
      SubMtx_initRandom(mtxU, SPOOLES_REAL, SUBMTX_SPARSE_COLUMNS, 
                      0, 0, nrowD, ncolU, nentU, ++seed) ;
   }
} else if ( CHV_IS_COMPLEX(chvT) ) {
   if ( sparsityflag == 0 ) {
      SubMtx_initRandom(mtxU, SPOOLES_COMPLEX, SUBMTX_DENSE_COLUMNS, 
                      0, 0, nrowD, ncolU, nentU, ++seed) ;
   } else {
      SubMtx_initRandom(mtxU, SPOOLES_COMPLEX, SUBMTX_SPARSE_COLUMNS, 
                      0, 0, nrowD, ncolU, nentU, ++seed) ;
   }
}
ivec = IVinit(offset + ncolT, -1) ;
IVramp(offset + ncolT, ivec, nrowD, 1) ;
IVshuffle(offset + ncolT, ivec, ++seed) ;
SubMtx_columnIndices(mtxU, &ncolU, &colindU) ;
IVcopy(ncolU, colindU, ivec) ;
IVqsortUp(ncolU, colindU) ;
IVfree(ivec) ;
MARKTIME(t2) ;
fprintf(msgFile, "\n %% CPU : %.3f to initialize U SubMtx object",
        t2 - t1) ;
fprintf(msgFile, "\n U = zeros(%d,%d) ;", nrowD, size) ;
SubMtx_writeForMatlab(mtxU, "U", msgFile) ;
if ( CHV_IS_NONSYMMETRIC(chvT) ) {
/*
   ----------------------------
   initialize the L SubMtx object
   ----------------------------
*/
   MARKTIME(t1) ;
   mtxL = SubMtx_new() ;
   if ( CHV_IS_REAL(chvT) ) {
      if ( sparsityflag == 0 ) {
         SubMtx_initRandom(mtxL, SPOOLES_REAL, SUBMTX_DENSE_ROWS,
                         0, 0, ncolU, nrowD, nentU, ++seed) ;
      } else {
         SubMtx_initRandom(mtxL, SPOOLES_REAL, SUBMTX_SPARSE_ROWS,
                         0, 0, ncolU, nrowD, nentU, ++seed) ;
      }
   } else if ( CHV_IS_COMPLEX(chvT) ) {
      if ( sparsityflag == 0 ) {
         SubMtx_initRandom(mtxL, SPOOLES_COMPLEX, SUBMTX_DENSE_ROWS,
                         0, 0, ncolU, nrowD, nentU, ++seed) ;
      } else {
         SubMtx_initRandom(mtxL, SPOOLES_COMPLEX, SUBMTX_SPARSE_ROWS,
                         0, 0, ncolU, nrowD, nentU, ++seed) ;
      }
   }
   SubMtx_rowIndices(mtxL, &nrowL, &rowindL) ;
   IVcopy(nrowL, rowindL, colindU) ;
   MARKTIME(t2) ;
   fprintf(msgFile, "\n %% CPU : %.3f to initialize L SubMtx object",
           t2 - t1) ;
   fprintf(msgFile, "\n L = zeros(%d,%d) ;", size, nrowD) ;
   SubMtx_writeForMatlab(mtxL, "L", msgFile) ;
} else {
   mtxL = NULL ;
}
/*
   --------------------------------
   compute the matrix-matrix update
   --------------------------------
*/
tempDV = DV_new() ;
ops = 8*nrowD*nrowD*ncolU ;
if ( CHV_IS_SYMMETRIC(chvT) ) {
   Chv_updateS(chvT, mtxD, mtxU, tempDV) ;
} else if ( CHV_IS_HERMITIAN(chvT) ) {
   Chv_updateH(chvT, mtxD, mtxU, tempDV) ;
} else if ( CHV_IS_NONSYMMETRIC(chvT) ) {
   Chv_updateN(chvT, mtxL, mtxD, mtxU, tempDV) ;
}
MARKTIME(t2) ;
fprintf(msgFile, "\n %% CPU : %.3f to compute m-m, %.3f mflops",
        t2 - t1, ops*1.e-6/(t2 - t1)) ;
if ( msglvl > 1 ) {
   fprintf(msgFile, "\n\n %% Z Chv object") ;
   fprintf(msgFile, "\n Z = zeros(%d,%d); ", size, size) ;
   Chv_writeForMatlab(chvT, "Z", msgFile) ;
   fflush(msgFile) ;
}
/*
   -----------------
   check with matlab
   -----------------
*/
if ( msglvl > 1 ) {
   if ( CHV_IS_HERMITIAN(chvT) ) {
      fprintf(msgFile, "\n\n B  =  ctranspose(U) * D * U ;") ;
   } else if ( CHV_IS_SYMMETRIC(chvT) ) {
      fprintf(msgFile, "\n\n B  =  transpose(U) * D * U ;") ;
   } else {
      fprintf(msgFile, "\n\n B  =  L * D * U ;") ;
   }
   fprintf(msgFile, 
           "\n\n for irow = 1:%d"
           "\n      for jcol = 1:%d"
           "\n         if T(irow,jcol) ~= 0.0"
           "\n            T(irow,jcol) = T(irow,jcol) - B(irow,jcol) ;"
           "\n         end"
           "\n      end"
           "\n   end"
           "\n emtx   = abs(Z - T) ;",
           size, size) ;
   fprintf(msgFile, "\n\n maxabs = max(max(emtx)) ") ;
   fflush(msgFile) ;
}
/*
   ------------------------
   free the working storage
   ------------------------
*/
if ( mtxL != NULL ) {
   SubMtx_free(mtxL) ;
}
Chv_free(chvT) ;
SubMtx_free(mtxD) ;
SubMtx_free(mtxU) ;
DV_free(tempDV) ;
Drand_free(drand) ;

fprintf(msgFile, "\n") ;

return(1) ; }
コード例 #14
0
ファイル: test_addChevron.c プロジェクト: JuliaFEM/SPOOLES
/*--------------------------------------------------------------------*/
int
main ( int argc, char *argv[] )
/*
   ---------------------------------------
   test the Chv_addChevron() method.

   created -- 98apr18, cca
   ---------------------------------------
*/
{
Chv     *chv ;
double   alpha[2] ;
double   imag, real, t1, t2 ;
double   *chvent, *entries ;
Drand    *drand ;
FILE     *msgFile ;
int      chvsize, count, ichv, ierr, ii, iloc, irow, jcol,
         lastcol, msglvl, ncol, nD, nent, nL, nrow, nU, 
         off, seed, symflag, type, upper ;
int      *chvind, *colind, *keys, *rowind, *temp ;

if ( argc != 10 ) {
   fprintf(stdout, 
           "\n\n usage : %s msglvl msgFile nD nU type symflag seed "
           "\n         alphareal alphaimag"
           "\n    msglvl  -- message level"
           "\n    msgFile -- message file"
           "\n    nD      -- # of rows and columns in the (1,1) block"
           "\n    nU      -- # of columns in the (1,2) block"
           "\n    type    -- entries type"
           "\n       1 --> real"
           "\n       2 --> complex"
           "\n    symflag -- symmetry flag"
           "\n       0 --> symmetric"
           "\n       1 --> hermitian"
           "\n       2 --> nonsymmetric"
           "\n    seed    -- random number seed"
           "\n    alpha   -- scaling parameter"
           "\n", argv[0]) ;
   return(0) ;
}
if ( (msglvl = atoi(argv[1])) < 0 ) {
   fprintf(stderr, "\n message level must be positive\n") ;
   exit(-1) ;
}
if ( strcmp(argv[2], "stdout") == 0 ) {
   msgFile = stdout ;
} else if ( (msgFile = fopen(argv[2], "a")) == NULL ) {
   fprintf(stderr, "\n unable to open file %s\n", argv[2]) ;
   return(-1) ;
}
nD       = atoi(argv[3]) ;
nU       = atoi(argv[4]) ;
type     = atoi(argv[5]) ;
symflag  = atoi(argv[6]) ;
seed     = atoi(argv[7]) ;
alpha[0] = atof(argv[8]) ;
alpha[1] = atof(argv[9]) ;
if (  nD <= 0 || nU < 0 || symflag < 0 || symflag > 2 ) {
   fprintf(stderr, "\n invalid input"
           "\n nD = %d, nU = %d, symflag = %d\n", nD, nU, symflag) ;
   exit(-1) ;
}
fprintf(msgFile, "\n alpha = %12.4e + %12.4e*i ;", alpha[0], alpha[1]) ;
nL = nU ;
/*
   --------------------------------------
   initialize the random number generator
   --------------------------------------
*/
drand = Drand_new() ;
Drand_init(drand) ;
Drand_setSeed(drand, seed) ;
Drand_setUniform(drand, -1.0, 1.0) ;
/*
   ----------------------------
   initialize the Chv object
   ----------------------------
*/
MARKTIME(t1) ;
chv = Chv_new() ;
Chv_init(chv, 0, nD, nL, nU, type, symflag) ;
MARKTIME(t2) ;
fprintf(msgFile, "\n %% CPU : %.3f to initialize chv object",
        t2 - t1) ;
fflush(msgFile) ;
Chv_columnIndices(chv, &ncol, &colind) ;
temp = IVinit(2*(nD+nU), -1) ;
IVramp(2*(nD+nU), temp, 0, 1) ;
IVshuffle(2*(nD+nU), temp, ++seed) ;
IVcopy(ncol, colind, temp) ;
IVqsortUp(ncol, colind) ;
if ( CHV_IS_NONSYMMETRIC(chv) ) {
   Chv_rowIndices(chv, &nrow, &rowind) ;
   IVcopy(nrow, rowind, colind) ;
}
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n %% column indices") ;
   IVfprintf(msgFile, ncol, colind) ;
}
lastcol = colind[ncol-1] ;
nent = Chv_nent(chv) ;
entries = Chv_entries(chv) ;
if ( CHV_IS_REAL(chv) ) {
   Drand_fillDvector(drand, nent, entries) ;
} else if ( CHV_IS_COMPLEX(chv) ) {
   Drand_fillDvector(drand, 2*nent, entries) ;
}
if ( CHV_IS_HERMITIAN(chv) ) {
/*
   ---------------------------------------------------------
   hermitian example, set imaginary part of diagonal to zero
   ---------------------------------------------------------
*/
   for ( irow = 0 ; irow < nD ; irow++ ) {
      Chv_complexEntry(chv, irow, irow, &real, &imag) ;
      Chv_setComplexEntry(chv, irow, irow, real, 0.0) ;
   }
}

if ( msglvl > 1 ) {
   fprintf(msgFile, "\n a = zeros(%d,%d) ;", lastcol+1, lastcol+1) ;
   Chv_writeForMatlab(chv, "a", msgFile) ;
}
/*
   --------------------------------------------------
   fill a chevron with random numbers and indices
   that are a subset of a front's, as in the assembly
   of original matrix entries.
   --------------------------------------------------
*/
Drand_setUniform(drand, 0, nD) ;
iloc = (int) Drand_value(drand) ;
ichv = colind[iloc] ;
if ( CHV_IS_SYMMETRIC(chv) || CHV_IS_HERMITIAN(chv) ) {
   upper = nD - iloc + nU ;
} else {
   upper = 2*(nD - iloc) - 1 + nL + nU ;
}
Drand_setUniform(drand, 1, upper) ;
chvsize = (int) Drand_value(drand) ;
fprintf(msgFile, "\n %% iloc = %d, ichv = %d, chvsize = %d", 
        iloc, ichv, chvsize) ;
chvind  = IVinit(chvsize, -1) ;
chvent  = DVinit(2*chvsize, 0.0) ;
Drand_setNormal(drand, 0.0, 1.0) ;
if ( CHV_IS_REAL(chv) ) {
   Drand_fillDvector(drand, chvsize, chvent) ;
} else if ( CHV_IS_COMPLEX(chv) ) {
   Drand_fillDvector(drand, 2*chvsize, chvent) ;
}
keys    = IVinit(upper+1, -1) ;
keys[0] = 0 ;
if ( CHV_IS_SYMMETRIC(chv) || CHV_IS_HERMITIAN(chv) ) {
   for ( ii = iloc + 1, count = 1 ; ii < nD + nU ; ii++ ) {
      keys[count++] = colind[ii] - ichv ;
   }
} else {
   for ( ii = iloc + 1, count = 1 ; ii < nD + nU ; ii++ ) {
      keys[count++] =   colind[ii] - ichv ;
      keys[count++] = - colind[ii] + ichv ;
   }
}
if ( msglvl > 3 ) {
   fprintf(msgFile, "\n %% iloc = %d, ichv = %d", iloc, ichv) ;
   fprintf(msgFile, "\n %% upper = %d", upper) ;
   fprintf(msgFile, "\n %% chvsize = %d", chvsize) ;
   fprintf(msgFile, "\n %% initial keys") ;
   IVfprintf(msgFile, count, keys) ;
}
   IVshuffle(count, keys, ++seed) ;
if ( msglvl > 3 ) {
   fprintf(msgFile, "\n %% shuffled keys") ;
   IVfp80(msgFile, count, keys, 80, &ierr) ;
}
IVcopy(chvsize, chvind, keys) ;
if ( CHV_IS_REAL(chv) ) {
   IVDVqsortUp(chvsize, chvind, chvent) ;
} else if ( CHV_IS_COMPLEX(chv) ) {
   IVZVqsortUp(chvsize, chvind, chvent) ;
}
if ( msglvl > 3 ) {
   fprintf(msgFile, "\n %% chvind") ;
   IVfprintf(msgFile, chvsize, chvind) ;
}
if ( CHV_IS_HERMITIAN(chv) ) {
   for ( ii = 0 ; ii < chvsize ; ii++ ) {
      if ( chvind[ii] == 0 ) {
         chvent[2*ii+1] = 0.0 ;
      }
   }
}
if ( msglvl > 1 ) {
   fprintf(msgFile, "\n b = zeros(%d,%d) ;", lastcol+1, lastcol+1) ;
   if ( CHV_IS_REAL(chv) ) {
      if ( CHV_IS_SYMMETRIC(chv) ) {
         for ( ii = 0 ; ii < chvsize ; ii++ ) {
            off = chvind[ii] ;
            fprintf(msgFile, "\n b(%d,%d) = %20.12e ;",
                    colind[iloc]+1, colind[iloc]+off+1, chvent[ii]) ;
            fprintf(msgFile, "\n b(%d,%d) = %20.12e ;",
                    colind[iloc]+off+1, colind[iloc]+1, chvent[ii]) ;
         }
      } else {
         for ( ii = 0 ; ii < chvsize ; ii++ ) {
            off = chvind[ii] ;
            if ( off > 0 ) {
               fprintf(msgFile, "\n b(%d,%d) = %20.12e ;",
                       colind[iloc]+1, colind[iloc]+off+1, chvent[ii]) ;
            } else {
               fprintf(msgFile, "\n b(%d,%d) = %20.12e ;",
                       colind[iloc]-off+1, colind[iloc]+1, chvent[ii]) ;
            }
         }
      }
   } else if ( CHV_IS_COMPLEX(chv) ) {
      if ( CHV_IS_SYMMETRIC(chv) || CHV_IS_HERMITIAN(chv) ) {
         for ( ii = 0 ; ii < chvsize ; ii++ ) {
            off = chvind[ii] ;
            fprintf(msgFile, "\n b(%d,%d) = %20.12e + %20.12e*i;",
                    colind[iloc]+1, colind[iloc]+off+1,
                    chvent[2*ii], chvent[2*ii+1]) ;
            if ( CHV_IS_HERMITIAN(chv) ) {
               fprintf(msgFile, "\n b(%d,%d) = %20.12e + %20.12e*i;",
                       colind[iloc]+off+1, colind[iloc]+1, 
                       chvent[2*ii], -chvent[2*ii+1]) ;
            } else {
               fprintf(msgFile, "\n b(%d,%d) = %20.12e + %20.12e*i;",
                       colind[iloc]+off+1, colind[iloc]+1, 
                       chvent[2*ii], chvent[2*ii+1]) ;
            }
         }
      } else {
         for ( ii = 0 ; ii < chvsize ; ii++ ) {
            off = chvind[ii] ;
            if ( off > 0 ) {
               fprintf(msgFile, "\n b(%d,%d) = %20.12e + %20.12e*i;",
                       colind[iloc]+1, colind[iloc]+off+1,
                       chvent[2*ii], chvent[2*ii+1]) ;
            } else {
               fprintf(msgFile, "\n b(%d,%d) = %20.12e + %20.12e*i;",
                       colind[iloc]-off+1, colind[iloc]+1, 
                       chvent[2*ii], chvent[2*ii+1]) ;
            }
         }
      }
   }
}
/*
   ------------------------------------
   add the chevron into the Chv object
   ------------------------------------
*/
Chv_addChevron(chv, alpha, ichv, chvsize, chvind, chvent) ;
if ( msglvl > 1 ) {
   fprintf(msgFile, "\n %% after adding the chevron") ;
   fprintf(msgFile, "\n c = zeros(%d,%d) ;", lastcol+1, lastcol+1) ;
   Chv_writeForMatlab(chv, "c", msgFile) ;
}
/*
   -----------------
   compute the error
   -----------------
*/
fprintf(msgFile, "\n max(max(abs(c - (a + alpha*b))))") ;
/*
   ------------------------
   free the working storage
   ------------------------
*/
Chv_free(chv) ;
Drand_free(drand) ;
IVfree(temp) ;
IVfree(chvind) ;
DVfree(chvent) ;
IVfree(keys) ;

fprintf(msgFile, "\n") ;

return(1) ; }
コード例 #15
0
ファイル: mkAdjGraph.c プロジェクト: fransklaver/SPOOLES
/*
   ----------------------------------------------------
   create a Graph object that holds the adjacency graph 
   of the assembled elements. 

   created -- 95nov03, cca
   ----------------------------------------------------
*/
Graph *
EGraph_mkAdjGraph ( 
   EGraph   *egraph 
) {
int     elem, esize, i, nelem, nvtx, v, vsize, w ;
int     *eind, *head, *link, *marker, *offsets, *vind ;
IVL     *eadjIVL, *gadjIVL ;
Graph   *graph ;
/*
   ---------------
   check the input
   ---------------
*/
if ( egraph == NULL || (eadjIVL = egraph->adjIVL) == NULL ) {
   fprintf(stderr, "\n fatal error in EGraph_mkAdjGraph(%p)"
           "\n bad input\n", egraph) ;
   spoolesFatal();
}
nelem  = egraph->nelem  ;
nvtx   = egraph->nvtx   ;
/*
   --------------------------------
   set up the linked list structure
   --------------------------------
*/
head    = IVinit(nvtx,  -1) ;
link    = IVinit(nelem, -1) ;
offsets = IVinit(nelem,  0) ;
/*
   -----------------------------------------------------------
   sort the vertices in each element list into ascending order
   and link them into their first vertex
   -----------------------------------------------------------
*/
for ( elem = 0 ; elem < nelem ; elem++ ) {
   IVL_listAndSize(eadjIVL, elem, &esize, &eind) ;
   if ( esize > 0 ) {
      IVqsortUp(esize, eind) ;
      v          = eind[0] ;
      link[elem] = head[v] ;
      head[v]    = elem    ;
   }
}
/*
   ---------------------------
   create the new Graph object
   ---------------------------
*/
graph = Graph_new() ;
Graph_init1(graph, egraph->type, nvtx, 0, 0, IVL_CHUNKED, IVL_CHUNKED) ;
gadjIVL = graph->adjIVL ;
/*
   ----------------------
   loop over the vertices
   ----------------------
*/
vind   = IVinit(nvtx, -1) ;
marker = IVinit(nvtx, -1) ;
for ( v = 0 ; v < nvtx ; v++ ) {
/*
   ---------------------------------
   loop over the supporting elements
   ---------------------------------
*/
   vsize = 0 ;
   vind[vsize++] = v ;
   marker[v]     = v ;
   while ( (elem = head[v]) != -1 ) {
/*
fprintf(stdout, "\n    checking out element %d :", jelem) ;
*/
      head[v] = link[elem] ;
      IVL_listAndSize(eadjIVL, elem, &esize, &eind) ;
      for ( i = 0 ; i < esize ; i++ ) {
         w = eind[i] ;
         if ( marker[w] != v ) {
            marker[w]     = v ;
            vind[vsize++] = w ;
         }
      }
      if ( (i = ++offsets[elem]) < esize ) {
         w          = eind[i] ;
         link[elem] = head[w] ;
         head[w]    = elem    ;
      }
   }
   IVqsortUp(vsize, vind) ;
   IVL_setList(gadjIVL, v, vsize, vind) ;
}
graph->nedges = gadjIVL->tsize ;
if ( egraph->type == 0 ) {
   graph->totvwght = nvtx ;
} else if ( egraph->type == 1 ) {
/*
   ------------------------------
   fill the vertex weights vector
   ------------------------------
*/
   IVcopy(nvtx, graph->vwghts, egraph->vwghts) ;
   graph->totvwght = IVsum(nvtx, graph->vwghts) ;
}
graph->totewght = graph->nedges ;
/*
   ------------------------
   free the working storage
   ------------------------
*/
IVfree(head)    ;
IVfree(link)    ;
IVfree(marker)  ;
IVfree(vind)    ;
IVfree(offsets) ;

return(graph) ; }
コード例 #16
0
ファイル: findInodes.c プロジェクト: damiannz/spooles
/*
   ------------------------------------------------------------------
   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 ; }