1 /*  compress.c  */
2 
3 #include "../Graph.h"
4 
5 #define MYDEBUG 0
6 #define MYTRACE 0
7 
8 /*--------------------------------------------------------------------*/
9 /*
10    ---------------------------------------------------------------
11    given a graph g and a fine-to-coarse map vector *mapIV,
12    return a compressed graph with type coarseType.
13    note, the compressed graph will have no trivial boundary
14          even if the original graph did have a boundary.
15 
16    created -- 96mar02, cca
17    ---------------------------------------------------------------
18 */
19 Graph *
Graph_compress2(Graph * g,IV * mapIV,int coarseType)20 Graph_compress2 (
21    Graph   *g,
22    IV      *mapIV,
23    int     coarseType
24 ) {
25 /*
26    -------------------------------------------
27    check input and get dimensions and pointers
28    -------------------------------------------
29 */
30 if (  g == NULL || mapIV == NULL
31    || g->nvtx != IV_size(mapIV)
32    || coarseType < 0 || 3 < coarseType ) {
33    fprintf(stderr, "\n fatal error in Graph_compress2(%p,%p,%d)"
34            "\n bad input\n", g, mapIV, coarseType) ;
35    if ( g != NULL ) {
36       Graph_writeStats(g, stderr) ;
37    }
38    if ( mapIV != NULL ) {
39       IV_writeStats(mapIV, stderr) ;
40    }
41    exit(-1) ;
42 }
43 return(Graph_compress(g, IV_entries(mapIV), coarseType)) ; }
44 
45 /*--------------------------------------------------------------------*/
46 /*
47    ---------------------------------------------------------------
48    given a graph g and a fine-to-coarse map vector cmap[],
49    return a compressed graph with type coarseType.
50    note, the compressed graph will have no trivial boundary
51          even if the original graph did have a boundary.
52 
53    created -- 95sep29, cca
54    ---------------------------------------------------------------
55 */
56 Graph *
Graph_compress(Graph * g,int cmap[],int coarseType)57 Graph_compress (
58    Graph   *g,
59    int     cmap[],
60    int     coarseType
61 ) {
62 Graph   *g2 ;
63 int     ierr, ii, j, jj, jsize, J, Jsize, k, K, ncvtx, nvtx, wght ;
64 int     *head, *indices, *jind, *Jind, *jwghts, *Jwghts,
65         *link, *mark, *vwghts, *Vwghts ;
66 IVL     *adjIVL, *AdjIVL, *ewghtIVL, *EwghtIVL ;
67 
68 #if MYTRACE > 0
69 fprintf(stdout, "\n just inside Graph_compress(%p,%p,%d)",
70         g, cmap, coarseType) ;
71 fflush(stdout) ;
72 #endif
73 /*
74    -------------------------------------------
75    check input and get dimensions and pointers
76    -------------------------------------------
77 */
78 if ( g == NULL || cmap == NULL || coarseType < 0 || 3 < coarseType ) {
79    fprintf(stderr, "\n fatal error in Graph_compress(%p,%p,%d)"
80            "\n bad input\n", g, cmap, coarseType) ;
81    exit(-1) ;
82 }
83 if ( (nvtx = g->nvtx) <= 0 ) {
84    fprintf(stderr, "\n fatal error in Graph_compress(%p,%p,%d)"
85            "\n nvtx = %d\n", g, cmap, coarseType, nvtx) ;
86    exit(-1) ;
87 }
88 if ( (adjIVL = g->adjIVL) == NULL ) {
89    fprintf(stderr, "\n fatal error in Graph_compress(%p,%p,%d)"
90            "\n adjIVL is NULL\n", g, cmap, coarseType) ;
91    exit(-1) ;
92 }
93 if ( g->type % 2 == 1 && (vwghts = g->vwghts) == NULL ) {
94    fprintf(stderr, "\n fatal error in Graph_compress(%p,%p,%d)"
95            "\n g->type = %d and g->vwghts is NULL\n",
96            g, cmap, coarseType, g->type) ;
97    exit(-1) ;
98 }
99 if ( g->type >= 2 && (ewghtIVL = g->ewghtIVL) == NULL ) {
100    fprintf(stderr, "\n fatal error in Graph_compress(%p,%p,%d)"
101            "\n g->type = %d and g->ewghtIVL is NULL\n",
102            g, cmap, coarseType, g->type) ;
103    exit(-1) ;
104 }
105 if ( IVmin(nvtx, cmap, &j) < 0 ) {
106    fprintf(stderr, "\n fatal error in Graph_compress(%p,%p,%d)"
107            "\n IVmin(cmap) = %d\n",
108            g, cmap, coarseType, IVmin(nvtx, cmap, &j)) ;
109    exit(-1) ;
110 }
111 ncvtx = 1 + IVmax(nvtx, cmap, &j) ;
112 #if MYDEBUG > 0
113 fprintf(stdout, "\n ncvtx = %d", ncvtx) ;
114 fflush(stdout) ;
115 #endif
116 /*
117    ----------------------------------
118    initialize the coarse graph object
119    ----------------------------------
120 */
121 g2 = Graph_new() ;
122 Graph_init1(g2, coarseType, ncvtx, 0, 0, IVL_CHUNKED, IVL_CHUNKED) ;
123 if ( (AdjIVL = g2->adjIVL) == NULL ) {
124    fprintf(stderr, "\n fatal error in Graph_compress(%p,%p,%d)"
125            "\n AdjIVL is NULL\n", g, cmap, coarseType) ;
126    exit(-1) ;
127 }
128 if ( g2->type % 2 == 1 && (Vwghts = g2->vwghts) == NULL ) {
129    fprintf(stderr, "\n fatal error in Graph_compress(%p,%p,%d)"
130            "\n g2->type = %d and g2->vwghts is NULL\n",
131            g, cmap, coarseType, g2->type) ;
132    exit(-1) ;
133 }
134 if ( g2->type >= 2 && (EwghtIVL = g2->ewghtIVL) == NULL ) {
135    fprintf(stderr, "\n fatal error in Graph_compress(%p,%p,%d)"
136            "\n g2->type = %d and g2->ewghtIVL is NULL\n",
137            g, cmap, coarseType, g2->type) ;
138    exit(-1) ;
139 }
140 #if MYDEBUG > 0
141 fprintf(stdout, "\n after initializing the coarse graph object") ;
142 Graph_writeStats(g2, stdout) ;
143 fflush(stdout) ;
144 #endif
145 /*
146    --------------------------------
147    set up the head and link vectors
148    --------------------------------
149 */
150 head = IVinit(ncvtx, -1) ;
151 link = IVinit(nvtx,  -1) ;
152 for ( j = 0 ; j < nvtx ; j++ ) {
153    J       = cmap[j] ;
154    link[j] = head[J] ;
155    head[J] =    j    ;
156 }
157 /*
158    ------------------------------------------------
159    fill the adjacency structure of the coarse graph
160    ------------------------------------------------
161 */
162 indices = IVinit2(ncvtx) ;
163 mark    = IVinit(ncvtx, -1) ;
164 for ( J = 0 ; J < ncvtx ; J++ ) {
165 #if MYDEBUG > 0
166    fprintf(stdout, "\n\n checking out J = %d", J) ;
167 #endif
168    Jsize = 0 ;
169    for ( j = head[J] ; j != -1 ; j = link[j] ) {
170       IVL_listAndSize(adjIVL, j, &jsize, &jind) ;
171 #if MYDEBUG > 0
172       fprintf(stdout, "\n    adj j = %d : ", j) ;
173       IVfp80(stdout, jsize, jind, 20, &ierr) ;
174 #endif
175       for ( ii = 0 ; ii < jsize ; ii++ ) {
176          if ( (k = jind[ii]) < nvtx ) {
177             K = cmap[k] ;
178 #if MYDEBUG > 0
179             fprintf(stdout, "\n    k = %d, K = %d", k, K) ;
180 #endif
181             if ( mark[K] != J ) {
182 #if MYDEBUG > 0
183                fprintf(stdout, ", added") ;
184 #endif
185                mark[K] = J ;
186                indices[Jsize++] = K ;
187             }
188          }
189       }
190    }
191    if ( Jsize > 0 ) {
192       IVqsortUp(Jsize, indices) ;
193    }
194    IVL_setList(AdjIVL, J, Jsize, indices) ;
195 #if MYDEBUG > 0
196    fprintf(stdout, "\n setting list %d :", J) ;
197    IVfp80(stdout, Jsize, indices, 20, &ierr) ;
198 #endif
199 }
200 g2->nedges = AdjIVL->tsize ;
201 IVfree(indices) ;
202 IVfree(mark) ;
203 
204 if ( coarseType % 2 == 1 ) {
205 /*
206    -------------------------------------------
207    fill the vertex weights of the coarse graph
208    -------------------------------------------
209 */
210    for ( J = 0 ; J < ncvtx ; J++ ) {
211       wght = 0 ;
212       for ( j = head[J] ; j != -1 ; j = link[j] ) {
213          if ( g->type % 2 == 1 ) {
214             wght += vwghts[j] ;
215          } else {
216             wght++ ;
217          }
218       }
219       Vwghts[J] = wght ;
220     }
221    g2->totvwght = IVsum(ncvtx, Vwghts) ;
222 #if MYDEBUG > 0
223    { int ierr ;
224       fprintf(stdout, "\n Vwghts(%d) : ", ncvtx) ;
225       IVfp80(stdout, ncvtx, Vwghts, 80, &ierr) ;
226       fflush(stdout) ;
227    }
228 #endif
229 } else {
230 /*
231    -------------------------------------------------
232    coarse graph does not have vertex weights,
233    set total vertex weight to the number of vertices
234    -------------------------------------------------
235 */
236    g2->totvwght = ncvtx ;
237 }
238 if ( coarseType >= 2 ) {
239 /*
240    -----------------------------------------
241    fill the edge weights of the coarse graph
242    -----------------------------------------
243 */
244    for ( J = 0 ; J < ncvtx ; J++ ) {
245       IVL_listAndSize(AdjIVL, J, &Jsize, &Jind) ;
246       IVL_setList(EwghtIVL, J, Jsize, NULL) ;
247    }
248    if ( g->type >= 2 ) {
249 /*
250       ---------------------------
251       fine graph had edge weights
252       ---------------------------
253 */
254       for ( j = 0 ; j < nvtx ; j++ ) {
255          J = cmap[j] ;
256          IVL_listAndSize(adjIVL,   j, &jsize, &jind) ;
257          IVL_listAndSize(ewghtIVL, j, &jsize, &jwghts) ;
258          IVL_listAndSize(AdjIVL,   J, &Jsize, &Jind) ;
259          IVL_listAndSize(EwghtIVL, J, &Jsize, &Jwghts) ;
260          for ( ii = 0 ; ii < jsize ; ii++ ) {
261             k = jind[ii] ;
262             if ( k < nvtx ) {
263                K = cmap[k] ;
264                for ( jj = 0 ; jj < Jsize ; jj++ ) {
265                   if ( Jind[jj] == K ) {
266                      Jwghts[jj] += jwghts[ii] ;
267                      break ;
268                   }
269                }
270             }
271          }
272       }
273    } else {
274 /*
275       ------------------------------------
276       fine graph did not have edge weights
277       ------------------------------------
278 */
279       for ( j = 0 ; j < nvtx ; j++ ) {
280          J = cmap[j] ;
281          IVL_listAndSize(adjIVL,   j, &jsize, &jind) ;
282          IVL_listAndSize(AdjIVL,   J, &Jsize, &Jind) ;
283          IVL_listAndSize(EwghtIVL, J, &Jsize, &Jwghts) ;
284          for ( ii = 0 ; ii < jsize ; ii++ ) {
285             k = jind[ii] ;
286             if ( k < nvtx ) {
287                K = cmap[k] ;
288                for ( jj = 0 ; jj < Jsize ; jj++ ) {
289                   if ( Jind[jj] == K ) {
290                      Jwghts[jj]++ ;
291                      break ;
292                   }
293                }
294             }
295          }
296       }
297    }
298    g2->totewght = IVL_sum(EwghtIVL) ;
299 } else {
300 /*
301    --------------------------------------------
302    coarse graph does not have edge weights,
303    set total edge weight to the number of edges
304    --------------------------------------------
305 */
306    g2->totewght = g2->nedges ;
307 }
308 /*
309    ------------------------------
310    free the head and link vectors
311    ------------------------------
312 */
313 IVfree(head) ;
314 IVfree(link) ;
315 
316 return(g2) ; }
317 
318 /*--------------------------------------------------------------------*/
319