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