xref: /petsc/src/ksp/pc/impls/tfs/ivec.c (revision 4c8c32f384357201972f9dd67b0f2e901704fd35)
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 *ivec_copy(register int *arg1, register int *arg2, register int n)
109 {
110   while (n--)  {*arg1++ = *arg2++;}
111   return(arg1);
112 }
113 
114 
115 
116 /**********************************ivec.c**************************************
117 Function ivec_zero()
118 
119 Input :
120 Output:
121 Return:
122 Description:
123 ***********************************ivec.c*************************************/
124 void
125 ivec_zero(register int *arg1, register int n)
126 {
127   while (n--)  {*arg1++ = 0;}
128 }
129 
130 
131 
132 /**********************************ivec.c**************************************
133 Function ivec_comp()
134 
135 Input :
136 Output:
137 Return:
138 Description:
139 ***********************************ivec.c*************************************/
140 void
141 ivec_comp(register int *arg1, register int n)
142 {
143   while (n--)  {*arg1 = ~*arg1; arg1++;}
144 }
145 
146 
147 
148 /**********************************ivec.c**************************************
149 Function ivec_neg_one()
150 
151 Input :
152 Output:
153 Return:
154 Description:
155 ***********************************ivec.c*************************************/
156 void
157 ivec_neg_one(register int *arg1, register int n)
158 {
159   while (n--)  {*arg1++ = -1;}
160 }
161 
162 
163 
164 /**********************************ivec.c**************************************
165 Function ivec_pos_one()
166 
167 Input :
168 Output:
169 Return:
170 Description:
171 ***********************************ivec.c*************************************/
172 void
173 ivec_pos_one(register int *arg1, register int n)
174 {
175   while (n--)  {*arg1++ = 1;}
176 }
177 
178 
179 
180 /**********************************ivec.c**************************************
181 Function ivec_c_index()
182 
183 Input :
184 Output:
185 Return:
186 Description:
187 ***********************************ivec.c*************************************/
188 void
189 ivec_c_index(register int *arg1, register int n)
190 {
191   register int i=0;
192 
193 
194   while (n--)  {*arg1++ = i++;}
195 }
196 
197 
198 
199 /**********************************ivec.c**************************************
200 Function ivec_fortran_index()
201 
202 Input :
203 Output:
204 Return:
205 Description:
206 ***********************************ivec.c*************************************/
207 void
208 ivec_fortran_index(register int *arg1, register int n)
209 {
210   register int i=0;
211 
212 
213   while (n--)  {*arg1++ = ++i;}
214 }
215 
216 
217 
218 /**********************************ivec.c**************************************
219 Function ivec_set()
220 
221 Input :
222 Output:
223 Return:
224 Description:
225 ***********************************ivec.c*************************************/
226 void
227 ivec_set(register int *arg1, register int arg2, register int n)
228 {
229   while (n--)  {*arg1++ = arg2;}
230 }
231 
232 
233 
234 /**********************************ivec.c**************************************
235 Function ivec_cmp()
236 
237 Input :
238 Output:
239 Return:
240 Description:
241 ***********************************ivec.c*************************************/
242 int
243 ivec_cmp(register int *arg1, register int *arg2, register int n)
244 {
245   while (n--)  {if (*arg1++ != *arg2++)  {return(FALSE);}}
246   return(TRUE);
247 }
248 
249 
250 
251 /**********************************ivec.c**************************************
252 Function ivec_max()
253 
254 Input :
255 Output:
256 Return:
257 Description:
258 ***********************************ivec.c*************************************/
259 void
260 ivec_max(register int *arg1, register int *arg2, register int n)
261 {
262   while (n--)  {*arg1 = MAX(*arg1,*arg2); arg1++; arg2++;}
263 }
264 
265 
266 
267 /**********************************ivec.c**************************************
268 Function ivec_min()
269 
270 Input :
271 Output:
272 Return:
273 Description:
274 ***********************************ivec.c*************************************/
275 void
276 ivec_min(register int *arg1, register int *arg2, register int n)
277 {
278   while (n--)  {*(arg1) = MIN(*arg1,*arg2); arg1++; arg2++;}
279 }
280 
281 
282 
283 /**********************************ivec.c**************************************
284 Function ivec_mult()
285 
286 Input :
287 Output:
288 Return:
289 Description:
290 ***********************************ivec.c*************************************/
291 void
292 ivec_mult(register int *arg1, register int *arg2, register int n)
293 {
294   while (n--)  {*arg1++ *= *arg2++;}
295 }
296 
297 
298 
299 /**********************************ivec.c**************************************
300 Function ivec_add()
301 
302 Input :
303 Output:
304 Return:
305 Description:
306 ***********************************ivec.c*************************************/
307 void
308 ivec_add(register int *arg1, register int *arg2, register int n)
309 {
310   while (n--)  {*arg1++ += *arg2++;}
311 }
312 
313 
314 
315 /**********************************ivec.c**************************************
316 Function ivec_lxor()
317 
318 Input :
319 Output:
320 Return:
321 Description:
322 ***********************************ivec.c*************************************/
323 void
324 ivec_lxor(register int *arg1, register int *arg2, register int n)
325 {
326   while (n--) {*arg1=((*arg1 || *arg2) && !(*arg1 && *arg2)); arg1++; arg2++;}
327 }
328 
329 
330 
331 /**********************************ivec.c**************************************
332 Function ivec_xor()
333 
334 Input :
335 Output:
336 Return:
337 Description:
338 ***********************************ivec.c*************************************/
339 void
340 ivec_xor(register int *arg1, register int *arg2, register int n)
341 {
342   while (n--)  {*arg1++ ^= *arg2++;}
343 }
344 
345 
346 
347 /**********************************ivec.c**************************************
348 Function ivec_or()
349 
350 Input :
351 Output:
352 Return:
353 Description:
354 ***********************************ivec.c*************************************/
355 void
356 ivec_or(register int *arg1, register int *arg2, register int n)
357 {
358   while (n--)  {*arg1++ |= *arg2++;}
359 }
360 
361 
362 
363 /**********************************ivec.c**************************************
364 Function ivec_lor()
365 
366 Input :
367 Output:
368 Return:
369 Description:
370 ***********************************ivec.c*************************************/
371 void
372 ivec_lor(register int *arg1, register int *arg2, register int n)
373 {
374   while (n--)  {*arg1 = (*arg1 || *arg2); arg1++; arg2++;}
375 }
376 
377 
378 
379 /**********************************ivec.c**************************************
380 Function ivec_or3()
381 
382 Input :
383 Output:
384 Return:
385 Description:
386 ***********************************ivec.c*************************************/
387 void
388 ivec_or3(register int *arg1, register int *arg2, register int *arg3,
389 	 register int n)
390 {
391   while (n--)  {*arg1++ = (*arg2++ | *arg3++);}
392 }
393 
394 
395 
396 /**********************************ivec.c**************************************
397 Function ivec_and()
398 
399 Input :
400 Output:
401 Return:
402 Description:
403 ***********************************ivec.c*************************************/
404 void
405 ivec_and(register int *arg1, register int *arg2, register int n)
406 {
407   while (n--)  {*arg1++ &= *arg2++;}
408 }
409 
410 
411 
412 /**********************************ivec.c**************************************
413 Function ivec_land()
414 
415 Input :
416 Output:
417 Return:
418 Description:
419 ***********************************ivec.c*************************************/
420 void
421 ivec_land(register int *arg1, register int *arg2, register int n)
422 {
423   while (n--) {*arg1 = (*arg1 && *arg2); arg1++; arg2++;}
424 }
425 
426 
427 
428 /**********************************ivec.c**************************************
429 Function ivec_and3()
430 
431 Input :
432 Output:
433 Return:
434 Description:
435 ***********************************ivec.c*************************************/
436 void
437 ivec_and3(register int *arg1, register int *arg2, register int *arg3,
438 	  register int n)
439 {
440   while (n--)  {*arg1++ = (*arg2++ & *arg3++);}
441 }
442 
443 
444 
445 /**********************************ivec.c**************************************
446 Function ivec_sum
447 
448 Input :
449 Output:
450 Return:
451 Description:
452 ***********************************ivec.c*************************************/
453 int ivec_sum(register int *arg1, register int n)
454 {
455   register int tmp = 0;
456 
457 
458   while (n--) {tmp += *arg1++;}
459   return(tmp);
460 }
461 
462 
463 
464 /**********************************ivec.c**************************************
465 Function ivec_reduce_and
466 
467 Input :
468 Output:
469 Return:
470 Description:
471 ***********************************ivec.c*************************************/
472 int ivec_reduce_and(register int *arg1, register int n)
473 {
474   register int tmp = ALL_ONES;
475 
476 
477   while (n--) {tmp &= *arg1++;}
478   return(tmp);
479 }
480 
481 
482 
483 /**********************************ivec.c**************************************
484 Function ivec_reduce_or
485 
486 Input :
487 Output:
488 Return:
489 Description:
490 ***********************************ivec.c*************************************/
491 int ivec_reduce_or(register int *arg1, register int n)
492 {
493   register int tmp = 0;
494 
495 
496   while (n--) {tmp |= *arg1++;}
497   return(tmp);
498 }
499 
500 
501 
502 /**********************************ivec.c**************************************
503 Function ivec_prod
504 
505 Input :
506 Output:
507 Return:
508 Description:
509 ***********************************ivec.c*************************************/
510 int ivec_prod(register int *arg1, register int n)
511 {
512   register int tmp = 1;
513 
514 
515   while (n--)  {tmp *= *arg1++;}
516   return(tmp);
517 }
518 
519 
520 
521 /**********************************ivec.c**************************************
522 Function ivec_u_sum
523 
524 Input :
525 Output:
526 Return:
527 Description:
528 ***********************************ivec.c*************************************/
529 int ivec_u_sum(register unsigned *arg1, register int n)
530 {
531   register unsigned tmp = 0;
532 
533 
534   while (n--)  {tmp += *arg1++;}
535   return(tmp);
536 }
537 
538 
539 
540 /**********************************ivec.c**************************************
541 Function ivec_lb()
542 
543 Input :
544 Output:
545 Return:
546 Description:
547 ***********************************ivec.c*************************************/
548 int
549 ivec_lb(register int *arg1, register int n)
550 {
551   register int min = INT_MAX;
552 
553 
554   while (n--)  {min = MIN(min,*arg1); arg1++;}
555   return(min);
556 }
557 
558 
559 
560 /**********************************ivec.c**************************************
561 Function ivec_ub()
562 
563 Input :
564 Output:
565 Return:
566 Description:
567 ***********************************ivec.c*************************************/
568 int
569 ivec_ub(register int *arg1, register int n)
570 {
571   register int max = INT_MIN;
572 
573 
574   while (n--)  {max = MAX(max,*arg1); arg1++;}
575   return(max);
576 }
577 
578 
579 
580 /**********************************ivec.c**************************************
581 Function split_buf()
582 
583 Input :
584 Output:
585 Return:
586 Description:
587 
588 assumes that sizeof(int) == 4bytes!!!
589 ***********************************ivec.c*************************************/
590 int
591 ivec_split_buf(int *buf1, int **buf2, register int size)
592 {
593   *buf2 = (buf1 + (size>>3));
594   return(size);
595 }
596 
597 
598 
599 /**********************************ivec.c**************************************
600 Function ivec_non_uniform()
601 
602 Input :
603 Output:
604 Return:
605 Description:
606 ***********************************ivec.c*************************************/
607 void
608 ivec_non_uniform(int *arg1, int *arg2, register int n, register int *arg3)
609 {
610   register int i, j, type;
611 
612 
613   /* LATER: if we're really motivated we can sort and then unsort */
614   for (i=0;i<n;)
615     {
616       /* clump 'em for now */
617       j=i+1;
618       type = arg3[i];
619       while ((j<n)&&(arg3[j]==type))
620 	{j++;}
621 
622       /* how many together */
623       j -= i;
624 
625       /* call appropriate ivec function */
626       if (type == GL_MAX)
627 	{ivec_max(arg1,arg2,j);}
628       else if (type == GL_MIN)
629 	{ivec_min(arg1,arg2,j);}
630       else if (type == GL_MULT)
631 	{ivec_mult(arg1,arg2,j);}
632       else if (type == GL_ADD)
633 	{ivec_add(arg1,arg2,j);}
634       else if (type == GL_B_XOR)
635 	{ivec_xor(arg1,arg2,j);}
636       else if (type == GL_B_OR)
637 	{ivec_or(arg1,arg2,j);}
638       else if (type == GL_B_AND)
639 	{ivec_and(arg1,arg2,j);}
640       else if (type == GL_L_XOR)
641 	{ivec_lxor(arg1,arg2,j);}
642       else if (type == GL_L_OR)
643 	{ivec_lor(arg1,arg2,j);}
644       else if (type == GL_L_AND)
645 	{ivec_land(arg1,arg2,j);}
646       else
647 	{error_msg_fatal("unrecognized type passed to ivec_non_uniform()!");}
648 
649       arg1+=j; arg2+=j; i+=j;
650     }
651 }
652 
653 
654 
655 /**********************************ivec.c**************************************
656 Function ivec_addr()
657 
658 Input :
659 Output:
660 Return:
661 Description:
662 ***********************************ivec.c*************************************/
663 vfp ivec_fct_addr(register int type)
664 {
665   if (type == NON_UNIFORM)
666     {return((void (*)(void*, void *, int, ...))&ivec_non_uniform);}
667   else if (type == GL_MAX)
668     {return((void (*)(void*, void *, int, ...))&ivec_max);}
669   else if (type == GL_MIN)
670     {return((void (*)(void*, void *, int, ...))&ivec_min);}
671   else if (type == GL_MULT)
672     {return((void (*)(void*, void *, int, ...))&ivec_mult);}
673   else if (type == GL_ADD)
674     {return((void (*)(void*, void *, int, ...))&ivec_add);}
675   else if (type == GL_B_XOR)
676     {return((void (*)(void*, void *, int, ...))&ivec_xor);}
677   else if (type == GL_B_OR)
678     {return((void (*)(void*, void *, int, ...))&ivec_or);}
679   else if (type == GL_B_AND)
680     {return((void (*)(void*, void *, int, ...))&ivec_and);}
681   else if (type == GL_L_XOR)
682     {return((void (*)(void*, void *, int, ...))&ivec_lxor);}
683   else if (type == GL_L_OR)
684     {return((void (*)(void*, void *, int, ...))&ivec_lor);}
685   else if (type == GL_L_AND)
686     {return((void (*)(void*, void *, int, ...))&ivec_land);}
687 
688   /* catch all ... not good if we get here */
689   return(NULL);
690 }
691 
692 
693 /**********************************ivec.c**************************************
694 Function ct_bits()
695 
696 Input :
697 Output:
698 Return:
699 Description: MUST FIX THIS!!!
700 ***********************************ivec.c*************************************/
701 #if defined(notusing)
702 static
703 int
704 ivec_ct_bits(register int *ptr, register int n)
705 {
706   register int tmp=0;
707 
708 
709   /* should expand to full 32 bit */
710   while (n--)
711     {
712       if (*ptr&128) {tmp++;}
713       if (*ptr&64)  {tmp++;}
714       if (*ptr&32)  {tmp++;}
715       if (*ptr&16)  {tmp++;}
716       if (*ptr&8)   {tmp++;}
717       if (*ptr&4)   {tmp++;}
718       if (*ptr&2)   {tmp++;}
719       if (*ptr&1)   {tmp++;}
720       ptr++;
721     }
722 
723   return(tmp);
724 }
725 #endif
726 
727 
728 /******************************************************************************
729 Function: ivec_sort().
730 
731 Input : offset of list to be sorted, number of elements to be sorted.
732 Output: sorted list (in ascending order).
733 Return: none.
734 Description: stack based (nonrecursive) quicksort w/brute-shell bottom.
735 ******************************************************************************/
736 void
737 ivec_sort(register int *ar, register int size)
738 {
739   register int *pi, *pj, temp;
740   register int **top_a = (int **) offset_stack;
741   register int *top_s = size_stack, *bottom_s = size_stack;
742 
743 
744   /* we're really interested in the offset of the last element */
745   /* ==> length of the list is now size + 1                    */
746   size--;
747 
748   /* do until we're done ... return when stack is exhausted */
749   for (;;)
750     {
751       /* if list is large enough use quicksort partition exchange code */
752       if (size > SORT_OPT)
753 	{
754 	  /* start up pointer at element 1 and down at size     */
755 	  pi = ar+1;
756 	  pj = ar+size;
757 
758 	  /* find middle element in list and swap w/ element 1 */
759 	  SWAP(*(ar+(size>>1)),*pi)
760 
761 	  /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
762 	  /* note ==> pivot_value in index 0                   */
763 	  if (*pi > *pj)
764 	    {SWAP(*pi,*pj)}
765 	  if (*ar > *pj)
766 	    {SWAP(*ar,*pj)}
767 	  else if (*pi > *ar)
768 	    {SWAP(*(ar),*(ar+1))}
769 
770 	  /* partition about pivot_value ...  	                    */
771 	  /* note lists of length 2 are not guaranteed to be sorted */
772 	  for(;;)
773 	    {
774 	      /* walk up ... and down ... swap if equal to pivot! */
775 	      do pi++; while (*pi<*ar);
776 	      do pj--; while (*pj>*ar);
777 
778 	      /* if we've crossed we're done */
779 	      if (pj<pi) break;
780 
781 	      /* else swap */
782 	      SWAP(*pi,*pj)
783 	    }
784 
785 	  /* place pivot_value in it's correct location */
786 	  SWAP(*ar,*pj)
787 
788 	  /* test stack_size to see if we've exhausted our stack */
789 	  if (top_s-bottom_s >= SORT_STACK)
790 	    {error_msg_fatal("ivec_sort() :: STACK EXHAUSTED!!!");}
791 
792 	  /* push right hand child iff length > 1 */
793 	  if ((*top_s = size-((int) (pi-ar))))
794 	    {
795 	      *(top_a++) = pi;
796 	      size -= *top_s+2;
797 	      top_s++;
798 	    }
799 	  /* set up for next loop iff there is something to do */
800 	  else if (size -= *top_s+2)
801 	    {;}
802 	  /* might as well pop - note NR_OPT >=2 ==> we're ok! */
803 	  else
804 	    {
805 	      ar = *(--top_a);
806 	      size = *(--top_s);
807 	    }
808 	}
809 
810       /* else sort small list directly then pop another off stack */
811       else
812 	{
813 	  /* insertion sort for bottom */
814           for (pj=ar+1;pj<=ar+size;pj++)
815             {
816               temp = *pj;
817               for (pi=pj-1;pi>=ar;pi--)
818                 {
819                   if (*pi <= temp) break;
820                   *(pi+1)=*pi;
821                 }
822               *(pi+1)=temp;
823 	    }
824 
825 	  /* check to see if stack is exhausted ==> DONE */
826 	  if (top_s==bottom_s) return;
827 
828 	  /* else pop another list from the stack */
829 	  ar = *(--top_a);
830 	  size = *(--top_s);
831 	}
832     }
833 }
834 
835 
836 
837 /******************************************************************************
838 Function: ivec_sort_companion().
839 
840 Input : offset of list to be sorted, number of elements to be sorted.
841 Output: sorted list (in ascending order).
842 Return: none.
843 Description: stack based (nonrecursive) quicksort w/brute-shell bottom.
844 ******************************************************************************/
845 void
846 ivec_sort_companion(register int *ar, register int *ar2, register int size)
847 {
848   register int *pi, *pj, temp, temp2;
849   register int **top_a = (int **)offset_stack;
850   register int *top_s = size_stack, *bottom_s = size_stack;
851   register int *pi2, *pj2;
852   register int mid;
853 
854 
855   /* we're really interested in the offset of the last element */
856   /* ==> length of the list is now size + 1                    */
857   size--;
858 
859   /* do until we're done ... return when stack is exhausted */
860   for (;;)
861     {
862       /* if list is large enough use quicksort partition exchange code */
863       if (size > SORT_OPT)
864 	{
865 	  /* start up pointer at element 1 and down at size     */
866 	  mid = size>>1;
867 	  pi = ar+1;
868 	  pj = ar+mid;
869 	  pi2 = ar2+1;
870 	  pj2 = ar2+mid;
871 
872 	  /* find middle element in list and swap w/ element 1 */
873 	  SWAP(*pi,*pj)
874 	  SWAP(*pi2,*pj2)
875 
876 	  /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
877 	  /* note ==> pivot_value in index 0                   */
878 	  pj = ar+size;
879 	  pj2 = ar2+size;
880 	  if (*pi > *pj)
881 	    {SWAP(*pi,*pj) SWAP(*pi2,*pj2)}
882 	  if (*ar > *pj)
883 	    {SWAP(*ar,*pj) SWAP(*ar2,*pj2)}
884 	  else if (*pi > *ar)
885 	    {SWAP(*(ar),*(ar+1)) SWAP(*(ar2),*(ar2+1))}
886 
887 	  /* partition about pivot_value ...  	                    */
888 	  /* note lists of length 2 are not guaranteed to be sorted */
889 	  for(;;)
890 	    {
891 	      /* walk up ... and down ... swap if equal to pivot! */
892 	      do {pi++; pi2++;} while (*pi<*ar);
893 	      do {pj--; pj2--;} while (*pj>*ar);
894 
895 	      /* if we've crossed we're done */
896 	      if (pj<pi) break;
897 
898 	      /* else swap */
899 	      SWAP(*pi,*pj)
900 	      SWAP(*pi2,*pj2)
901 	    }
902 
903 	  /* place pivot_value in it's correct location */
904 	  SWAP(*ar,*pj)
905 	  SWAP(*ar2,*pj2)
906 
907 	  /* test stack_size to see if we've exhausted our stack */
908 	  if (top_s-bottom_s >= SORT_STACK)
909 	    {error_msg_fatal("ivec_sort_companion() :: STACK EXHAUSTED!!!");}
910 
911 	  /* push right hand child iff length > 1 */
912 	  if ((*top_s = size-((int) (pi-ar))))
913 	    {
914 	      *(top_a++) = pi;
915 	      *(top_a++) = pi2;
916 	      size -= *top_s+2;
917 	      top_s++;
918 	    }
919 	  /* set up for next loop iff there is something to do */
920 	  else if (size -= *top_s+2)
921 	    {;}
922 	  /* might as well pop - note NR_OPT >=2 ==> we're ok! */
923 	  else
924 	    {
925 	      ar2 = *(--top_a);
926 	      ar  = *(--top_a);
927 	      size = *(--top_s);
928 	    }
929 	}
930 
931       /* else sort small list directly then pop another off stack */
932       else
933 	{
934 	  /* insertion sort for bottom */
935           for (pj=ar+1, pj2=ar2+1;pj<=ar+size;pj++,pj2++)
936             {
937               temp = *pj;
938               temp2 = *pj2;
939               for (pi=pj-1,pi2=pj2-1;pi>=ar;pi--,pi2--)
940                 {
941                   if (*pi <= temp) break;
942                   *(pi+1)=*pi;
943                   *(pi2+1)=*pi2;
944                 }
945               *(pi+1)=temp;
946               *(pi2+1)=temp2;
947 	    }
948 
949 	  /* check to see if stack is exhausted ==> DONE */
950 	  if (top_s==bottom_s) return;
951 
952 	  /* else pop another list from the stack */
953 	  ar2 = *(--top_a);
954 	  ar  = *(--top_a);
955 	  size = *(--top_s);
956 	}
957     }
958 }
959 
960 
961 
962 /******************************************************************************
963 Function: ivec_sort_companion_hack().
964 
965 Input : offset of list to be sorted, number of elements to be sorted.
966 Output: sorted list (in ascending order).
967 Return: none.
968 Description: stack based (nonrecursive) quicksort w/brute-shell bottom.
969 ******************************************************************************/
970 void
971 ivec_sort_companion_hack(register int *ar, register int **ar2,
972 			 register int size)
973 {
974   register int *pi, *pj, temp, *ptr;
975   register int **top_a = (int **)offset_stack;
976   register int *top_s = size_stack, *bottom_s = size_stack;
977   register int **pi2, **pj2;
978   register int mid;
979 
980 
981   /* we're really interested in the offset of the last element */
982   /* ==> length of the list is now size + 1                    */
983   size--;
984 
985   /* do until we're done ... return when stack is exhausted */
986   for (;;)
987     {
988       /* if list is large enough use quicksort partition exchange code */
989       if (size > SORT_OPT)
990 	{
991 	  /* start up pointer at element 1 and down at size     */
992 	  mid = size>>1;
993 	  pi = ar+1;
994 	  pj = ar+mid;
995 	  pi2 = ar2+1;
996 	  pj2 = ar2+mid;
997 
998 	  /* find middle element in list and swap w/ element 1 */
999 	  SWAP(*pi,*pj)
1000 	  P_SWAP(*pi2,*pj2)
1001 
1002 	  /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
1003 	  /* note ==> pivot_value in index 0                   */
1004 	  pj = ar+size;
1005 	  pj2 = ar2+size;
1006 	  if (*pi > *pj)
1007 	    {SWAP(*pi,*pj) P_SWAP(*pi2,*pj2)}
1008 	  if (*ar > *pj)
1009 	    {SWAP(*ar,*pj) P_SWAP(*ar2,*pj2)}
1010 	  else if (*pi > *ar)
1011 	    {SWAP(*(ar),*(ar+1)) P_SWAP(*(ar2),*(ar2+1))}
1012 
1013 	  /* partition about pivot_value ...  	                    */
1014 	  /* note lists of length 2 are not guaranteed to be sorted */
1015 	  for(;;)
1016 	    {
1017 	      /* walk up ... and down ... swap if equal to pivot! */
1018 	      do {pi++; pi2++;} while (*pi<*ar);
1019 	      do {pj--; pj2--;} while (*pj>*ar);
1020 
1021 	      /* if we've crossed we're done */
1022 	      if (pj<pi) break;
1023 
1024 	      /* else swap */
1025 	      SWAP(*pi,*pj)
1026 	      P_SWAP(*pi2,*pj2)
1027 	    }
1028 
1029 	  /* place pivot_value in it's correct location */
1030 	  SWAP(*ar,*pj)
1031 	  P_SWAP(*ar2,*pj2)
1032 
1033 	  /* test stack_size to see if we've exhausted our stack */
1034 	  if (top_s-bottom_s >= SORT_STACK)
1035          {error_msg_fatal("ivec_sort_companion_hack() :: STACK EXHAUSTED!!!");}
1036 
1037 	  /* push right hand child iff length > 1 */
1038 	  if ((*top_s = size-((int) (pi-ar))))
1039 	    {
1040 	      *(top_a++) = pi;
1041 	      *(top_a++) = (int*) pi2;
1042 	      size -= *top_s+2;
1043 	      top_s++;
1044 	    }
1045 	  /* set up for next loop iff there is something to do */
1046 	  else if (size -= *top_s+2)
1047 	    {;}
1048 	  /* might as well pop - note NR_OPT >=2 ==> we're ok! */
1049 	  else
1050 	    {
1051 	      ar2 = (int **) *(--top_a);
1052 	      ar  = *(--top_a);
1053 	      size = *(--top_s);
1054 	    }
1055 	}
1056 
1057       /* else sort small list directly then pop another off stack */
1058       else
1059 	{
1060 	  /* insertion sort for bottom */
1061           for (pj=ar+1, pj2=ar2+1;pj<=ar+size;pj++,pj2++)
1062             {
1063               temp = *pj;
1064               ptr = *pj2;
1065               for (pi=pj-1,pi2=pj2-1;pi>=ar;pi--,pi2--)
1066                 {
1067                   if (*pi <= temp) break;
1068                   *(pi+1)=*pi;
1069                   *(pi2+1)=*pi2;
1070                 }
1071               *(pi+1)=temp;
1072               *(pi2+1)=ptr;
1073 	    }
1074 
1075 	  /* check to see if stack is exhausted ==> DONE */
1076 	  if (top_s==bottom_s) return;
1077 
1078 	  /* else pop another list from the stack */
1079 	  ar2 = (int **)*(--top_a);
1080 	  ar  = *(--top_a);
1081 	  size = *(--top_s);
1082 	}
1083     }
1084 }
1085 
1086 
1087 
1088 /******************************************************************************
1089 Function: SMI_sort().
1090 Input : offset of list to be sorted, number of elements to be sorted.
1091 Output: sorted list (in ascending order).
1092 Return: none.
1093 Description: stack based (nonrecursive) quicksort w/brute-shell bottom.
1094 ******************************************************************************/
1095 void
1096 SMI_sort(void *ar1, void *ar2, int size, int type)
1097 {
1098   if (type == SORT_INTEGER)
1099     {
1100       if (ar2)
1101 	{ivec_sort_companion((int*)ar1,(int*)ar2,size);}
1102       else
1103 	{ivec_sort((int*)ar1,size);}
1104     }
1105   else if (type == SORT_INT_PTR)
1106     {
1107       if (ar2)
1108 	{ivec_sort_companion_hack((int*)ar1,(int **)ar2,size);}
1109       else
1110 	{ivec_sort((int*)ar1,size);}
1111     }
1112 
1113   else
1114     {
1115       error_msg_fatal("SMI_sort only does SORT_INTEGER!");
1116     }
1117 /*
1118   if (type == SORT_REAL)
1119     {
1120       if (ar2)
1121 	{rvec_sort_companion(ar2,ar1,size);}
1122       else
1123 	{rvec_sort(ar1,size);}
1124     }
1125 */
1126 }
1127 
1128 
1129 
1130 /**********************************ivec.c**************************************
1131 Function ivec_linear_search()
1132 
1133 Input :
1134 Output:
1135 Return:
1136 Description:
1137 ***********************************ivec.c*************************************/
1138 int
1139 ivec_linear_search(register int item, register int *list, register int n)
1140 {
1141   register int tmp = n-1;
1142 
1143   while (n--)  {if (*list++ == item) {return(tmp-n);}}
1144   return(-1);
1145 }
1146 
1147 
1148 
1149 /**********************************ivec.c**************************************
1150 Function ivec_binary_search()
1151 
1152 Input :
1153 Output:
1154 Return:
1155 Description:
1156 ***********************************ivec.c*************************************/
1157 int
1158 ivec_binary_search(register int item, register int *list, register int rh)
1159 {
1160   register int mid, lh=0;
1161 
1162   rh--;
1163   while (lh<=rh)
1164     {
1165       mid = (lh+rh)>>1;
1166       if (*(list+mid) == item)
1167 	{return(mid);}
1168       if (*(list+mid) > item)
1169 	{rh = mid-1;}
1170       else
1171 	{lh = mid+1;}
1172     }
1173   return(-1);
1174 }
1175 
1176 
1177 
1178 /**********************************ivec.c**************************************
1179 Function rvec_dump
1180 
1181 Input :
1182 Output:
1183 Return:
1184 Description:
1185 ***********************************ivec.c*************************************/
1186 void
1187 rvec_dump(REAL *v, int n, int tag, int tag2, char * s)
1188 {
1189   int i;
1190   printf("%2d %2d %s %2d :: ",tag,tag2,s,my_id);
1191   for (i=0;i<n;i++)
1192     {printf("%f ",v[i]);}
1193   printf("\n");
1194   fflush(stdout);
1195 }
1196 
1197 
1198 
1199 /**********************************ivec.c**************************************
1200 Function rvec_lb_ub()
1201 
1202 Input :
1203 Output:
1204 Return:
1205 Description:
1206 ***********************************ivec.c*************************************/
1207 void
1208 rvec_lb_ub(register REAL *arg1, register int n, REAL *lb, REAL *ub)
1209 {
1210   register REAL min =  REAL_MAX;
1211   register REAL max = -REAL_MAX;
1212 
1213   while (n--)
1214     {
1215      min = MIN(min,*arg1);
1216      max = MAX(max,*arg1);
1217      arg1++;
1218     }
1219 
1220   *lb=min;
1221   *ub=max;
1222 }
1223 
1224 
1225 
1226 /********************************ivec.c**************************************
1227 Function rvec_copy()
1228 
1229 Input :
1230 Output:
1231 Return:
1232 Description:
1233 *********************************ivec.c*************************************/
1234 void
1235 rvec_copy(register REAL *arg1, register REAL *arg2, register int n)
1236 {
1237   while (n--)  {*arg1++ = *arg2++;}
1238 }
1239 
1240 
1241 
1242 /********************************ivec.c**************************************
1243 Function rvec_zero()
1244 
1245 Input :
1246 Output:
1247 Return:
1248 Description:
1249 *********************************ivec.c*************************************/
1250 void
1251 rvec_zero(register REAL *arg1, register int n)
1252 {
1253   while (n--)  {*arg1++ = 0.0;}
1254 }
1255 
1256 
1257 
1258 /**********************************ivec.c**************************************
1259 Function rvec_one()
1260 
1261 Input :
1262 Output:
1263 Return:
1264 Description:
1265 ***********************************ivec.c*************************************/
1266 void
1267 rvec_one(register REAL *arg1, register int n)
1268 {
1269   while (n--)  {*arg1++ = 1.0;}
1270 }
1271 
1272 
1273 
1274 /**********************************ivec.c**************************************
1275 Function rvec_neg_one()
1276 
1277 Input :
1278 Output:
1279 Return:
1280 Description:
1281 ***********************************ivec.c*************************************/
1282 void
1283 rvec_neg_one(register REAL *arg1, register int n)
1284 {
1285   while (n--)  {*arg1++ = -1.0;}
1286 }
1287 
1288 
1289 
1290 /**********************************ivec.c**************************************
1291 Function rvec_set()
1292 
1293 Input :
1294 Output:
1295 Return:
1296 Description:
1297 ***********************************ivec.c*************************************/
1298 void
1299 rvec_set(register REAL *arg1, register REAL arg2, register int n)
1300 {
1301   while (n--)  {*arg1++ = arg2;}
1302 }
1303 
1304 
1305 
1306 /**********************************ivec.c**************************************
1307 Function rvec_scale()
1308 
1309 Input :
1310 Output:
1311 Return:
1312 Description:
1313 ***********************************ivec.c*************************************/
1314 void
1315 rvec_scale(register REAL *arg1, register REAL arg2, register int n)
1316 {
1317   while (n--)  {*arg1++ *= arg2;}
1318 }
1319 
1320 
1321 
1322 /********************************ivec.c**************************************
1323 Function rvec_add()
1324 
1325 Input :
1326 Output:
1327 Return:
1328 Description:
1329 *********************************ivec.c*************************************/
1330 void
1331 rvec_add(register REAL *arg1, register REAL *arg2, register int n)
1332 {
1333   while (n--)  {*arg1++ += *arg2++;}
1334 }
1335 
1336 
1337 
1338 /********************************ivec.c**************************************
1339 Function rvec_dot()
1340 
1341 Input :
1342 Output:
1343 Return:
1344 Description:
1345 *********************************ivec.c*************************************/
1346 REAL
1347 rvec_dot(register REAL *arg1, register REAL *arg2, register int n)
1348 {
1349   REAL dot=0.0;
1350 
1351   while (n--)  {dot+= *arg1++ * *arg2++;}
1352 
1353   return(dot);
1354 }
1355 
1356 
1357 
1358 /********************************ivec.c**************************************
1359 Function rvec_axpy()
1360 
1361 Input :
1362 Output:
1363 Return:
1364 Description:
1365 *********************************ivec.c*************************************/
1366 void
1367 rvec_axpy(register REAL *arg1, register REAL *arg2, register REAL scale,
1368 	  register int n)
1369 {
1370   while (n--)  {*arg1++ += scale * *arg2++;}
1371 }
1372 
1373 
1374 /********************************ivec.c**************************************
1375 Function rvec_mult()
1376 
1377 Input :
1378 Output:
1379 Return:
1380 Description:
1381 *********************************ivec.c*************************************/
1382 void
1383 rvec_mult(register REAL *arg1, register REAL *arg2, register int n)
1384 {
1385   while (n--)  {*arg1++ *= *arg2++;}
1386 }
1387 
1388 
1389 
1390 /********************************ivec.c**************************************
1391 Function rvec_max()
1392 
1393 Input :
1394 Output:
1395 Return:
1396 Description:
1397 *********************************ivec.c*************************************/
1398 void
1399 rvec_max(register REAL *arg1, register REAL *arg2, register int n)
1400 {
1401   while (n--)  {*arg1 = MAX(*arg1,*arg2); arg1++; arg2++;}
1402 }
1403 
1404 
1405 
1406 /********************************ivec.c**************************************
1407 Function rvec_max_abs()
1408 
1409 Input :
1410 Output:
1411 Return:
1412 Description:
1413 *********************************ivec.c*************************************/
1414 void
1415 rvec_max_abs(register REAL *arg1, register REAL *arg2, register int n)
1416 {
1417   while (n--)  {*arg1 = MAX_FABS(*arg1,*arg2); arg1++; arg2++;}
1418 }
1419 
1420 
1421 
1422 /********************************ivec.c**************************************
1423 Function rvec_min()
1424 
1425 Input :
1426 Output:
1427 Return:
1428 Description:
1429 *********************************ivec.c*************************************/
1430 void
1431 rvec_min(register REAL *arg1, register REAL *arg2, register int n)
1432 {
1433   while (n--)  {*arg1 = MIN(*arg1,*arg2); arg1++; arg2++;}
1434 }
1435 
1436 
1437 
1438 /********************************ivec.c**************************************
1439 Function rvec_min_abs()
1440 
1441 Input :
1442 Output:
1443 Return:
1444 Description:
1445 *********************************ivec.c*************************************/
1446 void
1447 rvec_min_abs(register REAL *arg1, register REAL *arg2, register int n)
1448 {
1449   while (n--)  {*arg1 = MIN_FABS(*arg1,*arg2); arg1++; arg2++;}
1450 }
1451 
1452 
1453 
1454 /********************************ivec.c**************************************
1455 Function rvec_exists()
1456 
1457 Input :
1458 Output:
1459 Return:
1460 Description:
1461 *********************************ivec.c*************************************/
1462 void
1463 rvec_exists(register REAL *arg1, register REAL *arg2, register int n)
1464 {
1465   while (n--)  {*arg1 = EXISTS(*arg1,*arg2); arg1++; arg2++;}
1466 }
1467 
1468 
1469 
1470 /**********************************ivec.c**************************************
1471 Function rvec_non_uniform()
1472 
1473 Input :
1474 Output:
1475 Return:
1476 Description:
1477 ***********************************ivec.c*************************************/
1478 void
1479 rvec_non_uniform(REAL *arg1, REAL *arg2, register int n, register int *arg3)
1480 {
1481   register int i, j, type;
1482 
1483 
1484   /* LATER: if we're really motivated we can sort and then unsort */
1485   for (i=0;i<n;)
1486     {
1487       /* clump 'em for now */
1488       j=i+1;
1489       type = arg3[i];
1490       while ((j<n)&&(arg3[j]==type))
1491 	{j++;}
1492 
1493       /* how many together */
1494       j -= i;
1495 
1496       /* call appropriate ivec function */
1497       if (type == GL_MAX)
1498 	{rvec_max(arg1,arg2,j);}
1499       else if (type == GL_MIN)
1500 	{rvec_min(arg1,arg2,j);}
1501       else if (type == GL_MULT)
1502 	{rvec_mult(arg1,arg2,j);}
1503       else if (type == GL_ADD)
1504 	{rvec_add(arg1,arg2,j);}
1505       else if (type == GL_MAX_ABS)
1506 	{rvec_max_abs(arg1,arg2,j);}
1507       else if (type == GL_MIN_ABS)
1508 	{rvec_min_abs(arg1,arg2,j);}
1509       else if (type == GL_EXISTS)
1510 	{rvec_exists(arg1,arg2,j);}
1511       else
1512 	{error_msg_fatal("unrecognized type passed to rvec_non_uniform()!");}
1513 
1514       arg1+=j; arg2+=j; i+=j;
1515     }
1516 }
1517 
1518 
1519 
1520 /**********************************ivec.c**************************************
1521 Function rvec_fct_addr()
1522 
1523 Input :
1524 Output:
1525 Return:
1526 Description:
1527 ***********************************ivec.c*************************************/
1528 vfp rvec_fct_addr(register int type)
1529 {
1530   if (type == NON_UNIFORM)
1531     {return((void (*)(void*, void *, int, ...))&rvec_non_uniform);}
1532   else if (type == GL_MAX)
1533     {return((void (*)(void*, void *, int, ...))&rvec_max);}
1534   else if (type == GL_MIN)
1535     {return((void (*)(void*, void *, int, ...))&rvec_min);}
1536   else if (type == GL_MULT)
1537     {return((void (*)(void*, void *, int, ...))&rvec_mult);}
1538   else if (type == GL_ADD)
1539     {return((void (*)(void*, void *, int, ...))&rvec_add);}
1540   else if (type == GL_MAX_ABS)
1541     {return((void (*)(void*, void *, int, ...))&rvec_max_abs);}
1542   else if (type == GL_MIN_ABS)
1543     {return((void (*)(void*, void *, int, ...))&rvec_min_abs);}
1544   else if (type == GL_EXISTS)
1545     {return((void (*)(void*, void *, int, ...))&rvec_exists);}
1546 
1547   /* catch all ... not good if we get here */
1548   return(NULL);
1549 }
1550 
1551 
1552 /******************************************************************************
1553 Function: my_sort().
1554 Input : offset of list to be sorted, number of elements to be sorted.
1555 Output: sorted list (in ascending order).
1556 Return: none.
1557 Description: stack based (nonrecursive) quicksort w/brute-shell bottom.
1558 ******************************************************************************/
1559 void
1560 rvec_sort(register REAL *ar, register int Size)
1561 {
1562   register REAL *pi, *pj, temp;
1563   register REAL **top_a = (REAL **)offset_stack;
1564   register PTRINT *top_s = psize_stack, *bottom_s = psize_stack;
1565   register PTRINT size = (PTRINT) Size;
1566 
1567   /* we're really interested in the offset of the last element */
1568   /* ==> length of the list is now size + 1                    */
1569   size--;
1570 
1571   /* do until we're done ... return when stack is exhausted */
1572   for (;;)
1573     {
1574       /* if list is large enough use quicksort partition exchange code */
1575       if (size > SORT_OPT)
1576 	{
1577 	  /* start up pointer at element 1 and down at size     */
1578 	  pi = ar+1;
1579 	  pj = ar+size;
1580 
1581 	  /* find middle element in list and swap w/ element 1 */
1582 	  SWAP(*(ar+(size>>1)),*pi)
1583 
1584 	  pj = ar+size;
1585 
1586 	  /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
1587 	  /* note ==> pivot_value in index 0                   */
1588 	  if (*pi > *pj)
1589 	    {SWAP(*pi,*pj)}
1590 	  if (*ar > *pj)
1591 	    {SWAP(*ar,*pj)}
1592 	  else if (*pi > *ar)
1593 	    {SWAP(*(ar),*(ar+1))}
1594 
1595 	  /* partition about pivot_value ...  	                    */
1596 	  /* note lists of length 2 are not guaranteed to be sorted */
1597 	  for(;;)
1598 	    {
1599 	      /* walk up ... and down ... swap if equal to pivot! */
1600 	      do pi++; while (*pi<*ar);
1601 	      do pj--; while (*pj>*ar);
1602 
1603 	      /* if we've crossed we're done */
1604 	      if (pj<pi) break;
1605 
1606 	      /* else swap */
1607 	      SWAP(*pi,*pj)
1608 	    }
1609 
1610 	  /* place pivot_value in it's correct location */
1611 	  SWAP(*ar,*pj)
1612 
1613 	  /* test stack_size to see if we've exhausted our stack */
1614 	  if (top_s-bottom_s >= SORT_STACK)
1615 	    {error_msg_fatal("\nSTACK EXHAUSTED!!!\n");}
1616 
1617 	  /* push right hand child iff length > 1 */
1618 	  if ((*top_s = size-(pi-ar)))
1619 	    {
1620 	      *(top_a++) = pi;
1621 	      size -= *top_s+2;
1622 	      top_s++;
1623 	    }
1624 	  /* set up for next loop iff there is something to do */
1625 	  else if (size -= *top_s+2)
1626 	    {;}
1627 	  /* might as well pop - note NR_OPT >=2 ==> we're ok! */
1628 	  else
1629 	    {
1630 	      ar = *(--top_a);
1631 	      size = *(--top_s);
1632 	    }
1633 	}
1634 
1635       /* else sort small list directly then pop another off stack */
1636       else
1637 	{
1638 	  /* insertion sort for bottom */
1639           for (pj=ar+1;pj<=ar+size;pj++)
1640             {
1641               temp = *pj;
1642               for (pi=pj-1;pi>=ar;pi--)
1643                 {
1644                   if (*pi <= temp) break;
1645                   *(pi+1)=*pi;
1646                 }
1647               *(pi+1)=temp;
1648 	    }
1649 
1650 	  /* check to see if stack is exhausted ==> DONE */
1651 	  if (top_s==bottom_s) return;
1652 
1653 	  /* else pop another list from the stack */
1654 	  ar = *(--top_a);
1655 	  size = *(--top_s);
1656 	}
1657     }
1658 }
1659 
1660 
1661 
1662 /******************************************************************************
1663 Function: my_sort().
1664 Input : offset of list to be sorted, number of elements to be sorted.
1665 Output: sorted list (in ascending order).
1666 Return: none.
1667 Description: stack based (nonrecursive) quicksort w/brute-shell bottom.
1668 ******************************************************************************/
1669 void
1670 rvec_sort_companion(register REAL *ar, register int *ar2, register int Size)
1671 {
1672   register REAL *pi, *pj, temp;
1673   register REAL **top_a = (REAL **)offset_stack;
1674   register PTRINT *top_s = psize_stack, *bottom_s = psize_stack;
1675   register PTRINT size = (PTRINT) Size;
1676 
1677   register int *pi2, *pj2;
1678   register int ptr;
1679   register PTRINT mid;
1680 
1681 
1682   /* we're really interested in the offset of the last element */
1683   /* ==> length of the list is now size + 1                    */
1684   size--;
1685 
1686   /* do until we're done ... return when stack is exhausted */
1687   for (;;)
1688     {
1689       /* if list is large enough use quicksort partition exchange code */
1690       if (size > SORT_OPT)
1691 	{
1692 	  /* start up pointer at element 1 and down at size     */
1693 	  mid = size>>1;
1694 	  pi = ar+1;
1695 	  pj = ar+mid;
1696 	  pi2 = ar2+1;
1697 	  pj2 = ar2+mid;
1698 
1699 	  /* find middle element in list and swap w/ element 1 */
1700 	  SWAP(*pi,*pj)
1701 	  P_SWAP(*pi2,*pj2)
1702 
1703 	  /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
1704 	  /* note ==> pivot_value in index 0                   */
1705 	  pj = ar+size;
1706 	  pj2 = ar2+size;
1707 	  if (*pi > *pj)
1708 	    {SWAP(*pi,*pj) P_SWAP(*pi2,*pj2)}
1709 	  if (*ar > *pj)
1710 	    {SWAP(*ar,*pj) P_SWAP(*ar2,*pj2)}
1711 	  else if (*pi > *ar)
1712 	    {SWAP(*(ar),*(ar+1)) P_SWAP(*(ar2),*(ar2+1))}
1713 
1714 	  /* partition about pivot_value ...  	                    */
1715 	  /* note lists of length 2 are not guaranteed to be sorted */
1716 	  for(;;)
1717 	    {
1718 	      /* walk up ... and down ... swap if equal to pivot! */
1719 	      do {pi++; pi2++;} while (*pi<*ar);
1720 	      do {pj--; pj2--;} while (*pj>*ar);
1721 
1722 	      /* if we've crossed we're done */
1723 	      if (pj<pi) break;
1724 
1725 	      /* else swap */
1726 	      SWAP(*pi,*pj)
1727 	      P_SWAP(*pi2,*pj2)
1728 	    }
1729 
1730 	  /* place pivot_value in it's correct location */
1731 	  SWAP(*ar,*pj)
1732 	  P_SWAP(*ar2,*pj2)
1733 
1734 	  /* test stack_size to see if we've exhausted our stack */
1735 	  if (top_s-bottom_s >= SORT_STACK)
1736 	    {error_msg_fatal("\nSTACK EXHAUSTED!!!\n");}
1737 
1738 	  /* push right hand child iff length > 1 */
1739 	  if ((*top_s = size-(pi-ar)))
1740 	    {
1741 	      *(top_a++) = pi;
1742 	      *(top_a++) = (REAL *) pi2;
1743 	      size -= *top_s+2;
1744 	      top_s++;
1745 	    }
1746 	  /* set up for next loop iff there is something to do */
1747 	  else if (size -= *top_s+2)
1748 	    {;}
1749 	  /* might as well pop - note NR_OPT >=2 ==> we're ok! */
1750 	  else
1751 	    {
1752 	      ar2 = (int*) *(--top_a);
1753 	      ar  = *(--top_a);
1754 	      size = *(--top_s);
1755 	    }
1756 	}
1757 
1758       /* else sort small list directly then pop another off stack */
1759       else
1760 	{
1761 	  /* insertion sort for bottom */
1762           for (pj=ar+1, pj2=ar2+1;pj<=ar+size;pj++,pj2++)
1763             {
1764               temp = *pj;
1765               ptr = *pj2;
1766               for (pi=pj-1,pi2=pj2-1;pi>=ar;pi--,pi2--)
1767                 {
1768                   if (*pi <= temp) break;
1769                   *(pi+1)=*pi;
1770                   *(pi2+1)=*pi2;
1771                 }
1772               *(pi+1)=temp;
1773               *(pi2+1)=ptr;
1774 	    }
1775 
1776 	  /* check to see if stack is exhausted ==> DONE */
1777 	  if (top_s==bottom_s) return;
1778 
1779 	  /* else pop another list from the stack */
1780 	  ar2 = (int*) *(--top_a);
1781 	  ar  = *(--top_a);
1782 	  size = *(--top_s);
1783 	}
1784     }
1785 }
1786 
1787 
1788 
1789 
1790 
1791 /**********************************ivec.c**************************************
1792 Function ivec_binary_search()
1793 
1794 Input :
1795 Output:
1796 Return:
1797 Description:
1798 ***********************************ivec.c*************************************/
1799 int
1800 rvec_binary_search(register REAL item, register REAL *list, register int rh)
1801 {
1802   register int mid, lh=0;
1803 
1804   rh--;
1805   while (lh<=rh)
1806     {
1807       mid = (lh+rh)>>1;
1808       if (*(list+mid) == item)
1809 	{return(mid);}
1810       if (*(list+mid) > item)
1811 	{rh = mid-1;}
1812       else
1813 	{lh = mid+1;}
1814     }
1815   return(-1);
1816 }
1817 
1818 
1819 
1820 
1821 
1822