1e5c89e4eSSatish Balay #define PETSC_DLL 2e5c89e4eSSatish Balay /* 3e5c89e4eSSatish Balay This file contains routines for sorting integers. Values are sorted in place. 4e5c89e4eSSatish Balay */ 5d382aafbSBarry Smith #include "petscsys.h" /*I "petscsys.h" I*/ 6e5c89e4eSSatish Balay 7e5c89e4eSSatish Balay #define SWAP(a,b,t) {t=a;a=b;b=t;} 8e5c89e4eSSatish Balay 9*ef8e3583SJed Brown #define MEDIAN(v,right) \ 10*ef8e3583SJed Brown (v[0]<v[right/2] \ 11*ef8e3583SJed Brown ? (v[right/2]<v[right] \ 12*ef8e3583SJed Brown ? right/2 \ 13*ef8e3583SJed Brown : (v[0]<v[right] ? right : 0)) \ 14*ef8e3583SJed Brown : (v[right]<v[right/2] \ 15*ef8e3583SJed Brown ? right/2 \ 16*ef8e3583SJed Brown : (v[0]<v[right] ? 0 : right))) 17*ef8e3583SJed Brown 18e5c89e4eSSatish Balay /* -----------------------------------------------------------------------*/ 19e5c89e4eSSatish Balay 20e5c89e4eSSatish Balay #undef __FUNCT__ 21e5c89e4eSSatish Balay #define __FUNCT__ "PetscSortInt_Private" 22e5c89e4eSSatish Balay /* 23e5c89e4eSSatish Balay A simple version of quicksort; taken from Kernighan and Ritchie, page 87. 24e5c89e4eSSatish Balay Assumes 0 origin for v, number of elements = right+1 (right is index of 25e5c89e4eSSatish Balay right-most member). 26e5c89e4eSSatish Balay */ 27*ef8e3583SJed Brown static void PetscSortInt_Private(PetscInt *v,PetscInt right) 28e5c89e4eSSatish Balay { 29*ef8e3583SJed Brown PetscInt i,j,pivot,tmp; 30e5c89e4eSSatish Balay 31e5c89e4eSSatish Balay if (right <= 1) { 32e5c89e4eSSatish Balay if (right == 1) { 33e5c89e4eSSatish Balay if (v[0] > v[1]) SWAP(v[0],v[1],tmp); 34e5c89e4eSSatish Balay } 35*ef8e3583SJed Brown return; 36e5c89e4eSSatish Balay } 37*ef8e3583SJed Brown i = MEDIAN(v,right); /* Choose a pivot */ 38*ef8e3583SJed Brown SWAP(v[0],v[i],tmp); /* Move it out of the way */ 39*ef8e3583SJed Brown pivot = v[0]; 40*ef8e3583SJed Brown for (i=0,j=right+1;;) { 41*ef8e3583SJed Brown while (++i < j && v[i] <= pivot); /* Scan from the left */ 42*ef8e3583SJed Brown while (v[--j] > pivot); /* Scan from the right */ 43*ef8e3583SJed Brown if (i >= j) break; 44*ef8e3583SJed Brown SWAP(v[i],v[j],tmp); 45e5c89e4eSSatish Balay } 46*ef8e3583SJed Brown SWAP(v[0],v[j],tmp); /* Put pivot back in place. */ 47*ef8e3583SJed Brown PetscSortInt_Private(v,j-1); 48*ef8e3583SJed Brown PetscSortInt_Private(v+j+1,right-(j+1)); 49e5c89e4eSSatish Balay } 50e5c89e4eSSatish Balay 51e5c89e4eSSatish Balay #undef __FUNCT__ 52e5c89e4eSSatish Balay #define __FUNCT__ "PetscSortInt" 53e5c89e4eSSatish Balay /*@ 54e5c89e4eSSatish Balay PetscSortInt - Sorts an array of integers in place in increasing order. 55e5c89e4eSSatish Balay 56e5c89e4eSSatish Balay Not Collective 57e5c89e4eSSatish Balay 58e5c89e4eSSatish Balay Input Parameters: 59e5c89e4eSSatish Balay + n - number of values 60e5c89e4eSSatish Balay - i - array of integers 61e5c89e4eSSatish Balay 62e5c89e4eSSatish Balay Level: intermediate 63e5c89e4eSSatish Balay 64e5c89e4eSSatish Balay Concepts: sorting^ints 65e5c89e4eSSatish Balay 66e5c89e4eSSatish Balay .seealso: PetscSortReal(), PetscSortIntWithPermutation() 67e5c89e4eSSatish Balay @*/ 688738c821SJed Brown PetscErrorCode PETSCSYS_DLLEXPORT PetscSortInt(PetscInt n,PetscInt i[]) 69e5c89e4eSSatish Balay { 70e5c89e4eSSatish Balay PetscInt j,k,tmp,ik; 71e5c89e4eSSatish Balay 72e5c89e4eSSatish Balay PetscFunctionBegin; 73e5c89e4eSSatish Balay if (n<8) { 74e5c89e4eSSatish Balay for (k=0; k<n; k++) { 75e5c89e4eSSatish Balay ik = i[k]; 76e5c89e4eSSatish Balay for (j=k+1; j<n; j++) { 77e5c89e4eSSatish Balay if (ik > i[j]) { 78e5c89e4eSSatish Balay SWAP(i[k],i[j],tmp); 79e5c89e4eSSatish Balay ik = i[k]; 80e5c89e4eSSatish Balay } 81e5c89e4eSSatish Balay } 82e5c89e4eSSatish Balay } 83e5c89e4eSSatish Balay } else { 84*ef8e3583SJed Brown PetscSortInt_Private(i,n-1); 85e5c89e4eSSatish Balay } 86e5c89e4eSSatish Balay PetscFunctionReturn(0); 87e5c89e4eSSatish Balay } 88e5c89e4eSSatish Balay 891db36a52SBarry Smith #undef __FUNCT__ 901db36a52SBarry Smith #define __FUNCT__ "PetscSortRemoveDupsInt" 911db36a52SBarry Smith /*@ 921db36a52SBarry Smith PetscSortRemoveDupsInt - Sorts an array of integers in place in increasing order removes all duplicate entries 931db36a52SBarry Smith 941db36a52SBarry Smith Not Collective 951db36a52SBarry Smith 961db36a52SBarry Smith Input Parameters: 971db36a52SBarry Smith + n - number of values 981db36a52SBarry Smith - ii - array of integers 991db36a52SBarry Smith 1001db36a52SBarry Smith Output Parameter: 1011db36a52SBarry Smith . n - number of non-redundant values 1021db36a52SBarry Smith 1031db36a52SBarry Smith Level: intermediate 1041db36a52SBarry Smith 1051db36a52SBarry Smith Concepts: sorting^ints 1061db36a52SBarry Smith 1071db36a52SBarry Smith .seealso: PetscSortReal(), PetscSortIntWithPermutation(), PetscSortInt() 1081db36a52SBarry Smith @*/ 1098738c821SJed Brown PetscErrorCode PETSCSYS_DLLEXPORT PetscSortRemoveDupsInt(PetscInt *n,PetscInt ii[]) 1101db36a52SBarry Smith { 1111db36a52SBarry Smith PetscErrorCode ierr; 1121db36a52SBarry Smith PetscInt i,s = 0,N = *n, b = 0; 1131db36a52SBarry Smith 1141db36a52SBarry Smith PetscFunctionBegin; 1151db36a52SBarry Smith ierr = PetscSortInt(N,ii);CHKERRQ(ierr); 1161db36a52SBarry Smith for (i=0; i<N-1; i++) { 1171db36a52SBarry Smith if (ii[b+s+1] == ii[b]) {ii[b+1] = ii[b+s+2]; s++;} 1181db36a52SBarry Smith else b++; 1191db36a52SBarry Smith } 1201db36a52SBarry Smith *n = N - s; 1211db36a52SBarry Smith PetscFunctionReturn(0); 1221db36a52SBarry Smith } 1231db36a52SBarry Smith 1241db36a52SBarry Smith 125e5c89e4eSSatish Balay /* -----------------------------------------------------------------------*/ 126e5c89e4eSSatish Balay #define SWAP2(a,b,c,d,t) {t=a;a=b;b=t;t=c;c=d;d=t;} 127e5c89e4eSSatish Balay 128e5c89e4eSSatish Balay #undef __FUNCT__ 129e5c89e4eSSatish Balay #define __FUNCT__ "PetscSortIntWithArray_Private" 130e5c89e4eSSatish Balay /* 131e5c89e4eSSatish Balay A simple version of quicksort; taken from Kernighan and Ritchie, page 87. 132e5c89e4eSSatish Balay Assumes 0 origin for v, number of elements = right+1 (right is index of 133e5c89e4eSSatish Balay right-most member). 134e5c89e4eSSatish Balay */ 135e5c89e4eSSatish Balay static PetscErrorCode PetscSortIntWithArray_Private(PetscInt *v,PetscInt *V,PetscInt right) 136e5c89e4eSSatish Balay { 137e5c89e4eSSatish Balay PetscErrorCode ierr; 138e5c89e4eSSatish Balay PetscInt i,vl,last,tmp; 139e5c89e4eSSatish Balay 140e5c89e4eSSatish Balay PetscFunctionBegin; 141e5c89e4eSSatish Balay if (right <= 1) { 142e5c89e4eSSatish Balay if (right == 1) { 143e5c89e4eSSatish Balay if (v[0] > v[1]) SWAP2(v[0],v[1],V[0],V[1],tmp); 144e5c89e4eSSatish Balay } 145e5c89e4eSSatish Balay PetscFunctionReturn(0); 146e5c89e4eSSatish Balay } 147e5c89e4eSSatish Balay SWAP2(v[0],v[right/2],V[0],V[right/2],tmp); 148e5c89e4eSSatish Balay vl = v[0]; 149e5c89e4eSSatish Balay last = 0; 150e5c89e4eSSatish Balay for (i=1; i<=right; i++) { 151e5c89e4eSSatish Balay if (v[i] < vl) {last++; SWAP2(v[last],v[i],V[last],V[i],tmp);} 152e5c89e4eSSatish Balay } 153e5c89e4eSSatish Balay SWAP2(v[0],v[last],V[0],V[last],tmp); 154e5c89e4eSSatish Balay ierr = PetscSortIntWithArray_Private(v,V,last-1);CHKERRQ(ierr); 155e5c89e4eSSatish Balay ierr = PetscSortIntWithArray_Private(v+last+1,V+last+1,right-(last+1));CHKERRQ(ierr); 156e5c89e4eSSatish Balay PetscFunctionReturn(0); 157e5c89e4eSSatish Balay } 158e5c89e4eSSatish Balay 159e5c89e4eSSatish Balay #undef __FUNCT__ 160e5c89e4eSSatish Balay #define __FUNCT__ "PetscSortIntWithArray" 161e5c89e4eSSatish Balay /*@ 162e5c89e4eSSatish Balay PetscSortIntWithArray - Sorts an array of integers in place in increasing order; 163e5c89e4eSSatish Balay changes a second array to match the sorted first array. 164e5c89e4eSSatish Balay 165e5c89e4eSSatish Balay Not Collective 166e5c89e4eSSatish Balay 167e5c89e4eSSatish Balay Input Parameters: 168e5c89e4eSSatish Balay + n - number of values 169e5c89e4eSSatish Balay . i - array of integers 170e5c89e4eSSatish Balay - I - second array of integers 171e5c89e4eSSatish Balay 172e5c89e4eSSatish Balay Level: intermediate 173e5c89e4eSSatish Balay 174e5c89e4eSSatish Balay Concepts: sorting^ints with array 175e5c89e4eSSatish Balay 176e5c89e4eSSatish Balay .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt() 177e5c89e4eSSatish Balay @*/ 1788738c821SJed Brown PetscErrorCode PETSCSYS_DLLEXPORT PetscSortIntWithArray(PetscInt n,PetscInt i[],PetscInt Ii[]) 179e5c89e4eSSatish Balay { 180e5c89e4eSSatish Balay PetscErrorCode ierr; 181e5c89e4eSSatish Balay PetscInt j,k,tmp,ik; 182e5c89e4eSSatish Balay 183e5c89e4eSSatish Balay PetscFunctionBegin; 184e5c89e4eSSatish Balay if (n<8) { 185e5c89e4eSSatish Balay for (k=0; k<n; k++) { 186e5c89e4eSSatish Balay ik = i[k]; 187e5c89e4eSSatish Balay for (j=k+1; j<n; j++) { 188e5c89e4eSSatish Balay if (ik > i[j]) { 189b7940d39SSatish Balay SWAP2(i[k],i[j],Ii[k],Ii[j],tmp); 190e5c89e4eSSatish Balay ik = i[k]; 191e5c89e4eSSatish Balay } 192e5c89e4eSSatish Balay } 193e5c89e4eSSatish Balay } 194e5c89e4eSSatish Balay } else { 195b7940d39SSatish Balay ierr = PetscSortIntWithArray_Private(i,Ii,n-1);CHKERRQ(ierr); 196e5c89e4eSSatish Balay } 197e5c89e4eSSatish Balay PetscFunctionReturn(0); 198e5c89e4eSSatish Balay } 199e5c89e4eSSatish Balay 2004d615ea0SBarry Smith #undef __FUNCT__ 2014d615ea0SBarry Smith #define __FUNCT__ "PetscSortMPIIntWithArray_Private" 2024d615ea0SBarry Smith /* 2034d615ea0SBarry Smith A simple version of quicksort; taken from Kernighan and Ritchie, page 87. 2044d615ea0SBarry Smith Assumes 0 origin for v, number of elements = right+1 (right is index of 2054d615ea0SBarry Smith right-most member). 2064d615ea0SBarry Smith */ 2074d615ea0SBarry Smith static PetscErrorCode PetscSortMPIIntWithArray_Private(PetscMPIInt *v,PetscMPIInt *V,PetscMPIInt right) 2084d615ea0SBarry Smith { 2094d615ea0SBarry Smith PetscErrorCode ierr; 2104d615ea0SBarry Smith PetscMPIInt i,vl,last,tmp; 2114d615ea0SBarry Smith 2124d615ea0SBarry Smith PetscFunctionBegin; 2134d615ea0SBarry Smith if (right <= 1) { 2144d615ea0SBarry Smith if (right == 1) { 2154d615ea0SBarry Smith if (v[0] > v[1]) SWAP2(v[0],v[1],V[0],V[1],tmp); 2164d615ea0SBarry Smith } 2174d615ea0SBarry Smith PetscFunctionReturn(0); 2184d615ea0SBarry Smith } 2194d615ea0SBarry Smith SWAP2(v[0],v[right/2],V[0],V[right/2],tmp); 2204d615ea0SBarry Smith vl = v[0]; 2214d615ea0SBarry Smith last = 0; 2224d615ea0SBarry Smith for (i=1; i<=right; i++) { 2234d615ea0SBarry Smith if (v[i] < vl) {last++; SWAP2(v[last],v[i],V[last],V[i],tmp);} 2244d615ea0SBarry Smith } 2254d615ea0SBarry Smith SWAP2(v[0],v[last],V[0],V[last],tmp); 2264d615ea0SBarry Smith ierr = PetscSortMPIIntWithArray_Private(v,V,last-1);CHKERRQ(ierr); 2274d615ea0SBarry Smith ierr = PetscSortMPIIntWithArray_Private(v+last+1,V+last+1,right-(last+1));CHKERRQ(ierr); 2284d615ea0SBarry Smith PetscFunctionReturn(0); 2294d615ea0SBarry Smith } 2304d615ea0SBarry Smith 2314d615ea0SBarry Smith #undef __FUNCT__ 2324d615ea0SBarry Smith #define __FUNCT__ "PetscSortMPIIntWithArray" 2334d615ea0SBarry Smith /*@ 2344d615ea0SBarry Smith PetscSortMPIIntWithArray - Sorts an array of integers in place in increasing order; 2354d615ea0SBarry Smith changes a second array to match the sorted first array. 2364d615ea0SBarry Smith 2374d615ea0SBarry Smith Not Collective 2384d615ea0SBarry Smith 2394d615ea0SBarry Smith Input Parameters: 2404d615ea0SBarry Smith + n - number of values 2414d615ea0SBarry Smith . i - array of integers 2424d615ea0SBarry Smith - I - second array of integers 2434d615ea0SBarry Smith 2444d615ea0SBarry Smith Level: intermediate 2454d615ea0SBarry Smith 2464d615ea0SBarry Smith Concepts: sorting^ints with array 2474d615ea0SBarry Smith 2484d615ea0SBarry Smith .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt() 2494d615ea0SBarry Smith @*/ 2508738c821SJed Brown PetscErrorCode PETSCSYS_DLLEXPORT PetscSortMPIIntWithArray(PetscMPIInt n,PetscMPIInt i[],PetscMPIInt Ii[]) 2514d615ea0SBarry Smith { 2524d615ea0SBarry Smith PetscErrorCode ierr; 2534d615ea0SBarry Smith PetscMPIInt j,k,tmp,ik; 2544d615ea0SBarry Smith 2554d615ea0SBarry Smith PetscFunctionBegin; 2564d615ea0SBarry Smith if (n<8) { 2574d615ea0SBarry Smith for (k=0; k<n; k++) { 2584d615ea0SBarry Smith ik = i[k]; 2594d615ea0SBarry Smith for (j=k+1; j<n; j++) { 2604d615ea0SBarry Smith if (ik > i[j]) { 2614d615ea0SBarry Smith SWAP2(i[k],i[j],Ii[k],Ii[j],tmp); 2624d615ea0SBarry Smith ik = i[k]; 2634d615ea0SBarry Smith } 2644d615ea0SBarry Smith } 2654d615ea0SBarry Smith } 2664d615ea0SBarry Smith } else { 2674d615ea0SBarry Smith ierr = PetscSortMPIIntWithArray_Private(i,Ii,n-1);CHKERRQ(ierr); 2684d615ea0SBarry Smith } 2694d615ea0SBarry Smith PetscFunctionReturn(0); 2704d615ea0SBarry Smith } 2714d615ea0SBarry Smith 272e5c89e4eSSatish Balay /* -----------------------------------------------------------------------*/ 273e5c89e4eSSatish Balay #define SWAP2IntScalar(a,b,c,d,t,ts) {t=a;a=b;b=t;ts=c;c=d;d=ts;} 274e5c89e4eSSatish Balay 275e5c89e4eSSatish Balay #undef __FUNCT__ 276e5c89e4eSSatish Balay #define __FUNCT__ "PetscSortIntWithScalarArray_Private" 277e5c89e4eSSatish Balay /* 278e5c89e4eSSatish Balay Modified from PetscSortIntWithArray_Private(). 279e5c89e4eSSatish Balay */ 280e5c89e4eSSatish Balay static PetscErrorCode PetscSortIntWithScalarArray_Private(PetscInt *v,PetscScalar *V,PetscInt right) 281e5c89e4eSSatish Balay { 282e5c89e4eSSatish Balay PetscErrorCode ierr; 283e5c89e4eSSatish Balay PetscInt i,vl,last,tmp; 284e5c89e4eSSatish Balay PetscScalar stmp; 285e5c89e4eSSatish Balay 286e5c89e4eSSatish Balay PetscFunctionBegin; 287e5c89e4eSSatish Balay if (right <= 1) { 288e5c89e4eSSatish Balay if (right == 1) { 289e5c89e4eSSatish Balay if (v[0] > v[1]) SWAP2IntScalar(v[0],v[1],V[0],V[1],tmp,stmp); 290e5c89e4eSSatish Balay } 291e5c89e4eSSatish Balay PetscFunctionReturn(0); 292e5c89e4eSSatish Balay } 293e5c89e4eSSatish Balay SWAP2IntScalar(v[0],v[right/2],V[0],V[right/2],tmp,stmp); 294e5c89e4eSSatish Balay vl = v[0]; 295e5c89e4eSSatish Balay last = 0; 296e5c89e4eSSatish Balay for (i=1; i<=right; i++) { 297e5c89e4eSSatish Balay if (v[i] < vl) {last++; SWAP2IntScalar(v[last],v[i],V[last],V[i],tmp,stmp);} 298e5c89e4eSSatish Balay } 299e5c89e4eSSatish Balay SWAP2IntScalar(v[0],v[last],V[0],V[last],tmp,stmp); 300e5c89e4eSSatish Balay ierr = PetscSortIntWithScalarArray_Private(v,V,last-1);CHKERRQ(ierr); 301e5c89e4eSSatish Balay ierr = PetscSortIntWithScalarArray_Private(v+last+1,V+last+1,right-(last+1));CHKERRQ(ierr); 302e5c89e4eSSatish Balay PetscFunctionReturn(0); 303e5c89e4eSSatish Balay } 304e5c89e4eSSatish Balay 305e5c89e4eSSatish Balay #undef __FUNCT__ 306e5c89e4eSSatish Balay #define __FUNCT__ "PetscSortIntWithScalarArray" 307e5c89e4eSSatish Balay /*@ 308e5c89e4eSSatish Balay PetscSortIntWithScalarArray - Sorts an array of integers in place in increasing order; 309e5c89e4eSSatish Balay changes a second SCALAR array to match the sorted first INTEGER array. 310e5c89e4eSSatish Balay 311e5c89e4eSSatish Balay Not Collective 312e5c89e4eSSatish Balay 313e5c89e4eSSatish Balay Input Parameters: 314e5c89e4eSSatish Balay + n - number of values 315e5c89e4eSSatish Balay . i - array of integers 316e5c89e4eSSatish Balay - I - second array of scalars 317e5c89e4eSSatish Balay 318e5c89e4eSSatish Balay Level: intermediate 319e5c89e4eSSatish Balay 320e5c89e4eSSatish Balay Concepts: sorting^ints with array 321e5c89e4eSSatish Balay 322e5c89e4eSSatish Balay .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt(), PetscSortIntWithArray() 323e5c89e4eSSatish Balay @*/ 3248738c821SJed Brown PetscErrorCode PETSCSYS_DLLEXPORT PetscSortIntWithScalarArray(PetscInt n,PetscInt i[],PetscScalar Ii[]) 325e5c89e4eSSatish Balay { 326e5c89e4eSSatish Balay PetscErrorCode ierr; 327e5c89e4eSSatish Balay PetscInt j,k,tmp,ik; 328e5c89e4eSSatish Balay PetscScalar stmp; 329e5c89e4eSSatish Balay 330e5c89e4eSSatish Balay PetscFunctionBegin; 331e5c89e4eSSatish Balay if (n<8) { 332e5c89e4eSSatish Balay for (k=0; k<n; k++) { 333e5c89e4eSSatish Balay ik = i[k]; 334e5c89e4eSSatish Balay for (j=k+1; j<n; j++) { 335e5c89e4eSSatish Balay if (ik > i[j]) { 336b7940d39SSatish Balay SWAP2IntScalar(i[k],i[j],Ii[k],Ii[j],tmp,stmp); 337e5c89e4eSSatish Balay ik = i[k]; 338e5c89e4eSSatish Balay } 339e5c89e4eSSatish Balay } 340e5c89e4eSSatish Balay } 341e5c89e4eSSatish Balay } else { 342b7940d39SSatish Balay ierr = PetscSortIntWithScalarArray_Private(i,Ii,n-1);CHKERRQ(ierr); 343e5c89e4eSSatish Balay } 344e5c89e4eSSatish Balay PetscFunctionReturn(0); 345e5c89e4eSSatish Balay } 346e5c89e4eSSatish Balay 347e5c89e4eSSatish Balay 348