/* fillFromOffsets.c */
#include "../Graph.h"
/*--------------------------------------------------------------------*/
/*
-------------------------------------------------------------------
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 ; }
/*--------------------------------------------------------------------*/
syntax highlighted by Code2HTML, v. 0.9.1