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