Actual source code: ivec.c

  1: /*$Id: ivec.c,v 1.2 2001/04/10 19:37:38 bsmith Exp $*/
  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 <stdio.h>
 24: #include <math.h>
 25: #include <float.h>
 26: #include <limits.h>

 28: #ifdef MPISRC
 29: #include <mpi.h>
 30: #endif


 33:  #include const.h
 34:  #include types.h
 35:  #include ivec.h
 36:  #include error.h
 37:  #include comm.h


 40: /* sorting args ivec.c ivec.c ... */
 41: #define   SORT_OPT        6     
 42: #define   SORT_STACK        50000


 45: /* allocate an address and size stack for sorter(s) */
 46: static void *offset_stack[2*SORT_STACK];
 47: static int   size_stack[SORT_STACK];
 48: static PTRINT psize_stack[SORT_STACK];



 52: /**********************************ivec.c**************************************
 53: Function ivec_dump()

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



 73: /**********************************ivec.c**************************************
 74: Function ivec_lb_ub()

 76: Input :
 77: Output:
 78: Return:
 79: Description:
 80: ***********************************ivec.c*************************************/
 81: void
 82: ivec_lb_ub(register int *arg1, register int n, int *lb, int *ub)
 83: {
 84:   register int min = INT_MAX;
 85:   register int max = INT_MIN;

 87:   while (n--)
 88:     {
 89:      min = MIN(min,*arg1);
 90:      max = MAX(max,*arg1);
 91:      arg1++;
 92:     }

 94:   *lb=min;
 95:   *ub=max;
 96: }



100: /**********************************ivec.c**************************************
101: Function ivec_copy()

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



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

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



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

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



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

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



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

168: Input :
169: Output:
170: Return:
171: Description:
172: ***********************************ivec.c*************************************/
173: void 
174: ivec_pos_one(register int *arg1, register int n)
175: {
176:   while (n--)  {*arg1++ = 1;}
177: }



181: /**********************************ivec.c**************************************
182: Function ivec_c_index()

184: Input :
185: Output:
186: Return:
187: Description:
188: ***********************************ivec.c*************************************/
189: void 
190: ivec_c_index(register int *arg1, register int n)
191: {
192:   register int i=0;


195:   while (n--)  {*arg1++ = i++;}
196: }



200: /**********************************ivec.c**************************************
201: Function ivec_fortran_index()

203: Input :
204: Output:
205: Return:
206: Description:
207: ***********************************ivec.c*************************************/
208: void 
209: ivec_fortran_index(register int *arg1, register int n)
210: {
211:   register int i=0;


214:   while (n--)  {*arg1++ = ++i;}
215: }



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

222: Input :
223: Output:
224: Return:
225: Description:
226: ***********************************ivec.c*************************************/
227: void 
228: ivec_set(register int *arg1, register int arg2, register int n)
229: {
230:   while (n--)  {*arg1++ = arg2;}
231: }



235: /**********************************ivec.c**************************************
236: Function ivec_cmp()

238: Input :
239: Output:
240: Return:
241: Description:
242: ***********************************ivec.c*************************************/
243: int
244: ivec_cmp(register int *arg1, register int *arg2, register int n)
245: {
246:   while (n--)  {if (*arg1++ != *arg2++)  {return(FALSE);}}
247:   return(TRUE);
248: }



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

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



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

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



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

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



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

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



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

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



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

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



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

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



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

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



380: /**********************************ivec.c**************************************
381: Function ivec_or3()

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



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

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



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

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



429: /**********************************ivec.c**************************************
430: Function ivec_and3()

432: Input :
433: Output:
434: Return:
435: Description:
436: ***********************************ivec.c*************************************/
437: void 
438: ivec_and3(register int *arg1, register int *arg2, register int *arg3, 
439:           register int n)
440: {
441:   while (n--)  {*arg1++ = (*arg2++ & *arg3++);}
442: }



446: /**********************************ivec.c**************************************
447: Function ivec_sum

449: Input : 
450: Output: 
451: Return: 
452: Description: 
453: ***********************************ivec.c*************************************/
454: int 
455: ivec_sum(register int *arg1, register int n)
456: {
457:   register int tmp = 0;


460:   while (n--) {tmp += *arg1++;}
461:   return(tmp);
462: }



466: /**********************************ivec.c**************************************
467: Function ivec_reduce_and

469: Input : 
470: Output: 
471: Return: 
472: Description: 
473: ***********************************ivec.c*************************************/
474: int 
475: ivec_reduce_and(register int *arg1, register int n)
476: {
477:   register int tmp = ALL_ONES;


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



486: /**********************************ivec.c**************************************
487: Function ivec_reduce_or

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


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



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

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


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



526: /**********************************ivec.c**************************************
527: Function ivec_u_sum

529: Input : 
530: Output: 
531: Return: 
532: Description: 
533: ***********************************ivec.c*************************************/
534: int 
535: ivec_u_sum(register unsigned *arg1, register int n)
536: {
537:   register unsigned tmp = 0;


540:   while (n--)  {tmp += *arg1++;}
541:   return(tmp);
542: }



546: /**********************************ivec.c**************************************
547: Function ivec_lb()

549: Input :
550: Output:
551: Return:
552: Description:
553: ***********************************ivec.c*************************************/
554: int 
555: ivec_lb(register int *arg1, register int n)
556: {
557:   register int min = INT_MAX;


560:   while (n--)  {min = MIN(min,*arg1); arg1++;}
561:   return(min);
562: }



566: /**********************************ivec.c**************************************
567: Function ivec_ub()

569: Input :
570: Output:
571: Return:
572: Description:
573: ***********************************ivec.c*************************************/
574: int 
575: ivec_ub(register int *arg1, register int n)
576: {
577:   register int max = INT_MIN;


580:   while (n--)  {max = MAX(max,*arg1); arg1++;}
581:   return(max);
582: }



586: /**********************************ivec.c**************************************
587: Function split_buf()

589: Input :
590: Output:
591: Return:
592: Description:

594: assumes that sizeof(int) == 4bytes!!!
595: ***********************************ivec.c*************************************/
596: int
597: ivec_split_buf(int *buf1, int **buf2, register int size)
598: {
599:   *buf2 = (buf1 + (size>>3));
600:   return(size);
601: }



605: /**********************************ivec.c**************************************
606: Function ivec_non_uniform()

608: Input :
609: Output:
610: Return:
611: Description:
612: ***********************************ivec.c*************************************/
613: void 
614: ivec_non_uniform(int *arg1, int *arg2, register int n, register int *arg3)
615: {
616:   register int i, j, type;


619:   /* LATER: if we're really motivated we can sort and then unsort */
620:   for (i=0;i<n;)
621:     {
622:       /* clump 'em for now */
623:       j=i+1;
624:       type = arg3[i];
625:       while ((j<n)&&(arg3[j]==type))
626:         {j++;}
627: 
628:       /* how many together */
629:       j -= i;

631:       /* call appropriate ivec function */
632:       if (type == GL_MAX)
633:         {ivec_max(arg1,arg2,j);}
634:       else if (type == GL_MIN)
635:         {ivec_min(arg1,arg2,j);}
636:       else if (type == GL_MULT)
637:         {ivec_mult(arg1,arg2,j);}
638:       else if (type == GL_ADD)
639:         {ivec_add(arg1,arg2,j);}
640:       else if (type == GL_B_XOR)
641:         {ivec_xor(arg1,arg2,j);}
642:       else if (type == GL_B_OR)
643:         {ivec_or(arg1,arg2,j);}
644:       else if (type == GL_B_AND)
645:         {ivec_and(arg1,arg2,j);}
646:       else if (type == GL_L_XOR)
647:         {ivec_lxor(arg1,arg2,j);}
648:       else if (type == GL_L_OR)
649:         {ivec_lor(arg1,arg2,j);}
650:       else if (type == GL_L_AND)
651:         {ivec_land(arg1,arg2,j);}
652:       else
653:         {error_msg_fatal("unrecognized type passed to ivec_non_uniform()!");}

655:       arg1+=j; arg2+=j; i+=j;
656:     }
657: }



661: /**********************************ivec.c**************************************
662: Function ivec_addr()

664: Input :
665: Output:
666: Return:
667: Description:
668: ***********************************ivec.c*************************************/
669: vfp ivec_fct_addr(register int type)
670: {
671:   if (type == NON_UNIFORM)
672:     {return((void (*)(void *, void *, int, ...))&ivec_non_uniform);}
673:   else if (type == GL_MAX)
674:     {return((void (*)(void *, void *, int, ...))&ivec_max);}
675:   else if (type == GL_MIN)
676:     {return((void (*)(void *, void *, int, ...))&ivec_min);}
677:   else if (type == GL_MULT)
678:     {return((void (*)(void *, void *, int, ...))&ivec_mult);}
679:   else if (type == GL_ADD)
680:     {return((void (*)(void *, void *, int, ...))&ivec_add);}
681:   else if (type == GL_B_XOR)
682:     {return((void (*)(void *, void *, int, ...))&ivec_xor);}
683:   else if (type == GL_B_OR)
684:     {return((void (*)(void *, void *, int, ...))&ivec_or);}
685:   else if (type == GL_B_AND)
686:     {return((void (*)(void *, void *, int, ...))&ivec_and);}
687:   else if (type == GL_L_XOR)
688:     {return((void (*)(void *, void *, int, ...))&ivec_lxor);}
689:   else if (type == GL_L_OR)
690:     {return((void (*)(void *, void *, int, ...))&ivec_lor);}
691:   else if (type == GL_L_AND)
692:     {return((void (*)(void *, void *, int, ...))&ivec_land);}

694:   /* catch all ... not good if we get here */
695:   return(NULL);
696: }


699: /**********************************ivec.c**************************************
700: Function ct_bits()

702: Input :
703: Output:
704: Return:
705: Description: MUST FIX THIS!!!
706: ***********************************ivec.c*************************************/
707: #if defined(notusing)
708: static
709: int 
710: ivec_ct_bits(register int *ptr, register int n)
711: {
712:   register int tmp=0;


715:   /* should expand to full 32 bit */
716:   while (n--)
717:     {
718:       if (*ptr&128) {tmp++;}
719:       if (*ptr&64)  {tmp++;}
720:       if (*ptr&32)  {tmp++;}
721:       if (*ptr&16)  {tmp++;}
722:       if (*ptr&8)   {tmp++;}
723:       if (*ptr&4)   {tmp++;}
724:       if (*ptr&2)   {tmp++;}
725:       if (*ptr&1)   {tmp++;}
726:       ptr++;
727:     }

729:   return(tmp);
730: }
731: #endif


734: /******************************************************************************
735: Function: ivec_sort().

737: Input : offset of list to be sorted, number of elements to be sorted.
738: Output: sorted list (in ascending order).
739: Return: none.
740: Description: stack based (nonrecursive) quicksort w/brute-shell bottom. 
741: ******************************************************************************/
742: void
743: ivec_sort(register int *ar, register int size)
744: {
745:   register int *pi, *pj, temp;
746:   register int **top_a = (int **) offset_stack;
747:   register int *top_s = size_stack, *bottom_s = size_stack;


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

754:   /* do until we're done ... return when stack is exhausted */
755:   for (;;)
756:     {
757:       /* if list is large enough use quicksort partition exchange code */
758:       if (size > SORT_OPT)
759:         {
760:           /* start up pointer at element 1 and down at size     */
761:           pi = ar+1;
762:           pj = ar+size;

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

767:           /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
768:           /* note ==> pivot_value in index 0                   */
769:           if (*pi > *pj)
770:             {SWAP(*pi,*pj)}
771:           if (*ar > *pj)
772:             {SWAP(*ar,*pj)}
773:           else if (*pi > *ar)
774:             {SWAP(*(ar),*(ar+1))}

776:           /* partition about pivot_value ...                              */
777:           /* note lists of length 2 are not guaranteed to be sorted */
778:           for(;;)
779:             {
780:               /* walk up ... and down ... swap if equal to pivot! */
781:               do pi++; while (*pi<*ar);
782:               do pj--; while (*pj>*ar);

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

787:               /* else swap */
788:               SWAP(*pi,*pj)
789:             }

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

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

798:           /* push right hand child iff length > 1 */
799:           if ((*top_s = size-((int) (pi-ar))))
800:             {
801:               *(top_a++) = pi;
802:               size -= *top_s+2;
803:               top_s++;
804:             }
805:           /* set up for next loop iff there is something to do */
806:           else if (size -= *top_s+2)
807:             {;}
808:           /* might as well pop - note NR_OPT >=2 ==> we're ok! */
809:           else
810:             {
811:               ar = *(--top_a);
812:               size = *(--top_s);
813:             }
814:         }

816:       /* else sort small list directly then pop another off stack */
817:       else
818:         {
819:           /* insertion sort for bottom */
820:           for (pj=ar+1;pj<=ar+size;pj++)
821:             {
822:               temp = *pj;
823:               for (pi=pj-1;pi>=ar;pi--)
824:                 {
825:                   if (*pi <= temp) break;
826:                   *(pi+1)=*pi;
827:                 }
828:               *(pi+1)=temp;
829:             }

831:           /* check to see if stack is exhausted ==> DONE */
832:           if (top_s==bottom_s) return;
833: 
834:           /* else pop another list from the stack */
835:           ar = *(--top_a);
836:           size = *(--top_s);
837:         }
838:     }
839: }



843: /******************************************************************************
844: Function: ivec_sort_companion().

846: Input : offset of list to be sorted, number of elements to be sorted.
847: Output: sorted list (in ascending order).
848: Return: none.
849: Description: stack based (nonrecursive) quicksort w/brute-shell bottom. 
850: ******************************************************************************/
851: void
852: ivec_sort_companion(register int *ar, register int *ar2, register int size)
853: {
854:   register int *pi, *pj, temp, temp2;
855:   register int **top_a = (int **)offset_stack;
856:   register int *top_s = size_stack, *bottom_s = size_stack;
857:   register int *pi2, *pj2;
858:   register int mid;


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

865:   /* do until we're done ... return when stack is exhausted */
866:   for (;;)
867:     {
868:       /* if list is large enough use quicksort partition exchange code */
869:       if (size > SORT_OPT)
870:         {
871:           /* start up pointer at element 1 and down at size     */
872:           mid = size>>1;
873:           pi = ar+1;
874:           pj = ar+mid;
875:           pi2 = ar2+1;
876:           pj2 = ar2+mid;

878:           /* find middle element in list and swap w/ element 1 */
879:           SWAP(*pi,*pj)
880:           SWAP(*pi2,*pj2)

882:           /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
883:           /* note ==> pivot_value in index 0                   */
884:           pj = ar+size;
885:           pj2 = ar2+size;
886:           if (*pi > *pj)
887:             {SWAP(*pi,*pj) SWAP(*pi2,*pj2)}
888:           if (*ar > *pj)
889:             {SWAP(*ar,*pj) SWAP(*ar2,*pj2)}
890:           else if (*pi > *ar)
891:             {SWAP(*(ar),*(ar+1)) SWAP(*(ar2),*(ar2+1))}

893:           /* partition about pivot_value ...                              */
894:           /* note lists of length 2 are not guaranteed to be sorted */
895:           for(;;)
896:             {
897:               /* walk up ... and down ... swap if equal to pivot! */
898:               do {pi++; pi2++;} while (*pi<*ar);
899:               do {pj--; pj2--;} while (*pj>*ar);

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

904:               /* else swap */
905:               SWAP(*pi,*pj)
906:               SWAP(*pi2,*pj2)
907:             }

909:           /* place pivot_value in it's correct location */
910:           SWAP(*ar,*pj)
911:           SWAP(*ar2,*pj2)

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

917:           /* push right hand child iff length > 1 */
918:           if ((*top_s = size-((int) (pi-ar))))
919:             {
920:               *(top_a++) = pi;
921:               *(top_a++) = pi2;
922:               size -= *top_s+2;
923:               top_s++;
924:             }
925:           /* set up for next loop iff there is something to do */
926:           else if (size -= *top_s+2)
927:             {;}
928:           /* might as well pop - note NR_OPT >=2 ==> we're ok! */
929:           else
930:             {
931:               ar2 = *(--top_a);
932:               ar  = *(--top_a);
933:               size = *(--top_s);
934:             }
935:         }

937:       /* else sort small list directly then pop another off stack */
938:       else
939:         {
940:           /* insertion sort for bottom */
941:           for (pj=ar+1, pj2=ar2+1;pj<=ar+size;pj++,pj2++)
942:             {
943:               temp = *pj;
944:               temp2 = *pj2;
945:               for (pi=pj-1,pi2=pj2-1;pi>=ar;pi--,pi2--)
946:                 {
947:                   if (*pi <= temp) break;
948:                   *(pi+1)=*pi;
949:                   *(pi2+1)=*pi2;
950:                 }
951:               *(pi+1)=temp;
952:               *(pi2+1)=temp2;
953:             }

955:           /* check to see if stack is exhausted ==> DONE */
956:           if (top_s==bottom_s) return;
957: 
958:           /* else pop another list from the stack */
959:           ar2 = *(--top_a);
960:           ar  = *(--top_a);
961:           size = *(--top_s);
962:         }
963:     }
964: }



968: /******************************************************************************
969: Function: ivec_sort_companion_hack().

971: Input : offset of list to be sorted, number of elements to be sorted.
972: Output: sorted list (in ascending order).
973: Return: none.
974: Description: stack based (nonrecursive) quicksort w/brute-shell bottom. 
975: ******************************************************************************/
976: void
977: ivec_sort_companion_hack(register int *ar, register int **ar2, 
978:                          register int size)
979: {
980:   register int *pi, *pj, temp, *ptr;
981:   register int **top_a = (int **)offset_stack;
982:   register int *top_s = size_stack, *bottom_s = size_stack;
983:   register int **pi2, **pj2;
984:   register int mid;


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

991:   /* do until we're done ... return when stack is exhausted */
992:   for (;;)
993:     {
994:       /* if list is large enough use quicksort partition exchange code */
995:       if (size > SORT_OPT)
996:         {
997:           /* start up pointer at element 1 and down at size     */
998:           mid = size>>1;
999:           pi = ar+1;
1000:           pj = ar+mid;
1001:           pi2 = ar2+1;
1002:           pj2 = ar2+mid;

1004:           /* find middle element in list and swap w/ element 1 */
1005:           SWAP(*pi,*pj)
1006:           P_SWAP(*pi2,*pj2)

1008:           /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
1009:           /* note ==> pivot_value in index 0                   */
1010:           pj = ar+size;
1011:           pj2 = ar2+size;
1012:           if (*pi > *pj)
1013:             {SWAP(*pi,*pj) P_SWAP(*pi2,*pj2)}
1014:           if (*ar > *pj)
1015:             {SWAP(*ar,*pj) P_SWAP(*ar2,*pj2)}
1016:           else if (*pi > *ar)
1017:             {SWAP(*(ar),*(ar+1)) P_SWAP(*(ar2),*(ar2+1))}

1019:           /* partition about pivot_value ...                              */
1020:           /* note lists of length 2 are not guaranteed to be sorted */
1021:           for(;;)
1022:             {
1023:               /* walk up ... and down ... swap if equal to pivot! */
1024:               do {pi++; pi2++;} while (*pi<*ar);
1025:               do {pj--; pj2--;} while (*pj>*ar);

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

1030:               /* else swap */
1031:               SWAP(*pi,*pj)
1032:               P_SWAP(*pi2,*pj2)
1033:             }

1035:           /* place pivot_value in it's correct location */
1036:           SWAP(*ar,*pj)
1037:           P_SWAP(*ar2,*pj2)

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

1043:           /* push right hand child iff length > 1 */
1044:           if ((*top_s = size-((int) (pi-ar))))
1045:             {
1046:               *(top_a++) = pi;
1047:               *(top_a++) = (int *) pi2;
1048:               size -= *top_s+2;
1049:               top_s++;
1050:             }
1051:           /* set up for next loop iff there is something to do */
1052:           else if (size -= *top_s+2)
1053:             {;}
1054:           /* might as well pop - note NR_OPT >=2 ==> we're ok! */
1055:           else
1056:             {
1057:               ar2 = (int **) *(--top_a);
1058:               ar  = *(--top_a);
1059:               size = *(--top_s);
1060:             }
1061:         }

1063:       /* else sort small list directly then pop another off stack */
1064:       else
1065:         {
1066:           /* insertion sort for bottom */
1067:           for (pj=ar+1, pj2=ar2+1;pj<=ar+size;pj++,pj2++)
1068:             {
1069:               temp = *pj;
1070:               ptr = *pj2;
1071:               for (pi=pj-1,pi2=pj2-1;pi>=ar;pi--,pi2--)
1072:                 {
1073:                   if (*pi <= temp) break;
1074:                   *(pi+1)=*pi;
1075:                   *(pi2+1)=*pi2;
1076:                 }
1077:               *(pi+1)=temp;
1078:               *(pi2+1)=ptr;
1079:             }

1081:           /* check to see if stack is exhausted ==> DONE */
1082:           if (top_s==bottom_s) return;
1083: 
1084:           /* else pop another list from the stack */
1085:           ar2 = (int **)*(--top_a);
1086:           ar  = *(--top_a);
1087:           size = *(--top_s);
1088:         }
1089:     }
1090: }



1094: /******************************************************************************
1095: Function: SMI_sort().
1096: Input : offset of list to be sorted, number of elements to be sorted.
1097: Output: sorted list (in ascending order).
1098: Return: none.
1099: Description: stack based (nonrecursive) quicksort w/brute-shell bottom. 
1100: ******************************************************************************/
1101: void
1102: SMI_sort(void *ar1, void *ar2, int size, int type)
1103: {
1104:   if (type == SORT_INTEGER)
1105:     {
1106:       if (ar2)
1107:         {ivec_sort_companion((int *)ar1,(int *)ar2,size);}
1108:       else
1109:         {ivec_sort((int*)ar1,size);}
1110:     }
1111:   else if (type == SORT_INT_PTR)
1112:     {
1113:       if (ar2)
1114:         {ivec_sort_companion_hack((int *)ar1,(int **)ar2,size);}
1115:       else
1116:         {ivec_sort((int*)ar1,size);}
1117:     }

1119:   else
1120:     {
1121:       error_msg_fatal("SMI_sort only does SORT_INTEGER!");
1122:     }
1123: /*
1124:   if (type == SORT_REAL)
1125:     {
1126:       if (ar2)
1127:         {rvec_sort_companion(ar2,ar1,size);}
1128:       else
1129:         {rvec_sort(ar1,size);}
1130:     }
1131: */
1132: }



1136: /**********************************ivec.c**************************************
1137: Function ivec_linear_search()

1139: Input :
1140: Output:
1141: Return:
1142: Description:
1143: ***********************************ivec.c*************************************/
1144: int
1145: ivec_linear_search(register int item, register int *list, register int n)
1146: {
1147:   register int tmp = n-1;

1149:   while (n--)  {if (*list++ == item) {return(tmp-n);}}
1150:   return(-1);
1151: }



1155: /**********************************ivec.c**************************************
1156: Function ivec_binary_search()

1158: Input :
1159: Output:
1160: Return:
1161: Description:
1162: ***********************************ivec.c*************************************/
1163: int
1164: ivec_binary_search(register int item, register int *list, register int rh)
1165: {
1166:   register int mid, lh=0;

1168:   rh--;
1169:   while (lh<=rh)
1170:     {
1171:       mid = (lh+rh)>>1;
1172:       if (*(list+mid) == item)
1173:         {return(mid);}
1174:       if (*(list+mid) > item)
1175:         {rh = mid-1;}
1176:       else
1177:         {lh = mid+1;}
1178:     }
1179:   return(-1);
1180: }



1184: /**********************************ivec.c**************************************
1185: Function rvec_dump

1187: Input : 
1188: Output: 
1189: Return: 
1190: Description: 
1191: ***********************************ivec.c*************************************/
1192: void
1193: rvec_dump(REAL *v, int n, int tag, int tag2, char * s)
1194: {
1195:   int i;
1196:   printf("%2d %2d %s %2d :: ",tag,tag2,s,my_id);
1197:   for (i=0;i<n;i++)
1198:     {printf("%f ",v[i]);}
1199:   printf("\n");
1200:   fflush(stdout);
1201: }



1205: /**********************************ivec.c**************************************
1206: Function rvec_lb_ub()

1208: Input :
1209: Output:
1210: Return:
1211: Description:
1212: ***********************************ivec.c*************************************/
1213: void
1214: rvec_lb_ub(register REAL *arg1, register int n, REAL *lb, REAL *ub)
1215: {
1216:   register REAL min =  REAL_MAX;
1217:   register REAL max = -REAL_MAX;

1219:   while (n--)
1220:     {
1221:      min = MIN(min,*arg1);
1222:      max = MAX(max,*arg1);
1223:      arg1++;
1224:     }

1226:   *lb=min;
1227:   *ub=max;
1228: }



1232: /********************************ivec.c**************************************
1233: Function rvec_copy()

1235: Input :
1236: Output:
1237: Return:
1238: Description:
1239: *********************************ivec.c*************************************/
1240: void 
1241: rvec_copy(register REAL *arg1, register REAL *arg2, register int n)
1242: {
1243:   while (n--)  {*arg1++ = *arg2++;}
1244: }



1248: /********************************ivec.c**************************************
1249: Function rvec_zero()

1251: Input :
1252: Output:
1253: Return:
1254: Description:
1255: *********************************ivec.c*************************************/
1256: void 
1257: rvec_zero(register REAL *arg1, register int n)
1258: {
1259:   while (n--)  {*arg1++ = 0.0;}
1260: }



1264: /**********************************ivec.c**************************************
1265: Function rvec_one()

1267: Input :
1268: Output:
1269: Return:
1270: Description:
1271: ***********************************ivec.c*************************************/
1272: void 
1273: rvec_one(register REAL *arg1, register int n)
1274: {
1275:   while (n--)  {*arg1++ = 1.0;}
1276: }



1280: /**********************************ivec.c**************************************
1281: Function rvec_neg_one()

1283: Input :
1284: Output:
1285: Return:
1286: Description:
1287: ***********************************ivec.c*************************************/
1288: void 
1289: rvec_neg_one(register REAL *arg1, register int n)
1290: {
1291:   while (n--)  {*arg1++ = -1.0;}
1292: }



1296: /**********************************ivec.c**************************************
1297: Function rvec_set()

1299: Input :
1300: Output:
1301: Return:
1302: Description:
1303: ***********************************ivec.c*************************************/
1304: void
1305: rvec_set(register REAL *arg1, register REAL arg2, register int n)
1306: {
1307:   while (n--)  {*arg1++ = arg2;}
1308: }



1312: /**********************************ivec.c**************************************
1313: Function rvec_scale()

1315: Input :
1316: Output:
1317: Return:
1318: Description:
1319: ***********************************ivec.c*************************************/
1320: void
1321: rvec_scale(register REAL *arg1, register REAL arg2, register int n)
1322: {
1323:   while (n--)  {*arg1++ *= arg2;}
1324: }



1328: /********************************ivec.c**************************************
1329: Function rvec_add()

1331: Input :
1332: Output:
1333: Return:
1334: Description:
1335: *********************************ivec.c*************************************/
1336: void 
1337: rvec_add(register REAL *arg1, register REAL *arg2, register int n)
1338: {
1339:   while (n--)  {*arg1++ += *arg2++;}
1340: }



1344: /********************************ivec.c**************************************
1345: Function rvec_dot()

1347: Input :
1348: Output:
1349: Return:
1350: Description:
1351: *********************************ivec.c*************************************/
1352: REAL
1353: rvec_dot(register REAL *arg1, register REAL *arg2, register int n)
1354: {
1355:   REAL dot=0.0;

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

1359:   return(dot);
1360: }



1364: /********************************ivec.c**************************************
1365: Function rvec_axpy()

1367: Input :
1368: Output:
1369: Return:
1370: Description:
1371: *********************************ivec.c*************************************/
1372: void
1373: rvec_axpy(register REAL *arg1, register REAL *arg2, register REAL scale, 
1374:           register int n)
1375: {
1376:   while (n--)  {*arg1++ += scale * *arg2++;}
1377: }


1380: /********************************ivec.c**************************************
1381: Function rvec_mult()

1383: Input :
1384: Output:
1385: Return:
1386: Description:
1387: *********************************ivec.c*************************************/
1388: void 
1389: rvec_mult(register REAL *arg1, register REAL *arg2, register int n)
1390: {
1391:   while (n--)  {*arg1++ *= *arg2++;}
1392: }



1396: /********************************ivec.c**************************************
1397: Function rvec_max()

1399: Input :
1400: Output:
1401: Return:
1402: Description:
1403: *********************************ivec.c*************************************/
1404: void 
1405: rvec_max(register REAL *arg1, register REAL *arg2, register int n)
1406: {
1407:   while (n--)  {*arg1 = MAX(*arg1,*arg2); arg1++; arg2++;}
1408: }



1412: /********************************ivec.c**************************************
1413: Function rvec_max_abs()

1415: Input :
1416: Output:
1417: Return:
1418: Description:
1419: *********************************ivec.c*************************************/
1420: void 
1421: rvec_max_abs(register REAL *arg1, register REAL *arg2, register int n)
1422: {
1423:   while (n--)  {*arg1 = MAX_FABS(*arg1,*arg2); arg1++; arg2++;}
1424: }



1428: /********************************ivec.c**************************************
1429: Function rvec_min()

1431: Input :
1432: Output:
1433: Return:
1434: Description:
1435: *********************************ivec.c*************************************/
1436: void 
1437: rvec_min(register REAL *arg1, register REAL *arg2, register int n)
1438: {
1439:   while (n--)  {*arg1 = MIN(*arg1,*arg2); arg1++; arg2++;}
1440: }



1444: /********************************ivec.c**************************************
1445: Function rvec_min_abs()

1447: Input :
1448: Output:
1449: Return:
1450: Description:
1451: *********************************ivec.c*************************************/
1452: void 
1453: rvec_min_abs(register REAL *arg1, register REAL *arg2, register int n)
1454: {
1455:   while (n--)  {*arg1 = MIN_FABS(*arg1,*arg2); arg1++; arg2++;}
1456: }



1460: /********************************ivec.c**************************************
1461: Function rvec_exists()

1463: Input :
1464: Output:
1465: Return:
1466: Description:
1467: *********************************ivec.c*************************************/
1468: void 
1469: rvec_exists(register REAL *arg1, register REAL *arg2, register int n)
1470: {
1471:   while (n--)  {*arg1 = EXISTS(*arg1,*arg2); arg1++; arg2++;}
1472: }



1476: /**********************************ivec.c**************************************
1477: Function rvec_non_uniform()

1479: Input :
1480: Output:
1481: Return:
1482: Description:
1483: ***********************************ivec.c*************************************/
1484: void 
1485: rvec_non_uniform(REAL *arg1, REAL *arg2, register int n, register int *arg3)
1486: {
1487:   register int i, j, type;


1490:   /* LATER: if we're really motivated we can sort and then unsort */
1491:   for (i=0;i<n;)
1492:     {
1493:       /* clump 'em for now */
1494:       j=i+1;
1495:       type = arg3[i];
1496:       while ((j<n)&&(arg3[j]==type))
1497:         {j++;}
1498: 
1499:       /* how many together */
1500:       j -= i;

1502:       /* call appropriate ivec function */
1503:       if (type == GL_MAX)
1504:         {rvec_max(arg1,arg2,j);}
1505:       else if (type == GL_MIN)
1506:         {rvec_min(arg1,arg2,j);}
1507:       else if (type == GL_MULT)
1508:         {rvec_mult(arg1,arg2,j);}
1509:       else if (type == GL_ADD)
1510:         {rvec_add(arg1,arg2,j);}
1511:       else if (type == GL_MAX_ABS)
1512:         {rvec_max_abs(arg1,arg2,j);}
1513:       else if (type == GL_MIN_ABS)
1514:         {rvec_min_abs(arg1,arg2,j);}
1515:       else if (type == GL_EXISTS)
1516:         {rvec_exists(arg1,arg2,j);}
1517:       else
1518:         {error_msg_fatal("unrecognized type passed to rvec_non_uniform()!");}

1520:       arg1+=j; arg2+=j; i+=j;
1521:     }
1522: }



1526: /**********************************ivec.c**************************************
1527: Function rvec_fct_addr()

1529: Input :
1530: Output:
1531: Return:
1532: Description:
1533: ***********************************ivec.c*************************************/
1534: vfp rvec_fct_addr(register int type)
1535: {
1536:   if (type == NON_UNIFORM)
1537:     {return((void (*)(void *, void *, int, ...))&rvec_non_uniform);}
1538:   else if (type == GL_MAX)
1539:     {return((void (*)(void *, void *, int, ...))&rvec_max);}
1540:   else if (type == GL_MIN)
1541:     {return((void (*)(void *, void *, int, ...))&rvec_min);}
1542:   else if (type == GL_MULT)
1543:     {return((void (*)(void *, void *, int, ...))&rvec_mult);}
1544:   else if (type == GL_ADD)
1545:     {return((void (*)(void *, void *, int, ...))&rvec_add);}
1546:   else if (type == GL_MAX_ABS)
1547:     {return((void (*)(void *, void *, int, ...))&rvec_max_abs);}
1548:   else if (type == GL_MIN_ABS)
1549:     {return((void (*)(void *, void *, int, ...))&rvec_min_abs);}
1550:   else if (type == GL_EXISTS)
1551:     {return((void (*)(void *, void *, int, ...))&rvec_exists);}

1553:   /* catch all ... not good if we get here */
1554:   return(NULL);
1555: }


1558: /******************************************************************************
1559: Function: my_sort().
1560: Input : offset of list to be sorted, number of elements to be sorted.
1561: Output: sorted list (in ascending order).
1562: Return: none.
1563: Description: stack based (nonrecursive) quicksort w/brute-shell bottom. 
1564: ******************************************************************************/
1565: void
1566: rvec_sort(register REAL *ar, register int Size)
1567: {
1568:   register REAL *pi, *pj, temp;
1569:   register REAL **top_a = (REAL **)offset_stack;
1570:   register PTRINT *top_s = psize_stack, *bottom_s = psize_stack;
1571:   register PTRINT size = (PTRINT) Size;

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

1577:   /* do until we're done ... return when stack is exhausted */
1578:   for (;;)
1579:     {
1580:       /* if list is large enough use quicksort partition exchange code */
1581:       if (size > SORT_OPT)
1582:         {
1583:           /* start up pointer at element 1 and down at size     */
1584:           pi = ar+1;
1585:           pj = ar+size;

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

1590:           pj = ar+size;

1592:           /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
1593:           /* note ==> pivot_value in index 0                   */
1594:           if (*pi > *pj)
1595:             {SWAP(*pi,*pj)}
1596:           if (*ar > *pj)
1597:             {SWAP(*ar,*pj)}
1598:           else if (*pi > *ar)
1599:             {SWAP(*(ar),*(ar+1))}

1601:           /* partition about pivot_value ...                              */
1602:           /* note lists of length 2 are not guaranteed to be sorted */
1603:           for(;;)
1604:             {
1605:               /* walk up ... and down ... swap if equal to pivot! */
1606:               do pi++; while (*pi<*ar);
1607:               do pj--; while (*pj>*ar);

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

1612:               /* else swap */
1613:               SWAP(*pi,*pj)
1614:             }

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

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

1623:           /* push right hand child iff length > 1 */
1624:           if ((*top_s = size-(pi-ar)))
1625:             {
1626:               *(top_a++) = pi;
1627:               size -= *top_s+2;
1628:               top_s++;
1629:             }
1630:           /* set up for next loop iff there is something to do */
1631:           else if (size -= *top_s+2)
1632:             {;}
1633:           /* might as well pop - note NR_OPT >=2 ==> we're ok! */
1634:           else
1635:             {
1636:               ar = *(--top_a);
1637:               size = *(--top_s);
1638:             }
1639:         }

1641:       /* else sort small list directly then pop another off stack */
1642:       else
1643:         {
1644:           /* insertion sort for bottom */
1645:           for (pj=ar+1;pj<=ar+size;pj++)
1646:             {
1647:               temp = *pj;
1648:               for (pi=pj-1;pi>=ar;pi--)
1649:                 {
1650:                   if (*pi <= temp) break;
1651:                   *(pi+1)=*pi;
1652:                 }
1653:               *(pi+1)=temp;
1654:             }

1656:           /* check to see if stack is exhausted ==> DONE */
1657:           if (top_s==bottom_s) return;
1658: 
1659:           /* else pop another list from the stack */
1660:           ar = *(--top_a);
1661:           size = *(--top_s);
1662:         }
1663:     }
1664: }



1668: /******************************************************************************
1669: Function: my_sort().
1670: Input : offset of list to be sorted, number of elements to be sorted.
1671: Output: sorted list (in ascending order).
1672: Return: none.
1673: Description: stack based (nonrecursive) quicksort w/brute-shell bottom. 
1674: ******************************************************************************/
1675: void
1676: rvec_sort_companion(register REAL *ar, register int *ar2, register int Size)
1677: {
1678:   register REAL *pi, *pj, temp;
1679:   register REAL **top_a = (REAL **)offset_stack;
1680:   register PTRINT *top_s = psize_stack, *bottom_s = psize_stack;
1681:   register PTRINT size = (PTRINT) Size;

1683:   register int *pi2, *pj2;
1684:   register int ptr;
1685:   register PTRINT mid;


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

1692:   /* do until we're done ... return when stack is exhausted */
1693:   for (;;)
1694:     {
1695:       /* if list is large enough use quicksort partition exchange code */
1696:       if (size > SORT_OPT)
1697:         {
1698:           /* start up pointer at element 1 and down at size     */
1699:           mid = size>>1;
1700:           pi = ar+1;
1701:           pj = ar+mid;
1702:           pi2 = ar2+1;
1703:           pj2 = ar2+mid;

1705:           /* find middle element in list and swap w/ element 1 */
1706:           SWAP(*pi,*pj)
1707:           P_SWAP(*pi2,*pj2)

1709:           /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
1710:           /* note ==> pivot_value in index 0                   */
1711:           pj = ar+size;
1712:           pj2 = ar2+size;
1713:           if (*pi > *pj)
1714:             {SWAP(*pi,*pj) P_SWAP(*pi2,*pj2)}
1715:           if (*ar > *pj)
1716:             {SWAP(*ar,*pj) P_SWAP(*ar2,*pj2)}
1717:           else if (*pi > *ar)
1718:             {SWAP(*(ar),*(ar+1)) P_SWAP(*(ar2),*(ar2+1))}

1720:           /* partition about pivot_value ...                              */
1721:           /* note lists of length 2 are not guaranteed to be sorted */
1722:           for(;;)
1723:             {
1724:               /* walk up ... and down ... swap if equal to pivot! */
1725:               do {pi++; pi2++;} while (*pi<*ar);
1726:               do {pj--; pj2--;} while (*pj>*ar);

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

1731:               /* else swap */
1732:               SWAP(*pi,*pj)
1733:               P_SWAP(*pi2,*pj2)
1734:             }

1736:           /* place pivot_value in it's correct location */
1737:           SWAP(*ar,*pj)
1738:           P_SWAP(*ar2,*pj2)

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

1744:           /* push right hand child iff length > 1 */
1745:           if ((*top_s = size-(pi-ar)))
1746:             {
1747:               *(top_a++) = pi;
1748:               *(top_a++) = (REAL *) pi2;
1749:               size -= *top_s+2;
1750:               top_s++;
1751:             }
1752:           /* set up for next loop iff there is something to do */
1753:           else if (size -= *top_s+2)
1754:             {;}
1755:           /* might as well pop - note NR_OPT >=2 ==> we're ok! */
1756:           else
1757:             {
1758:               ar2 = (int *) *(--top_a);
1759:               ar  = *(--top_a);
1760:               size = *(--top_s);
1761:             }
1762:         }

1764:       /* else sort small list directly then pop another off stack */
1765:       else
1766:         {
1767:           /* insertion sort for bottom */
1768:           for (pj=ar+1, pj2=ar2+1;pj<=ar+size;pj++,pj2++)
1769:             {
1770:               temp = *pj;
1771:               ptr = *pj2;
1772:               for (pi=pj-1,pi2=pj2-1;pi>=ar;pi--,pi2--)
1773:                 {
1774:                   if (*pi <= temp) break;
1775:                   *(pi+1)=*pi;
1776:                   *(pi2+1)=*pi2;
1777:                 }
1778:               *(pi+1)=temp;
1779:               *(pi2+1)=ptr;
1780:             }

1782:           /* check to see if stack is exhausted ==> DONE */
1783:           if (top_s==bottom_s) return;
1784: 
1785:           /* else pop another list from the stack */
1786:           ar2 = (int *) *(--top_a);
1787:           ar  = *(--top_a);
1788:           size = *(--top_s);
1789:         }
1790:     }
1791: }





1797: /**********************************ivec.c**************************************
1798: Function ivec_binary_search()

1800: Input :
1801: Output:
1802: Return:
1803: Description:
1804: ***********************************ivec.c*************************************/
1805: int
1806: rvec_binary_search(register REAL item, register REAL *list, register int rh)
1807: {
1808:   register int mid, lh=0;

1810:   rh--;
1811:   while (lh<=rh)
1812:     {
1813:       mid = (lh+rh)>>1;
1814:       if (*(list+mid) == item)
1815:         {return(mid);}
1816:       if (*(list+mid) > item)
1817:         {rh = mid-1;}
1818:       else
1819:         {lh = mid+1;}
1820:     }
1821:   return(-1);
1822: }