1e5c89e4eSSatish Balay #define PETSC_DLL 2e5c89e4eSSatish Balay /* 3e5c89e4eSSatish Balay This file contains routines for sorting integers. Values are sorted in place. 4e5c89e4eSSatish Balay 5e5c89e4eSSatish Balay 6e5c89e4eSSatish Balay The word "register" in this code is used to identify data that is not 7e5c89e4eSSatish Balay aliased. For some compilers, marking variables as register can improve 8e5c89e4eSSatish Balay the compiler optimizations. 9e5c89e4eSSatish Balay */ 10*d382aafbSBarry Smith #include "petscsys.h" /*I "petscsys.h" I*/ 11e5c89e4eSSatish Balay 12e5c89e4eSSatish Balay #define SWAP(a,b,t) {t=a;a=b;b=t;} 13e5c89e4eSSatish Balay 14e5c89e4eSSatish Balay /* -----------------------------------------------------------------------*/ 15e5c89e4eSSatish Balay 16e5c89e4eSSatish Balay #undef __FUNCT__ 17e5c89e4eSSatish Balay #define __FUNCT__ "PetscSortInt_Private" 18e5c89e4eSSatish Balay /* 19e5c89e4eSSatish Balay A simple version of quicksort; taken from Kernighan and Ritchie, page 87. 20e5c89e4eSSatish Balay Assumes 0 origin for v, number of elements = right+1 (right is index of 21e5c89e4eSSatish Balay right-most member). 22e5c89e4eSSatish Balay */ 23e5c89e4eSSatish Balay static PetscErrorCode PetscSortInt_Private(PetscInt *v,PetscInt right) 24e5c89e4eSSatish Balay { 25e5c89e4eSSatish Balay PetscErrorCode ierr; 26e5c89e4eSSatish Balay PetscInt i,vl,last,tmp; 27e5c89e4eSSatish Balay 28e5c89e4eSSatish Balay PetscFunctionBegin; 29e5c89e4eSSatish Balay if (right <= 1) { 30e5c89e4eSSatish Balay if (right == 1) { 31e5c89e4eSSatish Balay if (v[0] > v[1]) SWAP(v[0],v[1],tmp); 32e5c89e4eSSatish Balay } 33e5c89e4eSSatish Balay PetscFunctionReturn(0); 34e5c89e4eSSatish Balay } 35e5c89e4eSSatish Balay SWAP(v[0],v[right/2],tmp); 36e5c89e4eSSatish Balay vl = v[0]; 37e5c89e4eSSatish Balay last = 0; 38e5c89e4eSSatish Balay for (i=1; i<=right; i++) { 39e5c89e4eSSatish Balay if (v[i] < vl) {last++; SWAP(v[last],v[i],tmp);} 40e5c89e4eSSatish Balay } 41e5c89e4eSSatish Balay SWAP(v[0],v[last],tmp); 42e5c89e4eSSatish Balay ierr = PetscSortInt_Private(v,last-1);CHKERRQ(ierr); 43e5c89e4eSSatish Balay ierr = PetscSortInt_Private(v+last+1,right-(last+1));CHKERRQ(ierr); 44e5c89e4eSSatish Balay PetscFunctionReturn(0); 45e5c89e4eSSatish Balay } 46e5c89e4eSSatish Balay 47e5c89e4eSSatish Balay #undef __FUNCT__ 48e5c89e4eSSatish Balay #define __FUNCT__ "PetscSortInt" 49e5c89e4eSSatish Balay /*@ 50e5c89e4eSSatish Balay PetscSortInt - Sorts an array of integers in place in increasing order. 51e5c89e4eSSatish Balay 52e5c89e4eSSatish Balay Not Collective 53e5c89e4eSSatish Balay 54e5c89e4eSSatish Balay Input Parameters: 55e5c89e4eSSatish Balay + n - number of values 56e5c89e4eSSatish Balay - i - array of integers 57e5c89e4eSSatish Balay 58e5c89e4eSSatish Balay Level: intermediate 59e5c89e4eSSatish Balay 60e5c89e4eSSatish Balay Concepts: sorting^ints 61e5c89e4eSSatish Balay 62e5c89e4eSSatish Balay .seealso: PetscSortReal(), PetscSortIntWithPermutation() 63e5c89e4eSSatish Balay @*/ 64e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscSortInt(PetscInt n,PetscInt i[]) 65e5c89e4eSSatish Balay { 66e5c89e4eSSatish Balay PetscErrorCode ierr; 67e5c89e4eSSatish Balay PetscInt j,k,tmp,ik; 68e5c89e4eSSatish Balay 69e5c89e4eSSatish Balay PetscFunctionBegin; 70e5c89e4eSSatish Balay if (n<8) { 71e5c89e4eSSatish Balay for (k=0; k<n; k++) { 72e5c89e4eSSatish Balay ik = i[k]; 73e5c89e4eSSatish Balay for (j=k+1; j<n; j++) { 74e5c89e4eSSatish Balay if (ik > i[j]) { 75e5c89e4eSSatish Balay SWAP(i[k],i[j],tmp); 76e5c89e4eSSatish Balay ik = i[k]; 77e5c89e4eSSatish Balay } 78e5c89e4eSSatish Balay } 79e5c89e4eSSatish Balay } 80e5c89e4eSSatish Balay } else { 81e5c89e4eSSatish Balay ierr = PetscSortInt_Private(i,n-1);CHKERRQ(ierr); 82e5c89e4eSSatish Balay } 83e5c89e4eSSatish Balay PetscFunctionReturn(0); 84e5c89e4eSSatish Balay } 85e5c89e4eSSatish Balay 86e5c89e4eSSatish Balay /* -----------------------------------------------------------------------*/ 87e5c89e4eSSatish Balay #define SWAP2(a,b,c,d,t) {t=a;a=b;b=t;t=c;c=d;d=t;} 88e5c89e4eSSatish Balay 89e5c89e4eSSatish Balay #undef __FUNCT__ 90e5c89e4eSSatish Balay #define __FUNCT__ "PetscSortIntWithArray_Private" 91e5c89e4eSSatish Balay /* 92e5c89e4eSSatish Balay A simple version of quicksort; taken from Kernighan and Ritchie, page 87. 93e5c89e4eSSatish Balay Assumes 0 origin for v, number of elements = right+1 (right is index of 94e5c89e4eSSatish Balay right-most member). 95e5c89e4eSSatish Balay */ 96e5c89e4eSSatish Balay static PetscErrorCode PetscSortIntWithArray_Private(PetscInt *v,PetscInt *V,PetscInt right) 97e5c89e4eSSatish Balay { 98e5c89e4eSSatish Balay PetscErrorCode ierr; 99e5c89e4eSSatish Balay PetscInt i,vl,last,tmp; 100e5c89e4eSSatish Balay 101e5c89e4eSSatish Balay PetscFunctionBegin; 102e5c89e4eSSatish Balay if (right <= 1) { 103e5c89e4eSSatish Balay if (right == 1) { 104e5c89e4eSSatish Balay if (v[0] > v[1]) SWAP2(v[0],v[1],V[0],V[1],tmp); 105e5c89e4eSSatish Balay } 106e5c89e4eSSatish Balay PetscFunctionReturn(0); 107e5c89e4eSSatish Balay } 108e5c89e4eSSatish Balay SWAP2(v[0],v[right/2],V[0],V[right/2],tmp); 109e5c89e4eSSatish Balay vl = v[0]; 110e5c89e4eSSatish Balay last = 0; 111e5c89e4eSSatish Balay for (i=1; i<=right; i++) { 112e5c89e4eSSatish Balay if (v[i] < vl) {last++; SWAP2(v[last],v[i],V[last],V[i],tmp);} 113e5c89e4eSSatish Balay } 114e5c89e4eSSatish Balay SWAP2(v[0],v[last],V[0],V[last],tmp); 115e5c89e4eSSatish Balay ierr = PetscSortIntWithArray_Private(v,V,last-1);CHKERRQ(ierr); 116e5c89e4eSSatish Balay ierr = PetscSortIntWithArray_Private(v+last+1,V+last+1,right-(last+1));CHKERRQ(ierr); 117e5c89e4eSSatish Balay PetscFunctionReturn(0); 118e5c89e4eSSatish Balay } 119e5c89e4eSSatish Balay 120e5c89e4eSSatish Balay #undef __FUNCT__ 121e5c89e4eSSatish Balay #define __FUNCT__ "PetscSortIntWithArray" 122e5c89e4eSSatish Balay /*@ 123e5c89e4eSSatish Balay PetscSortIntWithArray - Sorts an array of integers in place in increasing order; 124e5c89e4eSSatish Balay changes a second array to match the sorted first array. 125e5c89e4eSSatish Balay 126e5c89e4eSSatish Balay Not Collective 127e5c89e4eSSatish Balay 128e5c89e4eSSatish Balay Input Parameters: 129e5c89e4eSSatish Balay + n - number of values 130e5c89e4eSSatish Balay . i - array of integers 131e5c89e4eSSatish Balay - I - second array of integers 132e5c89e4eSSatish Balay 133e5c89e4eSSatish Balay Level: intermediate 134e5c89e4eSSatish Balay 135e5c89e4eSSatish Balay Concepts: sorting^ints with array 136e5c89e4eSSatish Balay 137e5c89e4eSSatish Balay .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt() 138e5c89e4eSSatish Balay @*/ 139b7940d39SSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscSortIntWithArray(PetscInt n,PetscInt i[],PetscInt Ii[]) 140e5c89e4eSSatish Balay { 141e5c89e4eSSatish Balay PetscErrorCode ierr; 142e5c89e4eSSatish Balay PetscInt j,k,tmp,ik; 143e5c89e4eSSatish Balay 144e5c89e4eSSatish Balay PetscFunctionBegin; 145e5c89e4eSSatish Balay if (n<8) { 146e5c89e4eSSatish Balay for (k=0; k<n; k++) { 147e5c89e4eSSatish Balay ik = i[k]; 148e5c89e4eSSatish Balay for (j=k+1; j<n; j++) { 149e5c89e4eSSatish Balay if (ik > i[j]) { 150b7940d39SSatish Balay SWAP2(i[k],i[j],Ii[k],Ii[j],tmp); 151e5c89e4eSSatish Balay ik = i[k]; 152e5c89e4eSSatish Balay } 153e5c89e4eSSatish Balay } 154e5c89e4eSSatish Balay } 155e5c89e4eSSatish Balay } else { 156b7940d39SSatish Balay ierr = PetscSortIntWithArray_Private(i,Ii,n-1);CHKERRQ(ierr); 157e5c89e4eSSatish Balay } 158e5c89e4eSSatish Balay PetscFunctionReturn(0); 159e5c89e4eSSatish Balay } 160e5c89e4eSSatish Balay 1614d615ea0SBarry Smith #undef __FUNCT__ 1624d615ea0SBarry Smith #define __FUNCT__ "PetscSortMPIIntWithArray_Private" 1634d615ea0SBarry Smith /* 1644d615ea0SBarry Smith A simple version of quicksort; taken from Kernighan and Ritchie, page 87. 1654d615ea0SBarry Smith Assumes 0 origin for v, number of elements = right+1 (right is index of 1664d615ea0SBarry Smith right-most member). 1674d615ea0SBarry Smith */ 1684d615ea0SBarry Smith static PetscErrorCode PetscSortMPIIntWithArray_Private(PetscMPIInt *v,PetscMPIInt *V,PetscMPIInt right) 1694d615ea0SBarry Smith { 1704d615ea0SBarry Smith PetscErrorCode ierr; 1714d615ea0SBarry Smith PetscMPIInt i,vl,last,tmp; 1724d615ea0SBarry Smith 1734d615ea0SBarry Smith PetscFunctionBegin; 1744d615ea0SBarry Smith if (right <= 1) { 1754d615ea0SBarry Smith if (right == 1) { 1764d615ea0SBarry Smith if (v[0] > v[1]) SWAP2(v[0],v[1],V[0],V[1],tmp); 1774d615ea0SBarry Smith } 1784d615ea0SBarry Smith PetscFunctionReturn(0); 1794d615ea0SBarry Smith } 1804d615ea0SBarry Smith SWAP2(v[0],v[right/2],V[0],V[right/2],tmp); 1814d615ea0SBarry Smith vl = v[0]; 1824d615ea0SBarry Smith last = 0; 1834d615ea0SBarry Smith for (i=1; i<=right; i++) { 1844d615ea0SBarry Smith if (v[i] < vl) {last++; SWAP2(v[last],v[i],V[last],V[i],tmp);} 1854d615ea0SBarry Smith } 1864d615ea0SBarry Smith SWAP2(v[0],v[last],V[0],V[last],tmp); 1874d615ea0SBarry Smith ierr = PetscSortMPIIntWithArray_Private(v,V,last-1);CHKERRQ(ierr); 1884d615ea0SBarry Smith ierr = PetscSortMPIIntWithArray_Private(v+last+1,V+last+1,right-(last+1));CHKERRQ(ierr); 1894d615ea0SBarry Smith PetscFunctionReturn(0); 1904d615ea0SBarry Smith } 1914d615ea0SBarry Smith 1924d615ea0SBarry Smith #undef __FUNCT__ 1934d615ea0SBarry Smith #define __FUNCT__ "PetscSortMPIIntWithArray" 1944d615ea0SBarry Smith /*@ 1954d615ea0SBarry Smith PetscSortMPIIntWithArray - Sorts an array of integers in place in increasing order; 1964d615ea0SBarry Smith changes a second array to match the sorted first array. 1974d615ea0SBarry Smith 1984d615ea0SBarry Smith Not Collective 1994d615ea0SBarry Smith 2004d615ea0SBarry Smith Input Parameters: 2014d615ea0SBarry Smith + n - number of values 2024d615ea0SBarry Smith . i - array of integers 2034d615ea0SBarry Smith - I - second array of integers 2044d615ea0SBarry Smith 2054d615ea0SBarry Smith Level: intermediate 2064d615ea0SBarry Smith 2074d615ea0SBarry Smith Concepts: sorting^ints with array 2084d615ea0SBarry Smith 2094d615ea0SBarry Smith .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt() 2104d615ea0SBarry Smith @*/ 2114d615ea0SBarry Smith PetscErrorCode PETSC_DLLEXPORT PetscSortMPIIntWithArray(PetscMPIInt n,PetscMPIInt i[],PetscMPIInt Ii[]) 2124d615ea0SBarry Smith { 2134d615ea0SBarry Smith PetscErrorCode ierr; 2144d615ea0SBarry Smith PetscMPIInt j,k,tmp,ik; 2154d615ea0SBarry Smith 2164d615ea0SBarry Smith PetscFunctionBegin; 2174d615ea0SBarry Smith if (n<8) { 2184d615ea0SBarry Smith for (k=0; k<n; k++) { 2194d615ea0SBarry Smith ik = i[k]; 2204d615ea0SBarry Smith for (j=k+1; j<n; j++) { 2214d615ea0SBarry Smith if (ik > i[j]) { 2224d615ea0SBarry Smith SWAP2(i[k],i[j],Ii[k],Ii[j],tmp); 2234d615ea0SBarry Smith ik = i[k]; 2244d615ea0SBarry Smith } 2254d615ea0SBarry Smith } 2264d615ea0SBarry Smith } 2274d615ea0SBarry Smith } else { 2284d615ea0SBarry Smith ierr = PetscSortMPIIntWithArray_Private(i,Ii,n-1);CHKERRQ(ierr); 2294d615ea0SBarry Smith } 2304d615ea0SBarry Smith PetscFunctionReturn(0); 2314d615ea0SBarry Smith } 2324d615ea0SBarry Smith 233e5c89e4eSSatish Balay /* -----------------------------------------------------------------------*/ 234e5c89e4eSSatish Balay #define SWAP2IntScalar(a,b,c,d,t,ts) {t=a;a=b;b=t;ts=c;c=d;d=ts;} 235e5c89e4eSSatish Balay 236e5c89e4eSSatish Balay #undef __FUNCT__ 237e5c89e4eSSatish Balay #define __FUNCT__ "PetscSortIntWithScalarArray_Private" 238e5c89e4eSSatish Balay /* 239e5c89e4eSSatish Balay Modified from PetscSortIntWithArray_Private(). 240e5c89e4eSSatish Balay */ 241e5c89e4eSSatish Balay static PetscErrorCode PetscSortIntWithScalarArray_Private(PetscInt *v,PetscScalar *V,PetscInt right) 242e5c89e4eSSatish Balay { 243e5c89e4eSSatish Balay PetscErrorCode ierr; 244e5c89e4eSSatish Balay PetscInt i,vl,last,tmp; 245e5c89e4eSSatish Balay PetscScalar stmp; 246e5c89e4eSSatish Balay 247e5c89e4eSSatish Balay PetscFunctionBegin; 248e5c89e4eSSatish Balay if (right <= 1) { 249e5c89e4eSSatish Balay if (right == 1) { 250e5c89e4eSSatish Balay if (v[0] > v[1]) SWAP2IntScalar(v[0],v[1],V[0],V[1],tmp,stmp); 251e5c89e4eSSatish Balay } 252e5c89e4eSSatish Balay PetscFunctionReturn(0); 253e5c89e4eSSatish Balay } 254e5c89e4eSSatish Balay SWAP2IntScalar(v[0],v[right/2],V[0],V[right/2],tmp,stmp); 255e5c89e4eSSatish Balay vl = v[0]; 256e5c89e4eSSatish Balay last = 0; 257e5c89e4eSSatish Balay for (i=1; i<=right; i++) { 258e5c89e4eSSatish Balay if (v[i] < vl) {last++; SWAP2IntScalar(v[last],v[i],V[last],V[i],tmp,stmp);} 259e5c89e4eSSatish Balay } 260e5c89e4eSSatish Balay SWAP2IntScalar(v[0],v[last],V[0],V[last],tmp,stmp); 261e5c89e4eSSatish Balay ierr = PetscSortIntWithScalarArray_Private(v,V,last-1);CHKERRQ(ierr); 262e5c89e4eSSatish Balay ierr = PetscSortIntWithScalarArray_Private(v+last+1,V+last+1,right-(last+1));CHKERRQ(ierr); 263e5c89e4eSSatish Balay PetscFunctionReturn(0); 264e5c89e4eSSatish Balay } 265e5c89e4eSSatish Balay 266e5c89e4eSSatish Balay #undef __FUNCT__ 267e5c89e4eSSatish Balay #define __FUNCT__ "PetscSortIntWithScalarArray" 268e5c89e4eSSatish Balay /*@ 269e5c89e4eSSatish Balay PetscSortIntWithScalarArray - Sorts an array of integers in place in increasing order; 270e5c89e4eSSatish Balay changes a second SCALAR array to match the sorted first INTEGER array. 271e5c89e4eSSatish Balay 272e5c89e4eSSatish Balay Not Collective 273e5c89e4eSSatish Balay 274e5c89e4eSSatish Balay Input Parameters: 275e5c89e4eSSatish Balay + n - number of values 276e5c89e4eSSatish Balay . i - array of integers 277e5c89e4eSSatish Balay - I - second array of scalars 278e5c89e4eSSatish Balay 279e5c89e4eSSatish Balay Level: intermediate 280e5c89e4eSSatish Balay 281e5c89e4eSSatish Balay Concepts: sorting^ints with array 282e5c89e4eSSatish Balay 283e5c89e4eSSatish Balay .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt(), PetscSortIntWithArray() 284e5c89e4eSSatish Balay @*/ 285b7940d39SSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscSortIntWithScalarArray(PetscInt n,PetscInt i[],PetscScalar Ii[]) 286e5c89e4eSSatish Balay { 287e5c89e4eSSatish Balay PetscErrorCode ierr; 288e5c89e4eSSatish Balay PetscInt j,k,tmp,ik; 289e5c89e4eSSatish Balay PetscScalar stmp; 290e5c89e4eSSatish Balay 291e5c89e4eSSatish Balay PetscFunctionBegin; 292e5c89e4eSSatish Balay if (n<8) { 293e5c89e4eSSatish Balay for (k=0; k<n; k++) { 294e5c89e4eSSatish Balay ik = i[k]; 295e5c89e4eSSatish Balay for (j=k+1; j<n; j++) { 296e5c89e4eSSatish Balay if (ik > i[j]) { 297b7940d39SSatish Balay SWAP2IntScalar(i[k],i[j],Ii[k],Ii[j],tmp,stmp); 298e5c89e4eSSatish Balay ik = i[k]; 299e5c89e4eSSatish Balay } 300e5c89e4eSSatish Balay } 301e5c89e4eSSatish Balay } 302e5c89e4eSSatish Balay } else { 303b7940d39SSatish Balay ierr = PetscSortIntWithScalarArray_Private(i,Ii,n-1);CHKERRQ(ierr); 304e5c89e4eSSatish Balay } 305e5c89e4eSSatish Balay PetscFunctionReturn(0); 306e5c89e4eSSatish Balay } 307e5c89e4eSSatish Balay 308e5c89e4eSSatish Balay 309