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