Actual source code: ivec.c
1: #define PETSCKSP_DLL
3: /**********************************ivec.c**************************************
5: Author: Henry M. Tufo III
7: e-mail: hmt@cs.brown.edu
9: snail-mail:
10: Division of Applied Mathematics
11: Brown University
12: Providence, RI 02912
14: Last Modification:
15: 6.21.97
16: ***********************************ivec.c*************************************/
18: /**********************************ivec.c**************************************
19: File Description:
20: -----------------
22: ***********************************ivec.c*************************************/
23: #include src/ksp/pc/impls/tfs/tfs.h
25: /* sorting args ivec.c ivec.c ... */
26: #define SORT_OPT 6
27: #define SORT_STACK 50000
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];
37: /**********************************ivec.c**************************************
38: Function ivec_dump()
40: Input :
41: Output:
42: Return:
43: Description:
44: ***********************************ivec.c*************************************/
45: void
46: ivec_dump(int *v, int n, int tag, int tag2, char * s)
47: {
48: int i;
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: }
58: /**********************************ivec.c**************************************
59: Function ivec_lb_ub()
61: Input :
62: Output:
63: Return:
64: Description:
65: ***********************************ivec.c*************************************/
66: void
67: ivec_lb_ub( int *arg1, int n, int *lb, int *ub)
68: {
69: int min = INT_MAX;
70: int max = INT_MIN;
72: while (n--)
73: {
74: min = PetscMin(min,*arg1);
75: max = PetscMax(max,*arg1);
76: arg1++;
77: }
79: *lb=min;
80: *ub=max;
81: }
85: /**********************************ivec.c**************************************
86: Function ivec_copy()
88: Input :
89: Output:
90: Return:
91: Description:
92: ***********************************ivec.c*************************************/
93: int *ivec_copy( int *arg1, int *arg2, int n)
94: {
95: while (n--) {*arg1++ = *arg2++;}
96: return(arg1);
97: }
101: /**********************************ivec.c**************************************
102: Function ivec_zero()
104: Input :
105: Output:
106: Return:
107: Description:
108: ***********************************ivec.c*************************************/
109: void
110: ivec_zero( int *arg1, int n)
111: {
112: while (n--) {*arg1++ = 0;}
113: }
117: /**********************************ivec.c**************************************
118: Function ivec_comp()
120: Input :
121: Output:
122: Return:
123: Description:
124: ***********************************ivec.c*************************************/
125: void
126: ivec_comp( int *arg1, int n)
127: {
128: while (n--) {*arg1 = ~*arg1; arg1++;}
129: }
133: /**********************************ivec.c**************************************
134: Function ivec_neg_one()
136: Input :
137: Output:
138: Return:
139: Description:
140: ***********************************ivec.c*************************************/
141: void
142: ivec_neg_one( int *arg1, int n)
143: {
144: while (n--) {*arg1++ = -1;}
145: }
149: /**********************************ivec.c**************************************
150: Function ivec_pos_one()
152: Input :
153: Output:
154: Return:
155: Description:
156: ***********************************ivec.c*************************************/
157: void
158: ivec_pos_one( int *arg1, int n)
159: {
160: while (n--) {*arg1++ = 1;}
161: }
165: /**********************************ivec.c**************************************
166: Function ivec_c_index()
168: Input :
169: Output:
170: Return:
171: Description:
172: ***********************************ivec.c*************************************/
173: void
174: ivec_c_index( int *arg1, int n)
175: {
176: int i=0;
179: while (n--) {*arg1++ = i++;}
180: }
184: /**********************************ivec.c**************************************
185: Function ivec_fortran_index()
187: Input :
188: Output:
189: Return:
190: Description:
191: ***********************************ivec.c*************************************/
192: void
193: ivec_fortran_index( int *arg1, int n)
194: {
195: int i=0;
198: while (n--) {*arg1++ = ++i;}
199: }
203: /**********************************ivec.c**************************************
204: Function ivec_set()
206: Input :
207: Output:
208: Return:
209: Description:
210: ***********************************ivec.c*************************************/
211: void
212: ivec_set( int *arg1, int arg2, int n)
213: {
214: while (n--) {*arg1++ = arg2;}
215: }
219: /**********************************ivec.c**************************************
220: Function ivec_cmp()
222: Input :
223: Output:
224: Return:
225: Description:
226: ***********************************ivec.c*************************************/
227: int
228: ivec_cmp( int *arg1, int *arg2, int n)
229: {
230: while (n--) {if (*arg1++ != *arg2++) {return(FALSE);}}
231: return(TRUE);
232: }
236: /**********************************ivec.c**************************************
237: Function ivec_max()
239: Input :
240: Output:
241: Return:
242: Description:
243: ***********************************ivec.c*************************************/
244: void
245: ivec_max( int *arg1, int *arg2, int n)
246: {
247: while (n--) {*arg1 = PetscMax(*arg1,*arg2); arg1++; arg2++;}
248: }
252: /**********************************ivec.c**************************************
253: Function ivec_min()
255: Input :
256: Output:
257: Return:
258: Description:
259: ***********************************ivec.c*************************************/
260: void
261: ivec_min( int *arg1, int *arg2, int n)
262: {
263: while (n--) {*(arg1) = PetscMin(*arg1,*arg2); arg1++; arg2++;}
264: }
268: /**********************************ivec.c**************************************
269: Function ivec_mult()
271: Input :
272: Output:
273: Return:
274: Description:
275: ***********************************ivec.c*************************************/
276: void
277: ivec_mult( int *arg1, int *arg2, int n)
278: {
279: while (n--) {*arg1++ *= *arg2++;}
280: }
284: /**********************************ivec.c**************************************
285: Function ivec_add()
287: Input :
288: Output:
289: Return:
290: Description:
291: ***********************************ivec.c*************************************/
292: void
293: ivec_add( int *arg1, int *arg2, int n)
294: {
295: while (n--) {*arg1++ += *arg2++;}
296: }
300: /**********************************ivec.c**************************************
301: Function ivec_lxor()
303: Input :
304: Output:
305: Return:
306: Description:
307: ***********************************ivec.c*************************************/
308: void
309: ivec_lxor( int *arg1, int *arg2, int n)
310: {
311: while (n--) {*arg1=((*arg1 || *arg2) && !(*arg1 && *arg2)); arg1++; arg2++;}
312: }
316: /**********************************ivec.c**************************************
317: Function ivec_xor()
319: Input :
320: Output:
321: Return:
322: Description:
323: ***********************************ivec.c*************************************/
324: void
325: ivec_xor( int *arg1, int *arg2, int n)
326: {
327: while (n--) {*arg1++ ^= *arg2++;}
328: }
332: /**********************************ivec.c**************************************
333: Function ivec_or()
335: Input :
336: Output:
337: Return:
338: Description:
339: ***********************************ivec.c*************************************/
340: void
341: ivec_or( int *arg1, int *arg2, int n)
342: {
343: while (n--) {*arg1++ |= *arg2++;}
344: }
348: /**********************************ivec.c**************************************
349: Function ivec_lor()
351: Input :
352: Output:
353: Return:
354: Description:
355: ***********************************ivec.c*************************************/
356: void
357: ivec_lor( int *arg1, int *arg2, int n)
358: {
359: while (n--) {*arg1 = (*arg1 || *arg2); arg1++; arg2++;}
360: }
364: /**********************************ivec.c**************************************
365: Function ivec_or3()
367: Input :
368: Output:
369: Return:
370: Description:
371: ***********************************ivec.c*************************************/
372: void
373: ivec_or3( int *arg1, int *arg2, int *arg3,
374: int n)
375: {
376: while (n--) {*arg1++ = (*arg2++ | *arg3++);}
377: }
381: /**********************************ivec.c**************************************
382: Function ivec_and()
384: Input :
385: Output:
386: Return:
387: Description:
388: ***********************************ivec.c*************************************/
389: void
390: ivec_and( int *arg1, int *arg2, int n)
391: {
392: while (n--) {*arg1++ &= *arg2++;}
393: }
397: /**********************************ivec.c**************************************
398: Function ivec_land()
400: Input :
401: Output:
402: Return:
403: Description:
404: ***********************************ivec.c*************************************/
405: void
406: ivec_land( int *arg1, int *arg2, int n)
407: {
408: while (n--) {*arg1 = (*arg1 && *arg2); arg1++; arg2++;}
409: }
413: /**********************************ivec.c**************************************
414: Function ivec_and3()
416: Input :
417: Output:
418: Return:
419: Description:
420: ***********************************ivec.c*************************************/
421: void
422: ivec_and3( int *arg1, int *arg2, int *arg3,
423: int n)
424: {
425: while (n--) {*arg1++ = (*arg2++ & *arg3++);}
426: }
430: /**********************************ivec.c**************************************
431: Function ivec_sum
433: Input :
434: Output:
435: Return:
436: Description:
437: ***********************************ivec.c*************************************/
438: int ivec_sum( int *arg1, int n)
439: {
440: int tmp = 0;
443: while (n--) {tmp += *arg1++;}
444: return(tmp);
445: }
449: /**********************************ivec.c**************************************
450: Function ivec_reduce_and
452: Input :
453: Output:
454: Return:
455: Description:
456: ***********************************ivec.c*************************************/
457: int ivec_reduce_and( int *arg1, int n)
458: {
459: int tmp = ALL_ONES;
462: while (n--) {tmp &= *arg1++;}
463: return(tmp);
464: }
468: /**********************************ivec.c**************************************
469: Function ivec_reduce_or
471: Input :
472: Output:
473: Return:
474: Description:
475: ***********************************ivec.c*************************************/
476: int ivec_reduce_or( int *arg1, int n)
477: {
478: int tmp = 0;
481: while (n--) {tmp |= *arg1++;}
482: return(tmp);
483: }
487: /**********************************ivec.c**************************************
488: Function ivec_prod
490: Input :
491: Output:
492: Return:
493: Description:
494: ***********************************ivec.c*************************************/
495: int ivec_prod( int *arg1, int n)
496: {
497: int tmp = 1;
500: while (n--) {tmp *= *arg1++;}
501: return(tmp);
502: }
506: /**********************************ivec.c**************************************
507: Function ivec_u_sum
509: Input :
510: Output:
511: Return:
512: Description:
513: ***********************************ivec.c*************************************/
514: int ivec_u_sum( unsigned *arg1, int n)
515: {
516: unsigned tmp = 0;
519: while (n--) {tmp += *arg1++;}
520: return(tmp);
521: }
525: /**********************************ivec.c**************************************
526: Function ivec_lb()
528: Input :
529: Output:
530: Return:
531: Description:
532: ***********************************ivec.c*************************************/
533: int
534: ivec_lb( int *arg1, int n)
535: {
536: int min = INT_MAX;
539: while (n--) {min = PetscMin(min,*arg1); arg1++;}
540: return(min);
541: }
545: /**********************************ivec.c**************************************
546: Function ivec_ub()
548: Input :
549: Output:
550: Return:
551: Description:
552: ***********************************ivec.c*************************************/
553: int
554: ivec_ub( int *arg1, int n)
555: {
556: int max = INT_MIN;
559: while (n--) {max = PetscMax(max,*arg1); arg1++;}
560: return(max);
561: }
565: /**********************************ivec.c**************************************
566: Function split_buf()
568: Input :
569: Output:
570: Return:
571: Description:
573: assumes that sizeof(int) == 4bytes!!!
574: ***********************************ivec.c*************************************/
575: int
576: ivec_split_buf(int *buf1, int **buf2, int size)
577: {
578: *buf2 = (buf1 + (size>>3));
579: return(size);
580: }
584: /**********************************ivec.c**************************************
585: Function ivec_non_uniform()
587: Input :
588: Output:
589: Return:
590: Description:
591: ***********************************ivec.c*************************************/
592: void
593: ivec_non_uniform(int *arg1, int *arg2, int n, int *arg3)
594: {
595: int i, j, type;
598: /* LATER: if we're really motivated we can sort and then unsort */
599: for (i=0;i<n;)
600: {
601: /* clump 'em for now */
602: j=i+1;
603: type = arg3[i];
604: while ((j<n)&&(arg3[j]==type))
605: {j++;}
606:
607: /* how many together */
608: j -= i;
610: /* call appropriate ivec function */
611: if (type == GL_MAX)
612: {ivec_max(arg1,arg2,j);}
613: else if (type == GL_MIN)
614: {ivec_min(arg1,arg2,j);}
615: else if (type == GL_MULT)
616: {ivec_mult(arg1,arg2,j);}
617: else if (type == GL_ADD)
618: {ivec_add(arg1,arg2,j);}
619: else if (type == GL_B_XOR)
620: {ivec_xor(arg1,arg2,j);}
621: else if (type == GL_B_OR)
622: {ivec_or(arg1,arg2,j);}
623: else if (type == GL_B_AND)
624: {ivec_and(arg1,arg2,j);}
625: else if (type == GL_L_XOR)
626: {ivec_lxor(arg1,arg2,j);}
627: else if (type == GL_L_OR)
628: {ivec_lor(arg1,arg2,j);}
629: else if (type == GL_L_AND)
630: {ivec_land(arg1,arg2,j);}
631: else
632: {error_msg_fatal("unrecognized type passed to ivec_non_uniform()!");}
634: arg1+=j; arg2+=j; i+=j;
635: }
636: }
640: /**********************************ivec.c**************************************
641: Function ivec_addr()
643: Input :
644: Output:
645: Return:
646: Description:
647: ***********************************ivec.c*************************************/
648: vfp ivec_fct_addr( int type)
649: {
650: if (type == NON_UNIFORM)
651: {return((void (*)(void*, void *, int, ...))&ivec_non_uniform);}
652: else if (type == GL_MAX)
653: {return((void (*)(void*, void *, int, ...))&ivec_max);}
654: else if (type == GL_MIN)
655: {return((void (*)(void*, void *, int, ...))&ivec_min);}
656: else if (type == GL_MULT)
657: {return((void (*)(void*, void *, int, ...))&ivec_mult);}
658: else if (type == GL_ADD)
659: {return((void (*)(void*, void *, int, ...))&ivec_add);}
660: else if (type == GL_B_XOR)
661: {return((void (*)(void*, void *, int, ...))&ivec_xor);}
662: else if (type == GL_B_OR)
663: {return((void (*)(void*, void *, int, ...))&ivec_or);}
664: else if (type == GL_B_AND)
665: {return((void (*)(void*, void *, int, ...))&ivec_and);}
666: else if (type == GL_L_XOR)
667: {return((void (*)(void*, void *, int, ...))&ivec_lxor);}
668: else if (type == GL_L_OR)
669: {return((void (*)(void*, void *, int, ...))&ivec_lor);}
670: else if (type == GL_L_AND)
671: {return((void (*)(void*, void *, int, ...))&ivec_land);}
673: /* catch all ... not good if we get here */
674: return(NULL);
675: }
678: /**********************************ivec.c**************************************
679: Function ct_bits()
681: Input :
682: Output:
683: Return:
684: Description: MUST FIX THIS!!!
685: ***********************************ivec.c*************************************/
686: #if defined(notusing)
687: static
688: int
689: ivec_ct_bits( int *ptr, int n)
690: {
691: int tmp=0;
694: /* should expand to full 32 bit */
695: while (n--)
696: {
697: if (*ptr&128) {tmp++;}
698: if (*ptr&64) {tmp++;}
699: if (*ptr&32) {tmp++;}
700: if (*ptr&16) {tmp++;}
701: if (*ptr&8) {tmp++;}
702: if (*ptr&4) {tmp++;}
703: if (*ptr&2) {tmp++;}
704: if (*ptr&1) {tmp++;}
705: ptr++;
706: }
708: return(tmp);
709: }
710: #endif
713: /******************************************************************************
714: Function: ivec_sort().
716: Input : offset of list to be sorted, number of elements to be sorted.
717: Output: sorted list (in ascending order).
718: Return: none.
719: Description: stack based (nonrecursive) quicksort w/brute-shell bottom.
720: ******************************************************************************/
721: void
722: ivec_sort( int *ar, int size)
723: {
724: int *pi, *pj, temp;
725: int **top_a = (int **) offset_stack;
726: int *top_s = size_stack, *bottom_s = size_stack;
729: /* we're really interested in the offset of the last element */
730: /* ==> length of the list is now size + 1 */
731: size--;
733: /* do until we're done ... return when stack is exhausted */
734: for (;;)
735: {
736: /* if list is large enough use quicksort partition exchange code */
737: if (size > SORT_OPT)
738: {
739: /* start up pointer at element 1 and down at size */
740: pi = ar+1;
741: pj = ar+size;
743: /* find middle element in list and swap w/ element 1 */
744: SWAP(*(ar+(size>>1)),*pi)
746: /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
747: /* note ==> pivot_value in index 0 */
748: if (*pi > *pj)
749: {SWAP(*pi,*pj)}
750: if (*ar > *pj)
751: {SWAP(*ar,*pj)}
752: else if (*pi > *ar)
753: {SWAP(*(ar),*(ar+1))}
755: /* partition about pivot_value ... */
756: /* note lists of length 2 are not guaranteed to be sorted */
757: for(;;)
758: {
759: /* walk up ... and down ... swap if equal to pivot! */
760: do pi++; while (*pi<*ar);
761: do pj--; while (*pj>*ar);
763: /* if we've crossed we're done */
764: if (pj<pi) break;
766: /* else swap */
767: SWAP(*pi,*pj)
768: }
770: /* place pivot_value in it's correct location */
771: SWAP(*ar,*pj)
773: /* test stack_size to see if we've exhausted our stack */
774: if (top_s-bottom_s >= SORT_STACK)
775: {error_msg_fatal("ivec_sort() :: STACK EXHAUSTED!!!");}
777: /* push right hand child iff length > 1 */
778: if ((*top_s = size-((int) (pi-ar))))
779: {
780: *(top_a++) = pi;
781: size -= *top_s+2;
782: top_s++;
783: }
784: /* set up for next loop iff there is something to do */
785: else if (size -= *top_s+2)
786: {;}
787: /* might as well pop - note NR_OPT >=2 ==> we're ok! */
788: else
789: {
790: ar = *(--top_a);
791: size = *(--top_s);
792: }
793: }
795: /* else sort small list directly then pop another off stack */
796: else
797: {
798: /* insertion sort for bottom */
799: for (pj=ar+1;pj<=ar+size;pj++)
800: {
801: temp = *pj;
802: for (pi=pj-1;pi>=ar;pi--)
803: {
804: if (*pi <= temp) break;
805: *(pi+1)=*pi;
806: }
807: *(pi+1)=temp;
808: }
810: /* check to see if stack is exhausted ==> DONE */
811: if (top_s==bottom_s) return;
812:
813: /* else pop another list from the stack */
814: ar = *(--top_a);
815: size = *(--top_s);
816: }
817: }
818: }
822: /******************************************************************************
823: Function: ivec_sort_companion().
825: Input : offset of list to be sorted, number of elements to be sorted.
826: Output: sorted list (in ascending order).
827: Return: none.
828: Description: stack based (nonrecursive) quicksort w/brute-shell bottom.
829: ******************************************************************************/
830: void
831: ivec_sort_companion( int *ar, int *ar2, int size)
832: {
833: int *pi, *pj, temp, temp2;
834: int **top_a = (int **)offset_stack;
835: int *top_s = size_stack, *bottom_s = size_stack;
836: int *pi2, *pj2;
837: int mid;
840: /* we're really interested in the offset of the last element */
841: /* ==> length of the list is now size + 1 */
842: size--;
844: /* do until we're done ... return when stack is exhausted */
845: for (;;)
846: {
847: /* if list is large enough use quicksort partition exchange code */
848: if (size > SORT_OPT)
849: {
850: /* start up pointer at element 1 and down at size */
851: mid = size>>1;
852: pi = ar+1;
853: pj = ar+mid;
854: pi2 = ar2+1;
855: pj2 = ar2+mid;
857: /* find middle element in list and swap w/ element 1 */
858: SWAP(*pi,*pj)
859: SWAP(*pi2,*pj2)
861: /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
862: /* note ==> pivot_value in index 0 */
863: pj = ar+size;
864: pj2 = ar2+size;
865: if (*pi > *pj)
866: {SWAP(*pi,*pj) SWAP(*pi2,*pj2)}
867: if (*ar > *pj)
868: {SWAP(*ar,*pj) SWAP(*ar2,*pj2)}
869: else if (*pi > *ar)
870: {SWAP(*(ar),*(ar+1)) SWAP(*(ar2),*(ar2+1))}
872: /* partition about pivot_value ... */
873: /* note lists of length 2 are not guaranteed to be sorted */
874: for(;;)
875: {
876: /* walk up ... and down ... swap if equal to pivot! */
877: do {pi++; pi2++;} while (*pi<*ar);
878: do {pj--; pj2--;} while (*pj>*ar);
880: /* if we've crossed we're done */
881: if (pj<pi) break;
883: /* else swap */
884: SWAP(*pi,*pj)
885: SWAP(*pi2,*pj2)
886: }
888: /* place pivot_value in it's correct location */
889: SWAP(*ar,*pj)
890: SWAP(*ar2,*pj2)
892: /* test stack_size to see if we've exhausted our stack */
893: if (top_s-bottom_s >= SORT_STACK)
894: {error_msg_fatal("ivec_sort_companion() :: STACK EXHAUSTED!!!");}
896: /* push right hand child iff length > 1 */
897: if ((*top_s = size-((int) (pi-ar))))
898: {
899: *(top_a++) = pi;
900: *(top_a++) = pi2;
901: size -= *top_s+2;
902: top_s++;
903: }
904: /* set up for next loop iff there is something to do */
905: else if (size -= *top_s+2)
906: {;}
907: /* might as well pop - note NR_OPT >=2 ==> we're ok! */
908: else
909: {
910: ar2 = *(--top_a);
911: ar = *(--top_a);
912: size = *(--top_s);
913: }
914: }
916: /* else sort small list directly then pop another off stack */
917: else
918: {
919: /* insertion sort for bottom */
920: for (pj=ar+1, pj2=ar2+1;pj<=ar+size;pj++,pj2++)
921: {
922: temp = *pj;
923: temp2 = *pj2;
924: for (pi=pj-1,pi2=pj2-1;pi>=ar;pi--,pi2--)
925: {
926: if (*pi <= temp) break;
927: *(pi+1)=*pi;
928: *(pi2+1)=*pi2;
929: }
930: *(pi+1)=temp;
931: *(pi2+1)=temp2;
932: }
934: /* check to see if stack is exhausted ==> DONE */
935: if (top_s==bottom_s) return;
936:
937: /* else pop another list from the stack */
938: ar2 = *(--top_a);
939: ar = *(--top_a);
940: size = *(--top_s);
941: }
942: }
943: }
947: /******************************************************************************
948: Function: ivec_sort_companion_hack().
950: Input : offset of list to be sorted, number of elements to be sorted.
951: Output: sorted list (in ascending order).
952: Return: none.
953: Description: stack based (nonrecursive) quicksort w/brute-shell bottom.
954: ******************************************************************************/
955: void
956: ivec_sort_companion_hack( int *ar, int **ar2,
957: int size)
958: {
959: int *pi, *pj, temp, *ptr;
960: int **top_a = (int **)offset_stack;
961: int *top_s = size_stack, *bottom_s = size_stack;
962: int **pi2, **pj2;
963: int mid;
966: /* we're really interested in the offset of the last element */
967: /* ==> length of the list is now size + 1 */
968: size--;
970: /* do until we're done ... return when stack is exhausted */
971: for (;;)
972: {
973: /* if list is large enough use quicksort partition exchange code */
974: if (size > SORT_OPT)
975: {
976: /* start up pointer at element 1 and down at size */
977: mid = size>>1;
978: pi = ar+1;
979: pj = ar+mid;
980: pi2 = ar2+1;
981: pj2 = ar2+mid;
983: /* find middle element in list and swap w/ element 1 */
984: SWAP(*pi,*pj)
985: P_SWAP(*pi2,*pj2)
987: /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
988: /* note ==> pivot_value in index 0 */
989: pj = ar+size;
990: pj2 = ar2+size;
991: if (*pi > *pj)
992: {SWAP(*pi,*pj) P_SWAP(*pi2,*pj2)}
993: if (*ar > *pj)
994: {SWAP(*ar,*pj) P_SWAP(*ar2,*pj2)}
995: else if (*pi > *ar)
996: {SWAP(*(ar),*(ar+1)) P_SWAP(*(ar2),*(ar2+1))}
998: /* partition about pivot_value ... */
999: /* note lists of length 2 are not guaranteed to be sorted */
1000: for(;;)
1001: {
1002: /* walk up ... and down ... swap if equal to pivot! */
1003: do {pi++; pi2++;} while (*pi<*ar);
1004: do {pj--; pj2--;} while (*pj>*ar);
1006: /* if we've crossed we're done */
1007: if (pj<pi) break;
1009: /* else swap */
1010: SWAP(*pi,*pj)
1011: P_SWAP(*pi2,*pj2)
1012: }
1014: /* place pivot_value in it's correct location */
1015: SWAP(*ar,*pj)
1016: P_SWAP(*ar2,*pj2)
1018: /* test stack_size to see if we've exhausted our stack */
1019: if (top_s-bottom_s >= SORT_STACK)
1020: {error_msg_fatal("ivec_sort_companion_hack() :: STACK EXHAUSTED!!!");}
1022: /* push right hand child iff length > 1 */
1023: if ((*top_s = size-((int) (pi-ar))))
1024: {
1025: *(top_a++) = pi;
1026: *(top_a++) = (int*) pi2;
1027: size -= *top_s+2;
1028: top_s++;
1029: }
1030: /* set up for next loop iff there is something to do */
1031: else if (size -= *top_s+2)
1032: {;}
1033: /* might as well pop - note NR_OPT >=2 ==> we're ok! */
1034: else
1035: {
1036: ar2 = (int **) *(--top_a);
1037: ar = *(--top_a);
1038: size = *(--top_s);
1039: }
1040: }
1042: /* else sort small list directly then pop another off stack */
1043: else
1044: {
1045: /* insertion sort for bottom */
1046: for (pj=ar+1, pj2=ar2+1;pj<=ar+size;pj++,pj2++)
1047: {
1048: temp = *pj;
1049: ptr = *pj2;
1050: for (pi=pj-1,pi2=pj2-1;pi>=ar;pi--,pi2--)
1051: {
1052: if (*pi <= temp) break;
1053: *(pi+1)=*pi;
1054: *(pi2+1)=*pi2;
1055: }
1056: *(pi+1)=temp;
1057: *(pi2+1)=ptr;
1058: }
1060: /* check to see if stack is exhausted ==> DONE */
1061: if (top_s==bottom_s) return;
1062:
1063: /* else pop another list from the stack */
1064: ar2 = (int **)*(--top_a);
1065: ar = *(--top_a);
1066: size = *(--top_s);
1067: }
1068: }
1069: }
1073: /******************************************************************************
1074: Function: SMI_sort().
1075: Input : offset of list to be sorted, number of elements to be sorted.
1076: Output: sorted list (in ascending order).
1077: Return: none.
1078: Description: stack based (nonrecursive) quicksort w/brute-shell bottom.
1079: ******************************************************************************/
1080: void
1081: SMI_sort(void *ar1, void *ar2, int size, int type)
1082: {
1083: if (type == SORT_INTEGER)
1084: {
1085: if (ar2)
1086: {ivec_sort_companion((int*)ar1,(int*)ar2,size);}
1087: else
1088: {ivec_sort((int*)ar1,size);}
1089: }
1090: else if (type == SORT_INT_PTR)
1091: {
1092: if (ar2)
1093: {ivec_sort_companion_hack((int*)ar1,(int **)ar2,size);}
1094: else
1095: {ivec_sort((int*)ar1,size);}
1096: }
1098: else
1099: {
1100: error_msg_fatal("SMI_sort only does SORT_INTEGER!");
1101: }
1102: /*
1103: if (type == SORT_REAL)
1104: {
1105: if (ar2)
1106: {rvec_sort_companion(ar2,ar1,size);}
1107: else
1108: {rvec_sort(ar1,size);}
1109: }
1110: */
1111: }
1115: /**********************************ivec.c**************************************
1116: Function ivec_linear_search()
1118: Input :
1119: Output:
1120: Return:
1121: Description:
1122: ***********************************ivec.c*************************************/
1123: int
1124: ivec_linear_search( int item, int *list, int n)
1125: {
1126: int tmp = n-1;
1128: while (n--) {if (*list++ == item) {return(tmp-n);}}
1129: return(-1);
1130: }
1134: /**********************************ivec.c**************************************
1135: Function ivec_binary_search()
1137: Input :
1138: Output:
1139: Return:
1140: Description:
1141: ***********************************ivec.c*************************************/
1142: int
1143: ivec_binary_search( int item, int *list, int rh)
1144: {
1145: int mid, lh=0;
1147: rh--;
1148: while (lh<=rh)
1149: {
1150: mid = (lh+rh)>>1;
1151: if (*(list+mid) == item)
1152: {return(mid);}
1153: if (*(list+mid) > item)
1154: {rh = mid-1;}
1155: else
1156: {lh = mid+1;}
1157: }
1158: return(-1);
1159: }
1163: /**********************************ivec.c**************************************
1164: Function rvec_dump
1166: Input :
1167: Output:
1168: Return:
1169: Description:
1170: ***********************************ivec.c*************************************/
1171: void
1172: rvec_dump(PetscScalar *v, int n, int tag, int tag2, char * s)
1173: {
1174: int i;
1175: printf("%2d %2d %s %2d :: ",tag,tag2,s,my_id);
1176: for (i=0;i<n;i++)
1177: {printf("%f ",v[i]);}
1178: printf("\n");
1179: fflush(stdout);
1180: }
1184: /**********************************ivec.c**************************************
1185: Function rvec_lb_ub()
1187: Input :
1188: Output:
1189: Return:
1190: Description:
1191: ***********************************ivec.c*************************************/
1192: void
1193: rvec_lb_ub( PetscScalar *arg1, int n, PetscScalar *lb, PetscScalar *ub)
1194: {
1195: PetscScalar min = REAL_MAX;
1196: PetscScalar max = -REAL_MAX;
1198: while (n--)
1199: {
1200: min = PetscMin(min,*arg1);
1201: max = PetscMax(max,*arg1);
1202: arg1++;
1203: }
1205: *lb=min;
1206: *ub=max;
1207: }
1211: /********************************ivec.c**************************************
1212: Function rvec_copy()
1214: Input :
1215: Output:
1216: Return:
1217: Description:
1218: *********************************ivec.c*************************************/
1219: void
1220: rvec_copy( PetscScalar *arg1, PetscScalar *arg2, int n)
1221: {
1222: while (n--) {*arg1++ = *arg2++;}
1223: }
1227: /********************************ivec.c**************************************
1228: Function rvec_zero()
1230: Input :
1231: Output:
1232: Return:
1233: Description:
1234: *********************************ivec.c*************************************/
1235: void
1236: rvec_zero( PetscScalar *arg1, int n)
1237: {
1238: while (n--) {*arg1++ = 0.0;}
1239: }
1243: /**********************************ivec.c**************************************
1244: Function rvec_one()
1246: Input :
1247: Output:
1248: Return:
1249: Description:
1250: ***********************************ivec.c*************************************/
1251: void
1252: rvec_one( PetscScalar *arg1, int n)
1253: {
1254: while (n--) {*arg1++ = 1.0;}
1255: }
1259: /**********************************ivec.c**************************************
1260: Function rvec_neg_one()
1262: Input :
1263: Output:
1264: Return:
1265: Description:
1266: ***********************************ivec.c*************************************/
1267: void
1268: rvec_neg_one( PetscScalar *arg1, int n)
1269: {
1270: while (n--) {*arg1++ = -1.0;}
1271: }
1275: /**********************************ivec.c**************************************
1276: Function rvec_set()
1278: Input :
1279: Output:
1280: Return:
1281: Description:
1282: ***********************************ivec.c*************************************/
1283: void
1284: rvec_set( PetscScalar *arg1, PetscScalar arg2, int n)
1285: {
1286: while (n--) {*arg1++ = arg2;}
1287: }
1291: /**********************************ivec.c**************************************
1292: Function rvec_scale()
1294: Input :
1295: Output:
1296: Return:
1297: Description:
1298: ***********************************ivec.c*************************************/
1299: void
1300: rvec_scale( PetscScalar *arg1, PetscScalar arg2, int n)
1301: {
1302: while (n--) {*arg1++ *= arg2;}
1303: }
1307: /********************************ivec.c**************************************
1308: Function rvec_add()
1310: Input :
1311: Output:
1312: Return:
1313: Description:
1314: *********************************ivec.c*************************************/
1315: void
1316: rvec_add( PetscScalar *arg1, PetscScalar *arg2, int n)
1317: {
1318: while (n--) {*arg1++ += *arg2++;}
1319: }
1323: /********************************ivec.c**************************************
1324: Function rvec_dot()
1326: Input :
1327: Output:
1328: Return:
1329: Description:
1330: *********************************ivec.c*************************************/
1331: PetscScalar
1332: rvec_dot( PetscScalar *arg1, PetscScalar *arg2, int n)
1333: {
1334: PetscScalar dot=0.0;
1336: while (n--) {dot+= *arg1++ * *arg2++;}
1338: return(dot);
1339: }
1343: /********************************ivec.c**************************************
1344: Function rvec_axpy()
1346: Input :
1347: Output:
1348: Return:
1349: Description:
1350: *********************************ivec.c*************************************/
1351: void
1352: rvec_axpy( PetscScalar *arg1, PetscScalar *arg2, PetscScalar scale,
1353: int n)
1354: {
1355: while (n--) {*arg1++ += scale * *arg2++;}
1356: }
1359: /********************************ivec.c**************************************
1360: Function rvec_mult()
1362: Input :
1363: Output:
1364: Return:
1365: Description:
1366: *********************************ivec.c*************************************/
1367: void
1368: rvec_mult( PetscScalar *arg1, PetscScalar *arg2, int n)
1369: {
1370: while (n--) {*arg1++ *= *arg2++;}
1371: }
1375: /********************************ivec.c**************************************
1376: Function rvec_max()
1378: Input :
1379: Output:
1380: Return:
1381: Description:
1382: *********************************ivec.c*************************************/
1383: void
1384: rvec_max( PetscScalar *arg1, PetscScalar *arg2, int n)
1385: {
1386: while (n--) {*arg1 = PetscMax(*arg1,*arg2); arg1++; arg2++;}
1387: }
1391: /********************************ivec.c**************************************
1392: Function rvec_max_abs()
1394: Input :
1395: Output:
1396: Return:
1397: Description:
1398: *********************************ivec.c*************************************/
1399: void
1400: rvec_max_abs( PetscScalar *arg1, PetscScalar *arg2, int n)
1401: {
1402: while (n--) {*arg1 = MAX_FABS(*arg1,*arg2); arg1++; arg2++;}
1403: }
1407: /********************************ivec.c**************************************
1408: Function rvec_min()
1410: Input :
1411: Output:
1412: Return:
1413: Description:
1414: *********************************ivec.c*************************************/
1415: void
1416: rvec_min( PetscScalar *arg1, PetscScalar *arg2, int n)
1417: {
1418: while (n--) {*arg1 = PetscMin(*arg1,*arg2); arg1++; arg2++;}
1419: }
1423: /********************************ivec.c**************************************
1424: Function rvec_min_abs()
1426: Input :
1427: Output:
1428: Return:
1429: Description:
1430: *********************************ivec.c*************************************/
1431: void
1432: rvec_min_abs( PetscScalar *arg1, PetscScalar *arg2, int n)
1433: {
1434: while (n--) {*arg1 = MIN_FABS(*arg1,*arg2); arg1++; arg2++;}
1435: }
1439: /********************************ivec.c**************************************
1440: Function rvec_exists()
1442: Input :
1443: Output:
1444: Return:
1445: Description:
1446: *********************************ivec.c*************************************/
1447: void
1448: rvec_exists( PetscScalar *arg1, PetscScalar *arg2, int n)
1449: {
1450: while (n--) {*arg1 = EXISTS(*arg1,*arg2); arg1++; arg2++;}
1451: }
1455: /**********************************ivec.c**************************************
1456: Function rvec_non_uniform()
1458: Input :
1459: Output:
1460: Return:
1461: Description:
1462: ***********************************ivec.c*************************************/
1463: void
1464: rvec_non_uniform(PetscScalar *arg1, PetscScalar *arg2, int n, int *arg3)
1465: {
1466: int i, j, type;
1469: /* LATER: if we're really motivated we can sort and then unsort */
1470: for (i=0;i<n;)
1471: {
1472: /* clump 'em for now */
1473: j=i+1;
1474: type = arg3[i];
1475: while ((j<n)&&(arg3[j]==type))
1476: {j++;}
1477:
1478: /* how many together */
1479: j -= i;
1481: /* call appropriate ivec function */
1482: if (type == GL_MAX)
1483: {rvec_max(arg1,arg2,j);}
1484: else if (type == GL_MIN)
1485: {rvec_min(arg1,arg2,j);}
1486: else if (type == GL_MULT)
1487: {rvec_mult(arg1,arg2,j);}
1488: else if (type == GL_ADD)
1489: {rvec_add(arg1,arg2,j);}
1490: else if (type == GL_MAX_ABS)
1491: {rvec_max_abs(arg1,arg2,j);}
1492: else if (type == GL_MIN_ABS)
1493: {rvec_min_abs(arg1,arg2,j);}
1494: else if (type == GL_EXISTS)
1495: {rvec_exists(arg1,arg2,j);}
1496: else
1497: {error_msg_fatal("unrecognized type passed to rvec_non_uniform()!");}
1499: arg1+=j; arg2+=j; i+=j;
1500: }
1501: }
1505: /**********************************ivec.c**************************************
1506: Function rvec_fct_addr()
1508: Input :
1509: Output:
1510: Return:
1511: Description:
1512: ***********************************ivec.c*************************************/
1513: vfp rvec_fct_addr( int type)
1514: {
1515: if (type == NON_UNIFORM)
1516: {return((void (*)(void*, void *, int, ...))&rvec_non_uniform);}
1517: else if (type == GL_MAX)
1518: {return((void (*)(void*, void *, int, ...))&rvec_max);}
1519: else if (type == GL_MIN)
1520: {return((void (*)(void*, void *, int, ...))&rvec_min);}
1521: else if (type == GL_MULT)
1522: {return((void (*)(void*, void *, int, ...))&rvec_mult);}
1523: else if (type == GL_ADD)
1524: {return((void (*)(void*, void *, int, ...))&rvec_add);}
1525: else if (type == GL_MAX_ABS)
1526: {return((void (*)(void*, void *, int, ...))&rvec_max_abs);}
1527: else if (type == GL_MIN_ABS)
1528: {return((void (*)(void*, void *, int, ...))&rvec_min_abs);}
1529: else if (type == GL_EXISTS)
1530: {return((void (*)(void*, void *, int, ...))&rvec_exists);}
1532: /* catch all ... not good if we get here */
1533: return(NULL);
1534: }
1537: /******************************************************************************
1538: Function: my_sort().
1539: Input : offset of list to be sorted, number of elements to be sorted.
1540: Output: sorted list (in ascending order).
1541: Return: none.
1542: Description: stack based (nonrecursive) quicksort w/brute-shell bottom.
1543: ******************************************************************************/
1544: void
1545: rvec_sort( PetscScalar *ar, int Size)
1546: {
1547: PetscScalar *pi, *pj, temp;
1548: PetscScalar **top_a = (PetscScalar **)offset_stack;
1549: long *top_s = psize_stack, *bottom_s = psize_stack;
1550: long size = (long) Size;
1552: /* we're really interested in the offset of the last element */
1553: /* ==> length of the list is now size + 1 */
1554: size--;
1556: /* do until we're done ... return when stack is exhausted */
1557: for (;;)
1558: {
1559: /* if list is large enough use quicksort partition exchange code */
1560: if (size > SORT_OPT)
1561: {
1562: /* start up pointer at element 1 and down at size */
1563: pi = ar+1;
1564: pj = ar+size;
1566: /* find middle element in list and swap w/ element 1 */
1567: SWAP(*(ar+(size>>1)),*pi)
1569: pj = ar+size;
1571: /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
1572: /* note ==> pivot_value in index 0 */
1573: if (*pi > *pj)
1574: {SWAP(*pi,*pj)}
1575: if (*ar > *pj)
1576: {SWAP(*ar,*pj)}
1577: else if (*pi > *ar)
1578: {SWAP(*(ar),*(ar+1))}
1580: /* partition about pivot_value ... */
1581: /* note lists of length 2 are not guaranteed to be sorted */
1582: for(;;)
1583: {
1584: /* walk up ... and down ... swap if equal to pivot! */
1585: do pi++; while (*pi<*ar);
1586: do pj--; while (*pj>*ar);
1588: /* if we've crossed we're done */
1589: if (pj<pi) break;
1591: /* else swap */
1592: SWAP(*pi,*pj)
1593: }
1595: /* place pivot_value in it's correct location */
1596: SWAP(*ar,*pj)
1598: /* test stack_size to see if we've exhausted our stack */
1599: if (top_s-bottom_s >= SORT_STACK)
1600: {error_msg_fatal("\nSTACK EXHAUSTED!!!\n");}
1602: /* push right hand child iff length > 1 */
1603: if ((*top_s = size-(pi-ar)))
1604: {
1605: *(top_a++) = pi;
1606: size -= *top_s+2;
1607: top_s++;
1608: }
1609: /* set up for next loop iff there is something to do */
1610: else if (size -= *top_s+2)
1611: {;}
1612: /* might as well pop - note NR_OPT >=2 ==> we're ok! */
1613: else
1614: {
1615: ar = *(--top_a);
1616: size = *(--top_s);
1617: }
1618: }
1620: /* else sort small list directly then pop another off stack */
1621: else
1622: {
1623: /* insertion sort for bottom */
1624: for (pj=ar+1;pj<=ar+size;pj++)
1625: {
1626: temp = *pj;
1627: for (pi=pj-1;pi>=ar;pi--)
1628: {
1629: if (*pi <= temp) break;
1630: *(pi+1)=*pi;
1631: }
1632: *(pi+1)=temp;
1633: }
1635: /* check to see if stack is exhausted ==> DONE */
1636: if (top_s==bottom_s) return;
1637:
1638: /* else pop another list from the stack */
1639: ar = *(--top_a);
1640: size = *(--top_s);
1641: }
1642: }
1643: }
1647: /******************************************************************************
1648: Function: my_sort().
1649: Input : offset of list to be sorted, number of elements to be sorted.
1650: Output: sorted list (in ascending order).
1651: Return: none.
1652: Description: stack based (nonrecursive) quicksort w/brute-shell bottom.
1653: ******************************************************************************/
1654: void
1655: rvec_sort_companion( PetscScalar *ar, int *ar2, int Size)
1656: {
1657: PetscScalar *pi, *pj, temp;
1658: PetscScalar **top_a = (PetscScalar **)offset_stack;
1659: long *top_s = psize_stack, *bottom_s = psize_stack;
1660: long size = (long) Size;
1662: int *pi2, *pj2;
1663: int ptr;
1664: long mid;
1667: /* we're really interested in the offset of the last element */
1668: /* ==> length of the list is now size + 1 */
1669: size--;
1671: /* do until we're done ... return when stack is exhausted */
1672: for (;;)
1673: {
1674: /* if list is large enough use quicksort partition exchange code */
1675: if (size > SORT_OPT)
1676: {
1677: /* start up pointer at element 1 and down at size */
1678: mid = size>>1;
1679: pi = ar+1;
1680: pj = ar+mid;
1681: pi2 = ar2+1;
1682: pj2 = ar2+mid;
1684: /* find middle element in list and swap w/ element 1 */
1685: SWAP(*pi,*pj)
1686: P_SWAP(*pi2,*pj2)
1688: /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
1689: /* note ==> pivot_value in index 0 */
1690: pj = ar+size;
1691: pj2 = ar2+size;
1692: if (*pi > *pj)
1693: {SWAP(*pi,*pj) P_SWAP(*pi2,*pj2)}
1694: if (*ar > *pj)
1695: {SWAP(*ar,*pj) P_SWAP(*ar2,*pj2)}
1696: else if (*pi > *ar)
1697: {SWAP(*(ar),*(ar+1)) P_SWAP(*(ar2),*(ar2+1))}
1699: /* partition about pivot_value ... */
1700: /* note lists of length 2 are not guaranteed to be sorted */
1701: for(;;)
1702: {
1703: /* walk up ... and down ... swap if equal to pivot! */
1704: do {pi++; pi2++;} while (*pi<*ar);
1705: do {pj--; pj2--;} while (*pj>*ar);
1707: /* if we've crossed we're done */
1708: if (pj<pi) break;
1710: /* else swap */
1711: SWAP(*pi,*pj)
1712: P_SWAP(*pi2,*pj2)
1713: }
1715: /* place pivot_value in it's correct location */
1716: SWAP(*ar,*pj)
1717: P_SWAP(*ar2,*pj2)
1719: /* test stack_size to see if we've exhausted our stack */
1720: if (top_s-bottom_s >= SORT_STACK)
1721: {error_msg_fatal("\nSTACK EXHAUSTED!!!\n");}
1723: /* push right hand child iff length > 1 */
1724: if ((*top_s = size-(pi-ar)))
1725: {
1726: *(top_a++) = pi;
1727: *(top_a++) = (PetscScalar *) pi2;
1728: size -= *top_s+2;
1729: top_s++;
1730: }
1731: /* set up for next loop iff there is something to do */
1732: else if (size -= *top_s+2)
1733: {;}
1734: /* might as well pop - note NR_OPT >=2 ==> we're ok! */
1735: else
1736: {
1737: ar2 = (int*) *(--top_a);
1738: ar = *(--top_a);
1739: size = *(--top_s);
1740: }
1741: }
1743: /* else sort small list directly then pop another off stack */
1744: else
1745: {
1746: /* insertion sort for bottom */
1747: for (pj=ar+1, pj2=ar2+1;pj<=ar+size;pj++,pj2++)
1748: {
1749: temp = *pj;
1750: ptr = *pj2;
1751: for (pi=pj-1,pi2=pj2-1;pi>=ar;pi--,pi2--)
1752: {
1753: if (*pi <= temp) break;
1754: *(pi+1)=*pi;
1755: *(pi2+1)=*pi2;
1756: }
1757: *(pi+1)=temp;
1758: *(pi2+1)=ptr;
1759: }
1761: /* check to see if stack is exhausted ==> DONE */
1762: if (top_s==bottom_s) return;
1763:
1764: /* else pop another list from the stack */
1765: ar2 = (int*) *(--top_a);
1766: ar = *(--top_a);
1767: size = *(--top_s);
1768: }
1769: }
1770: }
1776: /**********************************ivec.c**************************************
1777: Function ivec_binary_search()
1779: Input :
1780: Output:
1781: Return:
1782: Description:
1783: ***********************************ivec.c*************************************/
1784: int
1785: rvec_binary_search( PetscScalar item, PetscScalar *list, int rh)
1786: {
1787: int mid, lh=0;
1789: rh--;
1790: while (lh<=rh)
1791: {
1792: mid = (lh+rh)>>1;
1793: if (*(list+mid) == item)
1794: {return(mid);}
1795: if (*(list+mid) > item)
1796: {rh = mid-1;}
1797: else
1798: {lh = mid+1;}
1799: }
1800: return(-1);
1801: }