xref: /petsc/src/ksp/pc/impls/tfs/ivec.c (revision 827bd09bbb551290dd2e51d0997dc3a77eecb2e6)
1 
2 /**********************************ivec.c**************************************
3 SPARSE GATHER-SCATTER PACKAGE: bss_malloc bss_malloc ivec error comm gs queue
4 
5 Author: Henry M. Tufo III
6 
7 e-mail: hmt@cs.brown.edu
8 
9 snail-mail:
10 Division of Applied Mathematics
11 Brown University
12 Providence, RI 02912
13 
14 Last Modification:
15 6.21.97
16 ***********************************ivec.c*************************************/
17 
18 /**********************************ivec.c**************************************
19 File Description:
20 -----------------
21 
22 ***********************************ivec.c*************************************/
23 #include <stdio.h>
24 #include <math.h>
25 #include <float.h>
26 #include <limits.h>
27 
28 #ifdef MPISRC
29 #include <mpi.h>
30 #endif
31 
32 
33 #include "const.h"
34 #include "types.h"
35 #include "ivec.h"
36 #include "error.h"
37 #include "comm.h"
38 
39 
40 /* sorting args ivec.c ivec.c ... */
41 #define   SORT_OPT	6
42 #define   SORT_STACK	50000
43 
44 
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];
49 
50 
51 
52 /**********************************ivec.c**************************************
53 Function ivec_dump()
54 
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 }
70 
71 
72 
73 /**********************************ivec.c**************************************
74 Function ivec_lb_ub()
75 
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;
86 
87   while (n--)
88     {
89      min = MIN(min,*arg1);
90      max = MAX(max,*arg1);
91      arg1++;
92     }
93 
94   *lb=min;
95   *ub=max;
96 }
97 
98 
99 
100 /**********************************ivec.c**************************************
101 Function ivec_copy()
102 
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 }
114 
115 
116 
117 /**********************************ivec.c**************************************
118 Function ivec_zero()
119 
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 }
130 
131 
132 
133 /**********************************ivec.c**************************************
134 Function ivec_comp()
135 
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 }
146 
147 
148 
149 /**********************************ivec.c**************************************
150 Function ivec_neg_one()
151 
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 }
162 
163 
164 
165 /**********************************ivec.c**************************************
166 Function ivec_pos_one()
167 
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 }
178 
179 
180 
181 /**********************************ivec.c**************************************
182 Function ivec_c_index()
183 
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;
193 
194 
195   while (n--)  {*arg1++ = i++;}
196 }
197 
198 
199 
200 /**********************************ivec.c**************************************
201 Function ivec_fortran_index()
202 
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;
212 
213 
214   while (n--)  {*arg1++ = ++i;}
215 }
216 
217 
218 
219 /**********************************ivec.c**************************************
220 Function ivec_set()
221 
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 }
232 
233 
234 
235 /**********************************ivec.c**************************************
236 Function ivec_cmp()
237 
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 }
249 
250 
251 
252 /**********************************ivec.c**************************************
253 Function ivec_max()
254 
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 }
265 
266 
267 
268 /**********************************ivec.c**************************************
269 Function ivec_min()
270 
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 }
281 
282 
283 
284 /**********************************ivec.c**************************************
285 Function ivec_mult()
286 
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 }
297 
298 
299 
300 /**********************************ivec.c**************************************
301 Function ivec_add()
302 
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 }
313 
314 
315 
316 /**********************************ivec.c**************************************
317 Function ivec_lxor()
318 
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 }
329 
330 
331 
332 /**********************************ivec.c**************************************
333 Function ivec_xor()
334 
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 }
345 
346 
347 
348 /**********************************ivec.c**************************************
349 Function ivec_or()
350 
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 }
361 
362 
363 
364 /**********************************ivec.c**************************************
365 Function ivec_lor()
366 
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 }
377 
378 
379 
380 /**********************************ivec.c**************************************
381 Function ivec_or3()
382 
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 }
394 
395 
396 
397 /**********************************ivec.c**************************************
398 Function ivec_and()
399 
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 }
410 
411 
412 
413 /**********************************ivec.c**************************************
414 Function ivec_land()
415 
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 }
426 
427 
428 
429 /**********************************ivec.c**************************************
430 Function ivec_and3()
431 
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 }
443 
444 
445 
446 /**********************************ivec.c**************************************
447 Function ivec_sum
448 
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;
458 
459 
460   while (n--) {tmp += *arg1++;}
461   return(tmp);
462 }
463 
464 
465 
466 /**********************************ivec.c**************************************
467 Function ivec_reduce_and
468 
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;
478 
479 
480   while (n--) {tmp &= *arg1++;}
481   return(tmp);
482 }
483 
484 
485 
486 /**********************************ivec.c**************************************
487 Function ivec_reduce_or
488 
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;
498 
499 
500   while (n--) {tmp |= *arg1++;}
501   return(tmp);
502 }
503 
504 
505 
506 /**********************************ivec.c**************************************
507 Function ivec_prod
508 
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;
518 
519 
520   while (n--)  {tmp *= *arg1++;}
521   return(tmp);
522 }
523 
524 
525 
526 /**********************************ivec.c**************************************
527 Function ivec_u_sum
528 
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;
538 
539 
540   while (n--)  {tmp += *arg1++;}
541   return(tmp);
542 }
543 
544 
545 
546 /**********************************ivec.c**************************************
547 Function ivec_lb()
548 
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;
558 
559 
560   while (n--)  {min = MIN(min,*arg1); arg1++;}
561   return(min);
562 }
563 
564 
565 
566 /**********************************ivec.c**************************************
567 Function ivec_ub()
568 
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;
578 
579 
580   while (n--)  {max = MAX(max,*arg1); arg1++;}
581   return(max);
582 }
583 
584 
585 
586 /**********************************ivec.c**************************************
587 Function split_buf()
588 
589 Input :
590 Output:
591 Return:
592 Description:
593 
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 }
602 
603 
604 
605 /**********************************ivec.c**************************************
606 Function ivec_non_uniform()
607 
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;
617 
618 
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;
630 
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()!");}
654 
655       arg1+=j; arg2+=j; i+=j;
656     }
657 }
658 
659 
660 
661 /**********************************ivec.c**************************************
662 Function ivec_addr()
663 
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);}
693 
694   /* catch all ... not good if we get here */
695   return(NULL);
696 }
697 
698 
699 /**********************************ivec.c**************************************
700 Function ct_bits()
701 
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;
713 
714 
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     }
728 
729   return(tmp);
730 }
731 #endif
732 
733 
734 /******************************************************************************
735 Function: ivec_sort().
736 
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;
748 
749 
750   /* we're really interested in the offset of the last element */
751   /* ==> length of the list is now size + 1                    */
752   size--;
753 
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;
763 
764 	  /* find middle element in list and swap w/ element 1 */
765 	  SWAP(*(ar+(size>>1)),*pi)
766 
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))}
775 
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);
783 
784 	      /* if we've crossed we're done */
785 	      if (pj<pi) break;
786 
787 	      /* else swap */
788 	      SWAP(*pi,*pj)
789 	    }
790 
791 	  /* place pivot_value in it's correct location */
792 	  SWAP(*ar,*pj)
793 
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!!!");}
797 
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 	}
815 
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 	    }
830 
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 }
840 
841 
842 
843 /******************************************************************************
844 Function: ivec_sort_companion().
845 
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;
859 
860 
861   /* we're really interested in the offset of the last element */
862   /* ==> length of the list is now size + 1                    */
863   size--;
864 
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;
877 
878 	  /* find middle element in list and swap w/ element 1 */
879 	  SWAP(*pi,*pj)
880 	  SWAP(*pi2,*pj2)
881 
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))}
892 
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);
900 
901 	      /* if we've crossed we're done */
902 	      if (pj<pi) break;
903 
904 	      /* else swap */
905 	      SWAP(*pi,*pj)
906 	      SWAP(*pi2,*pj2)
907 	    }
908 
909 	  /* place pivot_value in it's correct location */
910 	  SWAP(*ar,*pj)
911 	  SWAP(*ar2,*pj2)
912 
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!!!");}
916 
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 	}
936 
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 	    }
954 
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 }
965 
966 
967 
968 /******************************************************************************
969 Function: ivec_sort_companion_hack().
970 
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;
985 
986 
987   /* we're really interested in the offset of the last element */
988   /* ==> length of the list is now size + 1                    */
989   size--;
990 
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;
1003 
1004 	  /* find middle element in list and swap w/ element 1 */
1005 	  SWAP(*pi,*pj)
1006 	  P_SWAP(*pi2,*pj2)
1007 
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))}
1018 
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);
1026 
1027 	      /* if we've crossed we're done */
1028 	      if (pj<pi) break;
1029 
1030 	      /* else swap */
1031 	      SWAP(*pi,*pj)
1032 	      P_SWAP(*pi2,*pj2)
1033 	    }
1034 
1035 	  /* place pivot_value in it's correct location */
1036 	  SWAP(*ar,*pj)
1037 	  P_SWAP(*ar2,*pj2)
1038 
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!!!");}
1042 
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 	}
1062 
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 	    }
1080 
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 }
1091 
1092 
1093 
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     }
1118 
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 }
1133 
1134 
1135 
1136 /**********************************ivec.c**************************************
1137 Function ivec_linear_search()
1138 
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;
1148 
1149   while (n--)  {if (*list++ == item) {return(tmp-n);}}
1150   return(-1);
1151 }
1152 
1153 
1154 
1155 /**********************************ivec.c**************************************
1156 Function ivec_binary_search()
1157 
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;
1167 
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 }
1181 
1182 
1183 
1184 /**********************************ivec.c**************************************
1185 Function rvec_dump
1186 
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 }
1202 
1203 
1204 
1205 /**********************************ivec.c**************************************
1206 Function rvec_lb_ub()
1207 
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;
1218 
1219   while (n--)
1220     {
1221      min = MIN(min,*arg1);
1222      max = MAX(max,*arg1);
1223      arg1++;
1224     }
1225 
1226   *lb=min;
1227   *ub=max;
1228 }
1229 
1230 
1231 
1232 /********************************ivec.c**************************************
1233 Function rvec_copy()
1234 
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 }
1245 
1246 
1247 
1248 /********************************ivec.c**************************************
1249 Function rvec_zero()
1250 
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 }
1261 
1262 
1263 
1264 /**********************************ivec.c**************************************
1265 Function rvec_one()
1266 
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 }
1277 
1278 
1279 
1280 /**********************************ivec.c**************************************
1281 Function rvec_neg_one()
1282 
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 }
1293 
1294 
1295 
1296 /**********************************ivec.c**************************************
1297 Function rvec_set()
1298 
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 }
1309 
1310 
1311 
1312 /**********************************ivec.c**************************************
1313 Function rvec_scale()
1314 
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 }
1325 
1326 
1327 
1328 /********************************ivec.c**************************************
1329 Function rvec_add()
1330 
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 }
1341 
1342 
1343 
1344 /********************************ivec.c**************************************
1345 Function rvec_dot()
1346 
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;
1356 
1357   while (n--)  {dot+= *arg1++ * *arg2++;}
1358 
1359   return(dot);
1360 }
1361 
1362 
1363 
1364 /********************************ivec.c**************************************
1365 Function rvec_axpy()
1366 
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 }
1378 
1379 
1380 /********************************ivec.c**************************************
1381 Function rvec_mult()
1382 
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 }
1393 
1394 
1395 
1396 /********************************ivec.c**************************************
1397 Function rvec_max()
1398 
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 }
1409 
1410 
1411 
1412 /********************************ivec.c**************************************
1413 Function rvec_max_abs()
1414 
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 }
1425 
1426 
1427 
1428 /********************************ivec.c**************************************
1429 Function rvec_min()
1430 
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 }
1441 
1442 
1443 
1444 /********************************ivec.c**************************************
1445 Function rvec_min_abs()
1446 
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 }
1457 
1458 
1459 
1460 /********************************ivec.c**************************************
1461 Function rvec_exists()
1462 
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 }
1473 
1474 
1475 
1476 /**********************************ivec.c**************************************
1477 Function rvec_non_uniform()
1478 
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;
1488 
1489 
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;
1501 
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()!");}
1519 
1520       arg1+=j; arg2+=j; i+=j;
1521     }
1522 }
1523 
1524 
1525 
1526 /**********************************ivec.c**************************************
1527 Function rvec_fct_addr()
1528 
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);}
1552 
1553   /* catch all ... not good if we get here */
1554   return(NULL);
1555 }
1556 
1557 
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;
1572 
1573   /* we're really interested in the offset of the last element */
1574   /* ==> length of the list is now size + 1                    */
1575   size--;
1576 
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;
1586 
1587 	  /* find middle element in list and swap w/ element 1 */
1588 	  SWAP(*(ar+(size>>1)),*pi)
1589 
1590 	  pj = ar+size;
1591 
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))}
1600 
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);
1608 
1609 	      /* if we've crossed we're done */
1610 	      if (pj<pi) break;
1611 
1612 	      /* else swap */
1613 	      SWAP(*pi,*pj)
1614 	    }
1615 
1616 	  /* place pivot_value in it's correct location */
1617 	  SWAP(*ar,*pj)
1618 
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");}
1622 
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 	}
1640 
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 	    }
1655 
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 }
1665 
1666 
1667 
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;
1682 
1683   register int *pi2, *pj2;
1684   register int ptr;
1685   register PTRINT mid;
1686 
1687 
1688   /* we're really interested in the offset of the last element */
1689   /* ==> length of the list is now size + 1                    */
1690   size--;
1691 
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;
1704 
1705 	  /* find middle element in list and swap w/ element 1 */
1706 	  SWAP(*pi,*pj)
1707 	  P_SWAP(*pi2,*pj2)
1708 
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))}
1719 
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);
1727 
1728 	      /* if we've crossed we're done */
1729 	      if (pj<pi) break;
1730 
1731 	      /* else swap */
1732 	      SWAP(*pi,*pj)
1733 	      P_SWAP(*pi2,*pj2)
1734 	    }
1735 
1736 	  /* place pivot_value in it's correct location */
1737 	  SWAP(*ar,*pj)
1738 	  P_SWAP(*ar2,*pj2)
1739 
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");}
1743 
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 	}
1763 
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 	    }
1781 
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 }
1792 
1793 
1794 
1795 
1796 
1797 /**********************************ivec.c**************************************
1798 Function ivec_binary_search()
1799 
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;
1809 
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 }
1823 
1824 
1825 
1826 
1827 
1828