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