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