1 /* util.c */
2
3 #include "../IVL.h"
4
5 #define MYDEBUG 0
6
7 /*--------------------------------------------------------------------*/
8 /*
9 ----------------------------------------------
10 return the number of bytes taken by the object
11
12 created -- 95sep22, cca
13 ----------------------------------------------
14 */
15 int
IVL_sizeOf(IVL * ivl)16 IVL_sizeOf (
17 IVL *ivl
18 ) {
19 int nbytes ;
20 /*
21 ---------------
22 check the input
23 ---------------
24 */
25 if ( ivl == NULL ) {
26 fprintf(stderr, "\n fatal error in IVL_sizeOf(%p)"
27 "\n bad input\n", ivl) ;
28 exit(-1) ;
29 }
30 nbytes = sizeof(struct _IVL) ;
31 if ( ivl->nlist > 0 ) {
32 nbytes += ivl->nlist * (sizeof(int) + sizeof(int *)) ;
33 if ( ivl->type == IVL_SOLO ) {
34 nbytes += IVsum(ivl->nlist, ivl->sizes) * sizeof(int) ;
35 } else {
36 Ichunk *chunk ;
37 for ( chunk = ivl->chunk ;
38 chunk != NULL ;
39 chunk = chunk->next ) {
40 nbytes += sizeof(Ichunk) + chunk->size * sizeof(int) ;
41 }
42 }
43 }
44 return(nbytes) ; }
45
46 /*--------------------------------------------------------------------*/
47 /*
48 ---------------------------------------------------
49 purpose -- to return the minimum entry in the lists
50
51 created -- 95sep22, cca
52 ---------------------------------------------------
53 */
54 int
IVL_min(IVL * ivl)55 IVL_min (
56 IVL *ivl
57 ) {
58 int first, i, ilist, minval, nlist, size, val ;
59 int *ent ;
60 /*
61 ---------------
62 check the input
63 ---------------
64 */
65 if ( ivl == NULL || (nlist = ivl->nlist) <= 0 ) {
66 fprintf(stderr, "\n fatal error in IVL_min(%p)"
67 "\n bad input\n", ivl) ;
68 exit(-1) ;
69 }
70 first = 1 ;
71 minval = -1 ;
72 for ( ilist = 0 ; ilist < nlist ; ilist++ ) {
73 IVL_listAndSize(ivl, ilist, &size, &ent) ;
74 if ( size > 0 ) {
75 val = IVmin(size, ent, &i) ;
76 if ( first == 1 ) {
77 minval = val ;
78 first = 0 ;
79 } else if ( minval > val ) {
80 minval = val ;
81 }
82 }
83 }
84 return(minval) ; }
85
86 /*--------------------------------------------------------------------*/
87 /*
88 ---------------------------------------------------
89 purpose -- to return the maximum entry in the lists
90
91 created -- 95sep22, cca
92 ---------------------------------------------------
93 */
94 int
IVL_max(IVL * ivl)95 IVL_max (
96 IVL *ivl
97 ) {
98 int first, i, ilist, maxval, nlist, size, val ;
99 int *ent ;
100 /*
101 ---------------
102 check the input
103 ---------------
104 */
105 if ( ivl == NULL || (nlist = ivl->nlist) <= 0 ) {
106 fprintf(stderr, "\n fatal error in IVL_max(%p)"
107 "\n bad input\n", ivl) ;
108 exit(-1) ;
109 }
110 first = 1 ;
111 maxval = -1 ;
112 for ( ilist = 0 ; ilist < nlist ; ilist++ ) {
113 IVL_listAndSize(ivl, ilist, &size, &ent) ;
114 if ( size > 0 ) {
115 val = IVmax(size, ent, &i) ;
116 if ( first == 1 ) {
117 maxval = val ;
118 first = 0 ;
119 } else if ( maxval < val ) {
120 maxval = val ;
121 }
122 }
123 }
124 return(maxval) ; }
125
126 /*--------------------------------------------------------------------*/
127 /*
128 ----------------------------
129 return the maximum list size
130
131 created -- 95sep22, cca
132 ----------------------------
133 */
134 int
IVL_maxListSize(IVL * ivl)135 IVL_maxListSize (
136 IVL *ivl
137 ) {
138 int ilist, maxsize, nlist, size ;
139 int *ent ;
140 /*
141 -------------------
142 check for bad input
143 -------------------
144 */
145 if ( ivl == NULL || (nlist = ivl->nlist) <= 0 ) {
146 fprintf(stderr, "\n fatal error in IVL_maxListSize(%p)"
147 "\n bad input", ivl) ;
148 exit(-1) ;
149 }
150 for ( ilist = 0, maxsize = 0 ; ilist < nlist ; ilist++ ) {
151 IVL_listAndSize(ivl, ilist, &size, &ent) ;
152 if ( maxsize < size ) {
153 maxsize = size ;
154 }
155 }
156 return(maxsize) ; }
157
158 /*--------------------------------------------------------------------*/
159 /*
160 -------------------------------
161 return the sum of all the lists
162
163 created -- 95sep29, cca
164 -------------------------------
165 */
166 int
IVL_sum(IVL * ivl)167 IVL_sum (
168 IVL *ivl
169 ) {
170 int j, jsize, sum ;
171 int *jind ;
172
173 if ( ivl == NULL ) {
174 fprintf(stderr, "\n fatal error in IVL_sum(%p)"
175 "\n bad input\n", ivl) ;
176 exit(-1) ;
177 }
178 sum = 0 ;
179 for ( j = 0 ; j < ivl->nlist ; j++ ) {
180 IVL_listAndSize(ivl, j, &jsize, &jind) ;
181 if ( jsize > 0 ) {
182 sum = sum + IVsum(jsize, jind) ;
183 }
184 }
185 return(sum) ; }
186
187 /*--------------------------------------------------------------------*/
188 /*
189 -------------------------------------------
190 sort the adjacency lists in ascending order
191
192 created -- 95sep22, cca
193 -------------------------------------------
194 */
195 void
IVL_sortUp(IVL * ivl)196 IVL_sortUp (
197 IVL *ivl
198 ) {
199 int ilist, nlist, size ;
200 int *ent ;
201 /*
202 ---------------
203 check the input
204 ---------------
205 */
206 if ( ivl == NULL || (nlist = ivl->nlist) < 0 ) {
207 fprintf(stderr, "\n fatal error in IVL_sortUp(%p)"
208 "\n bad input\n", ivl) ;
209 exit(-1) ;
210 }
211
212 for ( ilist = 0 ; ilist < nlist ; ilist++ ) {
213 IVL_listAndSize(ivl, ilist, &size, &ent) ;
214 if ( size > 0 ) {
215 IVqsortUp(size, ent) ;
216 }
217 }
218 return ; }
219
220 /*--------------------------------------------------------------------*/
221 /*
222 -----------------------------------------------------
223 create an equivalence map
224 if ( map[j] == map[k] ) then
225 the lists for j and k are identical
226 endif
227 NOTE : each empty list is mapped to a different value
228
229 return value -- pointer to map[] vector
230
231 created -- 95mar15, cca
232 -----------------------------------------------------
233 */
234 int *
IVL_equivMap1(IVL * ivl)235 IVL_equivMap1 (
236 IVL *ivl
237 ) {
238 int first, ierr, ii, itest, jtest, nlist, nlist2, ntest, nv2, sum,
239 v, v2, vsize, w, wsize ;
240 int *chksum, *issorted, *map, *mark, *vadj, *vids, *wadj ;
241 /*
242 ---------------
243 check the input
244 ---------------
245 */
246 if ( ivl == NULL || (nlist = ivl->nlist) < 0 ) {
247 fprintf(stderr, "\n fatal error in IVL_equivMap(%p)"
248 "\n bad input\n", ivl) ;
249 exit(-1) ;
250 }
251 if ( nlist == 0 ) {
252 return(NULL) ;
253 }
254 /*
255 --------------
256 initialize map
257 --------------
258 */
259 map = IVinit(nlist, -1) ;
260 nlist2 = 0 ;
261 /*
262 ---------------------------------
263 sort the lists by their checksums
264 ---------------------------------
265 */
266 vids = IVinit(nlist, -1) ;
267 chksum = IVinit(nlist, -1) ;
268 for ( v = 0, ntest = 0 ; v < nlist ; v++ ) {
269 IVL_listAndSize(ivl, v, &vsize, &vadj) ;
270 if ( vsize > 0 ) {
271 /*
272 ---------------------------------------------
273 list is not empty, store list id and checksum
274 ---------------------------------------------
275 */
276 for ( ii = 0, sum = 0 ; ii < vsize ; ii++ ) {
277 sum += vadj[ii] ;
278 }
279 vids[ntest] = v ;
280 chksum[ntest] = sum ;
281 ntest++ ;
282 } else {
283 /*
284 ------------------------------
285 list is empty, map to new list
286 ------------------------------
287 */
288 map[v] = nlist2++ ;
289 }
290 }
291 #if MYDEBUG > 0
292 fprintf(stdout, "\n before sort, vids") ;
293 IVfp80(stdout, ntest, vids, 80, &ierr) ;
294 fprintf(stdout, "\n before sort, chksum") ;
295 IVfp80(stdout, ntest, chksum, 80, &ierr) ;
296 fflush(stdout) ;
297 #endif
298 IV2qsortUp(ntest, chksum, vids) ;
299 #if MYDEBUG > 0
300 fprintf(stdout, "\n after sort, vids") ;
301 IVfp80(stdout, ntest, vids, 80, &ierr) ;
302 fprintf(stdout, "\n after sort, chksum") ;
303 IVfp80(stdout, ntest, chksum, 80, &ierr) ;
304 fflush(stdout) ;
305 #endif
306 /*
307 -----------------------------------------------------------------
308 loop over the nonempty lists in the order of increasing checksums
309 -----------------------------------------------------------------
310 */
311 issorted = IVinit(nlist, -1) ;
312 for ( itest = 0 ; itest < ntest ; itest++ ) {
313 v = vids[itest] ;
314 if ( map[v] == -1 ) {
315 /*
316 -------------------------------------------------
317 list v has not been found to be indistinguishable
318 to any other list, map it to a new list
319 -------------------------------------------------
320 */
321 map[v] = nlist2++ ;
322 #if MYDEBUG > 0
323 fprintf(stdout, "\n setting map[%d] = %d, chksum[%d] = %d",
324 v, map[v], itest, chksum[itest]) ;
325 fflush(stdout) ;
326 #endif
327 /*
328 --------------------------------------
329 loop over lists with the same checksum
330 --------------------------------------
331 */
332 IVL_listAndSize(ivl, v, &vsize, &vadj) ;
333 first = 1 ;
334 for ( jtest = itest + 1 ; jtest < ntest ; jtest++ ) {
335 w = vids[jtest] ;
336 #if MYDEBUG > 0
337 fprintf(stdout, "\n comparing with %d, chksum[%d] = %d",
338 w, jtest, chksum[jtest]) ;
339 fflush(stdout) ;
340 #endif
341 if ( chksum[itest] != chksum[jtest] ) {
342 /*
343 --------------------------------------------------
344 checksums are not equal, list v cannot be the same
345 as any following list, break out of test loop
346 --------------------------------------------------
347 */
348 break ;
349 } else {
350 /*
351 -----------------------------------------------------
352 lists v and w have the same checksum
353 if the list sizes are the same then compare the lists
354 -----------------------------------------------------
355 */
356 IVL_listAndSize(ivl, w, &wsize, &wadj) ;
357 #if MYDEBUG > 0
358 fprintf(stdout, "\n vsize = %d, wsize = %d", vsize, wsize) ;
359 fflush(stdout) ;
360 #endif
361 if ( vsize == wsize ) {
362 if ( issorted[v] != 1 ) {
363 #if MYDEBUG > 0
364 fprintf(stdout, "\n sorting list for %d", v) ;
365 fflush(stdout) ;
366 #endif
367 issorted[v] = 1 ;
368 IVqsortUp(vsize, vadj) ;
369 }
370 if ( issorted[w] != 1 ) {
371 #if MYDEBUG > 0
372 fprintf(stdout, "\n sorting list for %d", w) ;
373 fflush(stdout) ;
374 #endif
375 issorted[w] = 1 ;
376 IVqsortUp(wsize, wadj) ;
377 }
378 for ( ii = 0 ; ii < vsize ; ii++ ) {
379 if ( vadj[ii] != wadj[ii] ) {
380 break ;
381 }
382 }
383 if ( ii == vsize ) {
384 /*
385 ----------------------------------
386 lists are identical, set map for w
387 ----------------------------------
388 */
389 #if MYDEBUG > 0
390 fprintf(stdout, "\n lists are identical") ;
391 fflush(stdout) ;
392 #endif
393 map[w] = map[v] ;
394 }
395 }
396 }
397 }
398 }
399 }
400 IVfree(issorted) ;
401 IVfree(chksum) ;
402 IVfree(vids) ;
403 #if MYDEBUG > 0
404 fprintf(stdout, "\n initial map") ;
405 IVfp80(stdout, nlist, map, 80, &ierr) ;
406 fflush(stdout) ;
407 #endif
408 /*
409 ----------------------------------------------------
410 now modify the map to ensure
411 if v2 < w2 then
412 min { v | map[v] = v2 } < min { w | map[w] = w2 }
413 endif
414 ----------------------------------------------------
415 */
416 mark = IVinit(nlist2, -1) ;
417 for ( v = 0, nv2 = 0 ; v < nlist ; v++ ) {
418 v2 = map[v] ;
419 if ( mark[v2] == -1 ) {
420 mark[v2] = nv2++ ;
421 }
422 map[v] = mark[v2] ;
423 }
424 IVfree(mark) ;
425 #if MYDEBUG > 0
426 fprintf(stdout, "\n final map") ;
427 IVfp80(stdout, nlist, map, 80, &ierr) ;
428 fflush(stdout) ;
429 #endif
430
431 return(map) ; }
432
433 /*--------------------------------------------------------------------*/
434 /*
435 -----------------------------------------------------
436 create an equivalence map
437 if ( map[j] == map[k] ) then
438 the lists for j and k are identical
439 endif
440 NOTE : each empty list is mapped to a different value
441
442 return value -- pointer to map IV object
443
444 created -- 96mar15, cca
445 -----------------------------------------------------
446 */
447 IV *
IVL_equivMap2(IVL * ivl)448 IVL_equivMap2 (
449 IVL *ivl
450 ) {
451 int *map ;
452 IV *mapIV ;
453
454 if ( (map = IVL_equivMap1(ivl)) == NULL ) {
455 mapIV = NULL ;
456 } else {
457 mapIV = IV_new() ;
458 IV_init2(mapIV, ivl->nlist, ivl->nlist, 1, map) ;
459 }
460 return(mapIV) ; }
461
462 /*--------------------------------------------------------------------*/
463 /*
464 ------------------------------------
465 overwrite each list with new entries
466
467 created -- 96oct03, cca
468 ------------------------------------
469 */
470 void
IVL_overwrite(IVL * ivl,IV * oldToNewIV)471 IVL_overwrite (
472 IVL *ivl,
473 IV *oldToNewIV
474 ) {
475 int ii, ilist, nlist, range, size ;
476 int *list, *oldToNew ;
477 /*
478 ---------------
479 check the input
480 ---------------
481 */
482 if ( ivl == NULL || oldToNewIV == NULL ) {
483 fprintf(stderr, "\n fatal error in IVL_overwrite(%p,%p)"
484 "\n bad input\n", ivl, oldToNewIV) ;
485 exit(-1) ;
486 }
487 oldToNew = IV_entries(oldToNewIV) ;
488 range = IV_size(oldToNewIV) ;
489 nlist = ivl->nlist ;
490 for ( ilist = 0 ; ilist < nlist ; ilist++ ) {
491 IVL_listAndSize(ivl, ilist, &size, &list) ;
492 for ( ii = 0 ; ii < size ; ii++ ) {
493 if ( 0 <= list[ii] && list[ii] < range ) {
494 list[ii] = oldToNew[list[ii]] ;
495 }
496 }
497 }
498 return ; }
499
500 /*--------------------------------------------------------------------*/
501 /*
502 ---------------------------------------------------
503 given an IVL object and a map from old list entries
504 to new list entries, create a new IVL object whose
505 new list entries contain no duplicates.
506
507 return value -- pointer to new IVL object
508
509 created -- 96nov07, cca
510 ---------------------------------------------------
511 */
512 IVL *
IVL_mapEntries(IVL * ivl,IV * mapIV)513 IVL_mapEntries (
514 IVL *ivl,
515 IV *mapIV
516 ) {
517 int count, ierr, ii, ilist, maxsize, nlist, range, size, value ;
518 int *list, *map, *newlist ;
519 IVL *newIVL ;
520 /*
521 ---------------
522 check the input
523 ---------------
524 */
525 if ( ivl == NULL || mapIV == NULL ) {
526 fprintf(stderr, "\n fatal error in IVL_mapEntries(%p,%p)"
527 "\n bad input\n", ivl, mapIV) ;
528 exit(-1) ;
529 }
530 nlist = ivl->nlist ;
531 range = IV_size(mapIV) ;
532 map = IV_entries(mapIV) ;
533 #if MYDEBUG > 0
534 fprintf(stdout, "\n nlist = %d, range = %d, map = %p",
535 nlist, range, map) ;
536 #endif
537 if ( nlist <= 0 || range < 0 || map == NULL ) {
538 return(NULL) ;
539 }
540 /*
541 -------------------------
542 create the new IVL object
543 -------------------------
544 */
545 newIVL = IVL_new();
546 IVL_init1(newIVL, IVL_CHUNKED, nlist) ;
547 /*
548 -------------------
549 loop over the lists
550 -------------------
551 */
552 maxsize = IVL_maxListSize(ivl) ;
553 newlist = IVinit(maxsize, -1) ;
554 for ( ilist = 0 ; ilist < nlist ; ilist++ ) {
555 IVL_listAndSize(ivl, ilist, &size, &list) ;
556 #if MYDEBUG > 0
557 fprintf(stdout, "\n list %d :", ilist) ;
558 IVfp80(stdout, size, list, 10, &ierr) ;
559 #endif
560 for ( ii = 0, count = 0 ; ii < size ; ii++ ) {
561 if ( 0 <= list[ii] && list[ii] < range ) {
562 /*
563 -----------------------------------------
564 old entry is in range, store mapped value
565 -----------------------------------------
566 */
567 #if MYDEBUG > 0
568 fprintf(stdout, "\n newlist[%d] = map[%d] = %d",
569 count, list[ii], map[list[ii]]) ;
570 #endif
571 newlist[count++] = map[list[ii]] ;
572 }
573 }
574 if ( count > 0 ) {
575 /*
576 ------------------------------------
577 sort the new list in ascending order
578 ------------------------------------
579 */
580 #if MYDEBUG > 0
581 fprintf(stdout, "\n unsorted list %d :", ilist) ;
582 IVfp80(stdout, count, newlist, 10, &ierr) ;
583 #endif
584 IVqsortUp(count, newlist) ;
585 #if MYDEBUG > 0
586 fprintf(stdout, "\n sorted list %d :", ilist) ;
587 IVfp80(stdout, count, newlist, 10, &ierr) ;
588 #endif
589 /*
590 -----------------------
591 purge duplicate entries
592 -----------------------
593 */
594 size = count ;
595 value = -1 ;
596 for ( ii = count = 0 ; ii < size ; ii++ ) {
597 if ( newlist[ii] != value ) {
598 #if MYDEBUG > 0
599 fprintf(stdout, "\n keeping entry %d", newlist[ii]) ;
600 #endif
601 newlist[count++] = newlist[ii] ;
602 value = newlist[ii] ;
603 }
604 }
605 }
606 /*
607 ----------------------------------
608 set the list in the new IVL object
609 ----------------------------------
610 */
611 IVL_setList(newIVL, ilist, count, newlist) ;
612 }
613 IVfree(newlist) ;
614
615 return(newIVL) ; }
616
617 /*--------------------------------------------------------------------*/
618 /*
619 ----------------------------------------------------------------
620 IVL object ivl1 absorbs the lists and data from IVL object ivl2.
621 the lists in ivl2 are mapped into lists in ivl1 using the mapIV
622 IV object.
623
624 created -- 96dec06, cca
625 ----------------------------------------------------------------
626 */
627 void
IVL_absorbIVL(IVL * ivl1,IVL * ivl2,IV * mapIV)628 IVL_absorbIVL (
629 IVL *ivl1,
630 IVL *ivl2,
631 IV *mapIV
632 ) {
633 Ichunk *chunk ;
634 int ilist, jlist, nlist2, size ;
635 int *ivec, *map ;
636 /*
637 ---------------
638 check the input
639 ---------------
640 */
641 if ( ivl1 == NULL || ivl2 == NULL || mapIV == NULL ) {
642 fprintf(stderr, "\n fatal error in IVL_absorbIVL(%p,%p,%p)"
643 "\n bad input\n", ivl1, ivl2, mapIV) ;
644 exit(-1) ;
645 }
646 if ( (map = IV_entries(mapIV)) == NULL ) {
647 fprintf(stderr, "\n fatal error in IVL_absorbIVL(%p,%p,%p)"
648 "\n IV_entries(mapIV) is NULL\n", ivl1, ivl2, mapIV) ;
649 exit(-1) ;
650 }
651 /*
652 --------------------------------------------
653 check that the sizes of ivl2 and mapIV agree
654 --------------------------------------------
655 */
656 if ( IV_size(mapIV) != (nlist2 = ivl2->nlist) ) {
657 fprintf(stderr, "\n fatal error in IVL_absorbIVL(%p,%p,%p)"
658 "\n ivl2->nlist = %d, IV_size(mapIV) = %d\n",
659 ivl1, ivl2, mapIV, nlist2, IV_size(mapIV)) ;
660 exit(-1) ;
661 }
662 /*
663 -------------------------------
664 for each list in ivl2
665 get size and pointer
666 get mapped list in ivl1
667 set size and pointer in ivl1
668 -------------------------------
669 */
670 for ( ilist = 0 ; ilist < nlist2 ; ilist++ ) {
671 IVL_listAndSize(ivl2, ilist, &size, &ivec) ;
672 if ( (jlist = map[ilist]) >= 0 ) {
673 IVL_setPointerToList(ivl1, jlist, size, ivec) ;
674 }
675 }
676 if ( (chunk = ivl2->chunk) != NULL ) {
677 /*
678 -------------------------------------------
679 move the chunks of memory from ivl2 to ivl1
680 -------------------------------------------
681 */
682 while ( chunk->next != NULL ) {
683 chunk = chunk->next ;
684 }
685 chunk->next = ivl1->chunk ;
686 ivl1->chunk = ivl2->chunk ;
687 ivl2->chunk = NULL ;
688 }
689 return ; }
690
691 /*--------------------------------------------------------------------*/
692 /*
693 -----------------------------------------------------------------
694 purpose -- expand the lists in an IVL object.
695
696 this method was created in support of a symbolic factorization.
697 an IVL object is constructed using a compressed graph.
698 it must be expanded to reflect the compressed graph.
699 the number of lists does not change (there is one list per front)
700 but the size of each list may change. so we create a new IVL
701 object that contains entries for the uncompressed graph.
702
703 created -- 97feb13, cca
704 -----------------------------------------------------------------
705 */
706 IVL *
IVL_expand(IVL * ivl,IV * eqmapIV)707 IVL_expand (
708 IVL *ivl,
709 IV *eqmapIV
710 ) {
711 int count, ii, ilist, jj, kk, nlist1, nlist2, nvtx, size ;
712 int *head, *link, *list, *map, *temp ;
713 IVL *ivl2 ;
714 /*
715 ---------------
716 check the input
717 ---------------
718 */
719 if ( ivl == NULL || eqmapIV == NULL ) {
720 fprintf(stderr, "\n fatal error in IVL_expand(%p,%p)"
721 "\n bad input\n", ivl, eqmapIV) ;
722 exit(-1) ;
723 }
724 nlist1 = ivl->nlist ;
725 /*
726 -------------------------------
727 get the head[]/link[] structure
728 -------------------------------
729 */
730 IV_sizeAndEntries(eqmapIV, &nlist2, &map) ;
731 nvtx = 1 + IV_max(eqmapIV) ;
732 #if MYDEBUG > 0
733 fprintf(stdout, "\n nlist1 = %d, nlist2 = %d", nlist1, nlist2) ;
734 fflush(stdout) ;
735 #endif
736 head = IVinit(nvtx, -1) ;
737 link = IVinit(nlist2, -1) ;
738 for ( ii = nlist2 - 1 ; ii >= 0 ; ii-- ) {
739 if ( (jj = map[ii]) < 0 || jj >= nvtx ) {
740 fprintf(stderr, "\n fatal error in IVL_expand(%p,%p)"
741 "\n nlist1 = %d, nvtx = %d, map[%d] = %d\n",
742 ivl, eqmapIV, nlist1, nvtx, ii, jj) ;
743 exit(-1) ;
744 }
745 link[ii] = head[jj] ;
746 head[jj] = ii ;
747 }
748 #if MYDEBUG > 0
749 fprintf(stdout, "\n head/link structure created") ;
750 fflush(stdout) ;
751 #endif
752 /*
753 ---------------------------
754 allocate the new IVL object
755 ---------------------------
756 */
757 ivl2 = IVL_new() ;
758 IVL_init1(ivl2, IVL_CHUNKED, nlist1) ;
759 temp = IVinit(nlist2, -1) ;
760 for ( ilist = 0 ; ilist < nlist1 ; ilist++ ) {
761 IVL_listAndSize(ivl, ilist, &size, &list) ;
762 #if MYDEBUG > 0
763 fprintf(stdout, "\n\n working on list %d", ilist) ;
764 IVfprintf(stdout, size, list) ;
765 fflush(stdout) ;
766 #endif
767 for ( ii = 0, count = 0 ; ii < size ; ii++ ) {
768 jj = list[ii] ;
769 for ( kk = head[jj] ; kk != -1 ; kk = link[kk] ) {
770 temp[count++] = kk ;
771 }
772 }
773 IVL_setList(ivl2, ilist, count, temp) ;
774 }
775 /*
776 ------------------------
777 free the working storage
778 ------------------------
779 */
780 IVfree(head) ;
781 IVfree(link) ;
782 IVfree(temp) ;
783
784 return(ivl2) ; }
785
786 /*--------------------------------------------------------------------*/
787