Actual source code: ivec.c

  1: #define PETSCKSP_DLL

  3: /**********************************ivec.c**************************************

  5: Author: Henry M. Tufo III

  7: e-mail: hmt@cs.brown.edu

  9: snail-mail:
 10: Division of Applied Mathematics
 11: Brown University
 12: Providence, RI 02912

 14: Last Modification: 
 15: 6.21.97
 16: ***********************************ivec.c*************************************/

 18: /**********************************ivec.c**************************************
 19: File Description:
 20: -----------------

 22: ***********************************ivec.c*************************************/
 23:  #include src/ksp/pc/impls/tfs/tfs.h

 25: /* sorting args ivec.c ivec.c ... */
 26: #define   SORT_OPT        6     
 27: #define   SORT_STACK        50000


 30: /* allocate an address and size stack for sorter(s) */
 31: static void *offset_stack[2*SORT_STACK];
 32: static int   size_stack[SORT_STACK];
 33: static long psize_stack[SORT_STACK];



 37: /**********************************ivec.c**************************************
 38: Function ivec_dump()

 40: Input :
 41: Output:
 42: Return:
 43: Description:
 44: ***********************************ivec.c*************************************/
 45: void
 46: ivec_dump(int *v, int n, int tag, int tag2, char * s)
 47: {
 48:   int i;
 49:   printf("%2d %2d %s %2d :: ",tag,tag2,s,my_id);
 50:   for (i=0;i<n;i++)
 51:     {printf("%2d ",v[i]);}
 52:   printf("\n");
 53:   fflush(stdout);
 54: }



 58: /**********************************ivec.c**************************************
 59: Function ivec_lb_ub()

 61: Input :
 62: Output:
 63: Return:
 64: Description:
 65: ***********************************ivec.c*************************************/
 66: void
 67: ivec_lb_ub( int *arg1,  int n, int *lb, int *ub)
 68: {
 69:    int min = INT_MAX;
 70:    int max = INT_MIN;

 72:   while (n--)
 73:     {
 74:      min = PetscMin(min,*arg1);
 75:      max = PetscMax(max,*arg1);
 76:      arg1++;
 77:     }

 79:   *lb=min;
 80:   *ub=max;
 81: }



 85: /**********************************ivec.c**************************************
 86: Function ivec_copy()

 88: Input :
 89: Output:
 90: Return:
 91: Description:
 92: ***********************************ivec.c*************************************/
 93: int *ivec_copy( int *arg1,  int *arg2,  int n)
 94: {
 95:   while (n--)  {*arg1++ = *arg2++;}
 96:   return(arg1);
 97: }



101: /**********************************ivec.c**************************************
102: Function ivec_zero()

104: Input :
105: Output:
106: Return:
107: Description:
108: ***********************************ivec.c*************************************/
109: void 
110: ivec_zero( int *arg1,  int n)
111: {
112:   while (n--)  {*arg1++ = 0;}
113: }



117: /**********************************ivec.c**************************************
118: Function ivec_comp()

120: Input :
121: Output:
122: Return:
123: Description:
124: ***********************************ivec.c*************************************/
125: void 
126: ivec_comp( int *arg1,  int n)
127: {
128:   while (n--)  {*arg1 = ~*arg1; arg1++;}
129: }



133: /**********************************ivec.c**************************************
134: Function ivec_neg_one()

136: Input :
137: Output:
138: Return:
139: Description:
140: ***********************************ivec.c*************************************/
141: void 
142: ivec_neg_one( int *arg1,  int n)
143: {
144:   while (n--)  {*arg1++ = -1;}
145: }



149: /**********************************ivec.c**************************************
150: Function ivec_pos_one()

152: Input :
153: Output:
154: Return:
155: Description:
156: ***********************************ivec.c*************************************/
157: void 
158: ivec_pos_one( int *arg1,  int n)
159: {
160:   while (n--)  {*arg1++ = 1;}
161: }



165: /**********************************ivec.c**************************************
166: Function ivec_c_index()

168: Input :
169: Output:
170: Return:
171: Description:
172: ***********************************ivec.c*************************************/
173: void 
174: ivec_c_index( int *arg1,  int n)
175: {
176:    int i=0;


179:   while (n--)  {*arg1++ = i++;}
180: }



184: /**********************************ivec.c**************************************
185: Function ivec_fortran_index()

187: Input :
188: Output:
189: Return:
190: Description:
191: ***********************************ivec.c*************************************/
192: void 
193: ivec_fortran_index( int *arg1,  int n)
194: {
195:    int i=0;


198:   while (n--)  {*arg1++ = ++i;}
199: }



203: /**********************************ivec.c**************************************
204: Function ivec_set()

206: Input :
207: Output:
208: Return:
209: Description:
210: ***********************************ivec.c*************************************/
211: void 
212: ivec_set( int *arg1,  int arg2,  int n)
213: {
214:   while (n--)  {*arg1++ = arg2;}
215: }



219: /**********************************ivec.c**************************************
220: Function ivec_cmp()

222: Input :
223: Output:
224: Return:
225: Description:
226: ***********************************ivec.c*************************************/
227: int
228: ivec_cmp( int *arg1,  int *arg2,  int n)
229: {
230:   while (n--)  {if (*arg1++ != *arg2++)  {return(FALSE);}}
231:   return(TRUE);
232: }



236: /**********************************ivec.c**************************************
237: Function ivec_max()

239: Input :
240: Output:
241: Return:
242: Description:
243: ***********************************ivec.c*************************************/
244: void 
245: ivec_max( int *arg1,  int *arg2,  int n)
246: {
247:   while (n--)  {*arg1 = PetscMax(*arg1,*arg2); arg1++; arg2++;}
248: }



252: /**********************************ivec.c**************************************
253: Function ivec_min()

255: Input :
256: Output:
257: Return:
258: Description:
259: ***********************************ivec.c*************************************/
260: void 
261: ivec_min( int *arg1,  int *arg2,  int n)
262: {
263:   while (n--)  {*(arg1) = PetscMin(*arg1,*arg2); arg1++; arg2++;}
264: }



268: /**********************************ivec.c**************************************
269: Function ivec_mult()

271: Input :
272: Output:
273: Return:
274: Description:
275: ***********************************ivec.c*************************************/
276: void 
277: ivec_mult( int *arg1,  int *arg2,  int n)
278: {
279:   while (n--)  {*arg1++ *= *arg2++;}
280: }



284: /**********************************ivec.c**************************************
285: Function ivec_add()

287: Input :
288: Output:
289: Return:
290: Description:
291: ***********************************ivec.c*************************************/
292: void 
293: ivec_add( int *arg1,  int *arg2,  int n)
294: {
295:   while (n--)  {*arg1++ += *arg2++;}
296: }



300: /**********************************ivec.c**************************************
301: Function ivec_lxor()

303: Input :
304: Output:
305: Return:
306: Description:
307: ***********************************ivec.c*************************************/
308: void 
309: ivec_lxor( int *arg1,  int *arg2,  int n)
310: {
311:   while (n--) {*arg1=((*arg1 || *arg2) && !(*arg1 && *arg2)); arg1++; arg2++;}
312: }



316: /**********************************ivec.c**************************************
317: Function ivec_xor()

319: Input :
320: Output:
321: Return:
322: Description:
323: ***********************************ivec.c*************************************/
324: void 
325: ivec_xor( int *arg1,  int *arg2,  int n)
326: {
327:   while (n--)  {*arg1++ ^= *arg2++;}
328: }



332: /**********************************ivec.c**************************************
333: Function ivec_or()

335: Input :
336: Output:
337: Return:
338: Description:
339: ***********************************ivec.c*************************************/
340: void 
341: ivec_or( int *arg1,  int *arg2,  int n)
342: {
343:   while (n--)  {*arg1++ |= *arg2++;}
344: }



348: /**********************************ivec.c**************************************
349: Function ivec_lor()

351: Input :
352: Output:
353: Return:
354: Description:
355: ***********************************ivec.c*************************************/
356: void 
357: ivec_lor( int *arg1,  int *arg2,  int n)
358: {
359:   while (n--)  {*arg1 = (*arg1 || *arg2); arg1++; arg2++;}
360: }



364: /**********************************ivec.c**************************************
365: Function ivec_or3()

367: Input :
368: Output:
369: Return:
370: Description:
371: ***********************************ivec.c*************************************/
372: void 
373: ivec_or3( int *arg1,  int *arg2,  int *arg3, 
374:           int n)
375: {
376:   while (n--)  {*arg1++ = (*arg2++ | *arg3++);}
377: }



381: /**********************************ivec.c**************************************
382: Function ivec_and()

384: Input :
385: Output:
386: Return:
387: Description:
388: ***********************************ivec.c*************************************/
389: void 
390: ivec_and( int *arg1,  int *arg2,  int n)
391: {
392:   while (n--)  {*arg1++ &= *arg2++;}
393: }



397: /**********************************ivec.c**************************************
398: Function ivec_land()

400: Input :
401: Output:
402: Return:
403: Description:
404: ***********************************ivec.c*************************************/
405: void 
406: ivec_land( int *arg1,  int *arg2,  int n)
407: {
408:   while (n--) {*arg1 = (*arg1 && *arg2); arg1++; arg2++;}
409: }



413: /**********************************ivec.c**************************************
414: Function ivec_and3()

416: Input :
417: Output:
418: Return:
419: Description:
420: ***********************************ivec.c*************************************/
421: void 
422: ivec_and3( int *arg1,  int *arg2,  int *arg3, 
423:            int n)
424: {
425:   while (n--)  {*arg1++ = (*arg2++ & *arg3++);}
426: }



430: /**********************************ivec.c**************************************
431: Function ivec_sum

433: Input : 
434: Output: 
435: Return: 
436: Description: 
437: ***********************************ivec.c*************************************/
438: int ivec_sum( int *arg1,  int n)
439: {
440:    int tmp = 0;


443:   while (n--) {tmp += *arg1++;}
444:   return(tmp);
445: }



449: /**********************************ivec.c**************************************
450: Function ivec_reduce_and

452: Input : 
453: Output: 
454: Return: 
455: Description: 
456: ***********************************ivec.c*************************************/
457: int ivec_reduce_and( int *arg1,  int n)
458: {
459:    int tmp = ALL_ONES;


462:   while (n--) {tmp &= *arg1++;}
463:   return(tmp);
464: }



468: /**********************************ivec.c**************************************
469: Function ivec_reduce_or

471: Input : 
472: Output: 
473: Return: 
474: Description: 
475: ***********************************ivec.c*************************************/
476: int ivec_reduce_or( int *arg1,  int n)
477: {
478:    int tmp = 0;


481:   while (n--) {tmp |= *arg1++;}
482:   return(tmp);
483: }



487: /**********************************ivec.c**************************************
488: Function ivec_prod

490: Input : 
491: Output: 
492: Return: 
493: Description: 
494: ***********************************ivec.c*************************************/
495: int ivec_prod( int *arg1,  int n)
496: {
497:    int tmp = 1;


500:   while (n--)  {tmp *= *arg1++;}
501:   return(tmp);
502: }



506: /**********************************ivec.c**************************************
507: Function ivec_u_sum

509: Input : 
510: Output: 
511: Return: 
512: Description: 
513: ***********************************ivec.c*************************************/
514: int ivec_u_sum( unsigned *arg1,  int n)
515: {
516:    unsigned tmp = 0;


519:   while (n--)  {tmp += *arg1++;}
520:   return(tmp);
521: }



525: /**********************************ivec.c**************************************
526: Function ivec_lb()

528: Input :
529: Output:
530: Return:
531: Description:
532: ***********************************ivec.c*************************************/
533: int 
534: ivec_lb( int *arg1,  int n)
535: {
536:    int min = INT_MAX;


539:   while (n--)  {min = PetscMin(min,*arg1); arg1++;}
540:   return(min);
541: }



545: /**********************************ivec.c**************************************
546: Function ivec_ub()

548: Input :
549: Output:
550: Return:
551: Description:
552: ***********************************ivec.c*************************************/
553: int 
554: ivec_ub( int *arg1,  int n)
555: {
556:    int max = INT_MIN;


559:   while (n--)  {max = PetscMax(max,*arg1); arg1++;}
560:   return(max);
561: }



565: /**********************************ivec.c**************************************
566: Function split_buf()

568: Input :
569: Output:
570: Return:
571: Description:

573: assumes that sizeof(int) == 4bytes!!!
574: ***********************************ivec.c*************************************/
575: int
576: ivec_split_buf(int *buf1, int **buf2,  int size)
577: {
578:   *buf2 = (buf1 + (size>>3));
579:   return(size);
580: }



584: /**********************************ivec.c**************************************
585: Function ivec_non_uniform()

587: Input :
588: Output:
589: Return:
590: Description:
591: ***********************************ivec.c*************************************/
592: void 
593: ivec_non_uniform(int *arg1, int *arg2,  int n,  int *arg3)
594: {
595:    int i, j, type;


598:   /* LATER: if we're really motivated we can sort and then unsort */
599:   for (i=0;i<n;)
600:     {
601:       /* clump 'em for now */
602:       j=i+1;
603:       type = arg3[i];
604:       while ((j<n)&&(arg3[j]==type))
605:         {j++;}
606: 
607:       /* how many together */
608:       j -= i;

610:       /* call appropriate ivec function */
611:       if (type == GL_MAX)
612:         {ivec_max(arg1,arg2,j);}
613:       else if (type == GL_MIN)
614:         {ivec_min(arg1,arg2,j);}
615:       else if (type == GL_MULT)
616:         {ivec_mult(arg1,arg2,j);}
617:       else if (type == GL_ADD)
618:         {ivec_add(arg1,arg2,j);}
619:       else if (type == GL_B_XOR)
620:         {ivec_xor(arg1,arg2,j);}
621:       else if (type == GL_B_OR)
622:         {ivec_or(arg1,arg2,j);}
623:       else if (type == GL_B_AND)
624:         {ivec_and(arg1,arg2,j);}
625:       else if (type == GL_L_XOR)
626:         {ivec_lxor(arg1,arg2,j);}
627:       else if (type == GL_L_OR)
628:         {ivec_lor(arg1,arg2,j);}
629:       else if (type == GL_L_AND)
630:         {ivec_land(arg1,arg2,j);}
631:       else
632:         {error_msg_fatal("unrecognized type passed to ivec_non_uniform()!");}

634:       arg1+=j; arg2+=j; i+=j;
635:     }
636: }



640: /**********************************ivec.c**************************************
641: Function ivec_addr()

643: Input :
644: Output:
645: Return:
646: Description:
647: ***********************************ivec.c*************************************/
648: vfp ivec_fct_addr( int type)
649: {
650:   if (type == NON_UNIFORM)
651:     {return((void (*)(void*, void *, int, ...))&ivec_non_uniform);}
652:   else if (type == GL_MAX)
653:     {return((void (*)(void*, void *, int, ...))&ivec_max);}
654:   else if (type == GL_MIN)
655:     {return((void (*)(void*, void *, int, ...))&ivec_min);}
656:   else if (type == GL_MULT)
657:     {return((void (*)(void*, void *, int, ...))&ivec_mult);}
658:   else if (type == GL_ADD)
659:     {return((void (*)(void*, void *, int, ...))&ivec_add);}
660:   else if (type == GL_B_XOR)
661:     {return((void (*)(void*, void *, int, ...))&ivec_xor);}
662:   else if (type == GL_B_OR)
663:     {return((void (*)(void*, void *, int, ...))&ivec_or);}
664:   else if (type == GL_B_AND)
665:     {return((void (*)(void*, void *, int, ...))&ivec_and);}
666:   else if (type == GL_L_XOR)
667:     {return((void (*)(void*, void *, int, ...))&ivec_lxor);}
668:   else if (type == GL_L_OR)
669:     {return((void (*)(void*, void *, int, ...))&ivec_lor);}
670:   else if (type == GL_L_AND)
671:     {return((void (*)(void*, void *, int, ...))&ivec_land);}

673:   /* catch all ... not good if we get here */
674:   return(NULL);
675: }


678: /**********************************ivec.c**************************************
679: Function ct_bits()

681: Input :
682: Output:
683: Return:
684: Description: MUST FIX THIS!!!
685: ***********************************ivec.c*************************************/
686: #if defined(notusing)
687: static
688: int 
689: ivec_ct_bits( int *ptr,  int n)
690: {
691:    int tmp=0;


694:   /* should expand to full 32 bit */
695:   while (n--)
696:     {
697:       if (*ptr&128) {tmp++;}
698:       if (*ptr&64)  {tmp++;}
699:       if (*ptr&32)  {tmp++;}
700:       if (*ptr&16)  {tmp++;}
701:       if (*ptr&8)   {tmp++;}
702:       if (*ptr&4)   {tmp++;}
703:       if (*ptr&2)   {tmp++;}
704:       if (*ptr&1)   {tmp++;}
705:       ptr++;
706:     }

708:   return(tmp);
709: }
710: #endif


713: /******************************************************************************
714: Function: ivec_sort().

716: Input : offset of list to be sorted, number of elements to be sorted.
717: Output: sorted list (in ascending order).
718: Return: none.
719: Description: stack based (nonrecursive) quicksort w/brute-shell bottom. 
720: ******************************************************************************/
721: void
722: ivec_sort( int *ar,  int size)
723: {
724:    int *pi, *pj, temp;
725:    int **top_a = (int **) offset_stack;
726:    int *top_s = size_stack, *bottom_s = size_stack;


729:   /* we're really interested in the offset of the last element */
730:   /* ==> length of the list is now size + 1                    */
731:   size--;

733:   /* do until we're done ... return when stack is exhausted */
734:   for (;;)
735:     {
736:       /* if list is large enough use quicksort partition exchange code */
737:       if (size > SORT_OPT)
738:         {
739:           /* start up pointer at element 1 and down at size     */
740:           pi = ar+1;
741:           pj = ar+size;

743:           /* find middle element in list and swap w/ element 1 */
744:           SWAP(*(ar+(size>>1)),*pi)

746:           /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
747:           /* note ==> pivot_value in index 0                   */
748:           if (*pi > *pj)
749:             {SWAP(*pi,*pj)}
750:           if (*ar > *pj)
751:             {SWAP(*ar,*pj)}
752:           else if (*pi > *ar)
753:             {SWAP(*(ar),*(ar+1))}

755:           /* partition about pivot_value ...                              */
756:           /* note lists of length 2 are not guaranteed to be sorted */
757:           for(;;)
758:             {
759:               /* walk up ... and down ... swap if equal to pivot! */
760:               do pi++; while (*pi<*ar);
761:               do pj--; while (*pj>*ar);

763:               /* if we've crossed we're done */
764:               if (pj<pi) break;

766:               /* else swap */
767:               SWAP(*pi,*pj)
768:             }

770:           /* place pivot_value in it's correct location */
771:           SWAP(*ar,*pj)

773:           /* test stack_size to see if we've exhausted our stack */
774:           if (top_s-bottom_s >= SORT_STACK)
775:             {error_msg_fatal("ivec_sort() :: STACK EXHAUSTED!!!");}

777:           /* push right hand child iff length > 1 */
778:           if ((*top_s = size-((int) (pi-ar))))
779:             {
780:               *(top_a++) = pi;
781:               size -= *top_s+2;
782:               top_s++;
783:             }
784:           /* set up for next loop iff there is something to do */
785:           else if (size -= *top_s+2)
786:             {;}
787:           /* might as well pop - note NR_OPT >=2 ==> we're ok! */
788:           else
789:             {
790:               ar = *(--top_a);
791:               size = *(--top_s);
792:             }
793:         }

795:       /* else sort small list directly then pop another off stack */
796:       else
797:         {
798:           /* insertion sort for bottom */
799:           for (pj=ar+1;pj<=ar+size;pj++)
800:             {
801:               temp = *pj;
802:               for (pi=pj-1;pi>=ar;pi--)
803:                 {
804:                   if (*pi <= temp) break;
805:                   *(pi+1)=*pi;
806:                 }
807:               *(pi+1)=temp;
808:             }

810:           /* check to see if stack is exhausted ==> DONE */
811:           if (top_s==bottom_s) return;
812: 
813:           /* else pop another list from the stack */
814:           ar = *(--top_a);
815:           size = *(--top_s);
816:         }
817:     }
818: }



822: /******************************************************************************
823: Function: ivec_sort_companion().

825: Input : offset of list to be sorted, number of elements to be sorted.
826: Output: sorted list (in ascending order).
827: Return: none.
828: Description: stack based (nonrecursive) quicksort w/brute-shell bottom. 
829: ******************************************************************************/
830: void
831: ivec_sort_companion( int *ar,  int *ar2,  int size)
832: {
833:    int *pi, *pj, temp, temp2;
834:    int **top_a = (int **)offset_stack;
835:    int *top_s = size_stack, *bottom_s = size_stack;
836:    int *pi2, *pj2;
837:    int mid;


840:   /* we're really interested in the offset of the last element */
841:   /* ==> length of the list is now size + 1                    */
842:   size--;

844:   /* do until we're done ... return when stack is exhausted */
845:   for (;;)
846:     {
847:       /* if list is large enough use quicksort partition exchange code */
848:       if (size > SORT_OPT)
849:         {
850:           /* start up pointer at element 1 and down at size     */
851:           mid = size>>1;
852:           pi = ar+1;
853:           pj = ar+mid;
854:           pi2 = ar2+1;
855:           pj2 = ar2+mid;

857:           /* find middle element in list and swap w/ element 1 */
858:           SWAP(*pi,*pj)
859:           SWAP(*pi2,*pj2)

861:           /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
862:           /* note ==> pivot_value in index 0                   */
863:           pj = ar+size;
864:           pj2 = ar2+size;
865:           if (*pi > *pj)
866:             {SWAP(*pi,*pj) SWAP(*pi2,*pj2)}
867:           if (*ar > *pj)
868:             {SWAP(*ar,*pj) SWAP(*ar2,*pj2)}
869:           else if (*pi > *ar)
870:             {SWAP(*(ar),*(ar+1)) SWAP(*(ar2),*(ar2+1))}

872:           /* partition about pivot_value ...                              */
873:           /* note lists of length 2 are not guaranteed to be sorted */
874:           for(;;)
875:             {
876:               /* walk up ... and down ... swap if equal to pivot! */
877:               do {pi++; pi2++;} while (*pi<*ar);
878:               do {pj--; pj2--;} while (*pj>*ar);

880:               /* if we've crossed we're done */
881:               if (pj<pi) break;

883:               /* else swap */
884:               SWAP(*pi,*pj)
885:               SWAP(*pi2,*pj2)
886:             }

888:           /* place pivot_value in it's correct location */
889:           SWAP(*ar,*pj)
890:           SWAP(*ar2,*pj2)

892:           /* test stack_size to see if we've exhausted our stack */
893:           if (top_s-bottom_s >= SORT_STACK)
894:             {error_msg_fatal("ivec_sort_companion() :: STACK EXHAUSTED!!!");}

896:           /* push right hand child iff length > 1 */
897:           if ((*top_s = size-((int) (pi-ar))))
898:             {
899:               *(top_a++) = pi;
900:               *(top_a++) = pi2;
901:               size -= *top_s+2;
902:               top_s++;
903:             }
904:           /* set up for next loop iff there is something to do */
905:           else if (size -= *top_s+2)
906:             {;}
907:           /* might as well pop - note NR_OPT >=2 ==> we're ok! */
908:           else
909:             {
910:               ar2 = *(--top_a);
911:               ar  = *(--top_a);
912:               size = *(--top_s);
913:             }
914:         }

916:       /* else sort small list directly then pop another off stack */
917:       else
918:         {
919:           /* insertion sort for bottom */
920:           for (pj=ar+1, pj2=ar2+1;pj<=ar+size;pj++,pj2++)
921:             {
922:               temp = *pj;
923:               temp2 = *pj2;
924:               for (pi=pj-1,pi2=pj2-1;pi>=ar;pi--,pi2--)
925:                 {
926:                   if (*pi <= temp) break;
927:                   *(pi+1)=*pi;
928:                   *(pi2+1)=*pi2;
929:                 }
930:               *(pi+1)=temp;
931:               *(pi2+1)=temp2;
932:             }

934:           /* check to see if stack is exhausted ==> DONE */
935:           if (top_s==bottom_s) return;
936: 
937:           /* else pop another list from the stack */
938:           ar2 = *(--top_a);
939:           ar  = *(--top_a);
940:           size = *(--top_s);
941:         }
942:     }
943: }



947: /******************************************************************************
948: Function: ivec_sort_companion_hack().

950: Input : offset of list to be sorted, number of elements to be sorted.
951: Output: sorted list (in ascending order).
952: Return: none.
953: Description: stack based (nonrecursive) quicksort w/brute-shell bottom. 
954: ******************************************************************************/
955: void
956: ivec_sort_companion_hack( int *ar,  int **ar2, 
957:                           int size)
958: {
959:    int *pi, *pj, temp, *ptr;
960:    int **top_a = (int **)offset_stack;
961:    int *top_s = size_stack, *bottom_s = size_stack;
962:    int **pi2, **pj2;
963:    int mid;


966:   /* we're really interested in the offset of the last element */
967:   /* ==> length of the list is now size + 1                    */
968:   size--;

970:   /* do until we're done ... return when stack is exhausted */
971:   for (;;)
972:     {
973:       /* if list is large enough use quicksort partition exchange code */
974:       if (size > SORT_OPT)
975:         {
976:           /* start up pointer at element 1 and down at size     */
977:           mid = size>>1;
978:           pi = ar+1;
979:           pj = ar+mid;
980:           pi2 = ar2+1;
981:           pj2 = ar2+mid;

983:           /* find middle element in list and swap w/ element 1 */
984:           SWAP(*pi,*pj)
985:           P_SWAP(*pi2,*pj2)

987:           /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
988:           /* note ==> pivot_value in index 0                   */
989:           pj = ar+size;
990:           pj2 = ar2+size;
991:           if (*pi > *pj)
992:             {SWAP(*pi,*pj) P_SWAP(*pi2,*pj2)}
993:           if (*ar > *pj)
994:             {SWAP(*ar,*pj) P_SWAP(*ar2,*pj2)}
995:           else if (*pi > *ar)
996:             {SWAP(*(ar),*(ar+1)) P_SWAP(*(ar2),*(ar2+1))}

998:           /* partition about pivot_value ...                              */
999:           /* note lists of length 2 are not guaranteed to be sorted */
1000:           for(;;)
1001:             {
1002:               /* walk up ... and down ... swap if equal to pivot! */
1003:               do {pi++; pi2++;} while (*pi<*ar);
1004:               do {pj--; pj2--;} while (*pj>*ar);

1006:               /* if we've crossed we're done */
1007:               if (pj<pi) break;

1009:               /* else swap */
1010:               SWAP(*pi,*pj)
1011:               P_SWAP(*pi2,*pj2)
1012:             }

1014:           /* place pivot_value in it's correct location */
1015:           SWAP(*ar,*pj)
1016:           P_SWAP(*ar2,*pj2)

1018:           /* test stack_size to see if we've exhausted our stack */
1019:           if (top_s-bottom_s >= SORT_STACK)
1020:          {error_msg_fatal("ivec_sort_companion_hack() :: STACK EXHAUSTED!!!");}

1022:           /* push right hand child iff length > 1 */
1023:           if ((*top_s = size-((int) (pi-ar))))
1024:             {
1025:               *(top_a++) = pi;
1026:               *(top_a++) = (int*) pi2;
1027:               size -= *top_s+2;
1028:               top_s++;
1029:             }
1030:           /* set up for next loop iff there is something to do */
1031:           else if (size -= *top_s+2)
1032:             {;}
1033:           /* might as well pop - note NR_OPT >=2 ==> we're ok! */
1034:           else
1035:             {
1036:               ar2 = (int **) *(--top_a);
1037:               ar  = *(--top_a);
1038:               size = *(--top_s);
1039:             }
1040:         }

1042:       /* else sort small list directly then pop another off stack */
1043:       else
1044:         {
1045:           /* insertion sort for bottom */
1046:           for (pj=ar+1, pj2=ar2+1;pj<=ar+size;pj++,pj2++)
1047:             {
1048:               temp = *pj;
1049:               ptr = *pj2;
1050:               for (pi=pj-1,pi2=pj2-1;pi>=ar;pi--,pi2--)
1051:                 {
1052:                   if (*pi <= temp) break;
1053:                   *(pi+1)=*pi;
1054:                   *(pi2+1)=*pi2;
1055:                 }
1056:               *(pi+1)=temp;
1057:               *(pi2+1)=ptr;
1058:             }

1060:           /* check to see if stack is exhausted ==> DONE */
1061:           if (top_s==bottom_s) return;
1062: 
1063:           /* else pop another list from the stack */
1064:           ar2 = (int **)*(--top_a);
1065:           ar  = *(--top_a);
1066:           size = *(--top_s);
1067:         }
1068:     }
1069: }



1073: /******************************************************************************
1074: Function: SMI_sort().
1075: Input : offset of list to be sorted, number of elements to be sorted.
1076: Output: sorted list (in ascending order).
1077: Return: none.
1078: Description: stack based (nonrecursive) quicksort w/brute-shell bottom. 
1079: ******************************************************************************/
1080: void
1081: SMI_sort(void *ar1, void *ar2, int size, int type)
1082: {
1083:   if (type == SORT_INTEGER)
1084:     {
1085:       if (ar2)
1086:         {ivec_sort_companion((int*)ar1,(int*)ar2,size);}
1087:       else
1088:         {ivec_sort((int*)ar1,size);}
1089:     }
1090:   else if (type == SORT_INT_PTR)
1091:     {
1092:       if (ar2)
1093:         {ivec_sort_companion_hack((int*)ar1,(int **)ar2,size);}
1094:       else
1095:         {ivec_sort((int*)ar1,size);}
1096:     }

1098:   else
1099:     {
1100:       error_msg_fatal("SMI_sort only does SORT_INTEGER!");
1101:     }
1102: /*
1103:   if (type == SORT_REAL)
1104:     {
1105:       if (ar2)
1106:         {rvec_sort_companion(ar2,ar1,size);}
1107:       else
1108:         {rvec_sort(ar1,size);}
1109:     }
1110: */
1111: }



1115: /**********************************ivec.c**************************************
1116: Function ivec_linear_search()

1118: Input :
1119: Output:
1120: Return:
1121: Description:
1122: ***********************************ivec.c*************************************/
1123: int
1124: ivec_linear_search( int item,  int *list,  int n)
1125: {
1126:    int tmp = n-1;

1128:   while (n--)  {if (*list++ == item) {return(tmp-n);}}
1129:   return(-1);
1130: }



1134: /**********************************ivec.c**************************************
1135: Function ivec_binary_search()

1137: Input :
1138: Output:
1139: Return:
1140: Description:
1141: ***********************************ivec.c*************************************/
1142: int
1143: ivec_binary_search( int item,  int *list,  int rh)
1144: {
1145:    int mid, lh=0;

1147:   rh--;
1148:   while (lh<=rh)
1149:     {
1150:       mid = (lh+rh)>>1;
1151:       if (*(list+mid) == item)
1152:         {return(mid);}
1153:       if (*(list+mid) > item)
1154:         {rh = mid-1;}
1155:       else
1156:         {lh = mid+1;}
1157:     }
1158:   return(-1);
1159: }



1163: /**********************************ivec.c**************************************
1164: Function rvec_dump

1166: Input : 
1167: Output: 
1168: Return: 
1169: Description: 
1170: ***********************************ivec.c*************************************/
1171: void
1172: rvec_dump(PetscScalar *v, int n, int tag, int tag2, char * s)
1173: {
1174:   int i;
1175:   printf("%2d %2d %s %2d :: ",tag,tag2,s,my_id);
1176:   for (i=0;i<n;i++)
1177:     {printf("%f ",v[i]);}
1178:   printf("\n");
1179:   fflush(stdout);
1180: }



1184: /**********************************ivec.c**************************************
1185: Function rvec_lb_ub()

1187: Input :
1188: Output:
1189: Return:
1190: Description:
1191: ***********************************ivec.c*************************************/
1192: void
1193: rvec_lb_ub( PetscScalar *arg1,  int n, PetscScalar *lb, PetscScalar *ub)
1194: {
1195:    PetscScalar min =  REAL_MAX;
1196:    PetscScalar max = -REAL_MAX;

1198:   while (n--)
1199:     {
1200:      min = PetscMin(min,*arg1);
1201:      max = PetscMax(max,*arg1);
1202:      arg1++;
1203:     }

1205:   *lb=min;
1206:   *ub=max;
1207: }



1211: /********************************ivec.c**************************************
1212: Function rvec_copy()

1214: Input :
1215: Output:
1216: Return:
1217: Description:
1218: *********************************ivec.c*************************************/
1219: void 
1220: rvec_copy( PetscScalar *arg1,  PetscScalar *arg2,  int n)
1221: {
1222:   while (n--)  {*arg1++ = *arg2++;}
1223: }



1227: /********************************ivec.c**************************************
1228: Function rvec_zero()

1230: Input :
1231: Output:
1232: Return:
1233: Description:
1234: *********************************ivec.c*************************************/
1235: void 
1236: rvec_zero( PetscScalar *arg1,  int n)
1237: {
1238:   while (n--)  {*arg1++ = 0.0;}
1239: }



1243: /**********************************ivec.c**************************************
1244: Function rvec_one()

1246: Input :
1247: Output:
1248: Return:
1249: Description:
1250: ***********************************ivec.c*************************************/
1251: void 
1252: rvec_one( PetscScalar *arg1,  int n)
1253: {
1254:   while (n--)  {*arg1++ = 1.0;}
1255: }



1259: /**********************************ivec.c**************************************
1260: Function rvec_neg_one()

1262: Input :
1263: Output:
1264: Return:
1265: Description:
1266: ***********************************ivec.c*************************************/
1267: void 
1268: rvec_neg_one( PetscScalar *arg1,  int n)
1269: {
1270:   while (n--)  {*arg1++ = -1.0;}
1271: }



1275: /**********************************ivec.c**************************************
1276: Function rvec_set()

1278: Input :
1279: Output:
1280: Return:
1281: Description:
1282: ***********************************ivec.c*************************************/
1283: void
1284: rvec_set( PetscScalar *arg1,  PetscScalar arg2,  int n)
1285: {
1286:   while (n--)  {*arg1++ = arg2;}
1287: }



1291: /**********************************ivec.c**************************************
1292: Function rvec_scale()

1294: Input :
1295: Output:
1296: Return:
1297: Description:
1298: ***********************************ivec.c*************************************/
1299: void
1300: rvec_scale( PetscScalar *arg1,  PetscScalar arg2,  int n)
1301: {
1302:   while (n--)  {*arg1++ *= arg2;}
1303: }



1307: /********************************ivec.c**************************************
1308: Function rvec_add()

1310: Input :
1311: Output:
1312: Return:
1313: Description:
1314: *********************************ivec.c*************************************/
1315: void 
1316: rvec_add( PetscScalar *arg1,  PetscScalar *arg2,  int n)
1317: {
1318:   while (n--)  {*arg1++ += *arg2++;}
1319: }



1323: /********************************ivec.c**************************************
1324: Function rvec_dot()

1326: Input :
1327: Output:
1328: Return:
1329: Description:
1330: *********************************ivec.c*************************************/
1331: PetscScalar
1332: rvec_dot( PetscScalar *arg1,  PetscScalar *arg2,  int n)
1333: {
1334:   PetscScalar dot=0.0;

1336:   while (n--)  {dot+= *arg1++ * *arg2++;}

1338:   return(dot);
1339: }



1343: /********************************ivec.c**************************************
1344: Function rvec_axpy()

1346: Input :
1347: Output:
1348: Return:
1349: Description:
1350: *********************************ivec.c*************************************/
1351: void
1352: rvec_axpy( PetscScalar *arg1,  PetscScalar *arg2,  PetscScalar scale, 
1353:            int n)
1354: {
1355:   while (n--)  {*arg1++ += scale * *arg2++;}
1356: }


1359: /********************************ivec.c**************************************
1360: Function rvec_mult()

1362: Input :
1363: Output:
1364: Return:
1365: Description:
1366: *********************************ivec.c*************************************/
1367: void 
1368: rvec_mult( PetscScalar *arg1,  PetscScalar *arg2,  int n)
1369: {
1370:   while (n--)  {*arg1++ *= *arg2++;}
1371: }



1375: /********************************ivec.c**************************************
1376: Function rvec_max()

1378: Input :
1379: Output:
1380: Return:
1381: Description:
1382: *********************************ivec.c*************************************/
1383: void 
1384: rvec_max( PetscScalar *arg1,  PetscScalar *arg2,  int n)
1385: {
1386:   while (n--)  {*arg1 = PetscMax(*arg1,*arg2); arg1++; arg2++;}
1387: }



1391: /********************************ivec.c**************************************
1392: Function rvec_max_abs()

1394: Input :
1395: Output:
1396: Return:
1397: Description:
1398: *********************************ivec.c*************************************/
1399: void 
1400: rvec_max_abs( PetscScalar *arg1,  PetscScalar *arg2,  int n)
1401: {
1402:   while (n--)  {*arg1 = MAX_FABS(*arg1,*arg2); arg1++; arg2++;}
1403: }



1407: /********************************ivec.c**************************************
1408: Function rvec_min()

1410: Input :
1411: Output:
1412: Return:
1413: Description:
1414: *********************************ivec.c*************************************/
1415: void 
1416: rvec_min( PetscScalar *arg1,  PetscScalar *arg2,  int n)
1417: {
1418:   while (n--)  {*arg1 = PetscMin(*arg1,*arg2); arg1++; arg2++;}
1419: }



1423: /********************************ivec.c**************************************
1424: Function rvec_min_abs()

1426: Input :
1427: Output:
1428: Return:
1429: Description:
1430: *********************************ivec.c*************************************/
1431: void 
1432: rvec_min_abs( PetscScalar *arg1,  PetscScalar *arg2,  int n)
1433: {
1434:   while (n--)  {*arg1 = MIN_FABS(*arg1,*arg2); arg1++; arg2++;}
1435: }



1439: /********************************ivec.c**************************************
1440: Function rvec_exists()

1442: Input :
1443: Output:
1444: Return:
1445: Description:
1446: *********************************ivec.c*************************************/
1447: void 
1448: rvec_exists( PetscScalar *arg1,  PetscScalar *arg2,  int n)
1449: {
1450:   while (n--)  {*arg1 = EXISTS(*arg1,*arg2); arg1++; arg2++;}
1451: }



1455: /**********************************ivec.c**************************************
1456: Function rvec_non_uniform()

1458: Input :
1459: Output:
1460: Return:
1461: Description:
1462: ***********************************ivec.c*************************************/
1463: void 
1464: rvec_non_uniform(PetscScalar *arg1, PetscScalar *arg2,  int n,  int *arg3)
1465: {
1466:    int i, j, type;


1469:   /* LATER: if we're really motivated we can sort and then unsort */
1470:   for (i=0;i<n;)
1471:     {
1472:       /* clump 'em for now */
1473:       j=i+1;
1474:       type = arg3[i];
1475:       while ((j<n)&&(arg3[j]==type))
1476:         {j++;}
1477: 
1478:       /* how many together */
1479:       j -= i;

1481:       /* call appropriate ivec function */
1482:       if (type == GL_MAX)
1483:         {rvec_max(arg1,arg2,j);}
1484:       else if (type == GL_MIN)
1485:         {rvec_min(arg1,arg2,j);}
1486:       else if (type == GL_MULT)
1487:         {rvec_mult(arg1,arg2,j);}
1488:       else if (type == GL_ADD)
1489:         {rvec_add(arg1,arg2,j);}
1490:       else if (type == GL_MAX_ABS)
1491:         {rvec_max_abs(arg1,arg2,j);}
1492:       else if (type == GL_MIN_ABS)
1493:         {rvec_min_abs(arg1,arg2,j);}
1494:       else if (type == GL_EXISTS)
1495:         {rvec_exists(arg1,arg2,j);}
1496:       else
1497:         {error_msg_fatal("unrecognized type passed to rvec_non_uniform()!");}

1499:       arg1+=j; arg2+=j; i+=j;
1500:     }
1501: }



1505: /**********************************ivec.c**************************************
1506: Function rvec_fct_addr()

1508: Input :
1509: Output:
1510: Return:
1511: Description:
1512: ***********************************ivec.c*************************************/
1513: vfp rvec_fct_addr( int type)
1514: {
1515:   if (type == NON_UNIFORM)
1516:     {return((void (*)(void*, void *, int, ...))&rvec_non_uniform);}
1517:   else if (type == GL_MAX)
1518:     {return((void (*)(void*, void *, int, ...))&rvec_max);}
1519:   else if (type == GL_MIN)
1520:     {return((void (*)(void*, void *, int, ...))&rvec_min);}
1521:   else if (type == GL_MULT)
1522:     {return((void (*)(void*, void *, int, ...))&rvec_mult);}
1523:   else if (type == GL_ADD)
1524:     {return((void (*)(void*, void *, int, ...))&rvec_add);}
1525:   else if (type == GL_MAX_ABS)
1526:     {return((void (*)(void*, void *, int, ...))&rvec_max_abs);}
1527:   else if (type == GL_MIN_ABS)
1528:     {return((void (*)(void*, void *, int, ...))&rvec_min_abs);}
1529:   else if (type == GL_EXISTS)
1530:     {return((void (*)(void*, void *, int, ...))&rvec_exists);}

1532:   /* catch all ... not good if we get here */
1533:   return(NULL);
1534: }


1537: /******************************************************************************
1538: Function: my_sort().
1539: Input : offset of list to be sorted, number of elements to be sorted.
1540: Output: sorted list (in ascending order).
1541: Return: none.
1542: Description: stack based (nonrecursive) quicksort w/brute-shell bottom. 
1543: ******************************************************************************/
1544: void
1545: rvec_sort( PetscScalar *ar,  int Size)
1546: {
1547:    PetscScalar *pi, *pj, temp;
1548:    PetscScalar **top_a = (PetscScalar **)offset_stack;
1549:    long *top_s = psize_stack, *bottom_s = psize_stack;
1550:    long size = (long) Size;

1552:   /* we're really interested in the offset of the last element */
1553:   /* ==> length of the list is now size + 1                    */
1554:   size--;

1556:   /* do until we're done ... return when stack is exhausted */
1557:   for (;;)
1558:     {
1559:       /* if list is large enough use quicksort partition exchange code */
1560:       if (size > SORT_OPT)
1561:         {
1562:           /* start up pointer at element 1 and down at size     */
1563:           pi = ar+1;
1564:           pj = ar+size;

1566:           /* find middle element in list and swap w/ element 1 */
1567:           SWAP(*(ar+(size>>1)),*pi)

1569:           pj = ar+size;

1571:           /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
1572:           /* note ==> pivot_value in index 0                   */
1573:           if (*pi > *pj)
1574:             {SWAP(*pi,*pj)}
1575:           if (*ar > *pj)
1576:             {SWAP(*ar,*pj)}
1577:           else if (*pi > *ar)
1578:             {SWAP(*(ar),*(ar+1))}

1580:           /* partition about pivot_value ...                              */
1581:           /* note lists of length 2 are not guaranteed to be sorted */
1582:           for(;;)
1583:             {
1584:               /* walk up ... and down ... swap if equal to pivot! */
1585:               do pi++; while (*pi<*ar);
1586:               do pj--; while (*pj>*ar);

1588:               /* if we've crossed we're done */
1589:               if (pj<pi) break;

1591:               /* else swap */
1592:               SWAP(*pi,*pj)
1593:             }

1595:           /* place pivot_value in it's correct location */
1596:           SWAP(*ar,*pj)

1598:           /* test stack_size to see if we've exhausted our stack */
1599:           if (top_s-bottom_s >= SORT_STACK)
1600:             {error_msg_fatal("\nSTACK EXHAUSTED!!!\n");}

1602:           /* push right hand child iff length > 1 */
1603:           if ((*top_s = size-(pi-ar)))
1604:             {
1605:               *(top_a++) = pi;
1606:               size -= *top_s+2;
1607:               top_s++;
1608:             }
1609:           /* set up for next loop iff there is something to do */
1610:           else if (size -= *top_s+2)
1611:             {;}
1612:           /* might as well pop - note NR_OPT >=2 ==> we're ok! */
1613:           else
1614:             {
1615:               ar = *(--top_a);
1616:               size = *(--top_s);
1617:             }
1618:         }

1620:       /* else sort small list directly then pop another off stack */
1621:       else
1622:         {
1623:           /* insertion sort for bottom */
1624:           for (pj=ar+1;pj<=ar+size;pj++)
1625:             {
1626:               temp = *pj;
1627:               for (pi=pj-1;pi>=ar;pi--)
1628:                 {
1629:                   if (*pi <= temp) break;
1630:                   *(pi+1)=*pi;
1631:                 }
1632:               *(pi+1)=temp;
1633:             }

1635:           /* check to see if stack is exhausted ==> DONE */
1636:           if (top_s==bottom_s) return;
1637: 
1638:           /* else pop another list from the stack */
1639:           ar = *(--top_a);
1640:           size = *(--top_s);
1641:         }
1642:     }
1643: }



1647: /******************************************************************************
1648: Function: my_sort().
1649: Input : offset of list to be sorted, number of elements to be sorted.
1650: Output: sorted list (in ascending order).
1651: Return: none.
1652: Description: stack based (nonrecursive) quicksort w/brute-shell bottom. 
1653: ******************************************************************************/
1654: void
1655: rvec_sort_companion( PetscScalar *ar,  int *ar2,  int Size)
1656: {
1657:    PetscScalar *pi, *pj, temp;
1658:    PetscScalar **top_a = (PetscScalar **)offset_stack;
1659:    long *top_s = psize_stack, *bottom_s = psize_stack;
1660:    long size = (long) Size;

1662:    int *pi2, *pj2;
1663:    int ptr;
1664:    long mid;


1667:   /* we're really interested in the offset of the last element */
1668:   /* ==> length of the list is now size + 1                    */
1669:   size--;

1671:   /* do until we're done ... return when stack is exhausted */
1672:   for (;;)
1673:     {
1674:       /* if list is large enough use quicksort partition exchange code */
1675:       if (size > SORT_OPT)
1676:         {
1677:           /* start up pointer at element 1 and down at size     */
1678:           mid = size>>1;
1679:           pi = ar+1;
1680:           pj = ar+mid;
1681:           pi2 = ar2+1;
1682:           pj2 = ar2+mid;

1684:           /* find middle element in list and swap w/ element 1 */
1685:           SWAP(*pi,*pj)
1686:           P_SWAP(*pi2,*pj2)

1688:           /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
1689:           /* note ==> pivot_value in index 0                   */
1690:           pj = ar+size;
1691:           pj2 = ar2+size;
1692:           if (*pi > *pj)
1693:             {SWAP(*pi,*pj) P_SWAP(*pi2,*pj2)}
1694:           if (*ar > *pj)
1695:             {SWAP(*ar,*pj) P_SWAP(*ar2,*pj2)}
1696:           else if (*pi > *ar)
1697:             {SWAP(*(ar),*(ar+1)) P_SWAP(*(ar2),*(ar2+1))}

1699:           /* partition about pivot_value ...                              */
1700:           /* note lists of length 2 are not guaranteed to be sorted */
1701:           for(;;)
1702:             {
1703:               /* walk up ... and down ... swap if equal to pivot! */
1704:               do {pi++; pi2++;} while (*pi<*ar);
1705:               do {pj--; pj2--;} while (*pj>*ar);

1707:               /* if we've crossed we're done */
1708:               if (pj<pi) break;

1710:               /* else swap */
1711:               SWAP(*pi,*pj)
1712:               P_SWAP(*pi2,*pj2)
1713:             }

1715:           /* place pivot_value in it's correct location */
1716:           SWAP(*ar,*pj)
1717:           P_SWAP(*ar2,*pj2)

1719:           /* test stack_size to see if we've exhausted our stack */
1720:           if (top_s-bottom_s >= SORT_STACK)
1721:             {error_msg_fatal("\nSTACK EXHAUSTED!!!\n");}

1723:           /* push right hand child iff length > 1 */
1724:           if ((*top_s = size-(pi-ar)))
1725:             {
1726:               *(top_a++) = pi;
1727:               *(top_a++) = (PetscScalar *) pi2;
1728:               size -= *top_s+2;
1729:               top_s++;
1730:             }
1731:           /* set up for next loop iff there is something to do */
1732:           else if (size -= *top_s+2)
1733:             {;}
1734:           /* might as well pop - note NR_OPT >=2 ==> we're ok! */
1735:           else
1736:             {
1737:               ar2 = (int*) *(--top_a);
1738:               ar  = *(--top_a);
1739:               size = *(--top_s);
1740:             }
1741:         }

1743:       /* else sort small list directly then pop another off stack */
1744:       else
1745:         {
1746:           /* insertion sort for bottom */
1747:           for (pj=ar+1, pj2=ar2+1;pj<=ar+size;pj++,pj2++)
1748:             {
1749:               temp = *pj;
1750:               ptr = *pj2;
1751:               for (pi=pj-1,pi2=pj2-1;pi>=ar;pi--,pi2--)
1752:                 {
1753:                   if (*pi <= temp) break;
1754:                   *(pi+1)=*pi;
1755:                   *(pi2+1)=*pi2;
1756:                 }
1757:               *(pi+1)=temp;
1758:               *(pi2+1)=ptr;
1759:             }

1761:           /* check to see if stack is exhausted ==> DONE */
1762:           if (top_s==bottom_s) return;
1763: 
1764:           /* else pop another list from the stack */
1765:           ar2 = (int*) *(--top_a);
1766:           ar  = *(--top_a);
1767:           size = *(--top_s);
1768:         }
1769:     }
1770: }





1776: /**********************************ivec.c**************************************
1777: Function ivec_binary_search()

1779: Input :
1780: Output:
1781: Return:
1782: Description:
1783: ***********************************ivec.c*************************************/
1784: int
1785: rvec_binary_search( PetscScalar item,  PetscScalar *list,  int rh)
1786: {
1787:   int mid, lh=0;

1789:   rh--;
1790:   while (lh<=rh)
1791:     {
1792:       mid = (lh+rh)>>1;
1793:       if (*(list+mid) == item)
1794:         {return(mid);}
1795:       if (*(list+mid) > item)
1796:         {rh = mid-1;}
1797:       else
1798:         {lh = mid+1;}
1799:     }
1800:   return(-1);
1801: }