17d0a6c19SBarry Smith 2e5c89e4eSSatish Balay /* 3e5c89e4eSSatish Balay This file contains routines for sorting integers. Values are sorted in place. 4e5c89e4eSSatish Balay */ 5af0996ceSBarry Smith #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/ 6e5c89e4eSSatish Balay 7e5c89e4eSSatish Balay #define SWAP(a,b,t) {t=a;a=b;b=t;} 8e5c89e4eSSatish Balay 9a8582168SJed Brown #define MEDIAN3(v,a,b,c) \ 10a8582168SJed Brown (v[a]<v[b] \ 11a8582168SJed Brown ? (v[b]<v[c] \ 12a8582168SJed Brown ? b \ 13a8582168SJed Brown : (v[a]<v[c] ? c : a)) \ 14a8582168SJed Brown : (v[c]<v[b] \ 15a8582168SJed Brown ? b \ 16a8582168SJed Brown : (v[a]<v[c] ? a : c))) 17a8582168SJed Brown 18a8582168SJed Brown #define MEDIAN(v,right) MEDIAN3(v,right/4,right/2,right/4*3) 19ef8e3583SJed Brown 20e5c89e4eSSatish Balay /* -----------------------------------------------------------------------*/ 21e5c89e4eSSatish Balay 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 */ 27ef8e3583SJed Brown static void PetscSortInt_Private(PetscInt *v,PetscInt right) 28e5c89e4eSSatish Balay { 29ef8e3583SJed 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 } 35ef8e3583SJed Brown return; 36e5c89e4eSSatish Balay } 37ef8e3583SJed Brown i = MEDIAN(v,right); /* Choose a pivot */ 38ef8e3583SJed Brown SWAP(v[0],v[i],tmp); /* Move it out of the way */ 39ef8e3583SJed Brown pivot = v[0]; 40ef8e3583SJed Brown for (i=0,j=right+1;; ) { 41ef8e3583SJed Brown while (++i < j && v[i] <= pivot) ; /* Scan from the left */ 42ef8e3583SJed Brown while (v[--j] > pivot) ; /* Scan from the right */ 43ef8e3583SJed Brown if (i >= j) break; 44ef8e3583SJed Brown SWAP(v[i],v[j],tmp); 45e5c89e4eSSatish Balay } 46ef8e3583SJed Brown SWAP(v[0],v[j],tmp); /* Put pivot back in place. */ 47ef8e3583SJed Brown PetscSortInt_Private(v,j-1); 48ef8e3583SJed Brown PetscSortInt_Private(v+j+1,right-(j+1)); 49e5c89e4eSSatish Balay } 50e5c89e4eSSatish Balay 51e5c89e4eSSatish Balay /*@ 52e5c89e4eSSatish Balay PetscSortInt - Sorts an array of integers in place in increasing order. 53e5c89e4eSSatish Balay 54e5c89e4eSSatish Balay Not Collective 55e5c89e4eSSatish Balay 56e5c89e4eSSatish Balay Input Parameters: 57e5c89e4eSSatish Balay + n - number of values 58e5c89e4eSSatish Balay - i - array of integers 59e5c89e4eSSatish Balay 60e5c89e4eSSatish Balay Level: intermediate 61e5c89e4eSSatish Balay 62e5c89e4eSSatish Balay .seealso: PetscSortReal(), PetscSortIntWithPermutation() 63e5c89e4eSSatish Balay @*/ 647087cfbeSBarry Smith PetscErrorCode PetscSortInt(PetscInt n,PetscInt i[]) 65e5c89e4eSSatish Balay { 66e5c89e4eSSatish Balay PetscInt j,k,tmp,ik; 67e5c89e4eSSatish Balay 68e5c89e4eSSatish Balay PetscFunctionBegin; 69e5c89e4eSSatish Balay if (n<8) { 70e5c89e4eSSatish Balay for (k=0; k<n; k++) { 71e5c89e4eSSatish Balay ik = i[k]; 72e5c89e4eSSatish Balay for (j=k+1; j<n; j++) { 73e5c89e4eSSatish Balay if (ik > i[j]) { 74e5c89e4eSSatish Balay SWAP(i[k],i[j],tmp); 75e5c89e4eSSatish Balay ik = i[k]; 76e5c89e4eSSatish Balay } 77e5c89e4eSSatish Balay } 78e5c89e4eSSatish Balay } 79a297a907SKarl Rupp } else PetscSortInt_Private(i,n-1); 80e5c89e4eSSatish Balay PetscFunctionReturn(0); 81e5c89e4eSSatish Balay } 82e5c89e4eSSatish Balay 831db36a52SBarry Smith /*@ 8422ab5688SLisandro Dalcin PetscSortedRemoveDupsInt - Removes all duplicate entries of a sorted input array 8522ab5688SLisandro Dalcin 8622ab5688SLisandro Dalcin Not Collective 8722ab5688SLisandro Dalcin 8822ab5688SLisandro Dalcin Input Parameters: 8922ab5688SLisandro Dalcin + n - number of values 9022ab5688SLisandro Dalcin - ii - sorted array of integers 9122ab5688SLisandro Dalcin 9222ab5688SLisandro Dalcin Output Parameter: 9322ab5688SLisandro Dalcin . n - number of non-redundant values 9422ab5688SLisandro Dalcin 9522ab5688SLisandro Dalcin Level: intermediate 9622ab5688SLisandro Dalcin 9722ab5688SLisandro Dalcin .seealso: PetscSortInt() 9822ab5688SLisandro Dalcin @*/ 9922ab5688SLisandro Dalcin PetscErrorCode PetscSortedRemoveDupsInt(PetscInt *n,PetscInt ii[]) 10022ab5688SLisandro Dalcin { 10122ab5688SLisandro Dalcin PetscInt i,s = 0,N = *n, b = 0; 10222ab5688SLisandro Dalcin 10322ab5688SLisandro Dalcin PetscFunctionBegin; 10422ab5688SLisandro Dalcin for (i=0; i<N-1; i++) { 10522ab5688SLisandro Dalcin if (PetscUnlikely(ii[b+s+1] < ii[b])) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Input array is not sorted"); 10622ab5688SLisandro Dalcin if (ii[b+s+1] != ii[b]) { 10722ab5688SLisandro Dalcin ii[b+1] = ii[b+s+1]; b++; 10822ab5688SLisandro Dalcin } else s++; 10922ab5688SLisandro Dalcin } 11022ab5688SLisandro Dalcin *n = N - s; 11122ab5688SLisandro Dalcin PetscFunctionReturn(0); 11222ab5688SLisandro Dalcin } 11322ab5688SLisandro Dalcin 11422ab5688SLisandro Dalcin /*@ 1151db36a52SBarry Smith PetscSortRemoveDupsInt - Sorts an array of integers in place in increasing order removes all duplicate entries 1161db36a52SBarry Smith 1171db36a52SBarry Smith Not Collective 1181db36a52SBarry Smith 1191db36a52SBarry Smith Input Parameters: 1201db36a52SBarry Smith + n - number of values 1211db36a52SBarry Smith - ii - array of integers 1221db36a52SBarry Smith 1231db36a52SBarry Smith Output Parameter: 1241db36a52SBarry Smith . n - number of non-redundant values 1251db36a52SBarry Smith 1261db36a52SBarry Smith Level: intermediate 1271db36a52SBarry Smith 12822ab5688SLisandro Dalcin .seealso: PetscSortReal(), PetscSortIntWithPermutation(), PetscSortInt(), PetscSortedRemoveDupsInt() 1291db36a52SBarry Smith @*/ 1307087cfbeSBarry Smith PetscErrorCode PetscSortRemoveDupsInt(PetscInt *n,PetscInt ii[]) 1311db36a52SBarry Smith { 1321db36a52SBarry Smith PetscErrorCode ierr; 1331db36a52SBarry Smith 1341db36a52SBarry Smith PetscFunctionBegin; 13522ab5688SLisandro Dalcin ierr = PetscSortInt(*n,ii);CHKERRQ(ierr); 13622ab5688SLisandro Dalcin ierr = PetscSortedRemoveDupsInt(n,ii);CHKERRQ(ierr); 1371db36a52SBarry Smith PetscFunctionReturn(0); 1381db36a52SBarry Smith } 1391db36a52SBarry Smith 14060e03357SMatthew G Knepley /*@ 141d9f1162dSJed Brown PetscFindInt - Finds integer in a sorted array of integers 14260e03357SMatthew G Knepley 14360e03357SMatthew G Knepley Not Collective 14460e03357SMatthew G Knepley 14560e03357SMatthew G Knepley Input Parameters: 14660e03357SMatthew G Knepley + key - the integer to locate 147d9f1162dSJed Brown . n - number of values in the array 14860e03357SMatthew G Knepley - ii - array of integers 14960e03357SMatthew G Knepley 15060e03357SMatthew G Knepley Output Parameter: 151d9f1162dSJed Brown . loc - the location if found, otherwise -(slot+1) where slot is the place the value would go 15260e03357SMatthew G Knepley 15360e03357SMatthew G Knepley Level: intermediate 15460e03357SMatthew G Knepley 15560e03357SMatthew G Knepley .seealso: PetscSortInt(), PetscSortIntWithArray(), PetscSortRemoveDupsInt() 15660e03357SMatthew G Knepley @*/ 157026ec6cbSMatthew G Knepley PetscErrorCode PetscFindInt(PetscInt key, PetscInt n, const PetscInt ii[], PetscInt *loc) 15860e03357SMatthew G Knepley { 159d9f1162dSJed Brown PetscInt lo = 0,hi = n; 16060e03357SMatthew G Knepley 16160e03357SMatthew G Knepley PetscFunctionBegin; 16260e03357SMatthew G Knepley PetscValidPointer(loc,4); 16398781d82SMatthew G Knepley if (!n) {*loc = -1; PetscFunctionReturn(0);} 16498781d82SMatthew G Knepley PetscValidPointer(ii,3); 165d9f1162dSJed Brown while (hi - lo > 1) { 166d9f1162dSJed Brown PetscInt mid = lo + (hi - lo)/2; 167d9f1162dSJed Brown if (key < ii[mid]) hi = mid; 168d9f1162dSJed Brown else lo = mid; 16960e03357SMatthew G Knepley } 170d9f1162dSJed Brown *loc = key == ii[lo] ? lo : -(lo + (key > ii[lo]) + 1); 17160e03357SMatthew G Knepley PetscFunctionReturn(0); 17260e03357SMatthew G Knepley } 17360e03357SMatthew G Knepley 174d2aeb606SJed Brown /*@ 175d2aeb606SJed Brown PetscFindMPIInt - Finds MPI integer in a sorted array of integers 176d2aeb606SJed Brown 177d2aeb606SJed Brown Not Collective 178d2aeb606SJed Brown 179d2aeb606SJed Brown Input Parameters: 180d2aeb606SJed Brown + key - the integer to locate 181d2aeb606SJed Brown . n - number of values in the array 182d2aeb606SJed Brown - ii - array of integers 183d2aeb606SJed Brown 184d2aeb606SJed Brown Output Parameter: 185d2aeb606SJed Brown . loc - the location if found, otherwise -(slot+1) where slot is the place the value would go 186d2aeb606SJed Brown 187d2aeb606SJed Brown Level: intermediate 188d2aeb606SJed Brown 189d2aeb606SJed Brown .seealso: PetscSortInt(), PetscSortIntWithArray(), PetscSortRemoveDupsInt() 190d2aeb606SJed Brown @*/ 191d2aeb606SJed Brown PetscErrorCode PetscFindMPIInt(PetscMPIInt key, PetscInt n, const PetscMPIInt ii[], PetscInt *loc) 192d2aeb606SJed Brown { 193d2aeb606SJed Brown PetscInt lo = 0,hi = n; 194d2aeb606SJed Brown 195d2aeb606SJed Brown PetscFunctionBegin; 196d2aeb606SJed Brown PetscValidPointer(loc,4); 197d2aeb606SJed Brown if (!n) {*loc = -1; PetscFunctionReturn(0);} 198d2aeb606SJed Brown PetscValidPointer(ii,3); 199d2aeb606SJed Brown while (hi - lo > 1) { 200d2aeb606SJed Brown PetscInt mid = lo + (hi - lo)/2; 201d2aeb606SJed Brown if (key < ii[mid]) hi = mid; 202d2aeb606SJed Brown else lo = mid; 203d2aeb606SJed Brown } 204d2aeb606SJed Brown *loc = key == ii[lo] ? lo : -(lo + (key > ii[lo]) + 1); 205d2aeb606SJed Brown PetscFunctionReturn(0); 206d2aeb606SJed Brown } 2071db36a52SBarry Smith 208e5c89e4eSSatish Balay /* -----------------------------------------------------------------------*/ 209e5c89e4eSSatish Balay #define SWAP2(a,b,c,d,t) {t=a;a=b;b=t;t=c;c=d;d=t;} 210e5c89e4eSSatish Balay 211e5c89e4eSSatish Balay /* 212e5c89e4eSSatish Balay A simple version of quicksort; taken from Kernighan and Ritchie, page 87. 213e5c89e4eSSatish Balay Assumes 0 origin for v, number of elements = right+1 (right is index of 214e5c89e4eSSatish Balay right-most member). 215e5c89e4eSSatish Balay */ 216e5c89e4eSSatish Balay static PetscErrorCode PetscSortIntWithArray_Private(PetscInt *v,PetscInt *V,PetscInt right) 217e5c89e4eSSatish Balay { 218e5c89e4eSSatish Balay PetscErrorCode ierr; 219e5c89e4eSSatish Balay PetscInt i,vl,last,tmp; 220e5c89e4eSSatish Balay 221e5c89e4eSSatish Balay PetscFunctionBegin; 222e5c89e4eSSatish Balay if (right <= 1) { 223e5c89e4eSSatish Balay if (right == 1) { 224e5c89e4eSSatish Balay if (v[0] > v[1]) SWAP2(v[0],v[1],V[0],V[1],tmp); 225e5c89e4eSSatish Balay } 226e5c89e4eSSatish Balay PetscFunctionReturn(0); 227e5c89e4eSSatish Balay } 228e5c89e4eSSatish Balay SWAP2(v[0],v[right/2],V[0],V[right/2],tmp); 229e5c89e4eSSatish Balay vl = v[0]; 230e5c89e4eSSatish Balay last = 0; 231e5c89e4eSSatish Balay for (i=1; i<=right; i++) { 232e5c89e4eSSatish Balay if (v[i] < vl) {last++; SWAP2(v[last],v[i],V[last],V[i],tmp);} 233e5c89e4eSSatish Balay } 234e5c89e4eSSatish Balay SWAP2(v[0],v[last],V[0],V[last],tmp); 235e5c89e4eSSatish Balay ierr = PetscSortIntWithArray_Private(v,V,last-1);CHKERRQ(ierr); 236e5c89e4eSSatish Balay ierr = PetscSortIntWithArray_Private(v+last+1,V+last+1,right-(last+1));CHKERRQ(ierr); 237e5c89e4eSSatish Balay PetscFunctionReturn(0); 238e5c89e4eSSatish Balay } 239e5c89e4eSSatish Balay 240e5c89e4eSSatish Balay /*@ 241e5c89e4eSSatish Balay PetscSortIntWithArray - Sorts an array of integers in place in increasing order; 242e5c89e4eSSatish Balay changes a second array to match the sorted first array. 243e5c89e4eSSatish Balay 244e5c89e4eSSatish Balay Not Collective 245e5c89e4eSSatish Balay 246e5c89e4eSSatish Balay Input Parameters: 247e5c89e4eSSatish Balay + n - number of values 248e5c89e4eSSatish Balay . i - array of integers 249e5c89e4eSSatish Balay - I - second array of integers 250e5c89e4eSSatish Balay 251e5c89e4eSSatish Balay Level: intermediate 252e5c89e4eSSatish Balay 253e5c89e4eSSatish Balay .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt() 254e5c89e4eSSatish Balay @*/ 2557087cfbeSBarry Smith PetscErrorCode PetscSortIntWithArray(PetscInt n,PetscInt i[],PetscInt Ii[]) 256e5c89e4eSSatish Balay { 257e5c89e4eSSatish Balay PetscErrorCode ierr; 258e5c89e4eSSatish Balay PetscInt j,k,tmp,ik; 259e5c89e4eSSatish Balay 260e5c89e4eSSatish Balay PetscFunctionBegin; 261e5c89e4eSSatish Balay if (n<8) { 262e5c89e4eSSatish Balay for (k=0; k<n; k++) { 263e5c89e4eSSatish Balay ik = i[k]; 264e5c89e4eSSatish Balay for (j=k+1; j<n; j++) { 265e5c89e4eSSatish Balay if (ik > i[j]) { 266b7940d39SSatish Balay SWAP2(i[k],i[j],Ii[k],Ii[j],tmp); 267e5c89e4eSSatish Balay ik = i[k]; 268e5c89e4eSSatish Balay } 269e5c89e4eSSatish Balay } 270e5c89e4eSSatish Balay } 271e5c89e4eSSatish Balay } else { 272b7940d39SSatish Balay ierr = PetscSortIntWithArray_Private(i,Ii,n-1);CHKERRQ(ierr); 273e5c89e4eSSatish Balay } 274e5c89e4eSSatish Balay PetscFunctionReturn(0); 275e5c89e4eSSatish Balay } 276e5c89e4eSSatish Balay 277c1f0200aSDmitry Karpeev 278c1f0200aSDmitry Karpeev #define SWAP3(a,b,c,d,e,f,t) {t=a;a=b;b=t;t=c;c=d;d=t;t=e;e=f;f=t;} 279c1f0200aSDmitry Karpeev 280c1f0200aSDmitry Karpeev /* 281c1f0200aSDmitry Karpeev A simple version of quicksort; taken from Kernighan and Ritchie, page 87. 282c1f0200aSDmitry Karpeev Assumes 0 origin for v, number of elements = right+1 (right is index of 283c1f0200aSDmitry Karpeev right-most member). 284c1f0200aSDmitry Karpeev */ 285d7aa01a8SHong Zhang static PetscErrorCode PetscSortIntWithArrayPair_Private(PetscInt *L,PetscInt *J, PetscInt *K, PetscInt right) 286c1f0200aSDmitry Karpeev { 287c1f0200aSDmitry Karpeev PetscErrorCode ierr; 288c1f0200aSDmitry Karpeev PetscInt i,vl,last,tmp; 289c1f0200aSDmitry Karpeev 290c1f0200aSDmitry Karpeev PetscFunctionBegin; 291c1f0200aSDmitry Karpeev if (right <= 1) { 292c1f0200aSDmitry Karpeev if (right == 1) { 293d7aa01a8SHong Zhang if (L[0] > L[1]) SWAP3(L[0],L[1],J[0],J[1],K[0],K[1],tmp); 294c1f0200aSDmitry Karpeev } 295c1f0200aSDmitry Karpeev PetscFunctionReturn(0); 296c1f0200aSDmitry Karpeev } 297d7aa01a8SHong Zhang SWAP3(L[0],L[right/2],J[0],J[right/2],K[0],K[right/2],tmp); 298d7aa01a8SHong Zhang vl = L[0]; 299c1f0200aSDmitry Karpeev last = 0; 300c1f0200aSDmitry Karpeev for (i=1; i<=right; i++) { 301d7aa01a8SHong Zhang if (L[i] < vl) {last++; SWAP3(L[last],L[i],J[last],J[i],K[last],K[i],tmp);} 302c1f0200aSDmitry Karpeev } 303d7aa01a8SHong Zhang SWAP3(L[0],L[last],J[0],J[last],K[0],K[last],tmp); 304d7aa01a8SHong Zhang ierr = PetscSortIntWithArrayPair_Private(L,J,K,last-1);CHKERRQ(ierr); 305d7aa01a8SHong Zhang ierr = PetscSortIntWithArrayPair_Private(L+last+1,J+last+1,K+last+1,right-(last+1));CHKERRQ(ierr); 306c1f0200aSDmitry Karpeev PetscFunctionReturn(0); 307c1f0200aSDmitry Karpeev } 308c1f0200aSDmitry Karpeev 309c1f0200aSDmitry Karpeev /*@ 310c1f0200aSDmitry Karpeev PetscSortIntWithArrayPair - Sorts an array of integers in place in increasing order; 311c1f0200aSDmitry Karpeev changes a pair of integer arrays to match the sorted first array. 312c1f0200aSDmitry Karpeev 313c1f0200aSDmitry Karpeev Not Collective 314c1f0200aSDmitry Karpeev 315c1f0200aSDmitry Karpeev Input Parameters: 316c1f0200aSDmitry Karpeev + n - number of values 317c1f0200aSDmitry Karpeev . I - array of integers 318c1f0200aSDmitry Karpeev . J - second array of integers (first array of the pair) 319c1f0200aSDmitry Karpeev - K - third array of integers (second array of the pair) 320c1f0200aSDmitry Karpeev 321c1f0200aSDmitry Karpeev Level: intermediate 322c1f0200aSDmitry Karpeev 323c1f0200aSDmitry Karpeev .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortIntWithArray() 324c1f0200aSDmitry Karpeev @*/ 3256c2863d0SBarry Smith PetscErrorCode PetscSortIntWithArrayPair(PetscInt n,PetscInt L[],PetscInt J[], PetscInt K[]) 326c1f0200aSDmitry Karpeev { 327c1f0200aSDmitry Karpeev PetscErrorCode ierr; 328c1f0200aSDmitry Karpeev PetscInt j,k,tmp,ik; 329c1f0200aSDmitry Karpeev 330c1f0200aSDmitry Karpeev PetscFunctionBegin; 331c1f0200aSDmitry Karpeev if (n<8) { 332c1f0200aSDmitry Karpeev for (k=0; k<n; k++) { 333d7aa01a8SHong Zhang ik = L[k]; 334c1f0200aSDmitry Karpeev for (j=k+1; j<n; j++) { 335d7aa01a8SHong Zhang if (ik > L[j]) { 336d7aa01a8SHong Zhang SWAP3(L[k],L[j],J[k],J[j],K[k],K[j],tmp); 337d7aa01a8SHong Zhang ik = L[k]; 338c1f0200aSDmitry Karpeev } 339c1f0200aSDmitry Karpeev } 340c1f0200aSDmitry Karpeev } 341c1f0200aSDmitry Karpeev } else { 342d7aa01a8SHong Zhang ierr = PetscSortIntWithArrayPair_Private(L,J,K,n-1);CHKERRQ(ierr); 343c1f0200aSDmitry Karpeev } 344c1f0200aSDmitry Karpeev PetscFunctionReturn(0); 345c1f0200aSDmitry Karpeev } 346c1f0200aSDmitry Karpeev 34717d7d925SStefano Zampini /* 34817d7d925SStefano Zampini A simple version of quicksort; taken from Kernighan and Ritchie, page 87. 34917d7d925SStefano Zampini Assumes 0 origin for v, number of elements = right+1 (right is index of 35017d7d925SStefano Zampini right-most member). 35117d7d925SStefano Zampini */ 35217d7d925SStefano Zampini static void PetscSortMPIInt_Private(PetscMPIInt *v,PetscInt right) 35317d7d925SStefano Zampini { 35417d7d925SStefano Zampini PetscInt i,j; 35517d7d925SStefano Zampini PetscMPIInt pivot,tmp; 35617d7d925SStefano Zampini 35717d7d925SStefano Zampini if (right <= 1) { 35817d7d925SStefano Zampini if (right == 1) { 35917d7d925SStefano Zampini if (v[0] > v[1]) SWAP(v[0],v[1],tmp); 36017d7d925SStefano Zampini } 36117d7d925SStefano Zampini return; 36217d7d925SStefano Zampini } 36317d7d925SStefano Zampini i = MEDIAN(v,right); /* Choose a pivot */ 36417d7d925SStefano Zampini SWAP(v[0],v[i],tmp); /* Move it out of the way */ 36517d7d925SStefano Zampini pivot = v[0]; 36617d7d925SStefano Zampini for (i=0,j=right+1;; ) { 36717d7d925SStefano Zampini while (++i < j && v[i] <= pivot) ; /* Scan from the left */ 36817d7d925SStefano Zampini while (v[--j] > pivot) ; /* Scan from the right */ 36917d7d925SStefano Zampini if (i >= j) break; 37017d7d925SStefano Zampini SWAP(v[i],v[j],tmp); 37117d7d925SStefano Zampini } 37217d7d925SStefano Zampini SWAP(v[0],v[j],tmp); /* Put pivot back in place. */ 37317d7d925SStefano Zampini PetscSortMPIInt_Private(v,j-1); 37417d7d925SStefano Zampini PetscSortMPIInt_Private(v+j+1,right-(j+1)); 37517d7d925SStefano Zampini } 37617d7d925SStefano Zampini 37717d7d925SStefano Zampini /*@ 37817d7d925SStefano Zampini PetscSortMPIInt - Sorts an array of MPI integers in place in increasing order. 37917d7d925SStefano Zampini 38017d7d925SStefano Zampini Not Collective 38117d7d925SStefano Zampini 38217d7d925SStefano Zampini Input Parameters: 38317d7d925SStefano Zampini + n - number of values 38417d7d925SStefano Zampini - i - array of integers 38517d7d925SStefano Zampini 38617d7d925SStefano Zampini Level: intermediate 38717d7d925SStefano Zampini 38817d7d925SStefano Zampini .seealso: PetscSortReal(), PetscSortIntWithPermutation() 38917d7d925SStefano Zampini @*/ 39017d7d925SStefano Zampini PetscErrorCode PetscSortMPIInt(PetscInt n,PetscMPIInt i[]) 39117d7d925SStefano Zampini { 39217d7d925SStefano Zampini PetscInt j,k; 39317d7d925SStefano Zampini PetscMPIInt tmp,ik; 39417d7d925SStefano Zampini 39517d7d925SStefano Zampini PetscFunctionBegin; 39617d7d925SStefano Zampini if (n<8) { 39717d7d925SStefano Zampini for (k=0; k<n; k++) { 39817d7d925SStefano Zampini ik = i[k]; 39917d7d925SStefano Zampini for (j=k+1; j<n; j++) { 40017d7d925SStefano Zampini if (ik > i[j]) { 40117d7d925SStefano Zampini SWAP(i[k],i[j],tmp); 40217d7d925SStefano Zampini ik = i[k]; 40317d7d925SStefano Zampini } 40417d7d925SStefano Zampini } 40517d7d925SStefano Zampini } 406a297a907SKarl Rupp } else PetscSortMPIInt_Private(i,n-1); 40717d7d925SStefano Zampini PetscFunctionReturn(0); 40817d7d925SStefano Zampini } 40917d7d925SStefano Zampini 41017d7d925SStefano Zampini /*@ 41117d7d925SStefano Zampini PetscSortRemoveDupsMPIInt - Sorts an array of MPI integers in place in increasing order removes all duplicate entries 41217d7d925SStefano Zampini 41317d7d925SStefano Zampini Not Collective 41417d7d925SStefano Zampini 41517d7d925SStefano Zampini Input Parameters: 41617d7d925SStefano Zampini + n - number of values 41717d7d925SStefano Zampini - ii - array of integers 41817d7d925SStefano Zampini 41917d7d925SStefano Zampini Output Parameter: 42017d7d925SStefano Zampini . n - number of non-redundant values 42117d7d925SStefano Zampini 42217d7d925SStefano Zampini Level: intermediate 42317d7d925SStefano Zampini 42417d7d925SStefano Zampini .seealso: PetscSortReal(), PetscSortIntWithPermutation(), PetscSortInt() 42517d7d925SStefano Zampini @*/ 42617d7d925SStefano Zampini PetscErrorCode PetscSortRemoveDupsMPIInt(PetscInt *n,PetscMPIInt ii[]) 42717d7d925SStefano Zampini { 42817d7d925SStefano Zampini PetscErrorCode ierr; 42917d7d925SStefano Zampini PetscInt i,s = 0,N = *n, b = 0; 43017d7d925SStefano Zampini 43117d7d925SStefano Zampini PetscFunctionBegin; 43217d7d925SStefano Zampini ierr = PetscSortMPIInt(N,ii);CHKERRQ(ierr); 43317d7d925SStefano Zampini for (i=0; i<N-1; i++) { 434a297a907SKarl Rupp if (ii[b+s+1] != ii[b]) { 435a297a907SKarl Rupp ii[b+1] = ii[b+s+1]; b++; 436a297a907SKarl Rupp } else s++; 43717d7d925SStefano Zampini } 43817d7d925SStefano Zampini *n = N - s; 43917d7d925SStefano Zampini PetscFunctionReturn(0); 44017d7d925SStefano Zampini } 441c1f0200aSDmitry Karpeev 4424d615ea0SBarry Smith /* 4434d615ea0SBarry Smith A simple version of quicksort; taken from Kernighan and Ritchie, page 87. 4444d615ea0SBarry Smith Assumes 0 origin for v, number of elements = right+1 (right is index of 4454d615ea0SBarry Smith right-most member). 4464d615ea0SBarry Smith */ 4474d615ea0SBarry Smith static PetscErrorCode PetscSortMPIIntWithArray_Private(PetscMPIInt *v,PetscMPIInt *V,PetscMPIInt right) 4484d615ea0SBarry Smith { 4494d615ea0SBarry Smith PetscErrorCode ierr; 4504d615ea0SBarry Smith PetscMPIInt i,vl,last,tmp; 4514d615ea0SBarry Smith 4524d615ea0SBarry Smith PetscFunctionBegin; 4534d615ea0SBarry Smith if (right <= 1) { 4544d615ea0SBarry Smith if (right == 1) { 4554d615ea0SBarry Smith if (v[0] > v[1]) SWAP2(v[0],v[1],V[0],V[1],tmp); 4564d615ea0SBarry Smith } 4574d615ea0SBarry Smith PetscFunctionReturn(0); 4584d615ea0SBarry Smith } 4594d615ea0SBarry Smith SWAP2(v[0],v[right/2],V[0],V[right/2],tmp); 4604d615ea0SBarry Smith vl = v[0]; 4614d615ea0SBarry Smith last = 0; 4624d615ea0SBarry Smith for (i=1; i<=right; i++) { 4634d615ea0SBarry Smith if (v[i] < vl) {last++; SWAP2(v[last],v[i],V[last],V[i],tmp);} 4644d615ea0SBarry Smith } 4654d615ea0SBarry Smith SWAP2(v[0],v[last],V[0],V[last],tmp); 4664d615ea0SBarry Smith ierr = PetscSortMPIIntWithArray_Private(v,V,last-1);CHKERRQ(ierr); 4674d615ea0SBarry Smith ierr = PetscSortMPIIntWithArray_Private(v+last+1,V+last+1,right-(last+1));CHKERRQ(ierr); 4684d615ea0SBarry Smith PetscFunctionReturn(0); 4694d615ea0SBarry Smith } 4704d615ea0SBarry Smith 4714d615ea0SBarry Smith /*@ 4724d615ea0SBarry Smith PetscSortMPIIntWithArray - Sorts an array of integers in place in increasing order; 4734d615ea0SBarry Smith changes a second array to match the sorted first array. 4744d615ea0SBarry Smith 4754d615ea0SBarry Smith Not Collective 4764d615ea0SBarry Smith 4774d615ea0SBarry Smith Input Parameters: 4784d615ea0SBarry Smith + n - number of values 4794d615ea0SBarry Smith . i - array of integers 4804d615ea0SBarry Smith - I - second array of integers 4814d615ea0SBarry Smith 4824d615ea0SBarry Smith Level: intermediate 4834d615ea0SBarry Smith 4844d615ea0SBarry Smith .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt() 4854d615ea0SBarry Smith @*/ 4867087cfbeSBarry Smith PetscErrorCode PetscSortMPIIntWithArray(PetscMPIInt n,PetscMPIInt i[],PetscMPIInt Ii[]) 4874d615ea0SBarry Smith { 4884d615ea0SBarry Smith PetscErrorCode ierr; 4894d615ea0SBarry Smith PetscMPIInt j,k,tmp,ik; 4904d615ea0SBarry Smith 4914d615ea0SBarry Smith PetscFunctionBegin; 4924d615ea0SBarry Smith if (n<8) { 4934d615ea0SBarry Smith for (k=0; k<n; k++) { 4944d615ea0SBarry Smith ik = i[k]; 4954d615ea0SBarry Smith for (j=k+1; j<n; j++) { 4964d615ea0SBarry Smith if (ik > i[j]) { 4974d615ea0SBarry Smith SWAP2(i[k],i[j],Ii[k],Ii[j],tmp); 4984d615ea0SBarry Smith ik = i[k]; 4994d615ea0SBarry Smith } 5004d615ea0SBarry Smith } 5014d615ea0SBarry Smith } 5024d615ea0SBarry Smith } else { 5034d615ea0SBarry Smith ierr = PetscSortMPIIntWithArray_Private(i,Ii,n-1);CHKERRQ(ierr); 5044d615ea0SBarry Smith } 5054d615ea0SBarry Smith PetscFunctionReturn(0); 5064d615ea0SBarry Smith } 5074d615ea0SBarry Smith 508e5c89e4eSSatish Balay /* -----------------------------------------------------------------------*/ 5095569a785SJunchao Zhang #define SWAP2MPIIntInt(a,b,c,d,t1,t2) {t1=a;a=b;b=t1;t2=c;c=d;d=t2;} 5105569a785SJunchao Zhang 5115569a785SJunchao Zhang /* 5125569a785SJunchao Zhang A simple version of quicksort; taken from Kernighan and Ritchie, page 87. 5135569a785SJunchao Zhang Assumes 0 origin for v, number of elements = right+1 (right is index of 5145569a785SJunchao Zhang right-most member). 5155569a785SJunchao Zhang */ 5165569a785SJunchao Zhang static PetscErrorCode PetscSortMPIIntWithIntArray_Private(PetscMPIInt *v,PetscInt *V,PetscMPIInt right) 5175569a785SJunchao Zhang { 5185569a785SJunchao Zhang PetscErrorCode ierr; 5195569a785SJunchao Zhang PetscMPIInt i,vl,last,t1; 5205569a785SJunchao Zhang PetscInt t2; 5215569a785SJunchao Zhang 5225569a785SJunchao Zhang PetscFunctionBegin; 5235569a785SJunchao Zhang if (right <= 1) { 5245569a785SJunchao Zhang if (right == 1) { 5255569a785SJunchao Zhang if (v[0] > v[1]) SWAP2MPIIntInt(v[0],v[1],V[0],V[1],t1,t2); 5265569a785SJunchao Zhang } 5275569a785SJunchao Zhang PetscFunctionReturn(0); 5285569a785SJunchao Zhang } 5295569a785SJunchao Zhang SWAP2MPIIntInt(v[0],v[right/2],V[0],V[right/2],t1,t2); 5305569a785SJunchao Zhang vl = v[0]; 5315569a785SJunchao Zhang last = 0; 5325569a785SJunchao Zhang for (i=1; i<=right; i++) { 5335569a785SJunchao Zhang if (v[i] < vl) {last++; SWAP2MPIIntInt(v[last],v[i],V[last],V[i],t1,t2);} 5345569a785SJunchao Zhang } 5355569a785SJunchao Zhang SWAP2MPIIntInt(v[0],v[last],V[0],V[last],t1,t2); 5365569a785SJunchao Zhang ierr = PetscSortMPIIntWithIntArray_Private(v,V,last-1);CHKERRQ(ierr); 5375569a785SJunchao Zhang ierr = PetscSortMPIIntWithIntArray_Private(v+last+1,V+last+1,right-(last+1));CHKERRQ(ierr); 5385569a785SJunchao Zhang PetscFunctionReturn(0); 5395569a785SJunchao Zhang } 5405569a785SJunchao Zhang 5415569a785SJunchao Zhang /*@ 5425569a785SJunchao Zhang PetscSortMPIIntWithIntArray - Sorts an array of MPI integers in place in increasing order; 5435569a785SJunchao Zhang changes a second array of Petsc intergers to match the sorted first array. 5445569a785SJunchao Zhang 5455569a785SJunchao Zhang Not Collective 5465569a785SJunchao Zhang 5475569a785SJunchao Zhang Input Parameters: 5485569a785SJunchao Zhang + n - number of values 5495569a785SJunchao Zhang . i - array of MPI integers 5505569a785SJunchao Zhang - I - second array of Petsc integers 5515569a785SJunchao Zhang 5525569a785SJunchao Zhang Level: intermediate 5535569a785SJunchao Zhang 5545569a785SJunchao Zhang Notes: this routine is useful when one needs to sort MPI ranks with other integer arrays. 5555569a785SJunchao Zhang 5565569a785SJunchao Zhang .seealso: PetscSortMPIIntWithArray() 5575569a785SJunchao Zhang @*/ 5585569a785SJunchao Zhang PetscErrorCode PetscSortMPIIntWithIntArray(PetscMPIInt n,PetscMPIInt i[],PetscInt Ii[]) 5595569a785SJunchao Zhang { 5605569a785SJunchao Zhang PetscErrorCode ierr; 5615569a785SJunchao Zhang PetscMPIInt j,k,t1,ik; 5625569a785SJunchao Zhang PetscInt t2; 5635569a785SJunchao Zhang 5645569a785SJunchao Zhang PetscFunctionBegin; 5655569a785SJunchao Zhang if (n<8) { 5665569a785SJunchao Zhang for (k=0; k<n; k++) { 5675569a785SJunchao Zhang ik = i[k]; 5685569a785SJunchao Zhang for (j=k+1; j<n; j++) { 5695569a785SJunchao Zhang if (ik > i[j]) { 5705569a785SJunchao Zhang SWAP2MPIIntInt(i[k],i[j],Ii[k],Ii[j],t1,t2); 5715569a785SJunchao Zhang ik = i[k]; 5725569a785SJunchao Zhang } 5735569a785SJunchao Zhang } 5745569a785SJunchao Zhang } 5755569a785SJunchao Zhang } else { 5765569a785SJunchao Zhang ierr = PetscSortMPIIntWithIntArray_Private(i,Ii,n-1);CHKERRQ(ierr); 5775569a785SJunchao Zhang } 5785569a785SJunchao Zhang PetscFunctionReturn(0); 5795569a785SJunchao Zhang } 5805569a785SJunchao Zhang 5815569a785SJunchao Zhang /* -----------------------------------------------------------------------*/ 582e5c89e4eSSatish Balay #define SWAP2IntScalar(a,b,c,d,t,ts) {t=a;a=b;b=t;ts=c;c=d;d=ts;} 583e5c89e4eSSatish Balay 584e5c89e4eSSatish Balay /* 585e5c89e4eSSatish Balay Modified from PetscSortIntWithArray_Private(). 586e5c89e4eSSatish Balay */ 587e5c89e4eSSatish Balay static PetscErrorCode PetscSortIntWithScalarArray_Private(PetscInt *v,PetscScalar *V,PetscInt right) 588e5c89e4eSSatish Balay { 589e5c89e4eSSatish Balay PetscErrorCode ierr; 590e5c89e4eSSatish Balay PetscInt i,vl,last,tmp; 591e5c89e4eSSatish Balay PetscScalar stmp; 592e5c89e4eSSatish Balay 593e5c89e4eSSatish Balay PetscFunctionBegin; 594e5c89e4eSSatish Balay if (right <= 1) { 595e5c89e4eSSatish Balay if (right == 1) { 596e5c89e4eSSatish Balay if (v[0] > v[1]) SWAP2IntScalar(v[0],v[1],V[0],V[1],tmp,stmp); 597e5c89e4eSSatish Balay } 598e5c89e4eSSatish Balay PetscFunctionReturn(0); 599e5c89e4eSSatish Balay } 600e5c89e4eSSatish Balay SWAP2IntScalar(v[0],v[right/2],V[0],V[right/2],tmp,stmp); 601e5c89e4eSSatish Balay vl = v[0]; 602e5c89e4eSSatish Balay last = 0; 603e5c89e4eSSatish Balay for (i=1; i<=right; i++) { 604e5c89e4eSSatish Balay if (v[i] < vl) {last++; SWAP2IntScalar(v[last],v[i],V[last],V[i],tmp,stmp);} 605e5c89e4eSSatish Balay } 606e5c89e4eSSatish Balay SWAP2IntScalar(v[0],v[last],V[0],V[last],tmp,stmp); 607e5c89e4eSSatish Balay ierr = PetscSortIntWithScalarArray_Private(v,V,last-1);CHKERRQ(ierr); 608e5c89e4eSSatish Balay ierr = PetscSortIntWithScalarArray_Private(v+last+1,V+last+1,right-(last+1));CHKERRQ(ierr); 609e5c89e4eSSatish Balay PetscFunctionReturn(0); 610e5c89e4eSSatish Balay } 611e5c89e4eSSatish Balay 612e5c89e4eSSatish Balay /*@ 613e5c89e4eSSatish Balay PetscSortIntWithScalarArray - Sorts an array of integers in place in increasing order; 614e5c89e4eSSatish Balay changes a second SCALAR array to match the sorted first INTEGER array. 615e5c89e4eSSatish Balay 616e5c89e4eSSatish Balay Not Collective 617e5c89e4eSSatish Balay 618e5c89e4eSSatish Balay Input Parameters: 619e5c89e4eSSatish Balay + n - number of values 620e5c89e4eSSatish Balay . i - array of integers 621e5c89e4eSSatish Balay - I - second array of scalars 622e5c89e4eSSatish Balay 623e5c89e4eSSatish Balay Level: intermediate 624e5c89e4eSSatish Balay 625e5c89e4eSSatish Balay .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt(), PetscSortIntWithArray() 626e5c89e4eSSatish Balay @*/ 6277087cfbeSBarry Smith PetscErrorCode PetscSortIntWithScalarArray(PetscInt n,PetscInt i[],PetscScalar Ii[]) 628e5c89e4eSSatish Balay { 629e5c89e4eSSatish Balay PetscErrorCode ierr; 630e5c89e4eSSatish Balay PetscInt j,k,tmp,ik; 631e5c89e4eSSatish Balay PetscScalar stmp; 632e5c89e4eSSatish Balay 633e5c89e4eSSatish Balay PetscFunctionBegin; 634e5c89e4eSSatish Balay if (n<8) { 635e5c89e4eSSatish Balay for (k=0; k<n; k++) { 636e5c89e4eSSatish Balay ik = i[k]; 637e5c89e4eSSatish Balay for (j=k+1; j<n; j++) { 638e5c89e4eSSatish Balay if (ik > i[j]) { 639b7940d39SSatish Balay SWAP2IntScalar(i[k],i[j],Ii[k],Ii[j],tmp,stmp); 640e5c89e4eSSatish Balay ik = i[k]; 641e5c89e4eSSatish Balay } 642e5c89e4eSSatish Balay } 643e5c89e4eSSatish Balay } 644e5c89e4eSSatish Balay } else { 645b7940d39SSatish Balay ierr = PetscSortIntWithScalarArray_Private(i,Ii,n-1);CHKERRQ(ierr); 646e5c89e4eSSatish Balay } 647e5c89e4eSSatish Balay PetscFunctionReturn(0); 648e5c89e4eSSatish Balay } 649e5c89e4eSSatish Balay 650ece8f864SToby Isaac #define SWAP2IntData(a,b,c,d,t,td,siz) \ 651ece8f864SToby Isaac do { \ 652ece8f864SToby Isaac PetscErrorCode _ierr; \ 653ece8f864SToby Isaac t=a;a=b;b=t; \ 654ece8f864SToby Isaac _ierr = PetscMemcpy(td,c,siz);CHKERRQ(_ierr); \ 655ece8f864SToby Isaac _ierr = PetscMemcpy(c,d,siz);CHKERRQ(_ierr); \ 656ece8f864SToby Isaac _ierr = PetscMemcpy(d,td,siz);CHKERRQ(_ierr); \ 657ece8f864SToby Isaac } while(0) 65817df18f2SToby Isaac 65917df18f2SToby Isaac /* 66017df18f2SToby Isaac Modified from PetscSortIntWithArray_Private(). 66117df18f2SToby Isaac */ 66217df18f2SToby Isaac static PetscErrorCode PetscSortIntWithDataArray_Private(PetscInt *v,char *V,PetscInt right,size_t size,void *work) 66317df18f2SToby Isaac { 66417df18f2SToby Isaac PetscErrorCode ierr; 66517df18f2SToby Isaac PetscInt i,vl,last,tmp; 66617df18f2SToby Isaac 66717df18f2SToby Isaac PetscFunctionBegin; 66817df18f2SToby Isaac if (right <= 1) { 66917df18f2SToby Isaac if (right == 1) { 67017df18f2SToby Isaac if (v[0] > v[1]) SWAP2IntData(v[0],v[1],V,V+size,tmp,work,size); 67117df18f2SToby Isaac } 67217df18f2SToby Isaac PetscFunctionReturn(0); 67317df18f2SToby Isaac } 67417df18f2SToby Isaac SWAP2IntData(v[0],v[right/2],V,V+size*(right/2),tmp,work,size); 67517df18f2SToby Isaac vl = v[0]; 67617df18f2SToby Isaac last = 0; 67717df18f2SToby Isaac for (i=1; i<=right; i++) { 67817df18f2SToby Isaac if (v[i] < vl) {last++; SWAP2IntData(v[last],v[i],V+size*last,V+size*i,tmp,work,size);} 67917df18f2SToby Isaac } 68017df18f2SToby Isaac SWAP2IntData(v[0],v[last],V,V + size*last,tmp,work,size); 68117df18f2SToby Isaac ierr = PetscSortIntWithDataArray_Private(v,V,last-1,size,work);CHKERRQ(ierr); 68217df18f2SToby Isaac ierr = PetscSortIntWithDataArray_Private(v+last+1,V+size*(last+1),right-(last+1),size,work);CHKERRQ(ierr); 68317df18f2SToby Isaac PetscFunctionReturn(0); 68417df18f2SToby Isaac } 68517df18f2SToby Isaac 6866c2863d0SBarry Smith /*@C 68717df18f2SToby Isaac PetscSortIntWithDataArray - Sorts an array of integers in place in increasing order; 68817df18f2SToby Isaac changes a second array to match the sorted first INTEGER array. Unlike other sort routines, the user must 68917df18f2SToby Isaac provide workspace (the size of an element in the data array) to use when sorting. 69017df18f2SToby Isaac 69117df18f2SToby Isaac Not Collective 69217df18f2SToby Isaac 69317df18f2SToby Isaac Input Parameters: 69417df18f2SToby Isaac + n - number of values 69517df18f2SToby Isaac . i - array of integers 69617df18f2SToby Isaac . Ii - second array of data 69717df18f2SToby Isaac . size - sizeof elements in the data array in bytes 69817df18f2SToby Isaac - work - workspace of "size" bytes used when sorting 69917df18f2SToby Isaac 70017df18f2SToby Isaac Level: intermediate 70117df18f2SToby Isaac 70217df18f2SToby Isaac .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt(), PetscSortIntWithArray() 70317df18f2SToby Isaac @*/ 70417df18f2SToby Isaac PetscErrorCode PetscSortIntWithDataArray(PetscInt n,PetscInt i[],void *Ii,size_t size,void *work) 70517df18f2SToby Isaac { 70617df18f2SToby Isaac char *V = (char *) Ii; 70717df18f2SToby Isaac PetscErrorCode ierr; 70817df18f2SToby Isaac PetscInt j,k,tmp,ik; 70917df18f2SToby Isaac 71017df18f2SToby Isaac PetscFunctionBegin; 71117df18f2SToby Isaac if (n<8) { 71217df18f2SToby Isaac for (k=0; k<n; k++) { 71317df18f2SToby Isaac ik = i[k]; 71417df18f2SToby Isaac for (j=k+1; j<n; j++) { 71517df18f2SToby Isaac if (ik > i[j]) { 71617df18f2SToby Isaac SWAP2IntData(i[k],i[j],V+size*k,V+size*j,tmp,work,size); 71717df18f2SToby Isaac ik = i[k]; 71817df18f2SToby Isaac } 71917df18f2SToby Isaac } 72017df18f2SToby Isaac } 72117df18f2SToby Isaac } else { 72217df18f2SToby Isaac ierr = PetscSortIntWithDataArray_Private(i,V,n-1,size,work);CHKERRQ(ierr); 72317df18f2SToby Isaac } 72417df18f2SToby Isaac PetscFunctionReturn(0); 72517df18f2SToby Isaac } 72617df18f2SToby Isaac 727b4301105SBarry Smith 72821e72a00SBarry Smith /*@ 72921e72a00SBarry Smith PetscMergeIntArray - Merges two SORTED integer arrays, removes duplicate elements. 73021e72a00SBarry Smith 73121e72a00SBarry Smith Not Collective 73221e72a00SBarry Smith 73321e72a00SBarry Smith Input Parameters: 73421e72a00SBarry Smith + an - number of values in the first array 73521e72a00SBarry Smith . aI - first sorted array of integers 73621e72a00SBarry Smith . bn - number of values in the second array 73721e72a00SBarry Smith - bI - second array of integers 73821e72a00SBarry Smith 73921e72a00SBarry Smith Output Parameters: 74021e72a00SBarry Smith + n - number of values in the merged array 7416c2863d0SBarry Smith - L - merged sorted array, this is allocated if an array is not provided 74221e72a00SBarry Smith 74321e72a00SBarry Smith Level: intermediate 74421e72a00SBarry Smith 74521e72a00SBarry Smith .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt(), PetscSortIntWithArray() 74621e72a00SBarry Smith @*/ 7476c2863d0SBarry Smith PetscErrorCode PetscMergeIntArray(PetscInt an,const PetscInt aI[], PetscInt bn, const PetscInt bI[], PetscInt *n, PetscInt **L) 74821e72a00SBarry Smith { 74921e72a00SBarry Smith PetscErrorCode ierr; 75021e72a00SBarry Smith PetscInt *L_ = *L, ak, bk, k; 75121e72a00SBarry Smith 75221e72a00SBarry Smith if (!L_) { 75321e72a00SBarry Smith ierr = PetscMalloc1(an+bn, L);CHKERRQ(ierr); 75421e72a00SBarry Smith L_ = *L; 75521e72a00SBarry Smith } 75621e72a00SBarry Smith k = ak = bk = 0; 75721e72a00SBarry Smith while (ak < an && bk < bn) { 75821e72a00SBarry Smith if (aI[ak] == bI[bk]) { 75921e72a00SBarry Smith L_[k] = aI[ak]; 76021e72a00SBarry Smith ++ak; 76121e72a00SBarry Smith ++bk; 76221e72a00SBarry Smith ++k; 76321e72a00SBarry Smith } else if (aI[ak] < bI[bk]) { 76421e72a00SBarry Smith L_[k] = aI[ak]; 76521e72a00SBarry Smith ++ak; 76621e72a00SBarry Smith ++k; 76721e72a00SBarry Smith } else { 76821e72a00SBarry Smith L_[k] = bI[bk]; 76921e72a00SBarry Smith ++bk; 77021e72a00SBarry Smith ++k; 77121e72a00SBarry Smith } 77221e72a00SBarry Smith } 77321e72a00SBarry Smith if (ak < an) { 774*580bdb30SBarry Smith ierr = PetscArraycpy(L_+k,aI+ak,an-ak);CHKERRQ(ierr); 77521e72a00SBarry Smith k += (an-ak); 77621e72a00SBarry Smith } 77721e72a00SBarry Smith if (bk < bn) { 778*580bdb30SBarry Smith ierr = PetscArraycpy(L_+k,bI+bk,bn-bk);CHKERRQ(ierr); 77921e72a00SBarry Smith k += (bn-bk); 78021e72a00SBarry Smith } 78121e72a00SBarry Smith *n = k; 78221e72a00SBarry Smith PetscFunctionReturn(0); 78321e72a00SBarry Smith } 784b4301105SBarry Smith 785c1f0200aSDmitry Karpeev /*@ 78621e72a00SBarry Smith PetscMergeIntArrayPair - Merges two SORTED integer arrays that share NO common values along with an additional array of integers. 787c1f0200aSDmitry Karpeev The additional arrays are the same length as sorted arrays and are merged 788c1f0200aSDmitry Karpeev in the order determined by the merging of the sorted pair. 789c1f0200aSDmitry Karpeev 790c1f0200aSDmitry Karpeev Not Collective 791c1f0200aSDmitry Karpeev 792c1f0200aSDmitry Karpeev Input Parameters: 793c1f0200aSDmitry Karpeev + an - number of values in the first array 794c1f0200aSDmitry Karpeev . aI - first sorted array of integers 795c1f0200aSDmitry Karpeev . aJ - first additional array of integers 796c1f0200aSDmitry Karpeev . bn - number of values in the second array 797c1f0200aSDmitry Karpeev . bI - second array of integers 798c1f0200aSDmitry Karpeev - bJ - second additional of integers 799c1f0200aSDmitry Karpeev 800c1f0200aSDmitry Karpeev Output Parameters: 801c1f0200aSDmitry Karpeev + n - number of values in the merged array (== an + bn) 80214c49006SJed Brown . L - merged sorted array 803c1f0200aSDmitry Karpeev - J - merged additional array 804c1f0200aSDmitry Karpeev 80595452b02SPatrick Sanan Notes: 80695452b02SPatrick Sanan if L or J point to non-null arrays then this routine will assume they are of the approproate size and use them, otherwise this routine will allocate space for them 807c1f0200aSDmitry Karpeev Level: intermediate 808c1f0200aSDmitry Karpeev 809c1f0200aSDmitry Karpeev .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt(), PetscSortIntWithArray() 810c1f0200aSDmitry Karpeev @*/ 8116c2863d0SBarry Smith PetscErrorCode PetscMergeIntArrayPair(PetscInt an,const PetscInt aI[], const PetscInt aJ[], PetscInt bn, const PetscInt bI[], const PetscInt bJ[], PetscInt *n, PetscInt **L, PetscInt **J) 812c1f0200aSDmitry Karpeev { 813c1f0200aSDmitry Karpeev PetscErrorCode ierr; 81470d8d27cSBarry Smith PetscInt n_, *L_, *J_, ak, bk, k; 815c1f0200aSDmitry Karpeev 81614c49006SJed Brown PetscFunctionBegin; 81770d8d27cSBarry Smith PetscValidIntPointer(L,8); 81870d8d27cSBarry Smith PetscValidIntPointer(J,9); 819c1f0200aSDmitry Karpeev n_ = an + bn; 820c1f0200aSDmitry Karpeev *n = n_; 82170d8d27cSBarry Smith if (!*L) { 822785e854fSJed Brown ierr = PetscMalloc1(n_, L);CHKERRQ(ierr); 82370d8d27cSBarry Smith } 824d7aa01a8SHong Zhang L_ = *L; 82570d8d27cSBarry Smith if (!*J) { 82670d8d27cSBarry Smith ierr = PetscMalloc1(n_, J);CHKERRQ(ierr); 827c1f0200aSDmitry Karpeev } 828c1f0200aSDmitry Karpeev J_ = *J; 829c1f0200aSDmitry Karpeev k = ak = bk = 0; 830c1f0200aSDmitry Karpeev while (ak < an && bk < bn) { 831c1f0200aSDmitry Karpeev if (aI[ak] <= bI[bk]) { 832d7aa01a8SHong Zhang L_[k] = aI[ak]; 833c1f0200aSDmitry Karpeev J_[k] = aJ[ak]; 834c1f0200aSDmitry Karpeev ++ak; 835c1f0200aSDmitry Karpeev ++k; 836a297a907SKarl Rupp } else { 837d7aa01a8SHong Zhang L_[k] = bI[bk]; 838c1f0200aSDmitry Karpeev J_[k] = bJ[bk]; 839c1f0200aSDmitry Karpeev ++bk; 840c1f0200aSDmitry Karpeev ++k; 841c1f0200aSDmitry Karpeev } 842c1f0200aSDmitry Karpeev } 843c1f0200aSDmitry Karpeev if (ak < an) { 844*580bdb30SBarry Smith ierr = PetscArraycpy(L_+k,aI+ak,an-ak);CHKERRQ(ierr); 845*580bdb30SBarry Smith ierr = PetscArraycpy(J_+k,aJ+ak,an-ak);CHKERRQ(ierr); 846c1f0200aSDmitry Karpeev k += (an-ak); 847c1f0200aSDmitry Karpeev } 848c1f0200aSDmitry Karpeev if (bk < bn) { 849*580bdb30SBarry Smith ierr = PetscArraycpy(L_+k,bI+bk,bn-bk);CHKERRQ(ierr); 850*580bdb30SBarry Smith ierr = PetscArraycpy(J_+k,bJ+bk,bn-bk);CHKERRQ(ierr); 851c1f0200aSDmitry Karpeev } 852c1f0200aSDmitry Karpeev PetscFunctionReturn(0); 853c1f0200aSDmitry Karpeev } 854c1f0200aSDmitry Karpeev 855e498c390SJed Brown /*@ 856e498c390SJed Brown PetscMergeMPIIntArray - Merges two SORTED integer arrays. 857e498c390SJed Brown 858e498c390SJed Brown Not Collective 859e498c390SJed Brown 860e498c390SJed Brown Input Parameters: 861e498c390SJed Brown + an - number of values in the first array 862e498c390SJed Brown . aI - first sorted array of integers 863e498c390SJed Brown . bn - number of values in the second array 864e498c390SJed Brown - bI - second array of integers 865e498c390SJed Brown 866e498c390SJed Brown Output Parameters: 867e498c390SJed Brown + n - number of values in the merged array (<= an + bn) 868e498c390SJed Brown - L - merged sorted array, allocated if address of NULL pointer is passed 869e498c390SJed Brown 870e498c390SJed Brown Level: intermediate 871e498c390SJed Brown 872e498c390SJed Brown .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt(), PetscSortIntWithArray() 873e498c390SJed Brown @*/ 874e498c390SJed Brown PetscErrorCode PetscMergeMPIIntArray(PetscInt an,const PetscMPIInt aI[],PetscInt bn,const PetscMPIInt bI[],PetscInt *n,PetscMPIInt **L) 875e498c390SJed Brown { 876e498c390SJed Brown PetscErrorCode ierr; 877e498c390SJed Brown PetscInt ai,bi,k; 878e498c390SJed Brown 879e498c390SJed Brown PetscFunctionBegin; 880e498c390SJed Brown if (!*L) {ierr = PetscMalloc1((an+bn),L);CHKERRQ(ierr);} 881e498c390SJed Brown for (ai=0,bi=0,k=0; ai<an || bi<bn; ) { 882e498c390SJed Brown PetscInt t = -1; 883e498c390SJed Brown for ( ; ai<an && (!bn || aI[ai] <= bI[bi]); ai++) (*L)[k++] = t = aI[ai]; 884e498c390SJed Brown for ( ; bi<bn && bI[bi] == t; bi++); 885e498c390SJed Brown for ( ; bi<bn && (!an || bI[bi] <= aI[ai]); bi++) (*L)[k++] = t = bI[bi]; 886e498c390SJed Brown for ( ; ai<an && aI[ai] == t; ai++); 887e498c390SJed Brown } 888e498c390SJed Brown *n = k; 889e498c390SJed Brown PetscFunctionReturn(0); 890e498c390SJed Brown } 891e5c89e4eSSatish Balay 8926c2863d0SBarry Smith /*@C 89342eaa7f3SBarry Smith PetscProcessTree - Prepares tree data to be displayed graphically 89442eaa7f3SBarry Smith 89542eaa7f3SBarry Smith Not Collective 89642eaa7f3SBarry Smith 89742eaa7f3SBarry Smith Input Parameters: 89842eaa7f3SBarry Smith + n - number of values 89942eaa7f3SBarry Smith . mask - indicates those entries in the tree, location 0 is always masked 90042eaa7f3SBarry Smith - parentid - indicates the parent of each entry 90142eaa7f3SBarry Smith 90242eaa7f3SBarry Smith Output Parameters: 90342eaa7f3SBarry Smith + Nlevels - the number of levels 90442eaa7f3SBarry Smith . Level - for each node tells its level 90542eaa7f3SBarry Smith . Levelcnts - the number of nodes on each level 90642eaa7f3SBarry Smith . Idbylevel - a list of ids on each of the levels, first level followed by second etc 90742eaa7f3SBarry Smith - Column - for each id tells its column index 90842eaa7f3SBarry Smith 9096c2863d0SBarry Smith Level: developer 91042eaa7f3SBarry Smith 91195452b02SPatrick Sanan Notes: 91295452b02SPatrick Sanan This code is not currently used 91342eaa7f3SBarry Smith 91442eaa7f3SBarry Smith .seealso: PetscSortReal(), PetscSortIntWithPermutation() 91542eaa7f3SBarry Smith @*/ 9167087cfbeSBarry Smith PetscErrorCode PetscProcessTree(PetscInt n,const PetscBool mask[],const PetscInt parentid[],PetscInt *Nlevels,PetscInt **Level,PetscInt **Levelcnt,PetscInt **Idbylevel,PetscInt **Column) 91742eaa7f3SBarry Smith { 91842eaa7f3SBarry Smith PetscInt i,j,cnt,nmask = 0,nlevels = 0,*level,*levelcnt,levelmax = 0,*workid,*workparentid,tcnt = 0,*idbylevel,*column; 91942eaa7f3SBarry Smith PetscErrorCode ierr; 920ace3abfcSBarry Smith PetscBool done = PETSC_FALSE; 92142eaa7f3SBarry Smith 92242eaa7f3SBarry Smith PetscFunctionBegin; 92342eaa7f3SBarry Smith if (!mask[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mask of 0th location must be set"); 92442eaa7f3SBarry Smith for (i=0; i<n; i++) { 92542eaa7f3SBarry Smith if (mask[i]) continue; 92642eaa7f3SBarry Smith if (parentid[i] == i) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Node labeled as own parent"); 92742eaa7f3SBarry Smith if (parentid[i] && mask[parentid[i]]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Parent is masked"); 92842eaa7f3SBarry Smith } 92942eaa7f3SBarry Smith 93042eaa7f3SBarry Smith for (i=0; i<n; i++) { 93142eaa7f3SBarry Smith if (!mask[i]) nmask++; 93242eaa7f3SBarry Smith } 93342eaa7f3SBarry Smith 93442eaa7f3SBarry Smith /* determine the level in the tree of each node */ 9351795a4d1SJed Brown ierr = PetscCalloc1(n,&level);CHKERRQ(ierr); 936a297a907SKarl Rupp 93742eaa7f3SBarry Smith level[0] = 1; 93842eaa7f3SBarry Smith while (!done) { 93942eaa7f3SBarry Smith done = PETSC_TRUE; 94042eaa7f3SBarry Smith for (i=0; i<n; i++) { 94142eaa7f3SBarry Smith if (mask[i]) continue; 94242eaa7f3SBarry Smith if (!level[i] && level[parentid[i]]) level[i] = level[parentid[i]] + 1; 94342eaa7f3SBarry Smith else if (!level[i]) done = PETSC_FALSE; 94442eaa7f3SBarry Smith } 94542eaa7f3SBarry Smith } 94642eaa7f3SBarry Smith for (i=0; i<n; i++) { 94742eaa7f3SBarry Smith level[i]--; 94842eaa7f3SBarry Smith nlevels = PetscMax(nlevels,level[i]); 94942eaa7f3SBarry Smith } 95042eaa7f3SBarry Smith 95142eaa7f3SBarry Smith /* count the number of nodes on each level and its max */ 9521795a4d1SJed Brown ierr = PetscCalloc1(nlevels,&levelcnt);CHKERRQ(ierr); 95342eaa7f3SBarry Smith for (i=0; i<n; i++) { 95442eaa7f3SBarry Smith if (mask[i]) continue; 95542eaa7f3SBarry Smith levelcnt[level[i]-1]++; 95642eaa7f3SBarry Smith } 957a297a907SKarl Rupp for (i=0; i<nlevels;i++) levelmax = PetscMax(levelmax,levelcnt[i]); 95842eaa7f3SBarry Smith 95942eaa7f3SBarry Smith /* for each level sort the ids by the parent id */ 960dcca6d9dSJed Brown ierr = PetscMalloc2(levelmax,&workid,levelmax,&workparentid);CHKERRQ(ierr); 961785e854fSJed Brown ierr = PetscMalloc1(nmask,&idbylevel);CHKERRQ(ierr); 96242eaa7f3SBarry Smith for (j=1; j<=nlevels;j++) { 96342eaa7f3SBarry Smith cnt = 0; 96442eaa7f3SBarry Smith for (i=0; i<n; i++) { 96542eaa7f3SBarry Smith if (mask[i]) continue; 96642eaa7f3SBarry Smith if (level[i] != j) continue; 96742eaa7f3SBarry Smith workid[cnt] = i; 96842eaa7f3SBarry Smith workparentid[cnt++] = parentid[i]; 96942eaa7f3SBarry Smith } 97042eaa7f3SBarry Smith /* PetscIntView(cnt,workparentid,0); 97142eaa7f3SBarry Smith PetscIntView(cnt,workid,0); 97242eaa7f3SBarry Smith ierr = PetscSortIntWithArray(cnt,workparentid,workid);CHKERRQ(ierr); 97342eaa7f3SBarry Smith PetscIntView(cnt,workparentid,0); 97442eaa7f3SBarry Smith PetscIntView(cnt,workid,0);*/ 975*580bdb30SBarry Smith ierr = PetscArraycpy(idbylevel+tcnt,workid,cnt);CHKERRQ(ierr); 97642eaa7f3SBarry Smith tcnt += cnt; 97742eaa7f3SBarry Smith } 97842eaa7f3SBarry Smith if (tcnt != nmask) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Inconsistent count of unmasked nodes"); 97942eaa7f3SBarry Smith ierr = PetscFree2(workid,workparentid);CHKERRQ(ierr); 98042eaa7f3SBarry Smith 98142eaa7f3SBarry Smith /* for each node list its column */ 982785e854fSJed Brown ierr = PetscMalloc1(n,&column);CHKERRQ(ierr); 98342eaa7f3SBarry Smith cnt = 0; 98442eaa7f3SBarry Smith for (j=0; j<nlevels; j++) { 98542eaa7f3SBarry Smith for (i=0; i<levelcnt[j]; i++) { 98642eaa7f3SBarry Smith column[idbylevel[cnt++]] = i; 98742eaa7f3SBarry Smith } 98842eaa7f3SBarry Smith } 98942eaa7f3SBarry Smith 99042eaa7f3SBarry Smith *Nlevels = nlevels; 99142eaa7f3SBarry Smith *Level = level; 99242eaa7f3SBarry Smith *Levelcnt = levelcnt; 99342eaa7f3SBarry Smith *Idbylevel = idbylevel; 99442eaa7f3SBarry Smith *Column = column; 99542eaa7f3SBarry Smith PetscFunctionReturn(0); 99642eaa7f3SBarry Smith } 997