/* util.c */
#include "../GPart.h"
#define MYDEBUG 0
/*--------------------------------------------------------------------*/
/*
----------------------------------------------------
set the component weights from the compids[] vector
created -- 95oct05, cca
modified -- 95nov29, cca
----------------------------------------------------
*/
void
GPart_setCweights (
GPart *gpart
) {
Graph *g ;
int ierr, ii, last, ncomp, now, nvtx, u, usize, v, w ;
int *compids, *cweights, *list, *uadj, *vwghts ;
/*
--------------
check the data
--------------
*/
if ( gpart == NULL ) {
fprintf(stderr, "\n fatal error in GPart_setCweights(%p)"
"\n bad input\n", gpart) ;
exit(-1) ;
}
if ( (nvtx = gpart->nvtx) <= 0 || (g = gpart->g) == NULL ) {
fprintf(stderr, "\n fatal error in GPart_setCweights(%p)"
"\n bad Gpart object\n", gpart) ;
exit(-1) ;
}
/*
----------------------------------------------------------
set the component id of all non-multisector vertices to -1
----------------------------------------------------------
*/
compids = IV_entries(&gpart->compidsIV) ;
for ( v = 0 ; v < nvtx ; v++ ) {
if ( compids[v] != 0 ) {
compids[v] = -1 ;
}
}
/*
----------------------------------------------------------
compute the number of components and set the component ids
----------------------------------------------------------
*/
list = IVinit(nvtx, -1) ;
ncomp = 0 ;
for ( v = 0 ; v < nvtx ; v++ ) {
if ( compids[v] == -1 ) {
compids[v] = ++ncomp ;
now = last = 0 ;
list[now] = v ;
while ( now <= last ) {
u = list[now++] ;
Graph_adjAndSize(g, u, &usize, &uadj) ;
for ( ii = 0 ; ii < usize ; ii++ ) {
if ( (w = uadj[ii]) < nvtx && compids[w] == -1 ) {
compids[w] = ncomp ;
list[++last] = w ;
}
}
}
}
}
/*
----------------------------
set the number of components
----------------------------
*/
gpart->ncomp = ncomp ;
/*
-------------------------
set the component weights
-------------------------
*/
IV_setSize(&gpart->cweightsIV, 1 + ncomp) ;
cweights = IV_entries(&gpart->cweightsIV) ;
IVzero(1 + ncomp, cweights) ;
if ( (vwghts = gpart->g->vwghts) != NULL ) {
for ( v = 0 ; v < nvtx ; v++ ) {
cweights[compids[v]] += vwghts[v] ;
}
} else {
for ( v = 0 ; v < nvtx ; v++ ) {
cweights[compids[v]]++ ;
}
}
/*
------------------------
free the working storage
------------------------
*/
IVfree(list) ;
return ; }
/*--------------------------------------------------------------------*/
/*
----------------------------------------------
return the number of bytes taken by the object
created -- 95oct05, cca
----------------------------------------------
*/
int
GPart_sizeOf (
GPart *gpart
) {
int nbytes ;
if ( gpart == NULL ) {
fprintf(stderr, "\n fatal error in GPart_sizeOf(%p)"
"\n bad input\n", gpart) ;
exit(-1) ;
}
nbytes = sizeof(struct _GPart) ;
nbytes += IV_size(&gpart->compidsIV) ;
nbytes += IV_size(&gpart->cweightsIV) ;
nbytes += IV_size(&gpart->vtxMapIV) ;
return(nbytes) ; }
/*--------------------------------------------------------------------*/
/*
----------------------------------------------------
return 1 if vertex is adjacent to only one domain
and fill *pdomid with the domain's id
return 0 otherwise
created -- 95oct19, cca
-------------------------------------------------
*/
int
GPart_vtxIsAdjToOneDomain (
GPart *gpart,
int v,
int *pdomid
) {
Graph *g ;
int domid, ii, nvtx, u, Vi, vsize ;
int *compids, *vadj ;
/*
---------------
check the input
---------------
*/
if ( gpart == NULL || v < 0 || (nvtx = gpart->nvtx) <= v
|| (g = gpart->g) == NULL || pdomid == NULL ) {
fprintf(stderr,
"\n fatal error in GPart_vtxIsAdjToOneDomain(%p,%d,%p)"
"\n bad input\n", gpart, v, pdomid) ;
exit(-1) ;
}
compids = IV_entries(&gpart->compidsIV) ;
/*
------------------------------------------
fill domids[] with ids of adjacent domains
------------------------------------------
*/
Graph_adjAndSize(g, v, &vsize, &vadj) ;
domid = *pdomid = -1 ;
for ( ii = 0 ; ii < vsize ; ii++ ) {
if ( (u = vadj[ii]) < nvtx && (Vi = compids[u]) > 0 ) {
if ( domid == -1 ) {
*pdomid = domid = Vi ;
} else if ( Vi != domid ) {
return(0) ;
}
}
}
if ( domid == -1 ) {
return(0) ;
} else {
return(1) ; }
}
/*--------------------------------------------------------------------*/
/*
------------------------------------------------------
return 1 if the partition has a valid vertex separator
0 otherwise
created -- 95oct18, cca
------------------------------------------------------
*/
int
GPart_validVtxSep (
GPart *gpart
) {
Graph *g ;
int icomp, ii, nvtx, v, vsize, w ;
int *compids, *vadj ;
/*
---------------
check the input
---------------
*/
if ( gpart == NULL ) {
fprintf(stderr, "\n fatal error in GPart_validVtxSep(%p)"
"\n bad input\n", gpart) ;
exit(-1) ;
}
nvtx = gpart->nvtx ;
g = gpart->g ;
compids = IV_entries(&gpart->compidsIV) ;
/*
---------------------------------------------------
loop over the vertices
check that each non-separator vertex is adjacent to
vertices only in its component or in the separator
---------------------------------------------------
*/
for ( v = 0 ; v < nvtx ; v++ ) {
if ( (icomp = compids[v]) != 0 ) {
Graph_adjAndSize(g, v, &vsize, &vadj) ;
for ( ii = 0 ; ii < vsize ; ii++ ) {
if ( (w = vadj[ii]) < nvtx ) {
if ( compids[w] != 0 && compids[w] != icomp ) {
fprintf(stderr,
"\n vertex %d, component %d, is adjacent to vertex %d, component %d",
v, icomp, w, compids[w]) ;
return(0) ;
}
}
}
}
}
return(1) ; }
/*--------------------------------------------------------------------*/
/*
-------------------------------------
return an IV object filled with the
weights of the component's boundaries
created -- 96oct21, cca
-------------------------------------
*/
IV *
GPart_bndWeightsIV (
GPart *gpart
) {
Graph *graph ;
int icomp, ii, ncomp, nvtx, v, vsize, vwght, w ;
int *bnd, *compids, *cweights, *mark, *vadj, *vwghts ;
IV *bndIV ;
/*
---------------
check the input
---------------
*/
if ( gpart == NULL || (graph = gpart->g) == NULL ) {
fprintf(stderr, "\n fatal error in GPart_bndWeightsIV(%p)"
"\n bad input\n", gpart) ;
exit(-1) ;
}
nvtx = gpart->nvtx ;
ncomp = gpart->ncomp ;
compids = IV_entries(&gpart->compidsIV) ;
cweights = IV_entries(&gpart->cweightsIV) ;
vwghts = graph->vwghts ;
bndIV = IV_new() ;
IV_init(bndIV, 1 + ncomp, NULL) ;
IV_fill(bndIV, 0) ;
bnd = IV_entries(bndIV) ;
mark = IVinit(ncomp+1, -1) ;
for ( v = 0 ; v < nvtx ; v++ ) {
if ( compids[v] == 0 ) {
vwght = (vwghts == NULL) ? 1 : vwghts[v] ;
Graph_adjAndSize(graph, v, &vsize, &vadj) ;
for ( ii = 0 ; ii < vsize ; ii++ ) {
w = vadj[ii] ;
if ( (icomp = compids[w]) != 0 && mark[icomp] != v ) {
mark[icomp] = v ;
bnd[icomp] += vwght ;
}
}
}
}
IVfree(mark) ;
return(bndIV) ; }
/*--------------------------------------------------------------------*/
syntax highlighted by Code2HTML, v. 0.9.1