Actual source code: ivec.c

  2: /**********************************ivec.c**************************************
  3: SPARSE GATHER-SCATTER PACKAGE: bss_malloc bss_malloc ivec error comm gs queue

  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 petsc.h
 24: #include <float.h>
 25: #include <limits.h>


 28:  #include const.h
 29:  #include types.h
 30:  #include ivec.h
 31:  #include error.h
 32:  #include comm.h


 35: /* sorting args ivec.c ivec.c ... */
 36: #define   SORT_OPT        6     
 37: #define   SORT_STACK        50000


 40: /* allocate an address and size stack for sorter(s) */
 41: static void *offset_stack[2*SORT_STACK];
 42: static int   size_stack[SORT_STACK];
 43: static PTRINT psize_stack[SORT_STACK];



 47: /**********************************ivec.c**************************************
 48: Function ivec_dump()

 50: Input :
 51: Output:
 52: Return:
 53: Description:
 54: ***********************************ivec.c*************************************/
 55: void
 56: ivec_dump(int *v, int n, int tag, int tag2, char * s)
 57: {
 58:   int i;
 59:   printf("%2d %2d %s %2d :: ",tag,tag2,s,my_id);
 60:   for (i=0;i<n;i++)
 61:     {printf("%2d ",v[i]);}
 62:   printf("\n");
 63:   fflush(stdout);
 64: }



 68: /**********************************ivec.c**************************************
 69: Function ivec_lb_ub()

 71: Input :
 72: Output:
 73: Return:
 74: Description:
 75: ***********************************ivec.c*************************************/
 76: void
 77: ivec_lb_ub(register int *arg1, register int n, int *lb, int *ub)
 78: {
 79:   register int min = INT_MAX;
 80:   register int max = INT_MIN;

 82:   while (n--)
 83:     {
 84:      min = PetscMin(min,*arg1);
 85:      max = PetscMax(max,*arg1);
 86:      arg1++;
 87:     }

 89:   *lb=min;
 90:   *ub=max;
 91: }



 95: /**********************************ivec.c**************************************
 96: Function ivec_copy()

 98: Input :
 99: Output:
100: Return:
101: Description:
102: ***********************************ivec.c*************************************/
103: int *ivec_copy(register int *arg1, register int *arg2, register int n)
104: {
105:   while (n--)  {*arg1++ = *arg2++;}
106:   return(arg1);
107: }



111: /**********************************ivec.c**************************************
112: Function ivec_zero()

114: Input :
115: Output:
116: Return:
117: Description:
118: ***********************************ivec.c*************************************/
119: void 
120: ivec_zero(register int *arg1, register int n)
121: {
122:   while (n--)  {*arg1++ = 0;}
123: }



127: /**********************************ivec.c**************************************
128: Function ivec_comp()

130: Input :
131: Output:
132: Return:
133: Description:
134: ***********************************ivec.c*************************************/
135: void 
136: ivec_comp(register int *arg1, register int n)
137: {
138:   while (n--)  {*arg1 = ~*arg1; arg1++;}
139: }



143: /**********************************ivec.c**************************************
144: Function ivec_neg_one()

146: Input :
147: Output:
148: Return:
149: Description:
150: ***********************************ivec.c*************************************/
151: void 
152: ivec_neg_one(register int *arg1, register int n)
153: {
154:   while (n--)  {*arg1++ = -1;}
155: }



159: /**********************************ivec.c**************************************
160: Function ivec_pos_one()

162: Input :
163: Output:
164: Return:
165: Description:
166: ***********************************ivec.c*************************************/
167: void 
168: ivec_pos_one(register int *arg1, register int n)
169: {
170:   while (n--)  {*arg1++ = 1;}
171: }



175: /**********************************ivec.c**************************************
176: Function ivec_c_index()

178: Input :
179: Output:
180: Return:
181: Description:
182: ***********************************ivec.c*************************************/
183: void 
184: ivec_c_index(register int *arg1, register int n)
185: {
186:   register int i=0;


189:   while (n--)  {*arg1++ = i++;}
190: }



194: /**********************************ivec.c**************************************
195: Function ivec_fortran_index()

197: Input :
198: Output:
199: Return:
200: Description:
201: ***********************************ivec.c*************************************/
202: void 
203: ivec_fortran_index(register int *arg1, register int n)
204: {
205:   register int i=0;


208:   while (n--)  {*arg1++ = ++i;}
209: }



213: /**********************************ivec.c**************************************
214: Function ivec_set()

216: Input :
217: Output:
218: Return:
219: Description:
220: ***********************************ivec.c*************************************/
221: void 
222: ivec_set(register int *arg1, register int arg2, register int n)
223: {
224:   while (n--)  {*arg1++ = arg2;}
225: }



229: /**********************************ivec.c**************************************
230: Function ivec_cmp()

232: Input :
233: Output:
234: Return:
235: Description:
236: ***********************************ivec.c*************************************/
237: int
238: ivec_cmp(register int *arg1, register int *arg2, register int n)
239: {
240:   while (n--)  {if (*arg1++ != *arg2++)  {return(FALSE);}}
241:   return(TRUE);
242: }



246: /**********************************ivec.c**************************************
247: Function ivec_max()

249: Input :
250: Output:
251: Return:
252: Description:
253: ***********************************ivec.c*************************************/
254: void 
255: ivec_max(register int *arg1, register int *arg2, register int n)
256: {
257:   while (n--)  {*arg1 = PetscMax(*arg1,*arg2); arg1++; arg2++;}
258: }



262: /**********************************ivec.c**************************************
263: Function ivec_min()

265: Input :
266: Output:
267: Return:
268: Description:
269: ***********************************ivec.c*************************************/
270: void 
271: ivec_min(register int *arg1, register int *arg2, register int n)
272: {
273:   while (n--)  {*(arg1) = PetscMin(*arg1,*arg2); arg1++; arg2++;}
274: }



278: /**********************************ivec.c**************************************
279: Function ivec_mult()

281: Input :
282: Output:
283: Return:
284: Description:
285: ***********************************ivec.c*************************************/
286: void 
287: ivec_mult(register int *arg1, register int *arg2, register int n)
288: {
289:   while (n--)  {*arg1++ *= *arg2++;}
290: }



294: /**********************************ivec.c**************************************
295: Function ivec_add()

297: Input :
298: Output:
299: Return:
300: Description:
301: ***********************************ivec.c*************************************/
302: void 
303: ivec_add(register int *arg1, register int *arg2, register int n)
304: {
305:   while (n--)  {*arg1++ += *arg2++;}
306: }



310: /**********************************ivec.c**************************************
311: Function ivec_lxor()

313: Input :
314: Output:
315: Return:
316: Description:
317: ***********************************ivec.c*************************************/
318: void 
319: ivec_lxor(register int *arg1, register int *arg2, register int n)
320: {
321:   while (n--) {*arg1=((*arg1 || *arg2) && !(*arg1 && *arg2)); arg1++; arg2++;}
322: }



326: /**********************************ivec.c**************************************
327: Function ivec_xor()

329: Input :
330: Output:
331: Return:
332: Description:
333: ***********************************ivec.c*************************************/
334: void 
335: ivec_xor(register int *arg1, register int *arg2, register int n)
336: {
337:   while (n--)  {*arg1++ ^= *arg2++;}
338: }



342: /**********************************ivec.c**************************************
343: Function ivec_or()

345: Input :
346: Output:
347: Return:
348: Description:
349: ***********************************ivec.c*************************************/
350: void 
351: ivec_or(register int *arg1, register int *arg2, register int n)
352: {
353:   while (n--)  {*arg1++ |= *arg2++;}
354: }



358: /**********************************ivec.c**************************************
359: Function ivec_lor()

361: Input :
362: Output:
363: Return:
364: Description:
365: ***********************************ivec.c*************************************/
366: void 
367: ivec_lor(register int *arg1, register int *arg2, register int n)
368: {
369:   while (n--)  {*arg1 = (*arg1 || *arg2); arg1++; arg2++;}
370: }



374: /**********************************ivec.c**************************************
375: Function ivec_or3()

377: Input :
378: Output:
379: Return:
380: Description:
381: ***********************************ivec.c*************************************/
382: void 
383: ivec_or3(register int *arg1, register int *arg2, register int *arg3, 
384:          register int n)
385: {
386:   while (n--)  {*arg1++ = (*arg2++ | *arg3++);}
387: }



391: /**********************************ivec.c**************************************
392: Function ivec_and()

394: Input :
395: Output:
396: Return:
397: Description:
398: ***********************************ivec.c*************************************/
399: void 
400: ivec_and(register int *arg1, register int *arg2, register int n)
401: {
402:   while (n--)  {*arg1++ &= *arg2++;}
403: }



407: /**********************************ivec.c**************************************
408: Function ivec_land()

410: Input :
411: Output:
412: Return:
413: Description:
414: ***********************************ivec.c*************************************/
415: void 
416: ivec_land(register int *arg1, register int *arg2, register int n)
417: {
418:   while (n--) {*arg1 = (*arg1 && *arg2); arg1++; arg2++;}
419: }



423: /**********************************ivec.c**************************************
424: Function ivec_and3()

426: Input :
427: Output:
428: Return:
429: Description:
430: ***********************************ivec.c*************************************/
431: void 
432: ivec_and3(register int *arg1, register int *arg2, register int *arg3, 
433:           register int n)
434: {
435:   while (n--)  {*arg1++ = (*arg2++ & *arg3++);}
436: }



440: /**********************************ivec.c**************************************
441: Function ivec_sum

443: Input : 
444: Output: 
445: Return: 
446: Description: 
447: ***********************************ivec.c*************************************/
448: int ivec_sum(register int *arg1, register int n)
449: {
450:   register int tmp = 0;


453:   while (n--) {tmp += *arg1++;}
454:   return(tmp);
455: }



459: /**********************************ivec.c**************************************
460: Function ivec_reduce_and

462: Input : 
463: Output: 
464: Return: 
465: Description: 
466: ***********************************ivec.c*************************************/
467: int ivec_reduce_and(register int *arg1, register int n)
468: {
469:   register int tmp = ALL_ONES;


472:   while (n--) {tmp &= *arg1++;}
473:   return(tmp);
474: }



478: /**********************************ivec.c**************************************
479: Function ivec_reduce_or

481: Input : 
482: Output: 
483: Return: 
484: Description: 
485: ***********************************ivec.c*************************************/
486: int ivec_reduce_or(register int *arg1, register int n)
487: {
488:   register int tmp = 0;


491:   while (n--) {tmp |= *arg1++;}
492:   return(tmp);
493: }



497: /**********************************ivec.c**************************************
498: Function ivec_prod

500: Input : 
501: Output: 
502: Return: 
503: Description: 
504: ***********************************ivec.c*************************************/
505: int ivec_prod(register int *arg1, register int n)
506: {
507:   register int tmp = 1;


510:   while (n--)  {tmp *= *arg1++;}
511:   return(tmp);
512: }



516: /**********************************ivec.c**************************************
517: Function ivec_u_sum

519: Input : 
520: Output: 
521: Return: 
522: Description: 
523: ***********************************ivec.c*************************************/
524: int ivec_u_sum(register unsigned *arg1, register int n)
525: {
526:   register unsigned tmp = 0;


529:   while (n--)  {tmp += *arg1++;}
530:   return(tmp);
531: }



535: /**********************************ivec.c**************************************
536: Function ivec_lb()

538: Input :
539: Output:
540: Return:
541: Description:
542: ***********************************ivec.c*************************************/
543: int 
544: ivec_lb(register int *arg1, register int n)
545: {
546:   register int min = INT_MAX;


549:   while (n--)  {min = PetscMin(min,*arg1); arg1++;}
550:   return(min);
551: }



555: /**********************************ivec.c**************************************
556: Function ivec_ub()

558: Input :
559: Output:
560: Return:
561: Description:
562: ***********************************ivec.c*************************************/
563: int 
564: ivec_ub(register int *arg1, register int n)
565: {
566:   register int max = INT_MIN;


569:   while (n--)  {max = PetscMax(max,*arg1); arg1++;}
570:   return(max);
571: }



575: /**********************************ivec.c**************************************
576: Function split_buf()

578: Input :
579: Output:
580: Return:
581: Description:

583: assumes that sizeof(int) == 4bytes!!!
584: ***********************************ivec.c*************************************/
585: int
586: ivec_split_buf(int *buf1, int **buf2, register int size)
587: {
588:   *buf2 = (buf1 + (size>>3));
589:   return(size);
590: }



594: /**********************************ivec.c**************************************
595: Function ivec_non_uniform()

597: Input :
598: Output:
599: Return:
600: Description:
601: ***********************************ivec.c*************************************/
602: void 
603: ivec_non_uniform(int *arg1, int *arg2, register int n, register int *arg3)
604: {
605:   register int i, j, type;


608:   /* LATER: if we're really motivated we can sort and then unsort */
609:   for (i=0;i<n;)
610:     {
611:       /* clump 'em for now */
612:       j=i+1;
613:       type = arg3[i];
614:       while ((j<n)&&(arg3[j]==type))
615:         {j++;}
616: 
617:       /* how many together */
618:       j -= i;

620:       /* call appropriate ivec function */
621:       if (type == GL_MAX)
622:         {ivec_max(arg1,arg2,j);}
623:       else if (type == GL_MIN)
624:         {ivec_min(arg1,arg2,j);}
625:       else if (type == GL_MULT)
626:         {ivec_mult(arg1,arg2,j);}
627:       else if (type == GL_ADD)
628:         {ivec_add(arg1,arg2,j);}
629:       else if (type == GL_B_XOR)
630:         {ivec_xor(arg1,arg2,j);}
631:       else if (type == GL_B_OR)
632:         {ivec_or(arg1,arg2,j);}
633:       else if (type == GL_B_AND)
634:         {ivec_and(arg1,arg2,j);}
635:       else if (type == GL_L_XOR)
636:         {ivec_lxor(arg1,arg2,j);}
637:       else if (type == GL_L_OR)
638:         {ivec_lor(arg1,arg2,j);}
639:       else if (type == GL_L_AND)
640:         {ivec_land(arg1,arg2,j);}
641:       else
642:         {error_msg_fatal("unrecognized type passed to ivec_non_uniform()!");}

644:       arg1+=j; arg2+=j; i+=j;
645:     }
646: }



650: /**********************************ivec.c**************************************
651: Function ivec_addr()

653: Input :
654: Output:
655: Return:
656: Description:
657: ***********************************ivec.c*************************************/
658: vfp ivec_fct_addr(register int type)
659: {
660:   if (type == NON_UNIFORM)
661:     {return((void (*)(void*, void *, int, ...))&ivec_non_uniform);}
662:   else if (type == GL_MAX)
663:     {return((void (*)(void*, void *, int, ...))&ivec_max);}
664:   else if (type == GL_MIN)
665:     {return((void (*)(void*, void *, int, ...))&ivec_min);}
666:   else if (type == GL_MULT)
667:     {return((void (*)(void*, void *, int, ...))&ivec_mult);}
668:   else if (type == GL_ADD)
669:     {return((void (*)(void*, void *, int, ...))&ivec_add);}
670:   else if (type == GL_B_XOR)
671:     {return((void (*)(void*, void *, int, ...))&ivec_xor);}
672:   else if (type == GL_B_OR)
673:     {return((void (*)(void*, void *, int, ...))&ivec_or);}
674:   else if (type == GL_B_AND)
675:     {return((void (*)(void*, void *, int, ...))&ivec_and);}
676:   else if (type == GL_L_XOR)
677:     {return((void (*)(void*, void *, int, ...))&ivec_lxor);}
678:   else if (type == GL_L_OR)
679:     {return((void (*)(void*, void *, int, ...))&ivec_lor);}
680:   else if (type == GL_L_AND)
681:     {return((void (*)(void*, void *, int, ...))&ivec_land);}

683:   /* catch all ... not good if we get here */
684:   return(NULL);
685: }


688: /**********************************ivec.c**************************************
689: Function ct_bits()

691: Input :
692: Output:
693: Return:
694: Description: MUST FIX THIS!!!
695: ***********************************ivec.c*************************************/
696: #if defined(notusing)
697: static
698: int 
699: ivec_ct_bits(register int *ptr, register int n)
700: {
701:   register int tmp=0;


704:   /* should expand to full 32 bit */
705:   while (n--)
706:     {
707:       if (*ptr&128) {tmp++;}
708:       if (*ptr&64)  {tmp++;}
709:       if (*ptr&32)  {tmp++;}
710:       if (*ptr&16)  {tmp++;}
711:       if (*ptr&8)   {tmp++;}
712:       if (*ptr&4)   {tmp++;}
713:       if (*ptr&2)   {tmp++;}
714:       if (*ptr&1)   {tmp++;}
715:       ptr++;
716:     }

718:   return(tmp);
719: }
720: #endif


723: /******************************************************************************
724: Function: ivec_sort().

726: Input : offset of list to be sorted, number of elements to be sorted.
727: Output: sorted list (in ascending order).
728: Return: none.
729: Description: stack based (nonrecursive) quicksort w/brute-shell bottom. 
730: ******************************************************************************/
731: void
732: ivec_sort(register int *ar, register int size)
733: {
734:   register int *pi, *pj, temp;
735:   register int **top_a = (int **) offset_stack;
736:   register int *top_s = size_stack, *bottom_s = size_stack;


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

743:   /* do until we're done ... return when stack is exhausted */
744:   for (;;)
745:     {
746:       /* if list is large enough use quicksort partition exchange code */
747:       if (size > SORT_OPT)
748:         {
749:           /* start up pointer at element 1 and down at size     */
750:           pi = ar+1;
751:           pj = ar+size;

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

756:           /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
757:           /* note ==> pivot_value in index 0                   */
758:           if (*pi > *pj)
759:             {SWAP(*pi,*pj)}
760:           if (*ar > *pj)
761:             {SWAP(*ar,*pj)}
762:           else if (*pi > *ar)
763:             {SWAP(*(ar),*(ar+1))}

765:           /* partition about pivot_value ...                              */
766:           /* note lists of length 2 are not guaranteed to be sorted */
767:           for(;;)
768:             {
769:               /* walk up ... and down ... swap if equal to pivot! */
770:               do pi++; while (*pi<*ar);
771:               do pj--; while (*pj>*ar);

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

776:               /* else swap */
777:               SWAP(*pi,*pj)
778:             }

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

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

787:           /* push right hand child iff length > 1 */
788:           if ((*top_s = size-((int) (pi-ar))))
789:             {
790:               *(top_a++) = pi;
791:               size -= *top_s+2;
792:               top_s++;
793:             }
794:           /* set up for next loop iff there is something to do */
795:           else if (size -= *top_s+2)
796:             {;}
797:           /* might as well pop - note NR_OPT >=2 ==> we're ok! */
798:           else
799:             {
800:               ar = *(--top_a);
801:               size = *(--top_s);
802:             }
803:         }

805:       /* else sort small list directly then pop another off stack */
806:       else
807:         {
808:           /* insertion sort for bottom */
809:           for (pj=ar+1;pj<=ar+size;pj++)
810:             {
811:               temp = *pj;
812:               for (pi=pj-1;pi>=ar;pi--)
813:                 {
814:                   if (*pi <= temp) break;
815:                   *(pi+1)=*pi;
816:                 }
817:               *(pi+1)=temp;
818:             }

820:           /* check to see if stack is exhausted ==> DONE */
821:           if (top_s==bottom_s) return;
822: 
823:           /* else pop another list from the stack */
824:           ar = *(--top_a);
825:           size = *(--top_s);
826:         }
827:     }
828: }



832: /******************************************************************************
833: Function: ivec_sort_companion().

835: Input : offset of list to be sorted, number of elements to be sorted.
836: Output: sorted list (in ascending order).
837: Return: none.
838: Description: stack based (nonrecursive) quicksort w/brute-shell bottom. 
839: ******************************************************************************/
840: void
841: ivec_sort_companion(register int *ar, register int *ar2, register int size)
842: {
843:   register int *pi, *pj, temp, temp2;
844:   register int **top_a = (int **)offset_stack;
845:   register int *top_s = size_stack, *bottom_s = size_stack;
846:   register int *pi2, *pj2;
847:   register int mid;


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

854:   /* do until we're done ... return when stack is exhausted */
855:   for (;;)
856:     {
857:       /* if list is large enough use quicksort partition exchange code */
858:       if (size > SORT_OPT)
859:         {
860:           /* start up pointer at element 1 and down at size     */
861:           mid = size>>1;
862:           pi = ar+1;
863:           pj = ar+mid;
864:           pi2 = ar2+1;
865:           pj2 = ar2+mid;

867:           /* find middle element in list and swap w/ element 1 */
868:           SWAP(*pi,*pj)
869:           SWAP(*pi2,*pj2)

871:           /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
872:           /* note ==> pivot_value in index 0                   */
873:           pj = ar+size;
874:           pj2 = ar2+size;
875:           if (*pi > *pj)
876:             {SWAP(*pi,*pj) SWAP(*pi2,*pj2)}
877:           if (*ar > *pj)
878:             {SWAP(*ar,*pj) SWAP(*ar2,*pj2)}
879:           else if (*pi > *ar)
880:             {SWAP(*(ar),*(ar+1)) SWAP(*(ar2),*(ar2+1))}

882:           /* partition about pivot_value ...                              */
883:           /* note lists of length 2 are not guaranteed to be sorted */
884:           for(;;)
885:             {
886:               /* walk up ... and down ... swap if equal to pivot! */
887:               do {pi++; pi2++;} while (*pi<*ar);
888:               do {pj--; pj2--;} while (*pj>*ar);

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

893:               /* else swap */
894:               SWAP(*pi,*pj)
895:               SWAP(*pi2,*pj2)
896:             }

898:           /* place pivot_value in it's correct location */
899:           SWAP(*ar,*pj)
900:           SWAP(*ar2,*pj2)

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

906:           /* push right hand child iff length > 1 */
907:           if ((*top_s = size-((int) (pi-ar))))
908:             {
909:               *(top_a++) = pi;
910:               *(top_a++) = pi2;
911:               size -= *top_s+2;
912:               top_s++;
913:             }
914:           /* set up for next loop iff there is something to do */
915:           else if (size -= *top_s+2)
916:             {;}
917:           /* might as well pop - note NR_OPT >=2 ==> we're ok! */
918:           else
919:             {
920:               ar2 = *(--top_a);
921:               ar  = *(--top_a);
922:               size = *(--top_s);
923:             }
924:         }

926:       /* else sort small list directly then pop another off stack */
927:       else
928:         {
929:           /* insertion sort for bottom */
930:           for (pj=ar+1, pj2=ar2+1;pj<=ar+size;pj++,pj2++)
931:             {
932:               temp = *pj;
933:               temp2 = *pj2;
934:               for (pi=pj-1,pi2=pj2-1;pi>=ar;pi--,pi2--)
935:                 {
936:                   if (*pi <= temp) break;
937:                   *(pi+1)=*pi;
938:                   *(pi2+1)=*pi2;
939:                 }
940:               *(pi+1)=temp;
941:               *(pi2+1)=temp2;
942:             }

944:           /* check to see if stack is exhausted ==> DONE */
945:           if (top_s==bottom_s) return;
946: 
947:           /* else pop another list from the stack */
948:           ar2 = *(--top_a);
949:           ar  = *(--top_a);
950:           size = *(--top_s);
951:         }
952:     }
953: }



957: /******************************************************************************
958: Function: ivec_sort_companion_hack().

960: Input : offset of list to be sorted, number of elements to be sorted.
961: Output: sorted list (in ascending order).
962: Return: none.
963: Description: stack based (nonrecursive) quicksort w/brute-shell bottom. 
964: ******************************************************************************/
965: void
966: ivec_sort_companion_hack(register int *ar, register int **ar2, 
967:                          register int size)
968: {
969:   register int *pi, *pj, temp, *ptr;
970:   register int **top_a = (int **)offset_stack;
971:   register int *top_s = size_stack, *bottom_s = size_stack;
972:   register int **pi2, **pj2;
973:   register int mid;


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

980:   /* do until we're done ... return when stack is exhausted */
981:   for (;;)
982:     {
983:       /* if list is large enough use quicksort partition exchange code */
984:       if (size > SORT_OPT)
985:         {
986:           /* start up pointer at element 1 and down at size     */
987:           mid = size>>1;
988:           pi = ar+1;
989:           pj = ar+mid;
990:           pi2 = ar2+1;
991:           pj2 = ar2+mid;

993:           /* find middle element in list and swap w/ element 1 */
994:           SWAP(*pi,*pj)
995:           P_SWAP(*pi2,*pj2)

997:           /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
998:           /* note ==> pivot_value in index 0                   */
999:           pj = ar+size;
1000:           pj2 = ar2+size;
1001:           if (*pi > *pj)
1002:             {SWAP(*pi,*pj) P_SWAP(*pi2,*pj2)}
1003:           if (*ar > *pj)
1004:             {SWAP(*ar,*pj) P_SWAP(*ar2,*pj2)}
1005:           else if (*pi > *ar)
1006:             {SWAP(*(ar),*(ar+1)) P_SWAP(*(ar2),*(ar2+1))}

1008:           /* partition about pivot_value ...                              */
1009:           /* note lists of length 2 are not guaranteed to be sorted */
1010:           for(;;)
1011:             {
1012:               /* walk up ... and down ... swap if equal to pivot! */
1013:               do {pi++; pi2++;} while (*pi<*ar);
1014:               do {pj--; pj2--;} while (*pj>*ar);

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

1019:               /* else swap */
1020:               SWAP(*pi,*pj)
1021:               P_SWAP(*pi2,*pj2)
1022:             }

1024:           /* place pivot_value in it's correct location */
1025:           SWAP(*ar,*pj)
1026:           P_SWAP(*ar2,*pj2)

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

1032:           /* push right hand child iff length > 1 */
1033:           if ((*top_s = size-((int) (pi-ar))))
1034:             {
1035:               *(top_a++) = pi;
1036:               *(top_a++) = (int*) pi2;
1037:               size -= *top_s+2;
1038:               top_s++;
1039:             }
1040:           /* set up for next loop iff there is something to do */
1041:           else if (size -= *top_s+2)
1042:             {;}
1043:           /* might as well pop - note NR_OPT >=2 ==> we're ok! */
1044:           else
1045:             {
1046:               ar2 = (int **) *(--top_a);
1047:               ar  = *(--top_a);
1048:               size = *(--top_s);
1049:             }
1050:         }

1052:       /* else sort small list directly then pop another off stack */
1053:       else
1054:         {
1055:           /* insertion sort for bottom */
1056:           for (pj=ar+1, pj2=ar2+1;pj<=ar+size;pj++,pj2++)
1057:             {
1058:               temp = *pj;
1059:               ptr = *pj2;
1060:               for (pi=pj-1,pi2=pj2-1;pi>=ar;pi--,pi2--)
1061:                 {
1062:                   if (*pi <= temp) break;
1063:                   *(pi+1)=*pi;
1064:                   *(pi2+1)=*pi2;
1065:                 }
1066:               *(pi+1)=temp;
1067:               *(pi2+1)=ptr;
1068:             }

1070:           /* check to see if stack is exhausted ==> DONE */
1071:           if (top_s==bottom_s) return;
1072: 
1073:           /* else pop another list from the stack */
1074:           ar2 = (int **)*(--top_a);
1075:           ar  = *(--top_a);
1076:           size = *(--top_s);
1077:         }
1078:     }
1079: }



1083: /******************************************************************************
1084: Function: SMI_sort().
1085: Input : offset of list to be sorted, number of elements to be sorted.
1086: Output: sorted list (in ascending order).
1087: Return: none.
1088: Description: stack based (nonrecursive) quicksort w/brute-shell bottom. 
1089: ******************************************************************************/
1090: void
1091: SMI_sort(void *ar1, void *ar2, int size, int type)
1092: {
1093:   if (type == SORT_INTEGER)
1094:     {
1095:       if (ar2)
1096:         {ivec_sort_companion((int*)ar1,(int*)ar2,size);}
1097:       else
1098:         {ivec_sort((int*)ar1,size);}
1099:     }
1100:   else if (type == SORT_INT_PTR)
1101:     {
1102:       if (ar2)
1103:         {ivec_sort_companion_hack((int*)ar1,(int **)ar2,size);}
1104:       else
1105:         {ivec_sort((int*)ar1,size);}
1106:     }

1108:   else
1109:     {
1110:       error_msg_fatal("SMI_sort only does SORT_INTEGER!");
1111:     }
1112: /*
1113:   if (type == SORT_REAL)
1114:     {
1115:       if (ar2)
1116:         {rvec_sort_companion(ar2,ar1,size);}
1117:       else
1118:         {rvec_sort(ar1,size);}
1119:     }
1120: */
1121: }



1125: /**********************************ivec.c**************************************
1126: Function ivec_linear_search()

1128: Input :
1129: Output:
1130: Return:
1131: Description:
1132: ***********************************ivec.c*************************************/
1133: int
1134: ivec_linear_search(register int item, register int *list, register int n)
1135: {
1136:   register int tmp = n-1;

1138:   while (n--)  {if (*list++ == item) {return(tmp-n);}}
1139:   return(-1);
1140: }



1144: /**********************************ivec.c**************************************
1145: Function ivec_binary_search()

1147: Input :
1148: Output:
1149: Return:
1150: Description:
1151: ***********************************ivec.c*************************************/
1152: int
1153: ivec_binary_search(register int item, register int *list, register int rh)
1154: {
1155:   register int mid, lh=0;

1157:   rh--;
1158:   while (lh<=rh)
1159:     {
1160:       mid = (lh+rh)>>1;
1161:       if (*(list+mid) == item)
1162:         {return(mid);}
1163:       if (*(list+mid) > item)
1164:         {rh = mid-1;}
1165:       else
1166:         {lh = mid+1;}
1167:     }
1168:   return(-1);
1169: }



1173: /**********************************ivec.c**************************************
1174: Function rvec_dump

1176: Input : 
1177: Output: 
1178: Return: 
1179: Description: 
1180: ***********************************ivec.c*************************************/
1181: void
1182: rvec_dump(REAL *v, int n, int tag, int tag2, char * s)
1183: {
1184:   int i;
1185:   printf("%2d %2d %s %2d :: ",tag,tag2,s,my_id);
1186:   for (i=0;i<n;i++)
1187:     {printf("%f ",v[i]);}
1188:   printf("\n");
1189:   fflush(stdout);
1190: }



1194: /**********************************ivec.c**************************************
1195: Function rvec_lb_ub()

1197: Input :
1198: Output:
1199: Return:
1200: Description:
1201: ***********************************ivec.c*************************************/
1202: void
1203: rvec_lb_ub(register REAL *arg1, register int n, REAL *lb, REAL *ub)
1204: {
1205:   register REAL min =  REAL_MAX;
1206:   register REAL max = -REAL_MAX;

1208:   while (n--)
1209:     {
1210:      min = PetscMin(min,*arg1);
1211:      max = PetscMax(max,*arg1);
1212:      arg1++;
1213:     }

1215:   *lb=min;
1216:   *ub=max;
1217: }



1221: /********************************ivec.c**************************************
1222: Function rvec_copy()

1224: Input :
1225: Output:
1226: Return:
1227: Description:
1228: *********************************ivec.c*************************************/
1229: void 
1230: rvec_copy(register REAL *arg1, register REAL *arg2, register int n)
1231: {
1232:   while (n--)  {*arg1++ = *arg2++;}
1233: }



1237: /********************************ivec.c**************************************
1238: Function rvec_zero()

1240: Input :
1241: Output:
1242: Return:
1243: Description:
1244: *********************************ivec.c*************************************/
1245: void 
1246: rvec_zero(register REAL *arg1, register int n)
1247: {
1248:   while (n--)  {*arg1++ = 0.0;}
1249: }



1253: /**********************************ivec.c**************************************
1254: Function rvec_one()

1256: Input :
1257: Output:
1258: Return:
1259: Description:
1260: ***********************************ivec.c*************************************/
1261: void 
1262: rvec_one(register REAL *arg1, register int n)
1263: {
1264:   while (n--)  {*arg1++ = 1.0;}
1265: }



1269: /**********************************ivec.c**************************************
1270: Function rvec_neg_one()

1272: Input :
1273: Output:
1274: Return:
1275: Description:
1276: ***********************************ivec.c*************************************/
1277: void 
1278: rvec_neg_one(register REAL *arg1, register int n)
1279: {
1280:   while (n--)  {*arg1++ = -1.0;}
1281: }



1285: /**********************************ivec.c**************************************
1286: Function rvec_set()

1288: Input :
1289: Output:
1290: Return:
1291: Description:
1292: ***********************************ivec.c*************************************/
1293: void
1294: rvec_set(register REAL *arg1, register REAL arg2, register int n)
1295: {
1296:   while (n--)  {*arg1++ = arg2;}
1297: }



1301: /**********************************ivec.c**************************************
1302: Function rvec_scale()

1304: Input :
1305: Output:
1306: Return:
1307: Description:
1308: ***********************************ivec.c*************************************/
1309: void
1310: rvec_scale(register REAL *arg1, register REAL arg2, register int n)
1311: {
1312:   while (n--)  {*arg1++ *= arg2;}
1313: }



1317: /********************************ivec.c**************************************
1318: Function rvec_add()

1320: Input :
1321: Output:
1322: Return:
1323: Description:
1324: *********************************ivec.c*************************************/
1325: void 
1326: rvec_add(register REAL *arg1, register REAL *arg2, register int n)
1327: {
1328:   while (n--)  {*arg1++ += *arg2++;}
1329: }



1333: /********************************ivec.c**************************************
1334: Function rvec_dot()

1336: Input :
1337: Output:
1338: Return:
1339: Description:
1340: *********************************ivec.c*************************************/
1341: REAL
1342: rvec_dot(register REAL *arg1, register REAL *arg2, register int n)
1343: {
1344:   REAL dot=0.0;

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

1348:   return(dot);
1349: }



1353: /********************************ivec.c**************************************
1354: Function rvec_axpy()

1356: Input :
1357: Output:
1358: Return:
1359: Description:
1360: *********************************ivec.c*************************************/
1361: void
1362: rvec_axpy(register REAL *arg1, register REAL *arg2, register REAL scale, 
1363:           register int n)
1364: {
1365:   while (n--)  {*arg1++ += scale * *arg2++;}
1366: }


1369: /********************************ivec.c**************************************
1370: Function rvec_mult()

1372: Input :
1373: Output:
1374: Return:
1375: Description:
1376: *********************************ivec.c*************************************/
1377: void 
1378: rvec_mult(register REAL *arg1, register REAL *arg2, register int n)
1379: {
1380:   while (n--)  {*arg1++ *= *arg2++;}
1381: }



1385: /********************************ivec.c**************************************
1386: Function rvec_max()

1388: Input :
1389: Output:
1390: Return:
1391: Description:
1392: *********************************ivec.c*************************************/
1393: void 
1394: rvec_max(register REAL *arg1, register REAL *arg2, register int n)
1395: {
1396:   while (n--)  {*arg1 = PetscMax(*arg1,*arg2); arg1++; arg2++;}
1397: }



1401: /********************************ivec.c**************************************
1402: Function rvec_max_abs()

1404: Input :
1405: Output:
1406: Return:
1407: Description:
1408: *********************************ivec.c*************************************/
1409: void 
1410: rvec_max_abs(register REAL *arg1, register REAL *arg2, register int n)
1411: {
1412:   while (n--)  {*arg1 = MAX_FABS(*arg1,*arg2); arg1++; arg2++;}
1413: }



1417: /********************************ivec.c**************************************
1418: Function rvec_min()

1420: Input :
1421: Output:
1422: Return:
1423: Description:
1424: *********************************ivec.c*************************************/
1425: void 
1426: rvec_min(register REAL *arg1, register REAL *arg2, register int n)
1427: {
1428:   while (n--)  {*arg1 = PetscMin(*arg1,*arg2); arg1++; arg2++;}
1429: }



1433: /********************************ivec.c**************************************
1434: Function rvec_min_abs()

1436: Input :
1437: Output:
1438: Return:
1439: Description:
1440: *********************************ivec.c*************************************/
1441: void 
1442: rvec_min_abs(register REAL *arg1, register REAL *arg2, register int n)
1443: {
1444:   while (n--)  {*arg1 = MIN_FABS(*arg1,*arg2); arg1++; arg2++;}
1445: }



1449: /********************************ivec.c**************************************
1450: Function rvec_exists()

1452: Input :
1453: Output:
1454: Return:
1455: Description:
1456: *********************************ivec.c*************************************/
1457: void 
1458: rvec_exists(register REAL *arg1, register REAL *arg2, register int n)
1459: {
1460:   while (n--)  {*arg1 = EXISTS(*arg1,*arg2); arg1++; arg2++;}
1461: }



1465: /**********************************ivec.c**************************************
1466: Function rvec_non_uniform()

1468: Input :
1469: Output:
1470: Return:
1471: Description:
1472: ***********************************ivec.c*************************************/
1473: void 
1474: rvec_non_uniform(REAL *arg1, REAL *arg2, register int n, register int *arg3)
1475: {
1476:   register int i, j, type;


1479:   /* LATER: if we're really motivated we can sort and then unsort */
1480:   for (i=0;i<n;)
1481:     {
1482:       /* clump 'em for now */
1483:       j=i+1;
1484:       type = arg3[i];
1485:       while ((j<n)&&(arg3[j]==type))
1486:         {j++;}
1487: 
1488:       /* how many together */
1489:       j -= i;

1491:       /* call appropriate ivec function */
1492:       if (type == GL_MAX)
1493:         {rvec_max(arg1,arg2,j);}
1494:       else if (type == GL_MIN)
1495:         {rvec_min(arg1,arg2,j);}
1496:       else if (type == GL_MULT)
1497:         {rvec_mult(arg1,arg2,j);}
1498:       else if (type == GL_ADD)
1499:         {rvec_add(arg1,arg2,j);}
1500:       else if (type == GL_MAX_ABS)
1501:         {rvec_max_abs(arg1,arg2,j);}
1502:       else if (type == GL_MIN_ABS)
1503:         {rvec_min_abs(arg1,arg2,j);}
1504:       else if (type == GL_EXISTS)
1505:         {rvec_exists(arg1,arg2,j);}
1506:       else
1507:         {error_msg_fatal("unrecognized type passed to rvec_non_uniform()!");}

1509:       arg1+=j; arg2+=j; i+=j;
1510:     }
1511: }



1515: /**********************************ivec.c**************************************
1516: Function rvec_fct_addr()

1518: Input :
1519: Output:
1520: Return:
1521: Description:
1522: ***********************************ivec.c*************************************/
1523: vfp rvec_fct_addr(register int type)
1524: {
1525:   if (type == NON_UNIFORM)
1526:     {return((void (*)(void*, void *, int, ...))&rvec_non_uniform);}
1527:   else if (type == GL_MAX)
1528:     {return((void (*)(void*, void *, int, ...))&rvec_max);}
1529:   else if (type == GL_MIN)
1530:     {return((void (*)(void*, void *, int, ...))&rvec_min);}
1531:   else if (type == GL_MULT)
1532:     {return((void (*)(void*, void *, int, ...))&rvec_mult);}
1533:   else if (type == GL_ADD)
1534:     {return((void (*)(void*, void *, int, ...))&rvec_add);}
1535:   else if (type == GL_MAX_ABS)
1536:     {return((void (*)(void*, void *, int, ...))&rvec_max_abs);}
1537:   else if (type == GL_MIN_ABS)
1538:     {return((void (*)(void*, void *, int, ...))&rvec_min_abs);}
1539:   else if (type == GL_EXISTS)
1540:     {return((void (*)(void*, void *, int, ...))&rvec_exists);}

1542:   /* catch all ... not good if we get here */
1543:   return(NULL);
1544: }


1547: /******************************************************************************
1548: Function: my_sort().
1549: Input : offset of list to be sorted, number of elements to be sorted.
1550: Output: sorted list (in ascending order).
1551: Return: none.
1552: Description: stack based (nonrecursive) quicksort w/brute-shell bottom. 
1553: ******************************************************************************/
1554: void
1555: rvec_sort(register REAL *ar, register int Size)
1556: {
1557:   register REAL *pi, *pj, temp;
1558:   register REAL **top_a = (REAL **)offset_stack;
1559:   register PTRINT *top_s = psize_stack, *bottom_s = psize_stack;
1560:   register PTRINT size = (PTRINT) Size;

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

1566:   /* do until we're done ... return when stack is exhausted */
1567:   for (;;)
1568:     {
1569:       /* if list is large enough use quicksort partition exchange code */
1570:       if (size > SORT_OPT)
1571:         {
1572:           /* start up pointer at element 1 and down at size     */
1573:           pi = ar+1;
1574:           pj = ar+size;

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

1579:           pj = ar+size;

1581:           /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
1582:           /* note ==> pivot_value in index 0                   */
1583:           if (*pi > *pj)
1584:             {SWAP(*pi,*pj)}
1585:           if (*ar > *pj)
1586:             {SWAP(*ar,*pj)}
1587:           else if (*pi > *ar)
1588:             {SWAP(*(ar),*(ar+1))}

1590:           /* partition about pivot_value ...                              */
1591:           /* note lists of length 2 are not guaranteed to be sorted */
1592:           for(;;)
1593:             {
1594:               /* walk up ... and down ... swap if equal to pivot! */
1595:               do pi++; while (*pi<*ar);
1596:               do pj--; while (*pj>*ar);

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

1601:               /* else swap */
1602:               SWAP(*pi,*pj)
1603:             }

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

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

1612:           /* push right hand child iff length > 1 */
1613:           if ((*top_s = size-(pi-ar)))
1614:             {
1615:               *(top_a++) = pi;
1616:               size -= *top_s+2;
1617:               top_s++;
1618:             }
1619:           /* set up for next loop iff there is something to do */
1620:           else if (size -= *top_s+2)
1621:             {;}
1622:           /* might as well pop - note NR_OPT >=2 ==> we're ok! */
1623:           else
1624:             {
1625:               ar = *(--top_a);
1626:               size = *(--top_s);
1627:             }
1628:         }

1630:       /* else sort small list directly then pop another off stack */
1631:       else
1632:         {
1633:           /* insertion sort for bottom */
1634:           for (pj=ar+1;pj<=ar+size;pj++)
1635:             {
1636:               temp = *pj;
1637:               for (pi=pj-1;pi>=ar;pi--)
1638:                 {
1639:                   if (*pi <= temp) break;
1640:                   *(pi+1)=*pi;
1641:                 }
1642:               *(pi+1)=temp;
1643:             }

1645:           /* check to see if stack is exhausted ==> DONE */
1646:           if (top_s==bottom_s) return;
1647: 
1648:           /* else pop another list from the stack */
1649:           ar = *(--top_a);
1650:           size = *(--top_s);
1651:         }
1652:     }
1653: }



1657: /******************************************************************************
1658: Function: my_sort().
1659: Input : offset of list to be sorted, number of elements to be sorted.
1660: Output: sorted list (in ascending order).
1661: Return: none.
1662: Description: stack based (nonrecursive) quicksort w/brute-shell bottom. 
1663: ******************************************************************************/
1664: void
1665: rvec_sort_companion(register REAL *ar, register int *ar2, register int Size)
1666: {
1667:   register REAL *pi, *pj, temp;
1668:   register REAL **top_a = (REAL **)offset_stack;
1669:   register PTRINT *top_s = psize_stack, *bottom_s = psize_stack;
1670:   register PTRINT size = (PTRINT) Size;

1672:   register int *pi2, *pj2;
1673:   register int ptr;
1674:   register PTRINT mid;


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

1681:   /* do until we're done ... return when stack is exhausted */
1682:   for (;;)
1683:     {
1684:       /* if list is large enough use quicksort partition exchange code */
1685:       if (size > SORT_OPT)
1686:         {
1687:           /* start up pointer at element 1 and down at size     */
1688:           mid = size>>1;
1689:           pi = ar+1;
1690:           pj = ar+mid;
1691:           pi2 = ar2+1;
1692:           pj2 = ar2+mid;

1694:           /* find middle element in list and swap w/ element 1 */
1695:           SWAP(*pi,*pj)
1696:           P_SWAP(*pi2,*pj2)

1698:           /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
1699:           /* note ==> pivot_value in index 0                   */
1700:           pj = ar+size;
1701:           pj2 = ar2+size;
1702:           if (*pi > *pj)
1703:             {SWAP(*pi,*pj) P_SWAP(*pi2,*pj2)}
1704:           if (*ar > *pj)
1705:             {SWAP(*ar,*pj) P_SWAP(*ar2,*pj2)}
1706:           else if (*pi > *ar)
1707:             {SWAP(*(ar),*(ar+1)) P_SWAP(*(ar2),*(ar2+1))}

1709:           /* partition about pivot_value ...                              */
1710:           /* note lists of length 2 are not guaranteed to be sorted */
1711:           for(;;)
1712:             {
1713:               /* walk up ... and down ... swap if equal to pivot! */
1714:               do {pi++; pi2++;} while (*pi<*ar);
1715:               do {pj--; pj2--;} while (*pj>*ar);

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

1720:               /* else swap */
1721:               SWAP(*pi,*pj)
1722:               P_SWAP(*pi2,*pj2)
1723:             }

1725:           /* place pivot_value in it's correct location */
1726:           SWAP(*ar,*pj)
1727:           P_SWAP(*ar2,*pj2)

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

1733:           /* push right hand child iff length > 1 */
1734:           if ((*top_s = size-(pi-ar)))
1735:             {
1736:               *(top_a++) = pi;
1737:               *(top_a++) = (REAL *) pi2;
1738:               size -= *top_s+2;
1739:               top_s++;
1740:             }
1741:           /* set up for next loop iff there is something to do */
1742:           else if (size -= *top_s+2)
1743:             {;}
1744:           /* might as well pop - note NR_OPT >=2 ==> we're ok! */
1745:           else
1746:             {
1747:               ar2 = (int*) *(--top_a);
1748:               ar  = *(--top_a);
1749:               size = *(--top_s);
1750:             }
1751:         }

1753:       /* else sort small list directly then pop another off stack */
1754:       else
1755:         {
1756:           /* insertion sort for bottom */
1757:           for (pj=ar+1, pj2=ar2+1;pj<=ar+size;pj++,pj2++)
1758:             {
1759:               temp = *pj;
1760:               ptr = *pj2;
1761:               for (pi=pj-1,pi2=pj2-1;pi>=ar;pi--,pi2--)
1762:                 {
1763:                   if (*pi <= temp) break;
1764:                   *(pi+1)=*pi;
1765:                   *(pi2+1)=*pi2;
1766:                 }
1767:               *(pi+1)=temp;
1768:               *(pi2+1)=ptr;
1769:             }

1771:           /* check to see if stack is exhausted ==> DONE */
1772:           if (top_s==bottom_s) return;
1773: 
1774:           /* else pop another list from the stack */
1775:           ar2 = (int*) *(--top_a);
1776:           ar  = *(--top_a);
1777:           size = *(--top_s);
1778:         }
1779:     }
1780: }





1786: /**********************************ivec.c**************************************
1787: Function ivec_binary_search()

1789: Input :
1790: Output:
1791: Return:
1792: Description:
1793: ***********************************ivec.c*************************************/
1794: int
1795: rvec_binary_search(register REAL item, register REAL *list, register int rh)
1796: {
1797:   register int mid, lh=0;

1799:   rh--;
1800:   while (lh<=rh)
1801:     {
1802:       mid = (lh+rh)>>1;
1803:       if (*(list+mid) == item)
1804:         {return(mid);}
1805:       if (*(list+mid) > item)
1806:         {rh = mid-1;}
1807:       else
1808:         {lh = mid+1;}
1809:     }
1810:   return(-1);
1811: }