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 Concepts: sorting^ints 63e5c89e4eSSatish Balay 64e5c89e4eSSatish Balay .seealso: PetscSortReal(), PetscSortIntWithPermutation() 65e5c89e4eSSatish Balay @*/ 667087cfbeSBarry Smith PetscErrorCode PetscSortInt(PetscInt n,PetscInt i[]) 67e5c89e4eSSatish Balay { 68e5c89e4eSSatish Balay PetscInt j,k,tmp,ik; 69e5c89e4eSSatish Balay 70e5c89e4eSSatish Balay PetscFunctionBegin; 71e5c89e4eSSatish Balay if (n<8) { 72e5c89e4eSSatish Balay for (k=0; k<n; k++) { 73e5c89e4eSSatish Balay ik = i[k]; 74e5c89e4eSSatish Balay for (j=k+1; j<n; j++) { 75e5c89e4eSSatish Balay if (ik > i[j]) { 76e5c89e4eSSatish Balay SWAP(i[k],i[j],tmp); 77e5c89e4eSSatish Balay ik = i[k]; 78e5c89e4eSSatish Balay } 79e5c89e4eSSatish Balay } 80e5c89e4eSSatish Balay } 81a297a907SKarl Rupp } else PetscSortInt_Private(i,n-1); 82e5c89e4eSSatish Balay PetscFunctionReturn(0); 83e5c89e4eSSatish Balay } 84e5c89e4eSSatish Balay 851db36a52SBarry Smith /*@ 8622ab5688SLisandro Dalcin PetscSortedRemoveDupsInt - Removes all duplicate entries of a sorted input array 8722ab5688SLisandro Dalcin 8822ab5688SLisandro Dalcin Not Collective 8922ab5688SLisandro Dalcin 9022ab5688SLisandro Dalcin Input Parameters: 9122ab5688SLisandro Dalcin + n - number of values 9222ab5688SLisandro Dalcin - ii - sorted array of integers 9322ab5688SLisandro Dalcin 9422ab5688SLisandro Dalcin Output Parameter: 9522ab5688SLisandro Dalcin . n - number of non-redundant values 9622ab5688SLisandro Dalcin 9722ab5688SLisandro Dalcin Level: intermediate 9822ab5688SLisandro Dalcin 9922ab5688SLisandro Dalcin Concepts: sorting^ints 10022ab5688SLisandro Dalcin 10122ab5688SLisandro Dalcin .seealso: PetscSortInt() 10222ab5688SLisandro Dalcin @*/ 10322ab5688SLisandro Dalcin PetscErrorCode PetscSortedRemoveDupsInt(PetscInt *n,PetscInt ii[]) 10422ab5688SLisandro Dalcin { 10522ab5688SLisandro Dalcin PetscInt i,s = 0,N = *n, b = 0; 10622ab5688SLisandro Dalcin 10722ab5688SLisandro Dalcin PetscFunctionBegin; 10822ab5688SLisandro Dalcin for (i=0; i<N-1; i++) { 10922ab5688SLisandro Dalcin if (PetscUnlikely(ii[b+s+1] < ii[b])) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Input array is not sorted"); 11022ab5688SLisandro Dalcin if (ii[b+s+1] != ii[b]) { 11122ab5688SLisandro Dalcin ii[b+1] = ii[b+s+1]; b++; 11222ab5688SLisandro Dalcin } else s++; 11322ab5688SLisandro Dalcin } 11422ab5688SLisandro Dalcin *n = N - s; 11522ab5688SLisandro Dalcin PetscFunctionReturn(0); 11622ab5688SLisandro Dalcin } 11722ab5688SLisandro Dalcin 11822ab5688SLisandro Dalcin /*@ 1191db36a52SBarry Smith PetscSortRemoveDupsInt - Sorts an array of integers in place in increasing order removes all duplicate entries 1201db36a52SBarry Smith 1211db36a52SBarry Smith Not Collective 1221db36a52SBarry Smith 1231db36a52SBarry Smith Input Parameters: 1241db36a52SBarry Smith + n - number of values 1251db36a52SBarry Smith - ii - array of integers 1261db36a52SBarry Smith 1271db36a52SBarry Smith Output Parameter: 1281db36a52SBarry Smith . n - number of non-redundant values 1291db36a52SBarry Smith 1301db36a52SBarry Smith Level: intermediate 1311db36a52SBarry Smith 1321db36a52SBarry Smith Concepts: sorting^ints 1331db36a52SBarry Smith 13422ab5688SLisandro Dalcin .seealso: PetscSortReal(), PetscSortIntWithPermutation(), PetscSortInt(), PetscSortedRemoveDupsInt() 1351db36a52SBarry Smith @*/ 1367087cfbeSBarry Smith PetscErrorCode PetscSortRemoveDupsInt(PetscInt *n,PetscInt ii[]) 1371db36a52SBarry Smith { 1381db36a52SBarry Smith PetscErrorCode ierr; 1391db36a52SBarry Smith 1401db36a52SBarry Smith PetscFunctionBegin; 14122ab5688SLisandro Dalcin ierr = PetscSortInt(*n,ii);CHKERRQ(ierr); 14222ab5688SLisandro Dalcin ierr = PetscSortedRemoveDupsInt(n,ii);CHKERRQ(ierr); 1431db36a52SBarry Smith PetscFunctionReturn(0); 1441db36a52SBarry Smith } 1451db36a52SBarry Smith 14660e03357SMatthew G Knepley /*@ 147d9f1162dSJed Brown PetscFindInt - Finds integer in a sorted array of integers 14860e03357SMatthew G Knepley 14960e03357SMatthew G Knepley Not Collective 15060e03357SMatthew G Knepley 15160e03357SMatthew G Knepley Input Parameters: 15260e03357SMatthew G Knepley + key - the integer to locate 153d9f1162dSJed Brown . n - number of values in the array 15460e03357SMatthew G Knepley - ii - array of integers 15560e03357SMatthew G Knepley 15660e03357SMatthew G Knepley Output Parameter: 157d9f1162dSJed Brown . loc - the location if found, otherwise -(slot+1) where slot is the place the value would go 15860e03357SMatthew G Knepley 15960e03357SMatthew G Knepley Level: intermediate 16060e03357SMatthew G Knepley 16160e03357SMatthew G Knepley Concepts: sorting^ints 16260e03357SMatthew G Knepley 16360e03357SMatthew G Knepley .seealso: PetscSortInt(), PetscSortIntWithArray(), PetscSortRemoveDupsInt() 16460e03357SMatthew G Knepley @*/ 165026ec6cbSMatthew G Knepley PetscErrorCode PetscFindInt(PetscInt key, PetscInt n, const PetscInt ii[], PetscInt *loc) 16660e03357SMatthew G Knepley { 167d9f1162dSJed Brown PetscInt lo = 0,hi = n; 16860e03357SMatthew G Knepley 16960e03357SMatthew G Knepley PetscFunctionBegin; 17060e03357SMatthew G Knepley PetscValidPointer(loc,4); 17198781d82SMatthew G Knepley if (!n) {*loc = -1; PetscFunctionReturn(0);} 17298781d82SMatthew G Knepley PetscValidPointer(ii,3); 173d9f1162dSJed Brown while (hi - lo > 1) { 174d9f1162dSJed Brown PetscInt mid = lo + (hi - lo)/2; 175d9f1162dSJed Brown if (key < ii[mid]) hi = mid; 176d9f1162dSJed Brown else lo = mid; 17760e03357SMatthew G Knepley } 178d9f1162dSJed Brown *loc = key == ii[lo] ? lo : -(lo + (key > ii[lo]) + 1); 17960e03357SMatthew G Knepley PetscFunctionReturn(0); 18060e03357SMatthew G Knepley } 18160e03357SMatthew G Knepley 182d2aeb606SJed Brown /*@ 183d2aeb606SJed Brown PetscFindMPIInt - Finds MPI integer in a sorted array of integers 184d2aeb606SJed Brown 185d2aeb606SJed Brown Not Collective 186d2aeb606SJed Brown 187d2aeb606SJed Brown Input Parameters: 188d2aeb606SJed Brown + key - the integer to locate 189d2aeb606SJed Brown . n - number of values in the array 190d2aeb606SJed Brown - ii - array of integers 191d2aeb606SJed Brown 192d2aeb606SJed Brown Output Parameter: 193d2aeb606SJed Brown . loc - the location if found, otherwise -(slot+1) where slot is the place the value would go 194d2aeb606SJed Brown 195d2aeb606SJed Brown Level: intermediate 196d2aeb606SJed Brown 197d2aeb606SJed Brown Concepts: sorting^ints 198d2aeb606SJed Brown 199d2aeb606SJed Brown .seealso: PetscSortInt(), PetscSortIntWithArray(), PetscSortRemoveDupsInt() 200d2aeb606SJed Brown @*/ 201d2aeb606SJed Brown PetscErrorCode PetscFindMPIInt(PetscMPIInt key, PetscInt n, const PetscMPIInt ii[], PetscInt *loc) 202d2aeb606SJed Brown { 203d2aeb606SJed Brown PetscInt lo = 0,hi = n; 204d2aeb606SJed Brown 205d2aeb606SJed Brown PetscFunctionBegin; 206d2aeb606SJed Brown PetscValidPointer(loc,4); 207d2aeb606SJed Brown if (!n) {*loc = -1; PetscFunctionReturn(0);} 208d2aeb606SJed Brown PetscValidPointer(ii,3); 209d2aeb606SJed Brown while (hi - lo > 1) { 210d2aeb606SJed Brown PetscInt mid = lo + (hi - lo)/2; 211d2aeb606SJed Brown if (key < ii[mid]) hi = mid; 212d2aeb606SJed Brown else lo = mid; 213d2aeb606SJed Brown } 214d2aeb606SJed Brown *loc = key == ii[lo] ? lo : -(lo + (key > ii[lo]) + 1); 215d2aeb606SJed Brown PetscFunctionReturn(0); 216d2aeb606SJed Brown } 2171db36a52SBarry Smith 218e5c89e4eSSatish Balay /* -----------------------------------------------------------------------*/ 219e5c89e4eSSatish Balay #define SWAP2(a,b,c,d,t) {t=a;a=b;b=t;t=c;c=d;d=t;} 220e5c89e4eSSatish Balay 221e5c89e4eSSatish Balay /* 222e5c89e4eSSatish Balay A simple version of quicksort; taken from Kernighan and Ritchie, page 87. 223e5c89e4eSSatish Balay Assumes 0 origin for v, number of elements = right+1 (right is index of 224e5c89e4eSSatish Balay right-most member). 225e5c89e4eSSatish Balay */ 226e5c89e4eSSatish Balay static PetscErrorCode PetscSortIntWithArray_Private(PetscInt *v,PetscInt *V,PetscInt right) 227e5c89e4eSSatish Balay { 228e5c89e4eSSatish Balay PetscErrorCode ierr; 229e5c89e4eSSatish Balay PetscInt i,vl,last,tmp; 230e5c89e4eSSatish Balay 231e5c89e4eSSatish Balay PetscFunctionBegin; 232e5c89e4eSSatish Balay if (right <= 1) { 233e5c89e4eSSatish Balay if (right == 1) { 234e5c89e4eSSatish Balay if (v[0] > v[1]) SWAP2(v[0],v[1],V[0],V[1],tmp); 235e5c89e4eSSatish Balay } 236e5c89e4eSSatish Balay PetscFunctionReturn(0); 237e5c89e4eSSatish Balay } 238e5c89e4eSSatish Balay SWAP2(v[0],v[right/2],V[0],V[right/2],tmp); 239e5c89e4eSSatish Balay vl = v[0]; 240e5c89e4eSSatish Balay last = 0; 241e5c89e4eSSatish Balay for (i=1; i<=right; i++) { 242e5c89e4eSSatish Balay if (v[i] < vl) {last++; SWAP2(v[last],v[i],V[last],V[i],tmp);} 243e5c89e4eSSatish Balay } 244e5c89e4eSSatish Balay SWAP2(v[0],v[last],V[0],V[last],tmp); 245e5c89e4eSSatish Balay ierr = PetscSortIntWithArray_Private(v,V,last-1);CHKERRQ(ierr); 246e5c89e4eSSatish Balay ierr = PetscSortIntWithArray_Private(v+last+1,V+last+1,right-(last+1));CHKERRQ(ierr); 247e5c89e4eSSatish Balay PetscFunctionReturn(0); 248e5c89e4eSSatish Balay } 249e5c89e4eSSatish Balay 250e5c89e4eSSatish Balay /*@ 251e5c89e4eSSatish Balay PetscSortIntWithArray - Sorts an array of integers in place in increasing order; 252e5c89e4eSSatish Balay changes a second array to match the sorted first array. 253e5c89e4eSSatish Balay 254e5c89e4eSSatish Balay Not Collective 255e5c89e4eSSatish Balay 256e5c89e4eSSatish Balay Input Parameters: 257e5c89e4eSSatish Balay + n - number of values 258e5c89e4eSSatish Balay . i - array of integers 259e5c89e4eSSatish Balay - I - second array of integers 260e5c89e4eSSatish Balay 261e5c89e4eSSatish Balay Level: intermediate 262e5c89e4eSSatish Balay 263e5c89e4eSSatish Balay Concepts: sorting^ints with array 264e5c89e4eSSatish Balay 265e5c89e4eSSatish Balay .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt() 266e5c89e4eSSatish Balay @*/ 2677087cfbeSBarry Smith PetscErrorCode PetscSortIntWithArray(PetscInt n,PetscInt i[],PetscInt Ii[]) 268e5c89e4eSSatish Balay { 269e5c89e4eSSatish Balay PetscErrorCode ierr; 270e5c89e4eSSatish Balay PetscInt j,k,tmp,ik; 271e5c89e4eSSatish Balay 272e5c89e4eSSatish Balay PetscFunctionBegin; 273e5c89e4eSSatish Balay if (n<8) { 274e5c89e4eSSatish Balay for (k=0; k<n; k++) { 275e5c89e4eSSatish Balay ik = i[k]; 276e5c89e4eSSatish Balay for (j=k+1; j<n; j++) { 277e5c89e4eSSatish Balay if (ik > i[j]) { 278b7940d39SSatish Balay SWAP2(i[k],i[j],Ii[k],Ii[j],tmp); 279e5c89e4eSSatish Balay ik = i[k]; 280e5c89e4eSSatish Balay } 281e5c89e4eSSatish Balay } 282e5c89e4eSSatish Balay } 283e5c89e4eSSatish Balay } else { 284b7940d39SSatish Balay ierr = PetscSortIntWithArray_Private(i,Ii,n-1);CHKERRQ(ierr); 285e5c89e4eSSatish Balay } 286e5c89e4eSSatish Balay PetscFunctionReturn(0); 287e5c89e4eSSatish Balay } 288e5c89e4eSSatish Balay 289c1f0200aSDmitry Karpeev 290c1f0200aSDmitry 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;} 291c1f0200aSDmitry Karpeev 292c1f0200aSDmitry Karpeev /* 293c1f0200aSDmitry Karpeev A simple version of quicksort; taken from Kernighan and Ritchie, page 87. 294c1f0200aSDmitry Karpeev Assumes 0 origin for v, number of elements = right+1 (right is index of 295c1f0200aSDmitry Karpeev right-most member). 296c1f0200aSDmitry Karpeev */ 297d7aa01a8SHong Zhang static PetscErrorCode PetscSortIntWithArrayPair_Private(PetscInt *L,PetscInt *J, PetscInt *K, PetscInt right) 298c1f0200aSDmitry Karpeev { 299c1f0200aSDmitry Karpeev PetscErrorCode ierr; 300c1f0200aSDmitry Karpeev PetscInt i,vl,last,tmp; 301c1f0200aSDmitry Karpeev 302c1f0200aSDmitry Karpeev PetscFunctionBegin; 303c1f0200aSDmitry Karpeev if (right <= 1) { 304c1f0200aSDmitry Karpeev if (right == 1) { 305d7aa01a8SHong Zhang if (L[0] > L[1]) SWAP3(L[0],L[1],J[0],J[1],K[0],K[1],tmp); 306c1f0200aSDmitry Karpeev } 307c1f0200aSDmitry Karpeev PetscFunctionReturn(0); 308c1f0200aSDmitry Karpeev } 309d7aa01a8SHong Zhang SWAP3(L[0],L[right/2],J[0],J[right/2],K[0],K[right/2],tmp); 310d7aa01a8SHong Zhang vl = L[0]; 311c1f0200aSDmitry Karpeev last = 0; 312c1f0200aSDmitry Karpeev for (i=1; i<=right; i++) { 313d7aa01a8SHong Zhang if (L[i] < vl) {last++; SWAP3(L[last],L[i],J[last],J[i],K[last],K[i],tmp);} 314c1f0200aSDmitry Karpeev } 315d7aa01a8SHong Zhang SWAP3(L[0],L[last],J[0],J[last],K[0],K[last],tmp); 316d7aa01a8SHong Zhang ierr = PetscSortIntWithArrayPair_Private(L,J,K,last-1);CHKERRQ(ierr); 317d7aa01a8SHong Zhang ierr = PetscSortIntWithArrayPair_Private(L+last+1,J+last+1,K+last+1,right-(last+1));CHKERRQ(ierr); 318c1f0200aSDmitry Karpeev PetscFunctionReturn(0); 319c1f0200aSDmitry Karpeev } 320c1f0200aSDmitry Karpeev 321c1f0200aSDmitry Karpeev /*@ 322c1f0200aSDmitry Karpeev PetscSortIntWithArrayPair - Sorts an array of integers in place in increasing order; 323c1f0200aSDmitry Karpeev changes a pair of integer arrays to match the sorted first array. 324c1f0200aSDmitry Karpeev 325c1f0200aSDmitry Karpeev Not Collective 326c1f0200aSDmitry Karpeev 327c1f0200aSDmitry Karpeev Input Parameters: 328c1f0200aSDmitry Karpeev + n - number of values 329c1f0200aSDmitry Karpeev . I - array of integers 330c1f0200aSDmitry Karpeev . J - second array of integers (first array of the pair) 331c1f0200aSDmitry Karpeev - K - third array of integers (second array of the pair) 332c1f0200aSDmitry Karpeev 333c1f0200aSDmitry Karpeev Level: intermediate 334c1f0200aSDmitry Karpeev 335c1f0200aSDmitry Karpeev Concepts: sorting^ints with array pair 336c1f0200aSDmitry Karpeev 337c1f0200aSDmitry Karpeev .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortIntWithArray() 338c1f0200aSDmitry Karpeev @*/ 3396c2863d0SBarry Smith PetscErrorCode PetscSortIntWithArrayPair(PetscInt n,PetscInt L[],PetscInt J[], PetscInt K[]) 340c1f0200aSDmitry Karpeev { 341c1f0200aSDmitry Karpeev PetscErrorCode ierr; 342c1f0200aSDmitry Karpeev PetscInt j,k,tmp,ik; 343c1f0200aSDmitry Karpeev 344c1f0200aSDmitry Karpeev PetscFunctionBegin; 345c1f0200aSDmitry Karpeev if (n<8) { 346c1f0200aSDmitry Karpeev for (k=0; k<n; k++) { 347d7aa01a8SHong Zhang ik = L[k]; 348c1f0200aSDmitry Karpeev for (j=k+1; j<n; j++) { 349d7aa01a8SHong Zhang if (ik > L[j]) { 350d7aa01a8SHong Zhang SWAP3(L[k],L[j],J[k],J[j],K[k],K[j],tmp); 351d7aa01a8SHong Zhang ik = L[k]; 352c1f0200aSDmitry Karpeev } 353c1f0200aSDmitry Karpeev } 354c1f0200aSDmitry Karpeev } 355c1f0200aSDmitry Karpeev } else { 356d7aa01a8SHong Zhang ierr = PetscSortIntWithArrayPair_Private(L,J,K,n-1);CHKERRQ(ierr); 357c1f0200aSDmitry Karpeev } 358c1f0200aSDmitry Karpeev PetscFunctionReturn(0); 359c1f0200aSDmitry Karpeev } 360c1f0200aSDmitry Karpeev 36117d7d925SStefano Zampini /* 36217d7d925SStefano Zampini A simple version of quicksort; taken from Kernighan and Ritchie, page 87. 36317d7d925SStefano Zampini Assumes 0 origin for v, number of elements = right+1 (right is index of 36417d7d925SStefano Zampini right-most member). 36517d7d925SStefano Zampini */ 36617d7d925SStefano Zampini static void PetscSortMPIInt_Private(PetscMPIInt *v,PetscInt right) 36717d7d925SStefano Zampini { 36817d7d925SStefano Zampini PetscInt i,j; 36917d7d925SStefano Zampini PetscMPIInt pivot,tmp; 37017d7d925SStefano Zampini 37117d7d925SStefano Zampini if (right <= 1) { 37217d7d925SStefano Zampini if (right == 1) { 37317d7d925SStefano Zampini if (v[0] > v[1]) SWAP(v[0],v[1],tmp); 37417d7d925SStefano Zampini } 37517d7d925SStefano Zampini return; 37617d7d925SStefano Zampini } 37717d7d925SStefano Zampini i = MEDIAN(v,right); /* Choose a pivot */ 37817d7d925SStefano Zampini SWAP(v[0],v[i],tmp); /* Move it out of the way */ 37917d7d925SStefano Zampini pivot = v[0]; 38017d7d925SStefano Zampini for (i=0,j=right+1;; ) { 38117d7d925SStefano Zampini while (++i < j && v[i] <= pivot) ; /* Scan from the left */ 38217d7d925SStefano Zampini while (v[--j] > pivot) ; /* Scan from the right */ 38317d7d925SStefano Zampini if (i >= j) break; 38417d7d925SStefano Zampini SWAP(v[i],v[j],tmp); 38517d7d925SStefano Zampini } 38617d7d925SStefano Zampini SWAP(v[0],v[j],tmp); /* Put pivot back in place. */ 38717d7d925SStefano Zampini PetscSortMPIInt_Private(v,j-1); 38817d7d925SStefano Zampini PetscSortMPIInt_Private(v+j+1,right-(j+1)); 38917d7d925SStefano Zampini } 39017d7d925SStefano Zampini 39117d7d925SStefano Zampini /*@ 39217d7d925SStefano Zampini PetscSortMPIInt - Sorts an array of MPI integers in place in increasing order. 39317d7d925SStefano Zampini 39417d7d925SStefano Zampini Not Collective 39517d7d925SStefano Zampini 39617d7d925SStefano Zampini Input Parameters: 39717d7d925SStefano Zampini + n - number of values 39817d7d925SStefano Zampini - i - array of integers 39917d7d925SStefano Zampini 40017d7d925SStefano Zampini Level: intermediate 40117d7d925SStefano Zampini 40217d7d925SStefano Zampini Concepts: sorting^ints 40317d7d925SStefano Zampini 40417d7d925SStefano Zampini .seealso: PetscSortReal(), PetscSortIntWithPermutation() 40517d7d925SStefano Zampini @*/ 40617d7d925SStefano Zampini PetscErrorCode PetscSortMPIInt(PetscInt n,PetscMPIInt i[]) 40717d7d925SStefano Zampini { 40817d7d925SStefano Zampini PetscInt j,k; 40917d7d925SStefano Zampini PetscMPIInt tmp,ik; 41017d7d925SStefano Zampini 41117d7d925SStefano Zampini PetscFunctionBegin; 41217d7d925SStefano Zampini if (n<8) { 41317d7d925SStefano Zampini for (k=0; k<n; k++) { 41417d7d925SStefano Zampini ik = i[k]; 41517d7d925SStefano Zampini for (j=k+1; j<n; j++) { 41617d7d925SStefano Zampini if (ik > i[j]) { 41717d7d925SStefano Zampini SWAP(i[k],i[j],tmp); 41817d7d925SStefano Zampini ik = i[k]; 41917d7d925SStefano Zampini } 42017d7d925SStefano Zampini } 42117d7d925SStefano Zampini } 422a297a907SKarl Rupp } else PetscSortMPIInt_Private(i,n-1); 42317d7d925SStefano Zampini PetscFunctionReturn(0); 42417d7d925SStefano Zampini } 42517d7d925SStefano Zampini 42617d7d925SStefano Zampini /*@ 42717d7d925SStefano Zampini PetscSortRemoveDupsMPIInt - Sorts an array of MPI integers in place in increasing order removes all duplicate entries 42817d7d925SStefano Zampini 42917d7d925SStefano Zampini Not Collective 43017d7d925SStefano Zampini 43117d7d925SStefano Zampini Input Parameters: 43217d7d925SStefano Zampini + n - number of values 43317d7d925SStefano Zampini - ii - array of integers 43417d7d925SStefano Zampini 43517d7d925SStefano Zampini Output Parameter: 43617d7d925SStefano Zampini . n - number of non-redundant values 43717d7d925SStefano Zampini 43817d7d925SStefano Zampini Level: intermediate 43917d7d925SStefano Zampini 44017d7d925SStefano Zampini Concepts: sorting^ints 44117d7d925SStefano Zampini 44217d7d925SStefano Zampini .seealso: PetscSortReal(), PetscSortIntWithPermutation(), PetscSortInt() 44317d7d925SStefano Zampini @*/ 44417d7d925SStefano Zampini PetscErrorCode PetscSortRemoveDupsMPIInt(PetscInt *n,PetscMPIInt ii[]) 44517d7d925SStefano Zampini { 44617d7d925SStefano Zampini PetscErrorCode ierr; 44717d7d925SStefano Zampini PetscInt i,s = 0,N = *n, b = 0; 44817d7d925SStefano Zampini 44917d7d925SStefano Zampini PetscFunctionBegin; 45017d7d925SStefano Zampini ierr = PetscSortMPIInt(N,ii);CHKERRQ(ierr); 45117d7d925SStefano Zampini for (i=0; i<N-1; i++) { 452a297a907SKarl Rupp if (ii[b+s+1] != ii[b]) { 453a297a907SKarl Rupp ii[b+1] = ii[b+s+1]; b++; 454a297a907SKarl Rupp } else s++; 45517d7d925SStefano Zampini } 45617d7d925SStefano Zampini *n = N - s; 45717d7d925SStefano Zampini PetscFunctionReturn(0); 45817d7d925SStefano Zampini } 459c1f0200aSDmitry Karpeev 4604d615ea0SBarry Smith /* 4614d615ea0SBarry Smith A simple version of quicksort; taken from Kernighan and Ritchie, page 87. 4624d615ea0SBarry Smith Assumes 0 origin for v, number of elements = right+1 (right is index of 4634d615ea0SBarry Smith right-most member). 4644d615ea0SBarry Smith */ 4654d615ea0SBarry Smith static PetscErrorCode PetscSortMPIIntWithArray_Private(PetscMPIInt *v,PetscMPIInt *V,PetscMPIInt right) 4664d615ea0SBarry Smith { 4674d615ea0SBarry Smith PetscErrorCode ierr; 4684d615ea0SBarry Smith PetscMPIInt i,vl,last,tmp; 4694d615ea0SBarry Smith 4704d615ea0SBarry Smith PetscFunctionBegin; 4714d615ea0SBarry Smith if (right <= 1) { 4724d615ea0SBarry Smith if (right == 1) { 4734d615ea0SBarry Smith if (v[0] > v[1]) SWAP2(v[0],v[1],V[0],V[1],tmp); 4744d615ea0SBarry Smith } 4754d615ea0SBarry Smith PetscFunctionReturn(0); 4764d615ea0SBarry Smith } 4774d615ea0SBarry Smith SWAP2(v[0],v[right/2],V[0],V[right/2],tmp); 4784d615ea0SBarry Smith vl = v[0]; 4794d615ea0SBarry Smith last = 0; 4804d615ea0SBarry Smith for (i=1; i<=right; i++) { 4814d615ea0SBarry Smith if (v[i] < vl) {last++; SWAP2(v[last],v[i],V[last],V[i],tmp);} 4824d615ea0SBarry Smith } 4834d615ea0SBarry Smith SWAP2(v[0],v[last],V[0],V[last],tmp); 4844d615ea0SBarry Smith ierr = PetscSortMPIIntWithArray_Private(v,V,last-1);CHKERRQ(ierr); 4854d615ea0SBarry Smith ierr = PetscSortMPIIntWithArray_Private(v+last+1,V+last+1,right-(last+1));CHKERRQ(ierr); 4864d615ea0SBarry Smith PetscFunctionReturn(0); 4874d615ea0SBarry Smith } 4884d615ea0SBarry Smith 4894d615ea0SBarry Smith /*@ 4904d615ea0SBarry Smith PetscSortMPIIntWithArray - Sorts an array of integers in place in increasing order; 4914d615ea0SBarry Smith changes a second array to match the sorted first array. 4924d615ea0SBarry Smith 4934d615ea0SBarry Smith Not Collective 4944d615ea0SBarry Smith 4954d615ea0SBarry Smith Input Parameters: 4964d615ea0SBarry Smith + n - number of values 4974d615ea0SBarry Smith . i - array of integers 4984d615ea0SBarry Smith - I - second array of integers 4994d615ea0SBarry Smith 5004d615ea0SBarry Smith Level: intermediate 5014d615ea0SBarry Smith 5024d615ea0SBarry Smith Concepts: sorting^ints with array 5034d615ea0SBarry Smith 5044d615ea0SBarry Smith .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt() 5054d615ea0SBarry Smith @*/ 5067087cfbeSBarry Smith PetscErrorCode PetscSortMPIIntWithArray(PetscMPIInt n,PetscMPIInt i[],PetscMPIInt Ii[]) 5074d615ea0SBarry Smith { 5084d615ea0SBarry Smith PetscErrorCode ierr; 5094d615ea0SBarry Smith PetscMPIInt j,k,tmp,ik; 5104d615ea0SBarry Smith 5114d615ea0SBarry Smith PetscFunctionBegin; 5124d615ea0SBarry Smith if (n<8) { 5134d615ea0SBarry Smith for (k=0; k<n; k++) { 5144d615ea0SBarry Smith ik = i[k]; 5154d615ea0SBarry Smith for (j=k+1; j<n; j++) { 5164d615ea0SBarry Smith if (ik > i[j]) { 5174d615ea0SBarry Smith SWAP2(i[k],i[j],Ii[k],Ii[j],tmp); 5184d615ea0SBarry Smith ik = i[k]; 5194d615ea0SBarry Smith } 5204d615ea0SBarry Smith } 5214d615ea0SBarry Smith } 5224d615ea0SBarry Smith } else { 5234d615ea0SBarry Smith ierr = PetscSortMPIIntWithArray_Private(i,Ii,n-1);CHKERRQ(ierr); 5244d615ea0SBarry Smith } 5254d615ea0SBarry Smith PetscFunctionReturn(0); 5264d615ea0SBarry Smith } 5274d615ea0SBarry Smith 528e5c89e4eSSatish Balay /* -----------------------------------------------------------------------*/ 529e5c89e4eSSatish Balay #define SWAP2IntScalar(a,b,c,d,t,ts) {t=a;a=b;b=t;ts=c;c=d;d=ts;} 530e5c89e4eSSatish Balay 531e5c89e4eSSatish Balay /* 532e5c89e4eSSatish Balay Modified from PetscSortIntWithArray_Private(). 533e5c89e4eSSatish Balay */ 534e5c89e4eSSatish Balay static PetscErrorCode PetscSortIntWithScalarArray_Private(PetscInt *v,PetscScalar *V,PetscInt right) 535e5c89e4eSSatish Balay { 536e5c89e4eSSatish Balay PetscErrorCode ierr; 537e5c89e4eSSatish Balay PetscInt i,vl,last,tmp; 538e5c89e4eSSatish Balay PetscScalar stmp; 539e5c89e4eSSatish Balay 540e5c89e4eSSatish Balay PetscFunctionBegin; 541e5c89e4eSSatish Balay if (right <= 1) { 542e5c89e4eSSatish Balay if (right == 1) { 543e5c89e4eSSatish Balay if (v[0] > v[1]) SWAP2IntScalar(v[0],v[1],V[0],V[1],tmp,stmp); 544e5c89e4eSSatish Balay } 545e5c89e4eSSatish Balay PetscFunctionReturn(0); 546e5c89e4eSSatish Balay } 547e5c89e4eSSatish Balay SWAP2IntScalar(v[0],v[right/2],V[0],V[right/2],tmp,stmp); 548e5c89e4eSSatish Balay vl = v[0]; 549e5c89e4eSSatish Balay last = 0; 550e5c89e4eSSatish Balay for (i=1; i<=right; i++) { 551e5c89e4eSSatish Balay if (v[i] < vl) {last++; SWAP2IntScalar(v[last],v[i],V[last],V[i],tmp,stmp);} 552e5c89e4eSSatish Balay } 553e5c89e4eSSatish Balay SWAP2IntScalar(v[0],v[last],V[0],V[last],tmp,stmp); 554e5c89e4eSSatish Balay ierr = PetscSortIntWithScalarArray_Private(v,V,last-1);CHKERRQ(ierr); 555e5c89e4eSSatish Balay ierr = PetscSortIntWithScalarArray_Private(v+last+1,V+last+1,right-(last+1));CHKERRQ(ierr); 556e5c89e4eSSatish Balay PetscFunctionReturn(0); 557e5c89e4eSSatish Balay } 558e5c89e4eSSatish Balay 559e5c89e4eSSatish Balay /*@ 560e5c89e4eSSatish Balay PetscSortIntWithScalarArray - Sorts an array of integers in place in increasing order; 561e5c89e4eSSatish Balay changes a second SCALAR array to match the sorted first INTEGER array. 562e5c89e4eSSatish Balay 563e5c89e4eSSatish Balay Not Collective 564e5c89e4eSSatish Balay 565e5c89e4eSSatish Balay Input Parameters: 566e5c89e4eSSatish Balay + n - number of values 567e5c89e4eSSatish Balay . i - array of integers 568e5c89e4eSSatish Balay - I - second array of scalars 569e5c89e4eSSatish Balay 570e5c89e4eSSatish Balay Level: intermediate 571e5c89e4eSSatish Balay 572e5c89e4eSSatish Balay Concepts: sorting^ints with array 573e5c89e4eSSatish Balay 574e5c89e4eSSatish Balay .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt(), PetscSortIntWithArray() 575e5c89e4eSSatish Balay @*/ 5767087cfbeSBarry Smith PetscErrorCode PetscSortIntWithScalarArray(PetscInt n,PetscInt i[],PetscScalar Ii[]) 577e5c89e4eSSatish Balay { 578e5c89e4eSSatish Balay PetscErrorCode ierr; 579e5c89e4eSSatish Balay PetscInt j,k,tmp,ik; 580e5c89e4eSSatish Balay PetscScalar stmp; 581e5c89e4eSSatish Balay 582e5c89e4eSSatish Balay PetscFunctionBegin; 583e5c89e4eSSatish Balay if (n<8) { 584e5c89e4eSSatish Balay for (k=0; k<n; k++) { 585e5c89e4eSSatish Balay ik = i[k]; 586e5c89e4eSSatish Balay for (j=k+1; j<n; j++) { 587e5c89e4eSSatish Balay if (ik > i[j]) { 588b7940d39SSatish Balay SWAP2IntScalar(i[k],i[j],Ii[k],Ii[j],tmp,stmp); 589e5c89e4eSSatish Balay ik = i[k]; 590e5c89e4eSSatish Balay } 591e5c89e4eSSatish Balay } 592e5c89e4eSSatish Balay } 593e5c89e4eSSatish Balay } else { 594b7940d39SSatish Balay ierr = PetscSortIntWithScalarArray_Private(i,Ii,n-1);CHKERRQ(ierr); 595e5c89e4eSSatish Balay } 596e5c89e4eSSatish Balay PetscFunctionReturn(0); 597e5c89e4eSSatish Balay } 598e5c89e4eSSatish Balay 599ece8f864SToby Isaac #define SWAP2IntData(a,b,c,d,t,td,siz) \ 600ece8f864SToby Isaac do { \ 601ece8f864SToby Isaac PetscErrorCode _ierr; \ 602ece8f864SToby Isaac t=a;a=b;b=t; \ 603ece8f864SToby Isaac _ierr = PetscMemcpy(td,c,siz);CHKERRQ(_ierr); \ 604ece8f864SToby Isaac _ierr = PetscMemcpy(c,d,siz);CHKERRQ(_ierr); \ 605ece8f864SToby Isaac _ierr = PetscMemcpy(d,td,siz);CHKERRQ(_ierr); \ 606ece8f864SToby Isaac } while(0) 60717df18f2SToby Isaac 60817df18f2SToby Isaac /* 60917df18f2SToby Isaac Modified from PetscSortIntWithArray_Private(). 61017df18f2SToby Isaac */ 61117df18f2SToby Isaac static PetscErrorCode PetscSortIntWithDataArray_Private(PetscInt *v,char *V,PetscInt right,size_t size,void *work) 61217df18f2SToby Isaac { 61317df18f2SToby Isaac PetscErrorCode ierr; 61417df18f2SToby Isaac PetscInt i,vl,last,tmp; 61517df18f2SToby Isaac 61617df18f2SToby Isaac PetscFunctionBegin; 61717df18f2SToby Isaac if (right <= 1) { 61817df18f2SToby Isaac if (right == 1) { 61917df18f2SToby Isaac if (v[0] > v[1]) SWAP2IntData(v[0],v[1],V,V+size,tmp,work,size); 62017df18f2SToby Isaac } 62117df18f2SToby Isaac PetscFunctionReturn(0); 62217df18f2SToby Isaac } 62317df18f2SToby Isaac SWAP2IntData(v[0],v[right/2],V,V+size*(right/2),tmp,work,size); 62417df18f2SToby Isaac vl = v[0]; 62517df18f2SToby Isaac last = 0; 62617df18f2SToby Isaac for (i=1; i<=right; i++) { 62717df18f2SToby Isaac if (v[i] < vl) {last++; SWAP2IntData(v[last],v[i],V+size*last,V+size*i,tmp,work,size);} 62817df18f2SToby Isaac } 62917df18f2SToby Isaac SWAP2IntData(v[0],v[last],V,V + size*last,tmp,work,size); 63017df18f2SToby Isaac ierr = PetscSortIntWithDataArray_Private(v,V,last-1,size,work);CHKERRQ(ierr); 63117df18f2SToby Isaac ierr = PetscSortIntWithDataArray_Private(v+last+1,V+size*(last+1),right-(last+1),size,work);CHKERRQ(ierr); 63217df18f2SToby Isaac PetscFunctionReturn(0); 63317df18f2SToby Isaac } 63417df18f2SToby Isaac 6356c2863d0SBarry Smith /*@C 63617df18f2SToby Isaac PetscSortIntWithDataArray - Sorts an array of integers in place in increasing order; 63717df18f2SToby Isaac changes a second array to match the sorted first INTEGER array. Unlike other sort routines, the user must 63817df18f2SToby Isaac provide workspace (the size of an element in the data array) to use when sorting. 63917df18f2SToby Isaac 64017df18f2SToby Isaac Not Collective 64117df18f2SToby Isaac 64217df18f2SToby Isaac Input Parameters: 64317df18f2SToby Isaac + n - number of values 64417df18f2SToby Isaac . i - array of integers 64517df18f2SToby Isaac . Ii - second array of data 64617df18f2SToby Isaac . size - sizeof elements in the data array in bytes 64717df18f2SToby Isaac - work - workspace of "size" bytes used when sorting 64817df18f2SToby Isaac 64917df18f2SToby Isaac Level: intermediate 65017df18f2SToby Isaac 65117df18f2SToby Isaac Concepts: sorting^ints with array 65217df18f2SToby Isaac 65317df18f2SToby Isaac .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt(), PetscSortIntWithArray() 65417df18f2SToby Isaac @*/ 65517df18f2SToby Isaac PetscErrorCode PetscSortIntWithDataArray(PetscInt n,PetscInt i[],void *Ii,size_t size,void *work) 65617df18f2SToby Isaac { 65717df18f2SToby Isaac char *V = (char *) Ii; 65817df18f2SToby Isaac PetscErrorCode ierr; 65917df18f2SToby Isaac PetscInt j,k,tmp,ik; 66017df18f2SToby Isaac 66117df18f2SToby Isaac PetscFunctionBegin; 66217df18f2SToby Isaac if (n<8) { 66317df18f2SToby Isaac for (k=0; k<n; k++) { 66417df18f2SToby Isaac ik = i[k]; 66517df18f2SToby Isaac for (j=k+1; j<n; j++) { 66617df18f2SToby Isaac if (ik > i[j]) { 66717df18f2SToby Isaac SWAP2IntData(i[k],i[j],V+size*k,V+size*j,tmp,work,size); 66817df18f2SToby Isaac ik = i[k]; 66917df18f2SToby Isaac } 67017df18f2SToby Isaac } 67117df18f2SToby Isaac } 67217df18f2SToby Isaac } else { 67317df18f2SToby Isaac ierr = PetscSortIntWithDataArray_Private(i,V,n-1,size,work);CHKERRQ(ierr); 67417df18f2SToby Isaac } 67517df18f2SToby Isaac PetscFunctionReturn(0); 67617df18f2SToby Isaac } 67717df18f2SToby Isaac 678b4301105SBarry Smith 67921e72a00SBarry Smith /*@ 68021e72a00SBarry Smith PetscMergeIntArray - Merges two SORTED integer arrays, removes duplicate elements. 68121e72a00SBarry Smith 68221e72a00SBarry Smith Not Collective 68321e72a00SBarry Smith 68421e72a00SBarry Smith Input Parameters: 68521e72a00SBarry Smith + an - number of values in the first array 68621e72a00SBarry Smith . aI - first sorted array of integers 68721e72a00SBarry Smith . bn - number of values in the second array 68821e72a00SBarry Smith - bI - second array of integers 68921e72a00SBarry Smith 69021e72a00SBarry Smith Output Parameters: 69121e72a00SBarry Smith + n - number of values in the merged array 6926c2863d0SBarry Smith - L - merged sorted array, this is allocated if an array is not provided 69321e72a00SBarry Smith 69421e72a00SBarry Smith Level: intermediate 69521e72a00SBarry Smith 69621e72a00SBarry Smith Concepts: merging^arrays 69721e72a00SBarry Smith 69821e72a00SBarry Smith .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt(), PetscSortIntWithArray() 69921e72a00SBarry Smith @*/ 7006c2863d0SBarry Smith PetscErrorCode PetscMergeIntArray(PetscInt an,const PetscInt aI[], PetscInt bn, const PetscInt bI[], PetscInt *n, PetscInt **L) 70121e72a00SBarry Smith { 70221e72a00SBarry Smith PetscErrorCode ierr; 70321e72a00SBarry Smith PetscInt *L_ = *L, ak, bk, k; 70421e72a00SBarry Smith 70521e72a00SBarry Smith if (!L_) { 70621e72a00SBarry Smith ierr = PetscMalloc1(an+bn, L);CHKERRQ(ierr); 70721e72a00SBarry Smith L_ = *L; 70821e72a00SBarry Smith } 70921e72a00SBarry Smith k = ak = bk = 0; 71021e72a00SBarry Smith while (ak < an && bk < bn) { 71121e72a00SBarry Smith if (aI[ak] == bI[bk]) { 71221e72a00SBarry Smith L_[k] = aI[ak]; 71321e72a00SBarry Smith ++ak; 71421e72a00SBarry Smith ++bk; 71521e72a00SBarry Smith ++k; 71621e72a00SBarry Smith } else if (aI[ak] < bI[bk]) { 71721e72a00SBarry Smith L_[k] = aI[ak]; 71821e72a00SBarry Smith ++ak; 71921e72a00SBarry Smith ++k; 72021e72a00SBarry Smith } else { 72121e72a00SBarry Smith L_[k] = bI[bk]; 72221e72a00SBarry Smith ++bk; 72321e72a00SBarry Smith ++k; 72421e72a00SBarry Smith } 72521e72a00SBarry Smith } 72621e72a00SBarry Smith if (ak < an) { 72721e72a00SBarry Smith ierr = PetscMemcpy(L_+k,aI+ak,(an-ak)*sizeof(PetscInt));CHKERRQ(ierr); 72821e72a00SBarry Smith k += (an-ak); 72921e72a00SBarry Smith } 73021e72a00SBarry Smith if (bk < bn) { 73121e72a00SBarry Smith ierr = PetscMemcpy(L_+k,bI+bk,(bn-bk)*sizeof(PetscInt));CHKERRQ(ierr); 73221e72a00SBarry Smith k += (bn-bk); 73321e72a00SBarry Smith } 73421e72a00SBarry Smith *n = k; 73521e72a00SBarry Smith PetscFunctionReturn(0); 73621e72a00SBarry Smith } 737b4301105SBarry Smith 738c1f0200aSDmitry Karpeev /*@ 73921e72a00SBarry Smith PetscMergeIntArrayPair - Merges two SORTED integer arrays that share NO common values along with an additional array of integers. 740c1f0200aSDmitry Karpeev The additional arrays are the same length as sorted arrays and are merged 741c1f0200aSDmitry Karpeev in the order determined by the merging of the sorted pair. 742c1f0200aSDmitry Karpeev 743c1f0200aSDmitry Karpeev Not Collective 744c1f0200aSDmitry Karpeev 745c1f0200aSDmitry Karpeev Input Parameters: 746c1f0200aSDmitry Karpeev + an - number of values in the first array 747c1f0200aSDmitry Karpeev . aI - first sorted array of integers 748c1f0200aSDmitry Karpeev . aJ - first additional array of integers 749c1f0200aSDmitry Karpeev . bn - number of values in the second array 750c1f0200aSDmitry Karpeev . bI - second array of integers 751c1f0200aSDmitry Karpeev - bJ - second additional of integers 752c1f0200aSDmitry Karpeev 753c1f0200aSDmitry Karpeev Output Parameters: 754c1f0200aSDmitry Karpeev + n - number of values in the merged array (== an + bn) 75514c49006SJed Brown . L - merged sorted array 756c1f0200aSDmitry Karpeev - J - merged additional array 757c1f0200aSDmitry Karpeev 758*95452b02SPatrick Sanan Notes: 759*95452b02SPatrick 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 760c1f0200aSDmitry Karpeev Level: intermediate 761c1f0200aSDmitry Karpeev 762c1f0200aSDmitry Karpeev Concepts: merging^arrays 763c1f0200aSDmitry Karpeev 764c1f0200aSDmitry Karpeev .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt(), PetscSortIntWithArray() 765c1f0200aSDmitry Karpeev @*/ 7666c2863d0SBarry 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) 767c1f0200aSDmitry Karpeev { 768c1f0200aSDmitry Karpeev PetscErrorCode ierr; 76970d8d27cSBarry Smith PetscInt n_, *L_, *J_, ak, bk, k; 770c1f0200aSDmitry Karpeev 77114c49006SJed Brown PetscFunctionBegin; 77270d8d27cSBarry Smith PetscValidIntPointer(L,8); 77370d8d27cSBarry Smith PetscValidIntPointer(J,9); 774c1f0200aSDmitry Karpeev n_ = an + bn; 775c1f0200aSDmitry Karpeev *n = n_; 77670d8d27cSBarry Smith if (!*L) { 777785e854fSJed Brown ierr = PetscMalloc1(n_, L);CHKERRQ(ierr); 77870d8d27cSBarry Smith } 779d7aa01a8SHong Zhang L_ = *L; 78070d8d27cSBarry Smith if (!*J) { 78170d8d27cSBarry Smith ierr = PetscMalloc1(n_, J);CHKERRQ(ierr); 782c1f0200aSDmitry Karpeev } 783c1f0200aSDmitry Karpeev J_ = *J; 784c1f0200aSDmitry Karpeev k = ak = bk = 0; 785c1f0200aSDmitry Karpeev while (ak < an && bk < bn) { 786c1f0200aSDmitry Karpeev if (aI[ak] <= bI[bk]) { 787d7aa01a8SHong Zhang L_[k] = aI[ak]; 788c1f0200aSDmitry Karpeev J_[k] = aJ[ak]; 789c1f0200aSDmitry Karpeev ++ak; 790c1f0200aSDmitry Karpeev ++k; 791a297a907SKarl Rupp } else { 792d7aa01a8SHong Zhang L_[k] = bI[bk]; 793c1f0200aSDmitry Karpeev J_[k] = bJ[bk]; 794c1f0200aSDmitry Karpeev ++bk; 795c1f0200aSDmitry Karpeev ++k; 796c1f0200aSDmitry Karpeev } 797c1f0200aSDmitry Karpeev } 798c1f0200aSDmitry Karpeev if (ak < an) { 799d7aa01a8SHong Zhang ierr = PetscMemcpy(L_+k,aI+ak,(an-ak)*sizeof(PetscInt));CHKERRQ(ierr); 800c1f0200aSDmitry Karpeev ierr = PetscMemcpy(J_+k,aJ+ak,(an-ak)*sizeof(PetscInt));CHKERRQ(ierr); 801c1f0200aSDmitry Karpeev k += (an-ak); 802c1f0200aSDmitry Karpeev } 803c1f0200aSDmitry Karpeev if (bk < bn) { 804d7aa01a8SHong Zhang ierr = PetscMemcpy(L_+k,bI+bk,(bn-bk)*sizeof(PetscInt));CHKERRQ(ierr); 805c1f0200aSDmitry Karpeev ierr = PetscMemcpy(J_+k,bJ+bk,(bn-bk)*sizeof(PetscInt));CHKERRQ(ierr); 806c1f0200aSDmitry Karpeev } 807c1f0200aSDmitry Karpeev PetscFunctionReturn(0); 808c1f0200aSDmitry Karpeev } 809c1f0200aSDmitry Karpeev 810e498c390SJed Brown /*@ 811e498c390SJed Brown PetscMergeMPIIntArray - Merges two SORTED integer arrays. 812e498c390SJed Brown 813e498c390SJed Brown Not Collective 814e498c390SJed Brown 815e498c390SJed Brown Input Parameters: 816e498c390SJed Brown + an - number of values in the first array 817e498c390SJed Brown . aI - first sorted array of integers 818e498c390SJed Brown . bn - number of values in the second array 819e498c390SJed Brown - bI - second array of integers 820e498c390SJed Brown 821e498c390SJed Brown Output Parameters: 822e498c390SJed Brown + n - number of values in the merged array (<= an + bn) 823e498c390SJed Brown - L - merged sorted array, allocated if address of NULL pointer is passed 824e498c390SJed Brown 825e498c390SJed Brown Level: intermediate 826e498c390SJed Brown 827e498c390SJed Brown Concepts: merging^arrays 828e498c390SJed Brown 829e498c390SJed Brown .seealso: PetscSortReal(), PetscSortIntPermutation(), PetscSortInt(), PetscSortIntWithArray() 830e498c390SJed Brown @*/ 831e498c390SJed Brown PetscErrorCode PetscMergeMPIIntArray(PetscInt an,const PetscMPIInt aI[],PetscInt bn,const PetscMPIInt bI[],PetscInt *n,PetscMPIInt **L) 832e498c390SJed Brown { 833e498c390SJed Brown PetscErrorCode ierr; 834e498c390SJed Brown PetscInt ai,bi,k; 835e498c390SJed Brown 836e498c390SJed Brown PetscFunctionBegin; 837e498c390SJed Brown if (!*L) {ierr = PetscMalloc1((an+bn),L);CHKERRQ(ierr);} 838e498c390SJed Brown for (ai=0,bi=0,k=0; ai<an || bi<bn; ) { 839e498c390SJed Brown PetscInt t = -1; 840e498c390SJed Brown for ( ; ai<an && (!bn || aI[ai] <= bI[bi]); ai++) (*L)[k++] = t = aI[ai]; 841e498c390SJed Brown for ( ; bi<bn && bI[bi] == t; bi++); 842e498c390SJed Brown for ( ; bi<bn && (!an || bI[bi] <= aI[ai]); bi++) (*L)[k++] = t = bI[bi]; 843e498c390SJed Brown for ( ; ai<an && aI[ai] == t; ai++); 844e498c390SJed Brown } 845e498c390SJed Brown *n = k; 846e498c390SJed Brown PetscFunctionReturn(0); 847e498c390SJed Brown } 848e5c89e4eSSatish Balay 8496c2863d0SBarry Smith /*@C 85042eaa7f3SBarry Smith PetscProcessTree - Prepares tree data to be displayed graphically 85142eaa7f3SBarry Smith 85242eaa7f3SBarry Smith Not Collective 85342eaa7f3SBarry Smith 85442eaa7f3SBarry Smith Input Parameters: 85542eaa7f3SBarry Smith + n - number of values 85642eaa7f3SBarry Smith . mask - indicates those entries in the tree, location 0 is always masked 85742eaa7f3SBarry Smith - parentid - indicates the parent of each entry 85842eaa7f3SBarry Smith 85942eaa7f3SBarry Smith Output Parameters: 86042eaa7f3SBarry Smith + Nlevels - the number of levels 86142eaa7f3SBarry Smith . Level - for each node tells its level 86242eaa7f3SBarry Smith . Levelcnts - the number of nodes on each level 86342eaa7f3SBarry Smith . Idbylevel - a list of ids on each of the levels, first level followed by second etc 86442eaa7f3SBarry Smith - Column - for each id tells its column index 86542eaa7f3SBarry Smith 8666c2863d0SBarry Smith Level: developer 86742eaa7f3SBarry Smith 868*95452b02SPatrick Sanan Notes: 869*95452b02SPatrick Sanan This code is not currently used 87042eaa7f3SBarry Smith 87142eaa7f3SBarry Smith .seealso: PetscSortReal(), PetscSortIntWithPermutation() 87242eaa7f3SBarry Smith @*/ 8737087cfbeSBarry Smith PetscErrorCode PetscProcessTree(PetscInt n,const PetscBool mask[],const PetscInt parentid[],PetscInt *Nlevels,PetscInt **Level,PetscInt **Levelcnt,PetscInt **Idbylevel,PetscInt **Column) 87442eaa7f3SBarry Smith { 87542eaa7f3SBarry Smith PetscInt i,j,cnt,nmask = 0,nlevels = 0,*level,*levelcnt,levelmax = 0,*workid,*workparentid,tcnt = 0,*idbylevel,*column; 87642eaa7f3SBarry Smith PetscErrorCode ierr; 877ace3abfcSBarry Smith PetscBool done = PETSC_FALSE; 87842eaa7f3SBarry Smith 87942eaa7f3SBarry Smith PetscFunctionBegin; 88042eaa7f3SBarry Smith if (!mask[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mask of 0th location must be set"); 88142eaa7f3SBarry Smith for (i=0; i<n; i++) { 88242eaa7f3SBarry Smith if (mask[i]) continue; 88342eaa7f3SBarry Smith if (parentid[i] == i) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Node labeled as own parent"); 88442eaa7f3SBarry Smith if (parentid[i] && mask[parentid[i]]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Parent is masked"); 88542eaa7f3SBarry Smith } 88642eaa7f3SBarry Smith 88742eaa7f3SBarry Smith for (i=0; i<n; i++) { 88842eaa7f3SBarry Smith if (!mask[i]) nmask++; 88942eaa7f3SBarry Smith } 89042eaa7f3SBarry Smith 89142eaa7f3SBarry Smith /* determine the level in the tree of each node */ 8921795a4d1SJed Brown ierr = PetscCalloc1(n,&level);CHKERRQ(ierr); 893a297a907SKarl Rupp 89442eaa7f3SBarry Smith level[0] = 1; 89542eaa7f3SBarry Smith while (!done) { 89642eaa7f3SBarry Smith done = PETSC_TRUE; 89742eaa7f3SBarry Smith for (i=0; i<n; i++) { 89842eaa7f3SBarry Smith if (mask[i]) continue; 89942eaa7f3SBarry Smith if (!level[i] && level[parentid[i]]) level[i] = level[parentid[i]] + 1; 90042eaa7f3SBarry Smith else if (!level[i]) done = PETSC_FALSE; 90142eaa7f3SBarry Smith } 90242eaa7f3SBarry Smith } 90342eaa7f3SBarry Smith for (i=0; i<n; i++) { 90442eaa7f3SBarry Smith level[i]--; 90542eaa7f3SBarry Smith nlevels = PetscMax(nlevels,level[i]); 90642eaa7f3SBarry Smith } 90742eaa7f3SBarry Smith 90842eaa7f3SBarry Smith /* count the number of nodes on each level and its max */ 9091795a4d1SJed Brown ierr = PetscCalloc1(nlevels,&levelcnt);CHKERRQ(ierr); 91042eaa7f3SBarry Smith for (i=0; i<n; i++) { 91142eaa7f3SBarry Smith if (mask[i]) continue; 91242eaa7f3SBarry Smith levelcnt[level[i]-1]++; 91342eaa7f3SBarry Smith } 914a297a907SKarl Rupp for (i=0; i<nlevels;i++) levelmax = PetscMax(levelmax,levelcnt[i]); 91542eaa7f3SBarry Smith 91642eaa7f3SBarry Smith /* for each level sort the ids by the parent id */ 917dcca6d9dSJed Brown ierr = PetscMalloc2(levelmax,&workid,levelmax,&workparentid);CHKERRQ(ierr); 918785e854fSJed Brown ierr = PetscMalloc1(nmask,&idbylevel);CHKERRQ(ierr); 91942eaa7f3SBarry Smith for (j=1; j<=nlevels;j++) { 92042eaa7f3SBarry Smith cnt = 0; 92142eaa7f3SBarry Smith for (i=0; i<n; i++) { 92242eaa7f3SBarry Smith if (mask[i]) continue; 92342eaa7f3SBarry Smith if (level[i] != j) continue; 92442eaa7f3SBarry Smith workid[cnt] = i; 92542eaa7f3SBarry Smith workparentid[cnt++] = parentid[i]; 92642eaa7f3SBarry Smith } 92742eaa7f3SBarry Smith /* PetscIntView(cnt,workparentid,0); 92842eaa7f3SBarry Smith PetscIntView(cnt,workid,0); 92942eaa7f3SBarry Smith ierr = PetscSortIntWithArray(cnt,workparentid,workid);CHKERRQ(ierr); 93042eaa7f3SBarry Smith PetscIntView(cnt,workparentid,0); 93142eaa7f3SBarry Smith PetscIntView(cnt,workid,0);*/ 93242eaa7f3SBarry Smith ierr = PetscMemcpy(idbylevel+tcnt,workid,cnt*sizeof(PetscInt));CHKERRQ(ierr); 93342eaa7f3SBarry Smith tcnt += cnt; 93442eaa7f3SBarry Smith } 93542eaa7f3SBarry Smith if (tcnt != nmask) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Inconsistent count of unmasked nodes"); 93642eaa7f3SBarry Smith ierr = PetscFree2(workid,workparentid);CHKERRQ(ierr); 93742eaa7f3SBarry Smith 93842eaa7f3SBarry Smith /* for each node list its column */ 939785e854fSJed Brown ierr = PetscMalloc1(n,&column);CHKERRQ(ierr); 94042eaa7f3SBarry Smith cnt = 0; 94142eaa7f3SBarry Smith for (j=0; j<nlevels; j++) { 94242eaa7f3SBarry Smith for (i=0; i<levelcnt[j]; i++) { 94342eaa7f3SBarry Smith column[idbylevel[cnt++]] = i; 94442eaa7f3SBarry Smith } 94542eaa7f3SBarry Smith } 94642eaa7f3SBarry Smith 94742eaa7f3SBarry Smith *Nlevels = nlevels; 94842eaa7f3SBarry Smith *Level = level; 94942eaa7f3SBarry Smith *Levelcnt = levelcnt; 95042eaa7f3SBarry Smith *Idbylevel = idbylevel; 95142eaa7f3SBarry Smith *Column = column; 95242eaa7f3SBarry Smith PetscFunctionReturn(0); 95342eaa7f3SBarry Smith } 954