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