Actual source code: ivec.c
1: /*$Id: ivec.c,v 1.2 2001/04/10 19:37:38 bsmith Exp $*/
2: /**********************************ivec.c**************************************
3: SPARSE GATHER-SCATTER PACKAGE: bss_malloc bss_malloc ivec error comm gs queue
5: Author: Henry M. Tufo III
7: e-mail: hmt@cs.brown.edu
9: snail-mail:
10: Division of Applied Mathematics
11: Brown University
12: Providence, RI 02912
14: Last Modification:
15: 6.21.97
16: ***********************************ivec.c*************************************/
18: /**********************************ivec.c**************************************
19: File Description:
20: -----------------
22: ***********************************ivec.c*************************************/
23: #include <stdio.h>
24: #include <math.h>
25: #include <float.h>
26: #include <limits.h>
28: #ifdef MPISRC
29: #include <mpi.h>
30: #endif
33: #include const.h
34: #include types.h
35: #include ivec.h
36: #include error.h
37: #include comm.h
40: /* sorting args ivec.c ivec.c ... */
41: #define SORT_OPT 6
42: #define SORT_STACK 50000
45: /* allocate an address and size stack for sorter(s) */
46: static void *offset_stack[2*SORT_STACK];
47: static int size_stack[SORT_STACK];
48: static PTRINT psize_stack[SORT_STACK];
52: /**********************************ivec.c**************************************
53: Function ivec_dump()
55: Input :
56: Output:
57: Return:
58: Description:
59: ***********************************ivec.c*************************************/
60: void
61: ivec_dump(int *v, int n, int tag, int tag2, char * s)
62: {
63: int i;
64: printf("%2d %2d %s %2d :: ",tag,tag2,s,my_id);
65: for (i=0;i<n;i++)
66: {printf("%2d ",v[i]);}
67: printf("\n");
68: fflush(stdout);
69: }
73: /**********************************ivec.c**************************************
74: Function ivec_lb_ub()
76: Input :
77: Output:
78: Return:
79: Description:
80: ***********************************ivec.c*************************************/
81: void
82: ivec_lb_ub(register int *arg1, register int n, int *lb, int *ub)
83: {
84: register int min = INT_MAX;
85: register int max = INT_MIN;
87: while (n--)
88: {
89: min = MIN(min,*arg1);
90: max = MAX(max,*arg1);
91: arg1++;
92: }
94: *lb=min;
95: *ub=max;
96: }
100: /**********************************ivec.c**************************************
101: Function ivec_copy()
103: Input :
104: Output:
105: Return:
106: Description:
107: ***********************************ivec.c*************************************/
108: int *
109: ivec_copy(register int *arg1, register int *arg2, register int n)
110: {
111: while (n--) {*arg1++ = *arg2++;}
112: return(arg1);
113: }
117: /**********************************ivec.c**************************************
118: Function ivec_zero()
120: Input :
121: Output:
122: Return:
123: Description:
124: ***********************************ivec.c*************************************/
125: void
126: ivec_zero(register int *arg1, register int n)
127: {
128: while (n--) {*arg1++ = 0;}
129: }
133: /**********************************ivec.c**************************************
134: Function ivec_comp()
136: Input :
137: Output:
138: Return:
139: Description:
140: ***********************************ivec.c*************************************/
141: void
142: ivec_comp(register int *arg1, register int n)
143: {
144: while (n--) {*arg1 = ~*arg1; arg1++;}
145: }
149: /**********************************ivec.c**************************************
150: Function ivec_neg_one()
152: Input :
153: Output:
154: Return:
155: Description:
156: ***********************************ivec.c*************************************/
157: void
158: ivec_neg_one(register int *arg1, register int n)
159: {
160: while (n--) {*arg1++ = -1;}
161: }
165: /**********************************ivec.c**************************************
166: Function ivec_pos_one()
168: Input :
169: Output:
170: Return:
171: Description:
172: ***********************************ivec.c*************************************/
173: void
174: ivec_pos_one(register int *arg1, register int n)
175: {
176: while (n--) {*arg1++ = 1;}
177: }
181: /**********************************ivec.c**************************************
182: Function ivec_c_index()
184: Input :
185: Output:
186: Return:
187: Description:
188: ***********************************ivec.c*************************************/
189: void
190: ivec_c_index(register int *arg1, register int n)
191: {
192: register int i=0;
195: while (n--) {*arg1++ = i++;}
196: }
200: /**********************************ivec.c**************************************
201: Function ivec_fortran_index()
203: Input :
204: Output:
205: Return:
206: Description:
207: ***********************************ivec.c*************************************/
208: void
209: ivec_fortran_index(register int *arg1, register int n)
210: {
211: register int i=0;
214: while (n--) {*arg1++ = ++i;}
215: }
219: /**********************************ivec.c**************************************
220: Function ivec_set()
222: Input :
223: Output:
224: Return:
225: Description:
226: ***********************************ivec.c*************************************/
227: void
228: ivec_set(register int *arg1, register int arg2, register int n)
229: {
230: while (n--) {*arg1++ = arg2;}
231: }
235: /**********************************ivec.c**************************************
236: Function ivec_cmp()
238: Input :
239: Output:
240: Return:
241: Description:
242: ***********************************ivec.c*************************************/
243: int
244: ivec_cmp(register int *arg1, register int *arg2, register int n)
245: {
246: while (n--) {if (*arg1++ != *arg2++) {return(FALSE);}}
247: return(TRUE);
248: }
252: /**********************************ivec.c**************************************
253: Function ivec_max()
255: Input :
256: Output:
257: Return:
258: Description:
259: ***********************************ivec.c*************************************/
260: void
261: ivec_max(register int *arg1, register int *arg2, register int n)
262: {
263: while (n--) {*arg1 = MAX(*arg1,*arg2); arg1++; arg2++;}
264: }
268: /**********************************ivec.c**************************************
269: Function ivec_min()
271: Input :
272: Output:
273: Return:
274: Description:
275: ***********************************ivec.c*************************************/
276: void
277: ivec_min(register int *arg1, register int *arg2, register int n)
278: {
279: while (n--) {*(arg1) = MIN(*arg1,*arg2); arg1++; arg2++;}
280: }
284: /**********************************ivec.c**************************************
285: Function ivec_mult()
287: Input :
288: Output:
289: Return:
290: Description:
291: ***********************************ivec.c*************************************/
292: void
293: ivec_mult(register int *arg1, register int *arg2, register int n)
294: {
295: while (n--) {*arg1++ *= *arg2++;}
296: }
300: /**********************************ivec.c**************************************
301: Function ivec_add()
303: Input :
304: Output:
305: Return:
306: Description:
307: ***********************************ivec.c*************************************/
308: void
309: ivec_add(register int *arg1, register int *arg2, register int n)
310: {
311: while (n--) {*arg1++ += *arg2++;}
312: }
316: /**********************************ivec.c**************************************
317: Function ivec_lxor()
319: Input :
320: Output:
321: Return:
322: Description:
323: ***********************************ivec.c*************************************/
324: void
325: ivec_lxor(register int *arg1, register int *arg2, register int n)
326: {
327: while (n--) {*arg1=((*arg1 || *arg2) && !(*arg1 && *arg2)) ; arg1++; arg2++;}
328: }
332: /**********************************ivec.c**************************************
333: Function ivec_xor()
335: Input :
336: Output:
337: Return:
338: Description:
339: ***********************************ivec.c*************************************/
340: void
341: ivec_xor(register int *arg1, register int *arg2, register int n)
342: {
343: while (n--) {*arg1++ ^= *arg2++;}
344: }
348: /**********************************ivec.c**************************************
349: Function ivec_or()
351: Input :
352: Output:
353: Return:
354: Description:
355: ***********************************ivec.c*************************************/
356: void
357: ivec_or(register int *arg1, register int *arg2, register int n)
358: {
359: while (n--) {*arg1++ |= *arg2++;}
360: }
364: /**********************************ivec.c**************************************
365: Function ivec_lor()
367: Input :
368: Output:
369: Return:
370: Description:
371: ***********************************ivec.c*************************************/
372: void
373: ivec_lor(register int *arg1, register int *arg2, register int n)
374: {
375: while (n--) {*arg1 = (*arg1 || *arg2); arg1++; arg2++;}
376: }
380: /**********************************ivec.c**************************************
381: Function ivec_or3()
383: Input :
384: Output:
385: Return:
386: Description:
387: ***********************************ivec.c*************************************/
388: void
389: ivec_or3(register int *arg1, register int *arg2, register int *arg3,
390: register int n)
391: {
392: while (n--) {*arg1++ = (*arg2++ | *arg3++);}
393: }
397: /**********************************ivec.c**************************************
398: Function ivec_and()
400: Input :
401: Output:
402: Return:
403: Description:
404: ***********************************ivec.c*************************************/
405: void
406: ivec_and(register int *arg1, register int *arg2, register int n)
407: {
408: while (n--) {*arg1++ &= *arg2++;}
409: }
413: /**********************************ivec.c**************************************
414: Function ivec_land()
416: Input :
417: Output:
418: Return:
419: Description:
420: ***********************************ivec.c*************************************/
421: void
422: ivec_land(register int *arg1, register int *arg2, register int n)
423: {
424: while (n--) {*arg1 = (*arg1 && *arg2); arg1++; arg2++;}
425: }
429: /**********************************ivec.c**************************************
430: Function ivec_and3()
432: Input :
433: Output:
434: Return:
435: Description:
436: ***********************************ivec.c*************************************/
437: void
438: ivec_and3(register int *arg1, register int *arg2, register int *arg3,
439: register int n)
440: {
441: while (n--) {*arg1++ = (*arg2++ & *arg3++);}
442: }
446: /**********************************ivec.c**************************************
447: Function ivec_sum
449: Input :
450: Output:
451: Return:
452: Description:
453: ***********************************ivec.c*************************************/
454: int
455: ivec_sum(register int *arg1, register int n)
456: {
457: register int tmp = 0;
460: while (n--) {tmp += *arg1++;}
461: return(tmp);
462: }
466: /**********************************ivec.c**************************************
467: Function ivec_reduce_and
469: Input :
470: Output:
471: Return:
472: Description:
473: ***********************************ivec.c*************************************/
474: int
475: ivec_reduce_and(register int *arg1, register int n)
476: {
477: register int tmp = ALL_ONES;
480: while (n--) {tmp &= *arg1++;}
481: return(tmp);
482: }
486: /**********************************ivec.c**************************************
487: Function ivec_reduce_or
489: Input :
490: Output:
491: Return:
492: Description:
493: ***********************************ivec.c*************************************/
494: int
495: ivec_reduce_or(register int *arg1, register int n)
496: {
497: register int tmp = 0;
500: while (n--) {tmp |= *arg1++;}
501: return(tmp);
502: }
506: /**********************************ivec.c**************************************
507: Function ivec_prod
509: Input :
510: Output:
511: Return:
512: Description:
513: ***********************************ivec.c*************************************/
514: int
515: ivec_prod(register int *arg1, register int n)
516: {
517: register int tmp = 1;
520: while (n--) {tmp *= *arg1++;}
521: return(tmp);
522: }
526: /**********************************ivec.c**************************************
527: Function ivec_u_sum
529: Input :
530: Output:
531: Return:
532: Description:
533: ***********************************ivec.c*************************************/
534: int
535: ivec_u_sum(register unsigned *arg1, register int n)
536: {
537: register unsigned tmp = 0;
540: while (n--) {tmp += *arg1++;}
541: return(tmp);
542: }
546: /**********************************ivec.c**************************************
547: Function ivec_lb()
549: Input :
550: Output:
551: Return:
552: Description:
553: ***********************************ivec.c*************************************/
554: int
555: ivec_lb(register int *arg1, register int n)
556: {
557: register int min = INT_MAX;
560: while (n--) {min = MIN(min,*arg1); arg1++;}
561: return(min);
562: }
566: /**********************************ivec.c**************************************
567: Function ivec_ub()
569: Input :
570: Output:
571: Return:
572: Description:
573: ***********************************ivec.c*************************************/
574: int
575: ivec_ub(register int *arg1, register int n)
576: {
577: register int max = INT_MIN;
580: while (n--) {max = MAX(max,*arg1); arg1++;}
581: return(max);
582: }
586: /**********************************ivec.c**************************************
587: Function split_buf()
589: Input :
590: Output:
591: Return:
592: Description:
594: assumes that sizeof(int) == 4bytes!!!
595: ***********************************ivec.c*************************************/
596: int
597: ivec_split_buf(int *buf1, int **buf2, register int size)
598: {
599: *buf2 = (buf1 + (size>>3));
600: return(size);
601: }
605: /**********************************ivec.c**************************************
606: Function ivec_non_uniform()
608: Input :
609: Output:
610: Return:
611: Description:
612: ***********************************ivec.c*************************************/
613: void
614: ivec_non_uniform(int *arg1, int *arg2, register int n, register int *arg3)
615: {
616: register int i, j, type;
619: /* LATER: if we're really motivated we can sort and then unsort */
620: for (i=0;i<n;)
621: {
622: /* clump 'em for now */
623: j=i+1;
624: type = arg3[i];
625: while ((j<n)&&(arg3[j]==type))
626: {j++;}
627:
628: /* how many together */
629: j -= i;
631: /* call appropriate ivec function */
632: if (type == GL_MAX)
633: {ivec_max(arg1,arg2,j);}
634: else if (type == GL_MIN)
635: {ivec_min(arg1,arg2,j);}
636: else if (type == GL_MULT)
637: {ivec_mult(arg1,arg2,j);}
638: else if (type == GL_ADD)
639: {ivec_add(arg1,arg2,j);}
640: else if (type == GL_B_XOR)
641: {ivec_xor(arg1,arg2,j);}
642: else if (type == GL_B_OR)
643: {ivec_or(arg1,arg2,j);}
644: else if (type == GL_B_AND)
645: {ivec_and(arg1,arg2,j);}
646: else if (type == GL_L_XOR)
647: {ivec_lxor(arg1,arg2,j);}
648: else if (type == GL_L_OR)
649: {ivec_lor(arg1,arg2,j);}
650: else if (type == GL_L_AND)
651: {ivec_land(arg1,arg2,j);}
652: else
653: {error_msg_fatal("unrecognized type passed to ivec_non_uniform()!");}
655: arg1+=j; arg2+=j; i+=j;
656: }
657: }
661: /**********************************ivec.c**************************************
662: Function ivec_addr()
664: Input :
665: Output:
666: Return:
667: Description:
668: ***********************************ivec.c*************************************/
669: vfp ivec_fct_addr(register int type)
670: {
671: if (type == NON_UNIFORM)
672: {return((void (*)(void *, void *, int, ...))&ivec_non_uniform);}
673: else if (type == GL_MAX)
674: {return((void (*)(void *, void *, int, ...))&ivec_max);}
675: else if (type == GL_MIN)
676: {return((void (*)(void *, void *, int, ...))&ivec_min);}
677: else if (type == GL_MULT)
678: {return((void (*)(void *, void *, int, ...))&ivec_mult);}
679: else if (type == GL_ADD)
680: {return((void (*)(void *, void *, int, ...))&ivec_add);}
681: else if (type == GL_B_XOR)
682: {return((void (*)(void *, void *, int, ...))&ivec_xor);}
683: else if (type == GL_B_OR)
684: {return((void (*)(void *, void *, int, ...))&ivec_or);}
685: else if (type == GL_B_AND)
686: {return((void (*)(void *, void *, int, ...))&ivec_and);}
687: else if (type == GL_L_XOR)
688: {return((void (*)(void *, void *, int, ...))&ivec_lxor);}
689: else if (type == GL_L_OR)
690: {return((void (*)(void *, void *, int, ...))&ivec_lor);}
691: else if (type == GL_L_AND)
692: {return((void (*)(void *, void *, int, ...))&ivec_land);}
694: /* catch all ... not good if we get here */
695: return(NULL);
696: }
699: /**********************************ivec.c**************************************
700: Function ct_bits()
702: Input :
703: Output:
704: Return:
705: Description: MUST FIX THIS!!!
706: ***********************************ivec.c*************************************/
707: #if defined(notusing)
708: static
709: int
710: ivec_ct_bits(register int *ptr, register int n)
711: {
712: register int tmp=0;
715: /* should expand to full 32 bit */
716: while (n--)
717: {
718: if (*ptr&128) {tmp++;}
719: if (*ptr&64) {tmp++;}
720: if (*ptr&32) {tmp++;}
721: if (*ptr&16) {tmp++;}
722: if (*ptr&8) {tmp++;}
723: if (*ptr&4) {tmp++;}
724: if (*ptr&2) {tmp++;}
725: if (*ptr&1) {tmp++;}
726: ptr++;
727: }
729: return(tmp);
730: }
731: #endif
734: /******************************************************************************
735: Function: ivec_sort().
737: Input : offset of list to be sorted, number of elements to be sorted.
738: Output: sorted list (in ascending order).
739: Return: none.
740: Description: stack based (nonrecursive) quicksort w/brute-shell bottom.
741: ******************************************************************************/
742: void
743: ivec_sort(register int *ar, register int size)
744: {
745: register int *pi, *pj, temp;
746: register int **top_a = (int **) offset_stack;
747: register int *top_s = size_stack, *bottom_s = size_stack;
750: /* we're really interested in the offset of the last element */
751: /* ==> length of the list is now size + 1 */
752: size--;
754: /* do until we're done ... return when stack is exhausted */
755: for (;;)
756: {
757: /* if list is large enough use quicksort partition exchange code */
758: if (size > SORT_OPT)
759: {
760: /* start up pointer at element 1 and down at size */
761: pi = ar+1;
762: pj = ar+size;
764: /* find middle element in list and swap w/ element 1 */
765: SWAP(*(ar+(size>>1)),*pi)
767: /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
768: /* note ==> pivot_value in index 0 */
769: if (*pi > *pj)
770: {SWAP(*pi,*pj)}
771: if (*ar > *pj)
772: {SWAP(*ar,*pj)}
773: else if (*pi > *ar)
774: {SWAP(*(ar),*(ar+1))}
776: /* partition about pivot_value ... */
777: /* note lists of length 2 are not guaranteed to be sorted */
778: for(;;)
779: {
780: /* walk up ... and down ... swap if equal to pivot! */
781: do pi++; while (*pi<*ar);
782: do pj--; while (*pj>*ar);
784: /* if we've crossed we're done */
785: if (pj<pi) break;
787: /* else swap */
788: SWAP(*pi,*pj)
789: }
791: /* place pivot_value in it's correct location */
792: SWAP(*ar,*pj)
794: /* test stack_size to see if we've exhausted our stack */
795: if (top_s-bottom_s >= SORT_STACK)
796: {error_msg_fatal("ivec_sort() :: STACK EXHAUSTED!!!");}
798: /* push right hand child iff length > 1 */
799: if ((*top_s = size-((int) (pi-ar))))
800: {
801: *(top_a++) = pi;
802: size -= *top_s+2;
803: top_s++;
804: }
805: /* set up for next loop iff there is something to do */
806: else if (size -= *top_s+2)
807: {;}
808: /* might as well pop - note NR_OPT >=2 ==> we're ok! */
809: else
810: {
811: ar = *(--top_a);
812: size = *(--top_s);
813: }
814: }
816: /* else sort small list directly then pop another off stack */
817: else
818: {
819: /* insertion sort for bottom */
820: for (pj=ar+1;pj<=ar+size;pj++)
821: {
822: temp = *pj;
823: for (pi=pj-1;pi>=ar;pi--)
824: {
825: if (*pi <= temp) break;
826: *(pi+1)=*pi;
827: }
828: *(pi+1)=temp;
829: }
831: /* check to see if stack is exhausted ==> DONE */
832: if (top_s==bottom_s) return;
833:
834: /* else pop another list from the stack */
835: ar = *(--top_a);
836: size = *(--top_s);
837: }
838: }
839: }
843: /******************************************************************************
844: Function: ivec_sort_companion().
846: Input : offset of list to be sorted, number of elements to be sorted.
847: Output: sorted list (in ascending order).
848: Return: none.
849: Description: stack based (nonrecursive) quicksort w/brute-shell bottom.
850: ******************************************************************************/
851: void
852: ivec_sort_companion(register int *ar, register int *ar2, register int size)
853: {
854: register int *pi, *pj, temp, temp2;
855: register int **top_a = (int **)offset_stack;
856: register int *top_s = size_stack, *bottom_s = size_stack;
857: register int *pi2, *pj2;
858: register int mid;
861: /* we're really interested in the offset of the last element */
862: /* ==> length of the list is now size + 1 */
863: size--;
865: /* do until we're done ... return when stack is exhausted */
866: for (;;)
867: {
868: /* if list is large enough use quicksort partition exchange code */
869: if (size > SORT_OPT)
870: {
871: /* start up pointer at element 1 and down at size */
872: mid = size>>1;
873: pi = ar+1;
874: pj = ar+mid;
875: pi2 = ar2+1;
876: pj2 = ar2+mid;
878: /* find middle element in list and swap w/ element 1 */
879: SWAP(*pi,*pj)
880: SWAP(*pi2,*pj2)
882: /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
883: /* note ==> pivot_value in index 0 */
884: pj = ar+size;
885: pj2 = ar2+size;
886: if (*pi > *pj)
887: {SWAP(*pi,*pj) SWAP(*pi2,*pj2)}
888: if (*ar > *pj)
889: {SWAP(*ar,*pj) SWAP(*ar2,*pj2)}
890: else if (*pi > *ar)
891: {SWAP(*(ar),*(ar+1)) SWAP(*(ar2),*(ar2+1))}
893: /* partition about pivot_value ... */
894: /* note lists of length 2 are not guaranteed to be sorted */
895: for(;;)
896: {
897: /* walk up ... and down ... swap if equal to pivot! */
898: do {pi++; pi2++;} while (*pi<*ar);
899: do {pj--; pj2--;} while (*pj>*ar);
901: /* if we've crossed we're done */
902: if (pj<pi) break;
904: /* else swap */
905: SWAP(*pi,*pj)
906: SWAP(*pi2,*pj2)
907: }
909: /* place pivot_value in it's correct location */
910: SWAP(*ar,*pj)
911: SWAP(*ar2,*pj2)
913: /* test stack_size to see if we've exhausted our stack */
914: if (top_s-bottom_s >= SORT_STACK)
915: {error_msg_fatal("ivec_sort_companion() :: STACK EXHAUSTED!!!");}
917: /* push right hand child iff length > 1 */
918: if ((*top_s = size-((int) (pi-ar))))
919: {
920: *(top_a++) = pi;
921: *(top_a++) = pi2;
922: size -= *top_s+2;
923: top_s++;
924: }
925: /* set up for next loop iff there is something to do */
926: else if (size -= *top_s+2)
927: {;}
928: /* might as well pop - note NR_OPT >=2 ==> we're ok! */
929: else
930: {
931: ar2 = *(--top_a);
932: ar = *(--top_a);
933: size = *(--top_s);
934: }
935: }
937: /* else sort small list directly then pop another off stack */
938: else
939: {
940: /* insertion sort for bottom */
941: for (pj=ar+1, pj2=ar2+1;pj<=ar+size;pj++,pj2++)
942: {
943: temp = *pj;
944: temp2 = *pj2;
945: for (pi=pj-1,pi2=pj2-1;pi>=ar;pi--,pi2--)
946: {
947: if (*pi <= temp) break;
948: *(pi+1)=*pi;
949: *(pi2+1)=*pi2;
950: }
951: *(pi+1)=temp;
952: *(pi2+1)=temp2;
953: }
955: /* check to see if stack is exhausted ==> DONE */
956: if (top_s==bottom_s) return;
957:
958: /* else pop another list from the stack */
959: ar2 = *(--top_a);
960: ar = *(--top_a);
961: size = *(--top_s);
962: }
963: }
964: }
968: /******************************************************************************
969: Function: ivec_sort_companion_hack().
971: Input : offset of list to be sorted, number of elements to be sorted.
972: Output: sorted list (in ascending order).
973: Return: none.
974: Description: stack based (nonrecursive) quicksort w/brute-shell bottom.
975: ******************************************************************************/
976: void
977: ivec_sort_companion_hack(register int *ar, register int **ar2,
978: register int size)
979: {
980: register int *pi, *pj, temp, *ptr;
981: register int **top_a = (int **)offset_stack;
982: register int *top_s = size_stack, *bottom_s = size_stack;
983: register int **pi2, **pj2;
984: register int mid;
987: /* we're really interested in the offset of the last element */
988: /* ==> length of the list is now size + 1 */
989: size--;
991: /* do until we're done ... return when stack is exhausted */
992: for (;;)
993: {
994: /* if list is large enough use quicksort partition exchange code */
995: if (size > SORT_OPT)
996: {
997: /* start up pointer at element 1 and down at size */
998: mid = size>>1;
999: pi = ar+1;
1000: pj = ar+mid;
1001: pi2 = ar2+1;
1002: pj2 = ar2+mid;
1004: /* find middle element in list and swap w/ element 1 */
1005: SWAP(*pi,*pj)
1006: P_SWAP(*pi2,*pj2)
1008: /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
1009: /* note ==> pivot_value in index 0 */
1010: pj = ar+size;
1011: pj2 = ar2+size;
1012: if (*pi > *pj)
1013: {SWAP(*pi,*pj) P_SWAP(*pi2,*pj2)}
1014: if (*ar > *pj)
1015: {SWAP(*ar,*pj) P_SWAP(*ar2,*pj2)}
1016: else if (*pi > *ar)
1017: {SWAP(*(ar),*(ar+1)) P_SWAP(*(ar2),*(ar2+1))}
1019: /* partition about pivot_value ... */
1020: /* note lists of length 2 are not guaranteed to be sorted */
1021: for(;;)
1022: {
1023: /* walk up ... and down ... swap if equal to pivot! */
1024: do {pi++; pi2++;} while (*pi<*ar);
1025: do {pj--; pj2--;} while (*pj>*ar);
1027: /* if we've crossed we're done */
1028: if (pj<pi) break;
1030: /* else swap */
1031: SWAP(*pi,*pj)
1032: P_SWAP(*pi2,*pj2)
1033: }
1035: /* place pivot_value in it's correct location */
1036: SWAP(*ar,*pj)
1037: P_SWAP(*ar2,*pj2)
1039: /* test stack_size to see if we've exhausted our stack */
1040: if (top_s-bottom_s >= SORT_STACK)
1041: {error_msg_fatal("ivec_sort_companion_hack() :: STACK EXHAUSTED!!!");}
1043: /* push right hand child iff length > 1 */
1044: if ((*top_s = size-((int) (pi-ar))))
1045: {
1046: *(top_a++) = pi;
1047: *(top_a++) = (int *) pi2;
1048: size -= *top_s+2;
1049: top_s++;
1050: }
1051: /* set up for next loop iff there is something to do */
1052: else if (size -= *top_s+2)
1053: {;}
1054: /* might as well pop - note NR_OPT >=2 ==> we're ok! */
1055: else
1056: {
1057: ar2 = (int **) *(--top_a);
1058: ar = *(--top_a);
1059: size = *(--top_s);
1060: }
1061: }
1063: /* else sort small list directly then pop another off stack */
1064: else
1065: {
1066: /* insertion sort for bottom */
1067: for (pj=ar+1, pj2=ar2+1;pj<=ar+size;pj++,pj2++)
1068: {
1069: temp = *pj;
1070: ptr = *pj2;
1071: for (pi=pj-1,pi2=pj2-1;pi>=ar;pi--,pi2--)
1072: {
1073: if (*pi <= temp) break;
1074: *(pi+1)=*pi;
1075: *(pi2+1)=*pi2;
1076: }
1077: *(pi+1)=temp;
1078: *(pi2+1)=ptr;
1079: }
1081: /* check to see if stack is exhausted ==> DONE */
1082: if (top_s==bottom_s) return;
1083:
1084: /* else pop another list from the stack */
1085: ar2 = (int **)*(--top_a);
1086: ar = *(--top_a);
1087: size = *(--top_s);
1088: }
1089: }
1090: }
1094: /******************************************************************************
1095: Function: SMI_sort().
1096: Input : offset of list to be sorted, number of elements to be sorted.
1097: Output: sorted list (in ascending order).
1098: Return: none.
1099: Description: stack based (nonrecursive) quicksort w/brute-shell bottom.
1100: ******************************************************************************/
1101: void
1102: SMI_sort(void *ar1, void *ar2, int size, int type)
1103: {
1104: if (type == SORT_INTEGER)
1105: {
1106: if (ar2)
1107: {ivec_sort_companion((int *)ar1,(int *)ar2,size);}
1108: else
1109: {ivec_sort((int*)ar1,size);}
1110: }
1111: else if (type == SORT_INT_PTR)
1112: {
1113: if (ar2)
1114: {ivec_sort_companion_hack((int *)ar1,(int **)ar2,size);}
1115: else
1116: {ivec_sort((int*)ar1,size);}
1117: }
1119: else
1120: {
1121: error_msg_fatal("SMI_sort only does SORT_INTEGER!");
1122: }
1123: /*
1124: if (type == SORT_REAL)
1125: {
1126: if (ar2)
1127: {rvec_sort_companion(ar2,ar1,size);}
1128: else
1129: {rvec_sort(ar1,size);}
1130: }
1131: */
1132: }
1136: /**********************************ivec.c**************************************
1137: Function ivec_linear_search()
1139: Input :
1140: Output:
1141: Return:
1142: Description:
1143: ***********************************ivec.c*************************************/
1144: int
1145: ivec_linear_search(register int item, register int *list, register int n)
1146: {
1147: register int tmp = n-1;
1149: while (n--) {if (*list++ == item) {return(tmp-n);}}
1150: return(-1);
1151: }
1155: /**********************************ivec.c**************************************
1156: Function ivec_binary_search()
1158: Input :
1159: Output:
1160: Return:
1161: Description:
1162: ***********************************ivec.c*************************************/
1163: int
1164: ivec_binary_search(register int item, register int *list, register int rh)
1165: {
1166: register int mid, lh=0;
1168: rh--;
1169: while (lh<=rh)
1170: {
1171: mid = (lh+rh)>>1;
1172: if (*(list+mid) == item)
1173: {return(mid);}
1174: if (*(list+mid) > item)
1175: {rh = mid-1;}
1176: else
1177: {lh = mid+1;}
1178: }
1179: return(-1);
1180: }
1184: /**********************************ivec.c**************************************
1185: Function rvec_dump
1187: Input :
1188: Output:
1189: Return:
1190: Description:
1191: ***********************************ivec.c*************************************/
1192: void
1193: rvec_dump(REAL *v, int n, int tag, int tag2, char * s)
1194: {
1195: int i;
1196: printf("%2d %2d %s %2d :: ",tag,tag2,s,my_id);
1197: for (i=0;i<n;i++)
1198: {printf("%f ",v[i]);}
1199: printf("\n");
1200: fflush(stdout);
1201: }
1205: /**********************************ivec.c**************************************
1206: Function rvec_lb_ub()
1208: Input :
1209: Output:
1210: Return:
1211: Description:
1212: ***********************************ivec.c*************************************/
1213: void
1214: rvec_lb_ub(register REAL *arg1, register int n, REAL *lb, REAL *ub)
1215: {
1216: register REAL min = REAL_MAX;
1217: register REAL max = -REAL_MAX;
1219: while (n--)
1220: {
1221: min = MIN(min,*arg1);
1222: max = MAX(max,*arg1);
1223: arg1++;
1224: }
1226: *lb=min;
1227: *ub=max;
1228: }
1232: /********************************ivec.c**************************************
1233: Function rvec_copy()
1235: Input :
1236: Output:
1237: Return:
1238: Description:
1239: *********************************ivec.c*************************************/
1240: void
1241: rvec_copy(register REAL *arg1, register REAL *arg2, register int n)
1242: {
1243: while (n--) {*arg1++ = *arg2++;}
1244: }
1248: /********************************ivec.c**************************************
1249: Function rvec_zero()
1251: Input :
1252: Output:
1253: Return:
1254: Description:
1255: *********************************ivec.c*************************************/
1256: void
1257: rvec_zero(register REAL *arg1, register int n)
1258: {
1259: while (n--) {*arg1++ = 0.0;}
1260: }
1264: /**********************************ivec.c**************************************
1265: Function rvec_one()
1267: Input :
1268: Output:
1269: Return:
1270: Description:
1271: ***********************************ivec.c*************************************/
1272: void
1273: rvec_one(register REAL *arg1, register int n)
1274: {
1275: while (n--) {*arg1++ = 1.0;}
1276: }
1280: /**********************************ivec.c**************************************
1281: Function rvec_neg_one()
1283: Input :
1284: Output:
1285: Return:
1286: Description:
1287: ***********************************ivec.c*************************************/
1288: void
1289: rvec_neg_one(register REAL *arg1, register int n)
1290: {
1291: while (n--) {*arg1++ = -1.0;}
1292: }
1296: /**********************************ivec.c**************************************
1297: Function rvec_set()
1299: Input :
1300: Output:
1301: Return:
1302: Description:
1303: ***********************************ivec.c*************************************/
1304: void
1305: rvec_set(register REAL *arg1, register REAL arg2, register int n)
1306: {
1307: while (n--) {*arg1++ = arg2;}
1308: }
1312: /**********************************ivec.c**************************************
1313: Function rvec_scale()
1315: Input :
1316: Output:
1317: Return:
1318: Description:
1319: ***********************************ivec.c*************************************/
1320: void
1321: rvec_scale(register REAL *arg1, register REAL arg2, register int n)
1322: {
1323: while (n--) {*arg1++ *= arg2;}
1324: }
1328: /********************************ivec.c**************************************
1329: Function rvec_add()
1331: Input :
1332: Output:
1333: Return:
1334: Description:
1335: *********************************ivec.c*************************************/
1336: void
1337: rvec_add(register REAL *arg1, register REAL *arg2, register int n)
1338: {
1339: while (n--) {*arg1++ += *arg2++;}
1340: }
1344: /********************************ivec.c**************************************
1345: Function rvec_dot()
1347: Input :
1348: Output:
1349: Return:
1350: Description:
1351: *********************************ivec.c*************************************/
1352: REAL
1353: rvec_dot(register REAL *arg1, register REAL *arg2, register int n)
1354: {
1355: REAL dot=0.0;
1357: while (n--) {dot+= *arg1++ * *arg2++;}
1359: return(dot);
1360: }
1364: /********************************ivec.c**************************************
1365: Function rvec_axpy()
1367: Input :
1368: Output:
1369: Return:
1370: Description:
1371: *********************************ivec.c*************************************/
1372: void
1373: rvec_axpy(register REAL *arg1, register REAL *arg2, register REAL scale,
1374: register int n)
1375: {
1376: while (n--) {*arg1++ += scale * *arg2++;}
1377: }
1380: /********************************ivec.c**************************************
1381: Function rvec_mult()
1383: Input :
1384: Output:
1385: Return:
1386: Description:
1387: *********************************ivec.c*************************************/
1388: void
1389: rvec_mult(register REAL *arg1, register REAL *arg2, register int n)
1390: {
1391: while (n--) {*arg1++ *= *arg2++;}
1392: }
1396: /********************************ivec.c**************************************
1397: Function rvec_max()
1399: Input :
1400: Output:
1401: Return:
1402: Description:
1403: *********************************ivec.c*************************************/
1404: void
1405: rvec_max(register REAL *arg1, register REAL *arg2, register int n)
1406: {
1407: while (n--) {*arg1 = MAX(*arg1,*arg2); arg1++; arg2++;}
1408: }
1412: /********************************ivec.c**************************************
1413: Function rvec_max_abs()
1415: Input :
1416: Output:
1417: Return:
1418: Description:
1419: *********************************ivec.c*************************************/
1420: void
1421: rvec_max_abs(register REAL *arg1, register REAL *arg2, register int n)
1422: {
1423: while (n--) {*arg1 = MAX_FABS(*arg1,*arg2); arg1++; arg2++;}
1424: }
1428: /********************************ivec.c**************************************
1429: Function rvec_min()
1431: Input :
1432: Output:
1433: Return:
1434: Description:
1435: *********************************ivec.c*************************************/
1436: void
1437: rvec_min(register REAL *arg1, register REAL *arg2, register int n)
1438: {
1439: while (n--) {*arg1 = MIN(*arg1,*arg2); arg1++; arg2++;}
1440: }
1444: /********************************ivec.c**************************************
1445: Function rvec_min_abs()
1447: Input :
1448: Output:
1449: Return:
1450: Description:
1451: *********************************ivec.c*************************************/
1452: void
1453: rvec_min_abs(register REAL *arg1, register REAL *arg2, register int n)
1454: {
1455: while (n--) {*arg1 = MIN_FABS(*arg1,*arg2); arg1++; arg2++;}
1456: }
1460: /********************************ivec.c**************************************
1461: Function rvec_exists()
1463: Input :
1464: Output:
1465: Return:
1466: Description:
1467: *********************************ivec.c*************************************/
1468: void
1469: rvec_exists(register REAL *arg1, register REAL *arg2, register int n)
1470: {
1471: while (n--) {*arg1 = EXISTS(*arg1,*arg2); arg1++; arg2++;}
1472: }
1476: /**********************************ivec.c**************************************
1477: Function rvec_non_uniform()
1479: Input :
1480: Output:
1481: Return:
1482: Description:
1483: ***********************************ivec.c*************************************/
1484: void
1485: rvec_non_uniform(REAL *arg1, REAL *arg2, register int n, register int *arg3)
1486: {
1487: register int i, j, type;
1490: /* LATER: if we're really motivated we can sort and then unsort */
1491: for (i=0;i<n;)
1492: {
1493: /* clump 'em for now */
1494: j=i+1;
1495: type = arg3[i];
1496: while ((j<n)&&(arg3[j]==type))
1497: {j++;}
1498:
1499: /* how many together */
1500: j -= i;
1502: /* call appropriate ivec function */
1503: if (type == GL_MAX)
1504: {rvec_max(arg1,arg2,j);}
1505: else if (type == GL_MIN)
1506: {rvec_min(arg1,arg2,j);}
1507: else if (type == GL_MULT)
1508: {rvec_mult(arg1,arg2,j);}
1509: else if (type == GL_ADD)
1510: {rvec_add(arg1,arg2,j);}
1511: else if (type == GL_MAX_ABS)
1512: {rvec_max_abs(arg1,arg2,j);}
1513: else if (type == GL_MIN_ABS)
1514: {rvec_min_abs(arg1,arg2,j);}
1515: else if (type == GL_EXISTS)
1516: {rvec_exists(arg1,arg2,j);}
1517: else
1518: {error_msg_fatal("unrecognized type passed to rvec_non_uniform()!");}
1520: arg1+=j; arg2+=j; i+=j;
1521: }
1522: }
1526: /**********************************ivec.c**************************************
1527: Function rvec_fct_addr()
1529: Input :
1530: Output:
1531: Return:
1532: Description:
1533: ***********************************ivec.c*************************************/
1534: vfp rvec_fct_addr(register int type)
1535: {
1536: if (type == NON_UNIFORM)
1537: {return((void (*)(void *, void *, int, ...))&rvec_non_uniform);}
1538: else if (type == GL_MAX)
1539: {return((void (*)(void *, void *, int, ...))&rvec_max);}
1540: else if (type == GL_MIN)
1541: {return((void (*)(void *, void *, int, ...))&rvec_min);}
1542: else if (type == GL_MULT)
1543: {return((void (*)(void *, void *, int, ...))&rvec_mult);}
1544: else if (type == GL_ADD)
1545: {return((void (*)(void *, void *, int, ...))&rvec_add);}
1546: else if (type == GL_MAX_ABS)
1547: {return((void (*)(void *, void *, int, ...))&rvec_max_abs);}
1548: else if (type == GL_MIN_ABS)
1549: {return((void (*)(void *, void *, int, ...))&rvec_min_abs);}
1550: else if (type == GL_EXISTS)
1551: {return((void (*)(void *, void *, int, ...))&rvec_exists);}
1553: /* catch all ... not good if we get here */
1554: return(NULL);
1555: }
1558: /******************************************************************************
1559: Function: my_sort().
1560: Input : offset of list to be sorted, number of elements to be sorted.
1561: Output: sorted list (in ascending order).
1562: Return: none.
1563: Description: stack based (nonrecursive) quicksort w/brute-shell bottom.
1564: ******************************************************************************/
1565: void
1566: rvec_sort(register REAL *ar, register int Size)
1567: {
1568: register REAL *pi, *pj, temp;
1569: register REAL **top_a = (REAL **)offset_stack;
1570: register PTRINT *top_s = psize_stack, *bottom_s = psize_stack;
1571: register PTRINT size = (PTRINT) Size;
1573: /* we're really interested in the offset of the last element */
1574: /* ==> length of the list is now size + 1 */
1575: size--;
1577: /* do until we're done ... return when stack is exhausted */
1578: for (;;)
1579: {
1580: /* if list is large enough use quicksort partition exchange code */
1581: if (size > SORT_OPT)
1582: {
1583: /* start up pointer at element 1 and down at size */
1584: pi = ar+1;
1585: pj = ar+size;
1587: /* find middle element in list and swap w/ element 1 */
1588: SWAP(*(ar+(size>>1)),*pi)
1590: pj = ar+size;
1592: /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
1593: /* note ==> pivot_value in index 0 */
1594: if (*pi > *pj)
1595: {SWAP(*pi,*pj)}
1596: if (*ar > *pj)
1597: {SWAP(*ar,*pj)}
1598: else if (*pi > *ar)
1599: {SWAP(*(ar),*(ar+1))}
1601: /* partition about pivot_value ... */
1602: /* note lists of length 2 are not guaranteed to be sorted */
1603: for(;;)
1604: {
1605: /* walk up ... and down ... swap if equal to pivot! */
1606: do pi++; while (*pi<*ar);
1607: do pj--; while (*pj>*ar);
1609: /* if we've crossed we're done */
1610: if (pj<pi) break;
1612: /* else swap */
1613: SWAP(*pi,*pj)
1614: }
1616: /* place pivot_value in it's correct location */
1617: SWAP(*ar,*pj)
1619: /* test stack_size to see if we've exhausted our stack */
1620: if (top_s-bottom_s >= SORT_STACK)
1621: {error_msg_fatal("\nSTACK EXHAUSTED!!!\n");}
1623: /* push right hand child iff length > 1 */
1624: if ((*top_s = size-(pi-ar)))
1625: {
1626: *(top_a++) = pi;
1627: size -= *top_s+2;
1628: top_s++;
1629: }
1630: /* set up for next loop iff there is something to do */
1631: else if (size -= *top_s+2)
1632: {;}
1633: /* might as well pop - note NR_OPT >=2 ==> we're ok! */
1634: else
1635: {
1636: ar = *(--top_a);
1637: size = *(--top_s);
1638: }
1639: }
1641: /* else sort small list directly then pop another off stack */
1642: else
1643: {
1644: /* insertion sort for bottom */
1645: for (pj=ar+1;pj<=ar+size;pj++)
1646: {
1647: temp = *pj;
1648: for (pi=pj-1;pi>=ar;pi--)
1649: {
1650: if (*pi <= temp) break;
1651: *(pi+1)=*pi;
1652: }
1653: *(pi+1)=temp;
1654: }
1656: /* check to see if stack is exhausted ==> DONE */
1657: if (top_s==bottom_s) return;
1658:
1659: /* else pop another list from the stack */
1660: ar = *(--top_a);
1661: size = *(--top_s);
1662: }
1663: }
1664: }
1668: /******************************************************************************
1669: Function: my_sort().
1670: Input : offset of list to be sorted, number of elements to be sorted.
1671: Output: sorted list (in ascending order).
1672: Return: none.
1673: Description: stack based (nonrecursive) quicksort w/brute-shell bottom.
1674: ******************************************************************************/
1675: void
1676: rvec_sort_companion(register REAL *ar, register int *ar2, register int Size)
1677: {
1678: register REAL *pi, *pj, temp;
1679: register REAL **top_a = (REAL **)offset_stack;
1680: register PTRINT *top_s = psize_stack, *bottom_s = psize_stack;
1681: register PTRINT size = (PTRINT) Size;
1683: register int *pi2, *pj2;
1684: register int ptr;
1685: register PTRINT mid;
1688: /* we're really interested in the offset of the last element */
1689: /* ==> length of the list is now size + 1 */
1690: size--;
1692: /* do until we're done ... return when stack is exhausted */
1693: for (;;)
1694: {
1695: /* if list is large enough use quicksort partition exchange code */
1696: if (size > SORT_OPT)
1697: {
1698: /* start up pointer at element 1 and down at size */
1699: mid = size>>1;
1700: pi = ar+1;
1701: pj = ar+mid;
1702: pi2 = ar2+1;
1703: pj2 = ar2+mid;
1705: /* find middle element in list and swap w/ element 1 */
1706: SWAP(*pi,*pj)
1707: P_SWAP(*pi2,*pj2)
1709: /* order element 0,1,size-1 st {M,L,...,U} w/L<=M<=U */
1710: /* note ==> pivot_value in index 0 */
1711: pj = ar+size;
1712: pj2 = ar2+size;
1713: if (*pi > *pj)
1714: {SWAP(*pi,*pj) P_SWAP(*pi2,*pj2)}
1715: if (*ar > *pj)
1716: {SWAP(*ar,*pj) P_SWAP(*ar2,*pj2)}
1717: else if (*pi > *ar)
1718: {SWAP(*(ar),*(ar+1)) P_SWAP(*(ar2),*(ar2+1))}
1720: /* partition about pivot_value ... */
1721: /* note lists of length 2 are not guaranteed to be sorted */
1722: for(;;)
1723: {
1724: /* walk up ... and down ... swap if equal to pivot! */
1725: do {pi++; pi2++;} while (*pi<*ar);
1726: do {pj--; pj2--;} while (*pj>*ar);
1728: /* if we've crossed we're done */
1729: if (pj<pi) break;
1731: /* else swap */
1732: SWAP(*pi,*pj)
1733: P_SWAP(*pi2,*pj2)
1734: }
1736: /* place pivot_value in it's correct location */
1737: SWAP(*ar,*pj)
1738: P_SWAP(*ar2,*pj2)
1740: /* test stack_size to see if we've exhausted our stack */
1741: if (top_s-bottom_s >= SORT_STACK)
1742: {error_msg_fatal("\nSTACK EXHAUSTED!!!\n");}
1744: /* push right hand child iff length > 1 */
1745: if ((*top_s = size-(pi-ar)))
1746: {
1747: *(top_a++) = pi;
1748: *(top_a++) = (REAL *) pi2;
1749: size -= *top_s+2;
1750: top_s++;
1751: }
1752: /* set up for next loop iff there is something to do */
1753: else if (size -= *top_s+2)
1754: {;}
1755: /* might as well pop - note NR_OPT >=2 ==> we're ok! */
1756: else
1757: {
1758: ar2 = (int *) *(--top_a);
1759: ar = *(--top_a);
1760: size = *(--top_s);
1761: }
1762: }
1764: /* else sort small list directly then pop another off stack */
1765: else
1766: {
1767: /* insertion sort for bottom */
1768: for (pj=ar+1, pj2=ar2+1;pj<=ar+size;pj++,pj2++)
1769: {
1770: temp = *pj;
1771: ptr = *pj2;
1772: for (pi=pj-1,pi2=pj2-1;pi>=ar;pi--,pi2--)
1773: {
1774: if (*pi <= temp) break;
1775: *(pi+1)=*pi;
1776: *(pi2+1)=*pi2;
1777: }
1778: *(pi+1)=temp;
1779: *(pi2+1)=ptr;
1780: }
1782: /* check to see if stack is exhausted ==> DONE */
1783: if (top_s==bottom_s) return;
1784:
1785: /* else pop another list from the stack */
1786: ar2 = (int *) *(--top_a);
1787: ar = *(--top_a);
1788: size = *(--top_s);
1789: }
1790: }
1791: }
1797: /**********************************ivec.c**************************************
1798: Function ivec_binary_search()
1800: Input :
1801: Output:
1802: Return:
1803: Description:
1804: ***********************************ivec.c*************************************/
1805: int
1806: rvec_binary_search(register REAL item, register REAL *list, register int rh)
1807: {
1808: register int mid, lh=0;
1810: rh--;
1811: while (lh<=rh)
1812: {
1813: mid = (lh+rh)>>1;
1814: if (*(list+mid) == item)
1815: {return(mid);}
1816: if (*(list+mid) > item)
1817: {rh = mid-1;}
1818: else
1819: {lh = mid+1;}
1820: }
1821: return(-1);
1822: }