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