17d0a6c19SBarry Smith 2e5c89e4eSSatish Balay /* 3e5c89e4eSSatish Balay This file contains routines for sorting integers. Values are sorted in place. 4c4762a1bSJed Brown One can use src/sys/tests/ex52.c for benchmarking. 5e5c89e4eSSatish Balay */ 6af0996ceSBarry Smith #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/ 7f1cab4e1SJunchao Zhang #include <petsc/private/hashseti.h> 8e5c89e4eSSatish Balay 99371c9d4SSatish Balay #define MEDIAN3(v, a, b, c) (v[a] < v[b] ? (v[b] < v[c] ? (b) : (v[a] < v[c] ? (c) : (a))) : (v[c] < v[b] ? (b) : (v[a] < v[c] ? (a) : (c)))) 10a8582168SJed Brown 11a8582168SJed Brown #define MEDIAN(v, right) MEDIAN3(v, right / 4, right / 2, right / 4 * 3) 12ef8e3583SJed Brown 1359e16d97SJunchao Zhang /* Swap one, two or three pairs. Each pair can have its own type */ 149371c9d4SSatish Balay #define SWAP1(a, b, t1) \ 159371c9d4SSatish Balay do { \ 169371c9d4SSatish Balay t1 = a; \ 179371c9d4SSatish Balay a = b; \ 189371c9d4SSatish Balay b = t1; \ 199371c9d4SSatish Balay } while (0) 209371c9d4SSatish Balay #define SWAP2(a, b, c, d, t1, t2) \ 219371c9d4SSatish Balay do { \ 229371c9d4SSatish Balay t1 = a; \ 239371c9d4SSatish Balay a = b; \ 249371c9d4SSatish Balay b = t1; \ 259371c9d4SSatish Balay t2 = c; \ 269371c9d4SSatish Balay c = d; \ 279371c9d4SSatish Balay d = t2; \ 289371c9d4SSatish Balay } while (0) 299371c9d4SSatish Balay #define SWAP3(a, b, c, d, e, f, t1, t2, t3) \ 309371c9d4SSatish Balay do { \ 319371c9d4SSatish Balay t1 = a; \ 329371c9d4SSatish Balay a = b; \ 339371c9d4SSatish Balay b = t1; \ 349371c9d4SSatish Balay t2 = c; \ 359371c9d4SSatish Balay c = d; \ 369371c9d4SSatish Balay d = t2; \ 379371c9d4SSatish Balay t3 = e; \ 389371c9d4SSatish Balay e = f; \ 399371c9d4SSatish Balay f = t3; \ 409371c9d4SSatish Balay } while (0) 4159e16d97SJunchao Zhang 4259e16d97SJunchao Zhang /* Swap a & b, *c & *d. c, d, t2 are pointers to a type of size <siz> */ 4359e16d97SJunchao Zhang #define SWAP2Data(a, b, c, d, t1, t2, siz) \ 4459e16d97SJunchao Zhang do { \ 459371c9d4SSatish Balay t1 = a; \ 469371c9d4SSatish Balay a = b; \ 479371c9d4SSatish Balay b = t1; \ 489566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(t2, c, siz)); \ 499566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(c, d, siz)); \ 509566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(d, t2, siz)); \ 5159e16d97SJunchao Zhang } while (0) 52e5c89e4eSSatish Balay 53e5c89e4eSSatish Balay /* 5459e16d97SJunchao Zhang Partition X[lo,hi] into two parts: X[lo,l) <= pivot; X[r,hi] > pivot 55e5c89e4eSSatish Balay 5659e16d97SJunchao Zhang Input Parameters: 5759e16d97SJunchao Zhang + X - array to partition 5859e16d97SJunchao Zhang . pivot - a pivot of X[] 5959e16d97SJunchao Zhang . t1 - temp variable for X 6059e16d97SJunchao Zhang - lo,hi - lower and upper bound of the array 6159e16d97SJunchao Zhang 6259e16d97SJunchao Zhang Output Parameters: 6359e16d97SJunchao Zhang + l,r - of type PetscInt 6459e16d97SJunchao Zhang 6559e16d97SJunchao Zhang Notes: 6659e16d97SJunchao Zhang The TwoWayPartition2/3 variants also partition other arrays along with X. 6759e16d97SJunchao Zhang These arrays can have different types, so they provide their own temp t2,t3 6859e16d97SJunchao Zhang */ 6959e16d97SJunchao Zhang #define TwoWayPartition1(X, pivot, t1, lo, hi, l, r) \ 7059e16d97SJunchao Zhang do { \ 7159e16d97SJunchao Zhang l = lo; \ 7259e16d97SJunchao Zhang r = hi; \ 7359e16d97SJunchao Zhang while (1) { \ 7459e16d97SJunchao Zhang while (X[l] < pivot) l++; \ 7559e16d97SJunchao Zhang while (X[r] > pivot) r--; \ 769371c9d4SSatish Balay if (l >= r) { \ 779371c9d4SSatish Balay r++; \ 789371c9d4SSatish Balay break; \ 799371c9d4SSatish Balay } \ 8059e16d97SJunchao Zhang SWAP1(X[l], X[r], t1); \ 8159e16d97SJunchao Zhang l++; \ 8259e16d97SJunchao Zhang r--; \ 8359e16d97SJunchao Zhang } \ 8459e16d97SJunchao Zhang } while (0) 8559e16d97SJunchao Zhang 86ce605777SToby Isaac /* 87ce605777SToby Isaac Partition X[lo,hi] into two parts: X[lo,l) >= pivot; X[r,hi] < pivot 88ce605777SToby Isaac 89ce605777SToby Isaac Input Parameters: 90ce605777SToby Isaac + X - array to partition 91ce605777SToby Isaac . pivot - a pivot of X[] 92ce605777SToby Isaac . t1 - temp variable for X 93ce605777SToby Isaac - lo,hi - lower and upper bound of the array 94ce605777SToby Isaac 95ce605777SToby Isaac Output Parameters: 96ce605777SToby Isaac + l,r - of type PetscInt 97ce605777SToby Isaac 98ce605777SToby Isaac Notes: 99ce605777SToby Isaac The TwoWayPartition2/3 variants also partition other arrays along with X. 100ce605777SToby Isaac These arrays can have different types, so they provide their own temp t2,t3 101ce605777SToby Isaac */ 102ce605777SToby Isaac #define TwoWayPartitionReverse1(X, pivot, t1, lo, hi, l, r) \ 103ce605777SToby Isaac do { \ 104ce605777SToby Isaac l = lo; \ 105ce605777SToby Isaac r = hi; \ 106ce605777SToby Isaac while (1) { \ 107ce605777SToby Isaac while (X[l] > pivot) l++; \ 108ce605777SToby Isaac while (X[r] < pivot) r--; \ 1099371c9d4SSatish Balay if (l >= r) { \ 1109371c9d4SSatish Balay r++; \ 1119371c9d4SSatish Balay break; \ 1129371c9d4SSatish Balay } \ 113ce605777SToby Isaac SWAP1(X[l], X[r], t1); \ 114ce605777SToby Isaac l++; \ 115ce605777SToby Isaac r--; \ 116ce605777SToby Isaac } \ 117ce605777SToby Isaac } while (0) 118ce605777SToby Isaac 11959e16d97SJunchao Zhang #define TwoWayPartition2(X, Y, pivot, t1, t2, lo, hi, l, r) \ 12059e16d97SJunchao Zhang do { \ 12159e16d97SJunchao Zhang l = lo; \ 12259e16d97SJunchao Zhang r = hi; \ 12359e16d97SJunchao Zhang while (1) { \ 12459e16d97SJunchao Zhang while (X[l] < pivot) l++; \ 12559e16d97SJunchao Zhang while (X[r] > pivot) r--; \ 1269371c9d4SSatish Balay if (l >= r) { \ 1279371c9d4SSatish Balay r++; \ 1289371c9d4SSatish Balay break; \ 1299371c9d4SSatish Balay } \ 13059e16d97SJunchao Zhang SWAP2(X[l], X[r], Y[l], Y[r], t1, t2); \ 13159e16d97SJunchao Zhang l++; \ 13259e16d97SJunchao Zhang r--; \ 13359e16d97SJunchao Zhang } \ 13459e16d97SJunchao Zhang } while (0) 13559e16d97SJunchao Zhang 13659e16d97SJunchao Zhang #define TwoWayPartition3(X, Y, Z, pivot, t1, t2, t3, lo, hi, l, r) \ 13759e16d97SJunchao Zhang do { \ 13859e16d97SJunchao Zhang l = lo; \ 13959e16d97SJunchao Zhang r = hi; \ 14059e16d97SJunchao Zhang while (1) { \ 14159e16d97SJunchao Zhang while (X[l] < pivot) l++; \ 14259e16d97SJunchao Zhang while (X[r] > pivot) r--; \ 1439371c9d4SSatish Balay if (l >= r) { \ 1449371c9d4SSatish Balay r++; \ 1459371c9d4SSatish Balay break; \ 1469371c9d4SSatish Balay } \ 14759e16d97SJunchao Zhang SWAP3(X[l], X[r], Y[l], Y[r], Z[l], Z[r], t1, t2, t3); \ 14859e16d97SJunchao Zhang l++; \ 14959e16d97SJunchao Zhang r--; \ 15059e16d97SJunchao Zhang } \ 15159e16d97SJunchao Zhang } while (0) 15259e16d97SJunchao Zhang 15359e16d97SJunchao Zhang /* Templates for similar functions used below */ 1545f80ce2aSJacob Faibussowitsch #define QuickSort1(FuncName, X, n, pivot, t1) \ 15559e16d97SJunchao Zhang do { \ 156981bb840SJunchao Zhang PetscCount i, j, p, l, r, hi = n - 1; \ 15759e16d97SJunchao Zhang if (n < 8) { \ 15859e16d97SJunchao Zhang for (i = 0; i < n; i++) { \ 15959e16d97SJunchao Zhang pivot = X[i]; \ 16059e16d97SJunchao Zhang for (j = i + 1; j < n; j++) { \ 16159e16d97SJunchao Zhang if (pivot > X[j]) { \ 16259e16d97SJunchao Zhang SWAP1(X[i], X[j], t1); \ 16359e16d97SJunchao Zhang pivot = X[i]; \ 16459e16d97SJunchao Zhang } \ 16559e16d97SJunchao Zhang } \ 16659e16d97SJunchao Zhang } \ 16759e16d97SJunchao Zhang } else { \ 16859e16d97SJunchao Zhang p = MEDIAN(X, hi); \ 16959e16d97SJunchao Zhang pivot = X[p]; \ 17059e16d97SJunchao Zhang TwoWayPartition1(X, pivot, t1, 0, hi, l, r); \ 1719566063dSJacob Faibussowitsch PetscCall(FuncName(l, X)); \ 1729566063dSJacob Faibussowitsch PetscCall(FuncName(hi - r + 1, X + r)); \ 17359e16d97SJunchao Zhang } \ 17459e16d97SJunchao Zhang } while (0) 17559e16d97SJunchao Zhang 176ce605777SToby Isaac /* Templates for similar functions used below */ 1775f80ce2aSJacob Faibussowitsch #define QuickSortReverse1(FuncName, X, n, pivot, t1) \ 178ce605777SToby Isaac do { \ 179981bb840SJunchao Zhang PetscCount i, j, p, l, r, hi = n - 1; \ 180ce605777SToby Isaac if (n < 8) { \ 181ce605777SToby Isaac for (i = 0; i < n; i++) { \ 182ce605777SToby Isaac pivot = X[i]; \ 183ce605777SToby Isaac for (j = i + 1; j < n; j++) { \ 184ce605777SToby Isaac if (pivot < X[j]) { \ 185ce605777SToby Isaac SWAP1(X[i], X[j], t1); \ 186ce605777SToby Isaac pivot = X[i]; \ 187ce605777SToby Isaac } \ 188ce605777SToby Isaac } \ 189ce605777SToby Isaac } \ 190ce605777SToby Isaac } else { \ 191ce605777SToby Isaac p = MEDIAN(X, hi); \ 192ce605777SToby Isaac pivot = X[p]; \ 193ce605777SToby Isaac TwoWayPartitionReverse1(X, pivot, t1, 0, hi, l, r); \ 1949566063dSJacob Faibussowitsch PetscCall(FuncName(l, X)); \ 1959566063dSJacob Faibussowitsch PetscCall(FuncName(hi - r + 1, X + r)); \ 196ce605777SToby Isaac } \ 197ce605777SToby Isaac } while (0) 198ce605777SToby Isaac 1995f80ce2aSJacob Faibussowitsch #define QuickSort2(FuncName, X, Y, n, pivot, t1, t2) \ 20059e16d97SJunchao Zhang do { \ 201981bb840SJunchao Zhang PetscCount i, j, p, l, r, hi = n - 1; \ 20259e16d97SJunchao Zhang if (n < 8) { \ 20359e16d97SJunchao Zhang for (i = 0; i < n; i++) { \ 20459e16d97SJunchao Zhang pivot = X[i]; \ 20559e16d97SJunchao Zhang for (j = i + 1; j < n; j++) { \ 20659e16d97SJunchao Zhang if (pivot > X[j]) { \ 20759e16d97SJunchao Zhang SWAP2(X[i], X[j], Y[i], Y[j], t1, t2); \ 20859e16d97SJunchao Zhang pivot = X[i]; \ 20959e16d97SJunchao Zhang } \ 21059e16d97SJunchao Zhang } \ 21159e16d97SJunchao Zhang } \ 21259e16d97SJunchao Zhang } else { \ 21359e16d97SJunchao Zhang p = MEDIAN(X, hi); \ 21459e16d97SJunchao Zhang pivot = X[p]; \ 21559e16d97SJunchao Zhang TwoWayPartition2(X, Y, pivot, t1, t2, 0, hi, l, r); \ 2169566063dSJacob Faibussowitsch PetscCall(FuncName(l, X, Y)); \ 2179566063dSJacob Faibussowitsch PetscCall(FuncName(hi - r + 1, X + r, Y + r)); \ 21859e16d97SJunchao Zhang } \ 21959e16d97SJunchao Zhang } while (0) 22059e16d97SJunchao Zhang 2215f80ce2aSJacob Faibussowitsch #define QuickSort3(FuncName, X, Y, Z, n, pivot, t1, t2, t3) \ 22259e16d97SJunchao Zhang do { \ 223981bb840SJunchao Zhang PetscCount i, j, p, l, r, hi = n - 1; \ 22459e16d97SJunchao Zhang if (n < 8) { \ 22559e16d97SJunchao Zhang for (i = 0; i < n; i++) { \ 22659e16d97SJunchao Zhang pivot = X[i]; \ 22759e16d97SJunchao Zhang for (j = i + 1; j < n; j++) { \ 22859e16d97SJunchao Zhang if (pivot > X[j]) { \ 22959e16d97SJunchao Zhang SWAP3(X[i], X[j], Y[i], Y[j], Z[i], Z[j], t1, t2, t3); \ 23059e16d97SJunchao Zhang pivot = X[i]; \ 23159e16d97SJunchao Zhang } \ 23259e16d97SJunchao Zhang } \ 23359e16d97SJunchao Zhang } \ 23459e16d97SJunchao Zhang } else { \ 23559e16d97SJunchao Zhang p = MEDIAN(X, hi); \ 23659e16d97SJunchao Zhang pivot = X[p]; \ 23759e16d97SJunchao Zhang TwoWayPartition3(X, Y, Z, pivot, t1, t2, t3, 0, hi, l, r); \ 2389566063dSJacob Faibussowitsch PetscCall(FuncName(l, X, Y, Z)); \ 2399566063dSJacob Faibussowitsch PetscCall(FuncName(hi - r + 1, X + r, Y + r, Z + r)); \ 24059e16d97SJunchao Zhang } \ 24159e16d97SJunchao Zhang } while (0) 242e5c89e4eSSatish Balay 243e5c89e4eSSatish Balay /*@ 2446a7c706bSVaclav Hapla PetscSortedInt - Determines whether the array is sorted. 2456a7c706bSVaclav Hapla 2466a7c706bSVaclav Hapla Not Collective 2476a7c706bSVaclav Hapla 2486a7c706bSVaclav Hapla Input Parameters: 2496a7c706bSVaclav Hapla + n - number of values 2506a7c706bSVaclav Hapla - X - array of integers 2516a7c706bSVaclav Hapla 2526a7c706bSVaclav Hapla Output Parameters: 2536a7c706bSVaclav Hapla . sorted - flag whether the array is sorted 2546a7c706bSVaclav Hapla 2556a7c706bSVaclav Hapla Level: intermediate 2566a7c706bSVaclav Hapla 257db781477SPatrick Sanan .seealso: `PetscSortInt()`, `PetscSortedMPIInt()`, `PetscSortedReal()` 2586a7c706bSVaclav Hapla @*/ 2599371c9d4SSatish Balay PetscErrorCode PetscSortedInt(PetscInt n, const PetscInt X[], PetscBool *sorted) { 2606a7c706bSVaclav Hapla PetscFunctionBegin; 2615f80ce2aSJacob Faibussowitsch if (n) PetscValidIntPointer(X, 2); 2625f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(sorted, 3); 2636a7c706bSVaclav Hapla PetscSorted(n, X, *sorted); 2646a7c706bSVaclav Hapla PetscFunctionReturn(0); 2656a7c706bSVaclav Hapla } 2666a7c706bSVaclav Hapla 2676a7c706bSVaclav Hapla /*@ 268e5c89e4eSSatish Balay PetscSortInt - Sorts an array of integers in place in increasing order. 269e5c89e4eSSatish Balay 270e5c89e4eSSatish Balay Not Collective 271e5c89e4eSSatish Balay 272e5c89e4eSSatish Balay Input Parameters: 273e5c89e4eSSatish Balay + n - number of values 27459e16d97SJunchao Zhang - X - array of integers 275e5c89e4eSSatish Balay 276676f2a66SJacob Faibussowitsch Notes: 277676f2a66SJacob Faibussowitsch This function serves as an alternative to PetscIntSortSemiOrdered(), and may perform faster especially if the array 278a5b23f4aSJose E. Roman is completely random. There are exceptions to this and so it is __highly__ recommended that the user benchmark their 279676f2a66SJacob Faibussowitsch code to see which routine is fastest. 280676f2a66SJacob Faibussowitsch 281e5c89e4eSSatish Balay Level: intermediate 282e5c89e4eSSatish Balay 283db781477SPatrick Sanan .seealso: `PetscIntSortSemiOrdered()`, `PetscSortReal()`, `PetscSortIntWithPermutation()` 284e5c89e4eSSatish Balay @*/ 2859371c9d4SSatish Balay PetscErrorCode PetscSortInt(PetscInt n, PetscInt X[]) { 28659e16d97SJunchao Zhang PetscInt pivot, t1; 287e5c89e4eSSatish Balay 288e5c89e4eSSatish Balay PetscFunctionBegin; 2895f80ce2aSJacob Faibussowitsch if (n) PetscValidIntPointer(X, 2); 2905f80ce2aSJacob Faibussowitsch QuickSort1(PetscSortInt, X, n, pivot, t1); 291e5c89e4eSSatish Balay PetscFunctionReturn(0); 292e5c89e4eSSatish Balay } 293e5c89e4eSSatish Balay 2941db36a52SBarry Smith /*@ 295ce605777SToby Isaac PetscSortReverseInt - Sorts an array of integers in place in decreasing order. 296ce605777SToby Isaac 297ce605777SToby Isaac Not Collective 298ce605777SToby Isaac 299ce605777SToby Isaac Input Parameters: 300ce605777SToby Isaac + n - number of values 301ce605777SToby Isaac - X - array of integers 302ce605777SToby Isaac 303ce605777SToby Isaac Level: intermediate 304ce605777SToby Isaac 305db781477SPatrick Sanan .seealso: `PetscIntSortSemiOrdered()`, `PetscSortInt()`, `PetscSortIntWithPermutation()` 306ce605777SToby Isaac @*/ 3079371c9d4SSatish Balay PetscErrorCode PetscSortReverseInt(PetscInt n, PetscInt X[]) { 308ce605777SToby Isaac PetscInt pivot, t1; 309ce605777SToby Isaac 310ce605777SToby Isaac PetscFunctionBegin; 3115f80ce2aSJacob Faibussowitsch if (n) PetscValidIntPointer(X, 2); 3125f80ce2aSJacob Faibussowitsch QuickSortReverse1(PetscSortReverseInt, X, n, pivot, t1); 313ce605777SToby Isaac PetscFunctionReturn(0); 314ce605777SToby Isaac } 315ce605777SToby Isaac 316ce605777SToby Isaac /*@ 31722ab5688SLisandro Dalcin PetscSortedRemoveDupsInt - Removes all duplicate entries of a sorted input array 31822ab5688SLisandro Dalcin 31922ab5688SLisandro Dalcin Not Collective 32022ab5688SLisandro Dalcin 32122ab5688SLisandro Dalcin Input Parameters: 32222ab5688SLisandro Dalcin + n - number of values 32359e16d97SJunchao Zhang - X - sorted array of integers 32422ab5688SLisandro Dalcin 32522ab5688SLisandro Dalcin Output Parameter: 32622ab5688SLisandro Dalcin . n - number of non-redundant values 32722ab5688SLisandro Dalcin 32822ab5688SLisandro Dalcin Level: intermediate 32922ab5688SLisandro Dalcin 330db781477SPatrick Sanan .seealso: `PetscSortInt()` 33122ab5688SLisandro Dalcin @*/ 3329371c9d4SSatish Balay PetscErrorCode PetscSortedRemoveDupsInt(PetscInt *n, PetscInt X[]) { 33322ab5688SLisandro Dalcin PetscInt i, s = 0, N = *n, b = 0; 33422ab5688SLisandro Dalcin 33522ab5688SLisandro Dalcin PetscFunctionBegin; 3365f80ce2aSJacob Faibussowitsch PetscValidIntPointer(n, 1); 337fb61b9e4SStefano Zampini PetscCheckSorted(*n, X); 33822ab5688SLisandro Dalcin for (i = 0; i < N - 1; i++) { 33959e16d97SJunchao Zhang if (X[b + s + 1] != X[b]) { 3409371c9d4SSatish Balay X[b + 1] = X[b + s + 1]; 3419371c9d4SSatish Balay b++; 34222ab5688SLisandro Dalcin } else s++; 34322ab5688SLisandro Dalcin } 34422ab5688SLisandro Dalcin *n = N - s; 34522ab5688SLisandro Dalcin PetscFunctionReturn(0); 34622ab5688SLisandro Dalcin } 34722ab5688SLisandro Dalcin 34822ab5688SLisandro Dalcin /*@ 349b6a18d21SVaclav Hapla PetscSortedCheckDupsInt - Checks if a sorted integer array has duplicates 350b6a18d21SVaclav Hapla 351b6a18d21SVaclav Hapla Not Collective 352b6a18d21SVaclav Hapla 353b6a18d21SVaclav Hapla Input Parameters: 354b6a18d21SVaclav Hapla + n - number of values 355b6a18d21SVaclav Hapla - X - sorted array of integers 356b6a18d21SVaclav Hapla 357b6a18d21SVaclav Hapla Output Parameter: 358b6a18d21SVaclav Hapla . dups - True if the array has dups, otherwise false 359b6a18d21SVaclav Hapla 360b6a18d21SVaclav Hapla Level: intermediate 361b6a18d21SVaclav Hapla 362db781477SPatrick Sanan .seealso: `PetscSortInt()`, `PetscCheckDupsInt()`, `PetscSortRemoveDupsInt()`, `PetscSortedRemoveDupsInt()` 363b6a18d21SVaclav Hapla @*/ 3649371c9d4SSatish Balay PetscErrorCode PetscSortedCheckDupsInt(PetscInt n, const PetscInt X[], PetscBool *flg) { 365b6a18d21SVaclav Hapla PetscInt i; 366b6a18d21SVaclav Hapla 367b6a18d21SVaclav Hapla PetscFunctionBegin; 368b6a18d21SVaclav Hapla PetscCheckSorted(n, X); 369b6a18d21SVaclav Hapla *flg = PETSC_FALSE; 370b6a18d21SVaclav Hapla for (i = 0; i < n - 1; i++) { 371b6a18d21SVaclav Hapla if (X[i + 1] == X[i]) { 372b6a18d21SVaclav Hapla *flg = PETSC_TRUE; 373b6a18d21SVaclav Hapla break; 374b6a18d21SVaclav Hapla } 375b6a18d21SVaclav Hapla } 376b6a18d21SVaclav Hapla PetscFunctionReturn(0); 377b6a18d21SVaclav Hapla } 378b6a18d21SVaclav Hapla 379b6a18d21SVaclav Hapla /*@ 3801db36a52SBarry Smith PetscSortRemoveDupsInt - Sorts an array of integers in place in increasing order removes all duplicate entries 3811db36a52SBarry Smith 3821db36a52SBarry Smith Not Collective 3831db36a52SBarry Smith 3841db36a52SBarry Smith Input Parameters: 3851db36a52SBarry Smith + n - number of values 38659e16d97SJunchao Zhang - X - array of integers 3871db36a52SBarry Smith 3881db36a52SBarry Smith Output Parameter: 3891db36a52SBarry Smith . n - number of non-redundant values 3901db36a52SBarry Smith 3911db36a52SBarry Smith Level: intermediate 3921db36a52SBarry Smith 393db781477SPatrick Sanan .seealso: `PetscIntSortSemiOrdered()`, `PetscSortReal()`, `PetscSortIntWithPermutation()`, `PetscSortInt()`, `PetscSortedRemoveDupsInt()` 3941db36a52SBarry Smith @*/ 3959371c9d4SSatish Balay PetscErrorCode PetscSortRemoveDupsInt(PetscInt *n, PetscInt X[]) { 3961db36a52SBarry Smith PetscFunctionBegin; 3975f80ce2aSJacob Faibussowitsch PetscValidIntPointer(n, 1); 3989566063dSJacob Faibussowitsch PetscCall(PetscSortInt(*n, X)); 3999566063dSJacob Faibussowitsch PetscCall(PetscSortedRemoveDupsInt(n, X)); 4001db36a52SBarry Smith PetscFunctionReturn(0); 4011db36a52SBarry Smith } 4021db36a52SBarry Smith 40360e03357SMatthew G Knepley /*@ 404d9f1162dSJed Brown PetscFindInt - Finds integer in a sorted array of integers 40560e03357SMatthew G Knepley 40660e03357SMatthew G Knepley Not Collective 40760e03357SMatthew G Knepley 40860e03357SMatthew G Knepley Input Parameters: 40960e03357SMatthew G Knepley + key - the integer to locate 410d9f1162dSJed Brown . n - number of values in the array 41159e16d97SJunchao Zhang - X - array of integers 41260e03357SMatthew G Knepley 41360e03357SMatthew G Knepley Output Parameter: 414d9f1162dSJed Brown . loc - the location if found, otherwise -(slot+1) where slot is the place the value would go 41560e03357SMatthew G Knepley 41660e03357SMatthew G Knepley Level: intermediate 41760e03357SMatthew G Knepley 418db781477SPatrick Sanan .seealso: `PetscIntSortSemiOrdered()`, `PetscSortInt()`, `PetscSortIntWithArray()`, `PetscSortRemoveDupsInt()` 41960e03357SMatthew G Knepley @*/ 4209371c9d4SSatish Balay PetscErrorCode PetscFindInt(PetscInt key, PetscInt n, const PetscInt X[], PetscInt *loc) { 421d9f1162dSJed Brown PetscInt lo = 0, hi = n; 42260e03357SMatthew G Knepley 42360e03357SMatthew G Knepley PetscFunctionBegin; 4245f80ce2aSJacob Faibussowitsch PetscValidIntPointer(loc, 4); 4259371c9d4SSatish Balay if (!n) { 4269371c9d4SSatish Balay *loc = -1; 4279371c9d4SSatish Balay PetscFunctionReturn(0); 4289371c9d4SSatish Balay } 429dadcf809SJacob Faibussowitsch PetscValidIntPointer(X, 3); 4306a7c706bSVaclav Hapla PetscCheckSorted(n, X); 431d9f1162dSJed Brown while (hi - lo > 1) { 432d9f1162dSJed Brown PetscInt mid = lo + (hi - lo) / 2; 43359e16d97SJunchao Zhang if (key < X[mid]) hi = mid; 434d9f1162dSJed Brown else lo = mid; 43560e03357SMatthew G Knepley } 43659e16d97SJunchao Zhang *loc = key == X[lo] ? lo : -(lo + (key > X[lo]) + 1); 43760e03357SMatthew G Knepley PetscFunctionReturn(0); 43860e03357SMatthew G Knepley } 43960e03357SMatthew G Knepley 440d2aeb606SJed Brown /*@ 441f1cab4e1SJunchao Zhang PetscCheckDupsInt - Checks if an integer array has duplicates 442f1cab4e1SJunchao Zhang 443f1cab4e1SJunchao Zhang Not Collective 444f1cab4e1SJunchao Zhang 445f1cab4e1SJunchao Zhang Input Parameters: 446f1cab4e1SJunchao Zhang + n - number of values in the array 447f1cab4e1SJunchao Zhang - X - array of integers 448f1cab4e1SJunchao Zhang 449f1cab4e1SJunchao Zhang Output Parameter: 450f1cab4e1SJunchao Zhang . dups - True if the array has dups, otherwise false 451f1cab4e1SJunchao Zhang 452f1cab4e1SJunchao Zhang Level: intermediate 453f1cab4e1SJunchao Zhang 454db781477SPatrick Sanan .seealso: `PetscSortRemoveDupsInt()`, `PetscSortedCheckDupsInt()` 455f1cab4e1SJunchao Zhang @*/ 4569371c9d4SSatish Balay PetscErrorCode PetscCheckDupsInt(PetscInt n, const PetscInt X[], PetscBool *dups) { 457f1cab4e1SJunchao Zhang PetscInt i; 458f1cab4e1SJunchao Zhang PetscHSetI ht; 459f1cab4e1SJunchao Zhang PetscBool missing; 460f1cab4e1SJunchao Zhang 461f1cab4e1SJunchao Zhang PetscFunctionBegin; 4625f80ce2aSJacob Faibussowitsch if (n) PetscValidIntPointer(X, 2); 4635f80ce2aSJacob Faibussowitsch PetscValidBoolPointer(dups, 3); 464f1cab4e1SJunchao Zhang *dups = PETSC_FALSE; 465f1cab4e1SJunchao Zhang if (n > 1) { 4669566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&ht)); 4679566063dSJacob Faibussowitsch PetscCall(PetscHSetIResize(ht, n)); 468f1cab4e1SJunchao Zhang for (i = 0; i < n; i++) { 4699566063dSJacob Faibussowitsch PetscCall(PetscHSetIQueryAdd(ht, X[i], &missing)); 4709371c9d4SSatish Balay if (!missing) { 4719371c9d4SSatish Balay *dups = PETSC_TRUE; 4729371c9d4SSatish Balay break; 4739371c9d4SSatish Balay } 474f1cab4e1SJunchao Zhang } 4759566063dSJacob Faibussowitsch PetscCall(PetscHSetIDestroy(&ht)); 476f1cab4e1SJunchao Zhang } 477f1cab4e1SJunchao Zhang PetscFunctionReturn(0); 478f1cab4e1SJunchao Zhang } 479f1cab4e1SJunchao Zhang 480f1cab4e1SJunchao Zhang /*@ 481d2aeb606SJed Brown PetscFindMPIInt - Finds MPI integer in a sorted array of integers 482d2aeb606SJed Brown 483d2aeb606SJed Brown Not Collective 484d2aeb606SJed Brown 485d2aeb606SJed Brown Input Parameters: 486d2aeb606SJed Brown + key - the integer to locate 487d2aeb606SJed Brown . n - number of values in the array 48859e16d97SJunchao Zhang - X - array of integers 489d2aeb606SJed Brown 490d2aeb606SJed Brown Output Parameter: 491d2aeb606SJed Brown . loc - the location if found, otherwise -(slot+1) where slot is the place the value would go 492d2aeb606SJed Brown 493d2aeb606SJed Brown Level: intermediate 494d2aeb606SJed Brown 495db781477SPatrick Sanan .seealso: `PetscMPIIntSortSemiOrdered()`, `PetscSortInt()`, `PetscSortIntWithArray()`, `PetscSortRemoveDupsInt()` 496d2aeb606SJed Brown @*/ 4979371c9d4SSatish Balay PetscErrorCode PetscFindMPIInt(PetscMPIInt key, PetscInt n, const PetscMPIInt X[], PetscInt *loc) { 498d2aeb606SJed Brown PetscInt lo = 0, hi = n; 499d2aeb606SJed Brown 500d2aeb606SJed Brown PetscFunctionBegin; 501dadcf809SJacob Faibussowitsch PetscValidIntPointer(loc, 4); 5029371c9d4SSatish Balay if (!n) { 5039371c9d4SSatish Balay *loc = -1; 5049371c9d4SSatish Balay PetscFunctionReturn(0); 5059371c9d4SSatish Balay } 506dadcf809SJacob Faibussowitsch PetscValidIntPointer(X, 3); 5076a7c706bSVaclav Hapla PetscCheckSorted(n, X); 508d2aeb606SJed Brown while (hi - lo > 1) { 509d2aeb606SJed Brown PetscInt mid = lo + (hi - lo) / 2; 51059e16d97SJunchao Zhang if (key < X[mid]) hi = mid; 511d2aeb606SJed Brown else lo = mid; 512d2aeb606SJed Brown } 51359e16d97SJunchao Zhang *loc = key == X[lo] ? lo : -(lo + (key > X[lo]) + 1); 514e5c89e4eSSatish Balay PetscFunctionReturn(0); 515e5c89e4eSSatish Balay } 516e5c89e4eSSatish Balay 517e5c89e4eSSatish Balay /*@ 518e5c89e4eSSatish Balay PetscSortIntWithArray - Sorts an array of integers in place in increasing order; 519e5c89e4eSSatish Balay changes a second array to match the sorted first array. 520e5c89e4eSSatish Balay 521e5c89e4eSSatish Balay Not Collective 522e5c89e4eSSatish Balay 523e5c89e4eSSatish Balay Input Parameters: 524e5c89e4eSSatish Balay + n - number of values 52559e16d97SJunchao Zhang . X - array of integers 52659e16d97SJunchao Zhang - Y - second array of integers 527e5c89e4eSSatish Balay 528e5c89e4eSSatish Balay Level: intermediate 529e5c89e4eSSatish Balay 530db781477SPatrick Sanan .seealso: `PetscIntSortSemiOrderedWithArray()`, `PetscSortReal()`, `PetscSortIntWithPermutation()`, `PetscSortInt()`, `PetscSortIntWithCountArray()` 531e5c89e4eSSatish Balay @*/ 5329371c9d4SSatish Balay PetscErrorCode PetscSortIntWithArray(PetscInt n, PetscInt X[], PetscInt Y[]) { 53359e16d97SJunchao Zhang PetscInt pivot, t1, t2; 534e5c89e4eSSatish Balay 535e5c89e4eSSatish Balay PetscFunctionBegin; 5365f80ce2aSJacob Faibussowitsch QuickSort2(PetscSortIntWithArray, X, Y, n, pivot, t1, t2); 537c1f0200aSDmitry Karpeev PetscFunctionReturn(0); 538c1f0200aSDmitry Karpeev } 539c1f0200aSDmitry Karpeev 540c1f0200aSDmitry Karpeev /*@ 541c1f0200aSDmitry Karpeev PetscSortIntWithArrayPair - Sorts an array of integers in place in increasing order; 542c1f0200aSDmitry Karpeev changes a pair of integer arrays to match the sorted first array. 543c1f0200aSDmitry Karpeev 544c1f0200aSDmitry Karpeev Not Collective 545c1f0200aSDmitry Karpeev 546c1f0200aSDmitry Karpeev Input Parameters: 547c1f0200aSDmitry Karpeev + n - number of values 54859e16d97SJunchao Zhang . X - array of integers 54959e16d97SJunchao Zhang . Y - second array of integers (first array of the pair) 55059e16d97SJunchao Zhang - Z - third array of integers (second array of the pair) 551c1f0200aSDmitry Karpeev 552c1f0200aSDmitry Karpeev Level: intermediate 553c1f0200aSDmitry Karpeev 554db781477SPatrick Sanan .seealso: `PetscSortReal()`, `PetscSortIntWithPermutation()`, `PetscSortIntWithArray()`, `PetscIntSortSemiOrdered()`, `PetscSortIntWithIntCountArrayPair()` 555c1f0200aSDmitry Karpeev @*/ 5569371c9d4SSatish Balay PetscErrorCode PetscSortIntWithArrayPair(PetscInt n, PetscInt X[], PetscInt Y[], PetscInt Z[]) { 55759e16d97SJunchao Zhang PetscInt pivot, t1, t2, t3; 558c1f0200aSDmitry Karpeev 559c1f0200aSDmitry Karpeev PetscFunctionBegin; 5605f80ce2aSJacob Faibussowitsch QuickSort3(PetscSortIntWithArrayPair, X, Y, Z, n, pivot, t1, t2, t3); 561c1f0200aSDmitry Karpeev PetscFunctionReturn(0); 562c1f0200aSDmitry Karpeev } 563c1f0200aSDmitry Karpeev 56417d7d925SStefano Zampini /*@ 565981bb840SJunchao Zhang PetscSortIntWithCountArray - Sorts an array of integers in place in increasing order; 566981bb840SJunchao Zhang changes a second array to match the sorted first array. 567981bb840SJunchao Zhang 568981bb840SJunchao Zhang Not Collective 569981bb840SJunchao Zhang 570981bb840SJunchao Zhang Input Parameters: 571981bb840SJunchao Zhang + n - number of values 572981bb840SJunchao Zhang . X - array of integers 573981bb840SJunchao Zhang - Y - second array of PetscCounts (signed integers) 574981bb840SJunchao Zhang 575981bb840SJunchao Zhang Level: intermediate 576981bb840SJunchao Zhang 577db781477SPatrick Sanan .seealso: `PetscIntSortSemiOrderedWithArray()`, `PetscSortReal()`, `PetscSortIntPermutation()`, `PetscSortInt()`, `PetscSortIntWithArray()` 578981bb840SJunchao Zhang @*/ 5799371c9d4SSatish Balay PetscErrorCode PetscSortIntWithCountArray(PetscCount n, PetscInt X[], PetscCount Y[]) { 580981bb840SJunchao Zhang PetscInt pivot, t1; 581981bb840SJunchao Zhang PetscCount t2; 582981bb840SJunchao Zhang 583981bb840SJunchao Zhang PetscFunctionBegin; 5845f80ce2aSJacob Faibussowitsch QuickSort2(PetscSortIntWithCountArray, X, Y, n, pivot, t1, t2); 585981bb840SJunchao Zhang PetscFunctionReturn(0); 586981bb840SJunchao Zhang } 587981bb840SJunchao Zhang 588981bb840SJunchao Zhang /*@ 589981bb840SJunchao Zhang PetscSortIntWithIntCountArrayPair - Sorts an array of integers in place in increasing order; 590981bb840SJunchao Zhang changes an integer array and a PetscCount array to match the sorted first array. 591981bb840SJunchao Zhang 592981bb840SJunchao Zhang Not Collective 593981bb840SJunchao Zhang 594981bb840SJunchao Zhang Input Parameters: 595981bb840SJunchao Zhang + n - number of values 596981bb840SJunchao Zhang . X - array of integers 597981bb840SJunchao Zhang . Y - second array of integers (first array of the pair) 598981bb840SJunchao Zhang - Z - third array of PetscCounts (second array of the pair) 599981bb840SJunchao Zhang 600981bb840SJunchao Zhang Level: intermediate 601981bb840SJunchao Zhang 602981bb840SJunchao Zhang Notes: 603981bb840SJunchao Zhang Usually X, Y are matrix row/column indices, and Z is a permutation array and therefore Z's type is PetscCount to allow 2B+ nonzeros even with 32-bit PetscInt. 604981bb840SJunchao Zhang 605db781477SPatrick Sanan .seealso: `PetscSortReal()`, `PetscSortIntPermutation()`, `PetscSortIntWithArray()`, `PetscIntSortSemiOrdered()`, `PetscSortIntWithArrayPair()` 606981bb840SJunchao Zhang @*/ 6079371c9d4SSatish Balay PetscErrorCode PetscSortIntWithIntCountArrayPair(PetscCount n, PetscInt X[], PetscInt Y[], PetscCount Z[]) { 608981bb840SJunchao Zhang PetscInt pivot, t1, t2; /* pivot is take from X[], so its type is still PetscInt */ 609981bb840SJunchao Zhang PetscCount t3; /* temp for Z[] */ 610981bb840SJunchao Zhang 611981bb840SJunchao Zhang PetscFunctionBegin; 6125f80ce2aSJacob Faibussowitsch QuickSort3(PetscSortIntWithIntCountArrayPair, X, Y, Z, n, pivot, t1, t2, t3); 613981bb840SJunchao Zhang PetscFunctionReturn(0); 614981bb840SJunchao Zhang } 615981bb840SJunchao Zhang 616981bb840SJunchao Zhang /*@ 6176a7c706bSVaclav Hapla PetscSortedMPIInt - Determines whether the array is sorted. 6186a7c706bSVaclav Hapla 6196a7c706bSVaclav Hapla Not Collective 6206a7c706bSVaclav Hapla 6216a7c706bSVaclav Hapla Input Parameters: 6226a7c706bSVaclav Hapla + n - number of values 6236a7c706bSVaclav Hapla - X - array of integers 6246a7c706bSVaclav Hapla 6256a7c706bSVaclav Hapla Output Parameters: 6266a7c706bSVaclav Hapla . sorted - flag whether the array is sorted 6276a7c706bSVaclav Hapla 6286a7c706bSVaclav Hapla Level: intermediate 6296a7c706bSVaclav Hapla 630db781477SPatrick Sanan .seealso: `PetscMPIIntSortSemiOrdered()`, `PetscSortMPIInt()`, `PetscSortedInt()`, `PetscSortedReal()` 6316a7c706bSVaclav Hapla @*/ 6329371c9d4SSatish Balay PetscErrorCode PetscSortedMPIInt(PetscInt n, const PetscMPIInt X[], PetscBool *sorted) { 6336a7c706bSVaclav Hapla PetscFunctionBegin; 6346a7c706bSVaclav Hapla PetscSorted(n, X, *sorted); 6356a7c706bSVaclav Hapla PetscFunctionReturn(0); 6366a7c706bSVaclav Hapla } 6376a7c706bSVaclav Hapla 6386a7c706bSVaclav Hapla /*@ 63917d7d925SStefano Zampini PetscSortMPIInt - Sorts an array of MPI integers in place in increasing order. 64017d7d925SStefano Zampini 64117d7d925SStefano Zampini Not Collective 64217d7d925SStefano Zampini 64317d7d925SStefano Zampini Input Parameters: 64417d7d925SStefano Zampini + n - number of values 64559e16d97SJunchao Zhang - X - array of integers 64617d7d925SStefano Zampini 64717d7d925SStefano Zampini Level: intermediate 64817d7d925SStefano Zampini 649676f2a66SJacob Faibussowitsch Notes: 650676f2a66SJacob Faibussowitsch This function serves as an alternative to PetscMPIIntSortSemiOrdered(), and may perform faster especially if the array 651a5b23f4aSJose E. Roman is completely random. There are exceptions to this and so it is __highly__ recommended that the user benchmark their 652676f2a66SJacob Faibussowitsch code to see which routine is fastest. 653676f2a66SJacob Faibussowitsch 654db781477SPatrick Sanan .seealso: `PetscMPIIntSortSemiOrdered()`, `PetscSortReal()`, `PetscSortIntWithPermutation()` 65517d7d925SStefano Zampini @*/ 6569371c9d4SSatish Balay PetscErrorCode PetscSortMPIInt(PetscInt n, PetscMPIInt X[]) { 65759e16d97SJunchao Zhang PetscMPIInt pivot, t1; 65817d7d925SStefano Zampini 65917d7d925SStefano Zampini PetscFunctionBegin; 6605f80ce2aSJacob Faibussowitsch QuickSort1(PetscSortMPIInt, X, n, pivot, t1); 66117d7d925SStefano Zampini PetscFunctionReturn(0); 66217d7d925SStefano Zampini } 66317d7d925SStefano Zampini 66417d7d925SStefano Zampini /*@ 66517d7d925SStefano Zampini PetscSortRemoveDupsMPIInt - Sorts an array of MPI integers in place in increasing order removes all duplicate entries 66617d7d925SStefano Zampini 66717d7d925SStefano Zampini Not Collective 66817d7d925SStefano Zampini 66917d7d925SStefano Zampini Input Parameters: 67017d7d925SStefano Zampini + n - number of values 67159e16d97SJunchao Zhang - X - array of integers 67217d7d925SStefano Zampini 67317d7d925SStefano Zampini Output Parameter: 67417d7d925SStefano Zampini . n - number of non-redundant values 67517d7d925SStefano Zampini 67617d7d925SStefano Zampini Level: intermediate 67717d7d925SStefano Zampini 678db781477SPatrick Sanan .seealso: `PetscSortReal()`, `PetscSortIntWithPermutation()`, `PetscSortInt()` 67917d7d925SStefano Zampini @*/ 6809371c9d4SSatish Balay PetscErrorCode PetscSortRemoveDupsMPIInt(PetscInt *n, PetscMPIInt X[]) { 6815f80ce2aSJacob Faibussowitsch PetscInt s = 0, N = *n, b = 0; 68217d7d925SStefano Zampini 68317d7d925SStefano Zampini PetscFunctionBegin; 6849566063dSJacob Faibussowitsch PetscCall(PetscSortMPIInt(N, X)); 6855f80ce2aSJacob Faibussowitsch for (PetscInt i = 0; i < N - 1; i++) { 68659e16d97SJunchao Zhang if (X[b + s + 1] != X[b]) { 6879371c9d4SSatish Balay X[b + 1] = X[b + s + 1]; 6889371c9d4SSatish Balay b++; 689a297a907SKarl Rupp } else s++; 69017d7d925SStefano Zampini } 69117d7d925SStefano Zampini *n = N - s; 69217d7d925SStefano Zampini PetscFunctionReturn(0); 69317d7d925SStefano Zampini } 694c1f0200aSDmitry Karpeev 6954d615ea0SBarry Smith /*@ 6964d615ea0SBarry Smith PetscSortMPIIntWithArray - Sorts an array of integers in place in increasing order; 6974d615ea0SBarry Smith changes a second array to match the sorted first array. 6984d615ea0SBarry Smith 6994d615ea0SBarry Smith Not Collective 7004d615ea0SBarry Smith 7014d615ea0SBarry Smith Input Parameters: 7024d615ea0SBarry Smith + n - number of values 70359e16d97SJunchao Zhang . X - array of integers 70459e16d97SJunchao Zhang - Y - second array of integers 7054d615ea0SBarry Smith 7064d615ea0SBarry Smith Level: intermediate 7074d615ea0SBarry Smith 708db781477SPatrick Sanan .seealso: `PetscMPIIntSortSemiOrderedWithArray()`, `PetscSortReal()`, `PetscSortIntWithPermutation()`, `PetscSortInt()` 7094d615ea0SBarry Smith @*/ 7109371c9d4SSatish Balay PetscErrorCode PetscSortMPIIntWithArray(PetscMPIInt n, PetscMPIInt X[], PetscMPIInt Y[]) { 71159e16d97SJunchao Zhang PetscMPIInt pivot, t1, t2; 7124d615ea0SBarry Smith 7134d615ea0SBarry Smith PetscFunctionBegin; 7145f80ce2aSJacob Faibussowitsch QuickSort2(PetscSortMPIIntWithArray, X, Y, n, pivot, t1, t2); 7155569a785SJunchao Zhang PetscFunctionReturn(0); 7165569a785SJunchao Zhang } 7175569a785SJunchao Zhang 7185569a785SJunchao Zhang /*@ 7195569a785SJunchao Zhang PetscSortMPIIntWithIntArray - Sorts an array of MPI integers in place in increasing order; 7205569a785SJunchao Zhang changes a second array of Petsc intergers to match the sorted first array. 7215569a785SJunchao Zhang 7225569a785SJunchao Zhang Not Collective 7235569a785SJunchao Zhang 7245569a785SJunchao Zhang Input Parameters: 7255569a785SJunchao Zhang + n - number of values 72659e16d97SJunchao Zhang . X - array of MPI integers 72759e16d97SJunchao Zhang - Y - second array of Petsc integers 7285569a785SJunchao Zhang 7295569a785SJunchao Zhang Level: intermediate 7305569a785SJunchao Zhang 7315569a785SJunchao Zhang Notes: this routine is useful when one needs to sort MPI ranks with other integer arrays. 7325569a785SJunchao Zhang 733db781477SPatrick Sanan .seealso: `PetscSortMPIIntWithArray()`, `PetscIntSortSemiOrderedWithArray()`, `PetscTimSortWithArray()` 7345569a785SJunchao Zhang @*/ 7359371c9d4SSatish Balay PetscErrorCode PetscSortMPIIntWithIntArray(PetscMPIInt n, PetscMPIInt X[], PetscInt Y[]) { 73659e16d97SJunchao Zhang PetscMPIInt pivot, t1; 7375569a785SJunchao Zhang PetscInt t2; 7385569a785SJunchao Zhang 7395569a785SJunchao Zhang PetscFunctionBegin; 7405f80ce2aSJacob Faibussowitsch QuickSort2(PetscSortMPIIntWithIntArray, X, Y, n, pivot, t1, t2); 741e5c89e4eSSatish Balay PetscFunctionReturn(0); 742e5c89e4eSSatish Balay } 743e5c89e4eSSatish Balay 744e5c89e4eSSatish Balay /*@ 745e5c89e4eSSatish Balay PetscSortIntWithScalarArray - Sorts an array of integers in place in increasing order; 746e5c89e4eSSatish Balay changes a second SCALAR array to match the sorted first INTEGER array. 747e5c89e4eSSatish Balay 748e5c89e4eSSatish Balay Not Collective 749e5c89e4eSSatish Balay 750e5c89e4eSSatish Balay Input Parameters: 751e5c89e4eSSatish Balay + n - number of values 75259e16d97SJunchao Zhang . X - array of integers 75359e16d97SJunchao Zhang - Y - second array of scalars 754e5c89e4eSSatish Balay 755e5c89e4eSSatish Balay Level: intermediate 756e5c89e4eSSatish Balay 757db781477SPatrick Sanan .seealso: `PetscTimSortWithArray()`, `PetscSortReal()`, `PetscSortIntWithPermutation()`, `PetscSortInt()`, `PetscSortIntWithArray()` 758e5c89e4eSSatish Balay @*/ 7599371c9d4SSatish Balay PetscErrorCode PetscSortIntWithScalarArray(PetscInt n, PetscInt X[], PetscScalar Y[]) { 76059e16d97SJunchao Zhang PetscInt pivot, t1; 76159e16d97SJunchao Zhang PetscScalar t2; 762e5c89e4eSSatish Balay 763e5c89e4eSSatish Balay PetscFunctionBegin; 7645f80ce2aSJacob Faibussowitsch QuickSort2(PetscSortIntWithScalarArray, X, Y, n, pivot, t1, t2); 76517df18f2SToby Isaac PetscFunctionReturn(0); 76617df18f2SToby Isaac } 76717df18f2SToby Isaac 7686c2863d0SBarry Smith /*@C 76917df18f2SToby Isaac PetscSortIntWithDataArray - Sorts an array of integers in place in increasing order; 77017df18f2SToby Isaac changes a second array to match the sorted first INTEGER array. Unlike other sort routines, the user must 77117df18f2SToby Isaac provide workspace (the size of an element in the data array) to use when sorting. 77217df18f2SToby Isaac 77317df18f2SToby Isaac Not Collective 77417df18f2SToby Isaac 77517df18f2SToby Isaac Input Parameters: 77617df18f2SToby Isaac + n - number of values 77759e16d97SJunchao Zhang . X - array of integers 77859e16d97SJunchao Zhang . Y - second array of data 77917df18f2SToby Isaac . size - sizeof elements in the data array in bytes 78059e16d97SJunchao Zhang - t2 - workspace of "size" bytes used when sorting 78117df18f2SToby Isaac 78217df18f2SToby Isaac Level: intermediate 78317df18f2SToby Isaac 784db781477SPatrick Sanan .seealso: `PetscTimSortWithArray()`, `PetscSortReal()`, `PetscSortIntWithPermutation()`, `PetscSortInt()`, `PetscSortIntWithArray()` 78517df18f2SToby Isaac @*/ 7869371c9d4SSatish Balay PetscErrorCode PetscSortIntWithDataArray(PetscInt n, PetscInt X[], void *Y, size_t size, void *t2) { 78759e16d97SJunchao Zhang char *YY = (char *)Y; 7885f80ce2aSJacob Faibussowitsch PetscInt t1, pivot, hi = n - 1; 78917df18f2SToby Isaac 79017df18f2SToby Isaac PetscFunctionBegin; 79117df18f2SToby Isaac if (n < 8) { 7925f80ce2aSJacob Faibussowitsch for (PetscInt i = 0; i < n; i++) { 79359e16d97SJunchao Zhang pivot = X[i]; 7945f80ce2aSJacob Faibussowitsch for (PetscInt j = i + 1; j < n; j++) { 79559e16d97SJunchao Zhang if (pivot > X[j]) { 79659e16d97SJunchao Zhang SWAP2Data(X[i], X[j], YY + size * i, YY + size * j, t1, t2, size); 79759e16d97SJunchao Zhang pivot = X[i]; 79817df18f2SToby Isaac } 79917df18f2SToby Isaac } 80017df18f2SToby Isaac } 80117df18f2SToby Isaac } else { 80259e16d97SJunchao Zhang /* Two way partition */ 8035f80ce2aSJacob Faibussowitsch PetscInt l = 0, r = hi; 8045f80ce2aSJacob Faibussowitsch 8055f80ce2aSJacob Faibussowitsch pivot = X[MEDIAN(X, hi)]; 80659e16d97SJunchao Zhang while (1) { 80759e16d97SJunchao Zhang while (X[l] < pivot) l++; 80859e16d97SJunchao Zhang while (X[r] > pivot) r--; 8099371c9d4SSatish Balay if (l >= r) { 8109371c9d4SSatish Balay r++; 8119371c9d4SSatish Balay break; 8129371c9d4SSatish Balay } 81359e16d97SJunchao Zhang SWAP2Data(X[l], X[r], YY + size * l, YY + size * r, t1, t2, size); 81459e16d97SJunchao Zhang l++; 81559e16d97SJunchao Zhang r--; 81659e16d97SJunchao Zhang } 8179566063dSJacob Faibussowitsch PetscCall(PetscSortIntWithDataArray(l, X, Y, size, t2)); 8189566063dSJacob Faibussowitsch PetscCall(PetscSortIntWithDataArray(hi - r + 1, X + r, YY + size * r, size, t2)); 81917df18f2SToby Isaac } 82017df18f2SToby Isaac PetscFunctionReturn(0); 82117df18f2SToby Isaac } 82217df18f2SToby Isaac 82321e72a00SBarry Smith /*@ 82421e72a00SBarry Smith PetscMergeIntArray - Merges two SORTED integer arrays, removes duplicate elements. 82521e72a00SBarry Smith 82621e72a00SBarry Smith Not Collective 82721e72a00SBarry Smith 82821e72a00SBarry Smith Input Parameters: 82921e72a00SBarry Smith + an - number of values in the first array 83021e72a00SBarry Smith . aI - first sorted array of integers 83121e72a00SBarry Smith . bn - number of values in the second array 83221e72a00SBarry Smith - bI - second array of integers 83321e72a00SBarry Smith 83421e72a00SBarry Smith Output Parameters: 83521e72a00SBarry Smith + n - number of values in the merged array 8366c2863d0SBarry Smith - L - merged sorted array, this is allocated if an array is not provided 83721e72a00SBarry Smith 83821e72a00SBarry Smith Level: intermediate 83921e72a00SBarry Smith 840db781477SPatrick Sanan .seealso: `PetscSortReal()`, `PetscSortIntWithPermutation()`, `PetscSortInt()`, `PetscSortIntWithArray()` 84121e72a00SBarry Smith @*/ 8429371c9d4SSatish Balay PetscErrorCode PetscMergeIntArray(PetscInt an, const PetscInt aI[], PetscInt bn, const PetscInt bI[], PetscInt *n, PetscInt **L) { 84321e72a00SBarry Smith PetscInt *L_ = *L, ak, bk, k; 84421e72a00SBarry Smith 845362febeeSStefano Zampini PetscFunctionBegin; 84621e72a00SBarry Smith if (!L_) { 8479566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(an + bn, L)); 84821e72a00SBarry Smith L_ = *L; 84921e72a00SBarry Smith } 85021e72a00SBarry Smith k = ak = bk = 0; 85121e72a00SBarry Smith while (ak < an && bk < bn) { 85221e72a00SBarry Smith if (aI[ak] == bI[bk]) { 85321e72a00SBarry Smith L_[k] = aI[ak]; 85421e72a00SBarry Smith ++ak; 85521e72a00SBarry Smith ++bk; 85621e72a00SBarry Smith ++k; 85721e72a00SBarry Smith } else if (aI[ak] < bI[bk]) { 85821e72a00SBarry Smith L_[k] = aI[ak]; 85921e72a00SBarry Smith ++ak; 86021e72a00SBarry Smith ++k; 86121e72a00SBarry Smith } else { 86221e72a00SBarry Smith L_[k] = bI[bk]; 86321e72a00SBarry Smith ++bk; 86421e72a00SBarry Smith ++k; 86521e72a00SBarry Smith } 86621e72a00SBarry Smith } 86721e72a00SBarry Smith if (ak < an) { 8689566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(L_ + k, aI + ak, an - ak)); 86921e72a00SBarry Smith k += (an - ak); 87021e72a00SBarry Smith } 87121e72a00SBarry Smith if (bk < bn) { 8729566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(L_ + k, bI + bk, bn - bk)); 87321e72a00SBarry Smith k += (bn - bk); 87421e72a00SBarry Smith } 87521e72a00SBarry Smith *n = k; 87621e72a00SBarry Smith PetscFunctionReturn(0); 87721e72a00SBarry Smith } 878b4301105SBarry Smith 879c1f0200aSDmitry Karpeev /*@ 88021e72a00SBarry Smith PetscMergeIntArrayPair - Merges two SORTED integer arrays that share NO common values along with an additional array of integers. 881c1f0200aSDmitry Karpeev The additional arrays are the same length as sorted arrays and are merged 882c1f0200aSDmitry Karpeev in the order determined by the merging of the sorted pair. 883c1f0200aSDmitry Karpeev 884c1f0200aSDmitry Karpeev Not Collective 885c1f0200aSDmitry Karpeev 886c1f0200aSDmitry Karpeev Input Parameters: 887c1f0200aSDmitry Karpeev + an - number of values in the first array 888c1f0200aSDmitry Karpeev . aI - first sorted array of integers 889c1f0200aSDmitry Karpeev . aJ - first additional array of integers 890c1f0200aSDmitry Karpeev . bn - number of values in the second array 891c1f0200aSDmitry Karpeev . bI - second array of integers 892c1f0200aSDmitry Karpeev - bJ - second additional of integers 893c1f0200aSDmitry Karpeev 894c1f0200aSDmitry Karpeev Output Parameters: 895c1f0200aSDmitry Karpeev + n - number of values in the merged array (== an + bn) 89614c49006SJed Brown . L - merged sorted array 897c1f0200aSDmitry Karpeev - J - merged additional array 898c1f0200aSDmitry Karpeev 89995452b02SPatrick Sanan Notes: 90095452b02SPatrick 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 901c1f0200aSDmitry Karpeev Level: intermediate 902c1f0200aSDmitry Karpeev 903db781477SPatrick Sanan .seealso: `PetscIntSortSemiOrdered()`, `PetscSortReal()`, `PetscSortIntWithPermutation()`, `PetscSortInt()`, `PetscSortIntWithArray()` 904c1f0200aSDmitry Karpeev @*/ 9059371c9d4SSatish Balay PetscErrorCode PetscMergeIntArrayPair(PetscInt an, const PetscInt aI[], const PetscInt aJ[], PetscInt bn, const PetscInt bI[], const PetscInt bJ[], PetscInt *n, PetscInt **L, PetscInt **J) { 90670d8d27cSBarry Smith PetscInt n_, *L_, *J_, ak, bk, k; 907c1f0200aSDmitry Karpeev 90814c49006SJed Brown PetscFunctionBegin; 909dadcf809SJacob Faibussowitsch PetscValidPointer(L, 8); 910dadcf809SJacob Faibussowitsch PetscValidPointer(J, 9); 911c1f0200aSDmitry Karpeev n_ = an + bn; 912c1f0200aSDmitry Karpeev *n = n_; 913*48a46eb9SPierre Jolivet if (!*L) PetscCall(PetscMalloc1(n_, L)); 914d7aa01a8SHong Zhang L_ = *L; 915*48a46eb9SPierre Jolivet if (!*J) PetscCall(PetscMalloc1(n_, J)); 916c1f0200aSDmitry Karpeev J_ = *J; 917c1f0200aSDmitry Karpeev k = ak = bk = 0; 918c1f0200aSDmitry Karpeev while (ak < an && bk < bn) { 919c1f0200aSDmitry Karpeev if (aI[ak] <= bI[bk]) { 920d7aa01a8SHong Zhang L_[k] = aI[ak]; 921c1f0200aSDmitry Karpeev J_[k] = aJ[ak]; 922c1f0200aSDmitry Karpeev ++ak; 923c1f0200aSDmitry Karpeev ++k; 924a297a907SKarl Rupp } else { 925d7aa01a8SHong Zhang L_[k] = bI[bk]; 926c1f0200aSDmitry Karpeev J_[k] = bJ[bk]; 927c1f0200aSDmitry Karpeev ++bk; 928c1f0200aSDmitry Karpeev ++k; 929c1f0200aSDmitry Karpeev } 930c1f0200aSDmitry Karpeev } 931c1f0200aSDmitry Karpeev if (ak < an) { 9329566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(L_ + k, aI + ak, an - ak)); 9339566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(J_ + k, aJ + ak, an - ak)); 934c1f0200aSDmitry Karpeev k += (an - ak); 935c1f0200aSDmitry Karpeev } 936c1f0200aSDmitry Karpeev if (bk < bn) { 9379566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(L_ + k, bI + bk, bn - bk)); 9389566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(J_ + k, bJ + bk, bn - bk)); 939c1f0200aSDmitry Karpeev } 940c1f0200aSDmitry Karpeev PetscFunctionReturn(0); 941c1f0200aSDmitry Karpeev } 942c1f0200aSDmitry Karpeev 943e498c390SJed Brown /*@ 944e498c390SJed Brown PetscMergeMPIIntArray - Merges two SORTED integer arrays. 945e498c390SJed Brown 946e498c390SJed Brown Not Collective 947e498c390SJed Brown 948e498c390SJed Brown Input Parameters: 949e498c390SJed Brown + an - number of values in the first array 950e498c390SJed Brown . aI - first sorted array of integers 951e498c390SJed Brown . bn - number of values in the second array 952e498c390SJed Brown - bI - second array of integers 953e498c390SJed Brown 954e498c390SJed Brown Output Parameters: 955e498c390SJed Brown + n - number of values in the merged array (<= an + bn) 956e498c390SJed Brown - L - merged sorted array, allocated if address of NULL pointer is passed 957e498c390SJed Brown 958e498c390SJed Brown Level: intermediate 959e498c390SJed Brown 960db781477SPatrick Sanan .seealso: `PetscIntSortSemiOrdered()`, `PetscSortReal()`, `PetscSortIntWithPermutation()`, `PetscSortInt()`, `PetscSortIntWithArray()` 961e498c390SJed Brown @*/ 9629371c9d4SSatish Balay PetscErrorCode PetscMergeMPIIntArray(PetscInt an, const PetscMPIInt aI[], PetscInt bn, const PetscMPIInt bI[], PetscInt *n, PetscMPIInt **L) { 963e498c390SJed Brown PetscInt ai, bi, k; 964e498c390SJed Brown 965e498c390SJed Brown PetscFunctionBegin; 9669566063dSJacob Faibussowitsch if (!*L) PetscCall(PetscMalloc1((an + bn), L)); 967e498c390SJed Brown for (ai = 0, bi = 0, k = 0; ai < an || bi < bn;) { 968e498c390SJed Brown PetscInt t = -1; 969e498c390SJed Brown for (; ai < an && (!bn || aI[ai] <= bI[bi]); ai++) (*L)[k++] = t = aI[ai]; 9709371c9d4SSatish Balay for (; bi < bn && bI[bi] == t; bi++) 9719371c9d4SSatish Balay ; 972e498c390SJed Brown for (; bi < bn && (!an || bI[bi] <= aI[ai]); bi++) (*L)[k++] = t = bI[bi]; 9739371c9d4SSatish Balay for (; ai < an && aI[ai] == t; ai++) 9749371c9d4SSatish Balay ; 975e498c390SJed Brown } 976e498c390SJed Brown *n = k; 977e498c390SJed Brown PetscFunctionReturn(0); 978e498c390SJed Brown } 979e5c89e4eSSatish Balay 9806c2863d0SBarry Smith /*@C 98142eaa7f3SBarry Smith PetscProcessTree - Prepares tree data to be displayed graphically 98242eaa7f3SBarry Smith 98342eaa7f3SBarry Smith Not Collective 98442eaa7f3SBarry Smith 98542eaa7f3SBarry Smith Input Parameters: 98642eaa7f3SBarry Smith + n - number of values 98742eaa7f3SBarry Smith . mask - indicates those entries in the tree, location 0 is always masked 98842eaa7f3SBarry Smith - parentid - indicates the parent of each entry 98942eaa7f3SBarry Smith 99042eaa7f3SBarry Smith Output Parameters: 99142eaa7f3SBarry Smith + Nlevels - the number of levels 99242eaa7f3SBarry Smith . Level - for each node tells its level 99342eaa7f3SBarry Smith . Levelcnts - the number of nodes on each level 99442eaa7f3SBarry Smith . Idbylevel - a list of ids on each of the levels, first level followed by second etc 99542eaa7f3SBarry Smith - Column - for each id tells its column index 99642eaa7f3SBarry Smith 9976c2863d0SBarry Smith Level: developer 99842eaa7f3SBarry Smith 99995452b02SPatrick Sanan Notes: 100095452b02SPatrick Sanan This code is not currently used 100142eaa7f3SBarry Smith 1002db781477SPatrick Sanan .seealso: `PetscSortReal()`, `PetscSortIntWithPermutation()` 100342eaa7f3SBarry Smith @*/ 10049371c9d4SSatish Balay PetscErrorCode PetscProcessTree(PetscInt n, const PetscBool mask[], const PetscInt parentid[], PetscInt *Nlevels, PetscInt **Level, PetscInt **Levelcnt, PetscInt **Idbylevel, PetscInt **Column) { 100542eaa7f3SBarry Smith PetscInt i, j, cnt, nmask = 0, nlevels = 0, *level, *levelcnt, levelmax = 0, *workid, *workparentid, tcnt = 0, *idbylevel, *column; 1006ace3abfcSBarry Smith PetscBool done = PETSC_FALSE; 100742eaa7f3SBarry Smith 100842eaa7f3SBarry Smith PetscFunctionBegin; 100908401ef6SPierre Jolivet PetscCheck(mask[0], PETSC_COMM_SELF, PETSC_ERR_SUP, "Mask of 0th location must be set"); 101042eaa7f3SBarry Smith for (i = 0; i < n; i++) { 101142eaa7f3SBarry Smith if (mask[i]) continue; 101208401ef6SPierre Jolivet PetscCheck(parentid[i] != i, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Node labeled as own parent"); 1013cc73adaaSBarry Smith PetscCheck(!parentid[i] || !mask[parentid[i]], PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Parent is masked"); 101442eaa7f3SBarry Smith } 101542eaa7f3SBarry Smith 101642eaa7f3SBarry Smith for (i = 0; i < n; i++) { 101742eaa7f3SBarry Smith if (!mask[i]) nmask++; 101842eaa7f3SBarry Smith } 101942eaa7f3SBarry Smith 102042eaa7f3SBarry Smith /* determine the level in the tree of each node */ 10219566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(n, &level)); 1022a297a907SKarl Rupp 102342eaa7f3SBarry Smith level[0] = 1; 102442eaa7f3SBarry Smith while (!done) { 102542eaa7f3SBarry Smith done = PETSC_TRUE; 102642eaa7f3SBarry Smith for (i = 0; i < n; i++) { 102742eaa7f3SBarry Smith if (mask[i]) continue; 102842eaa7f3SBarry Smith if (!level[i] && level[parentid[i]]) level[i] = level[parentid[i]] + 1; 102942eaa7f3SBarry Smith else if (!level[i]) done = PETSC_FALSE; 103042eaa7f3SBarry Smith } 103142eaa7f3SBarry Smith } 103242eaa7f3SBarry Smith for (i = 0; i < n; i++) { 103342eaa7f3SBarry Smith level[i]--; 103442eaa7f3SBarry Smith nlevels = PetscMax(nlevels, level[i]); 103542eaa7f3SBarry Smith } 103642eaa7f3SBarry Smith 103742eaa7f3SBarry Smith /* count the number of nodes on each level and its max */ 10389566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nlevels, &levelcnt)); 103942eaa7f3SBarry Smith for (i = 0; i < n; i++) { 104042eaa7f3SBarry Smith if (mask[i]) continue; 104142eaa7f3SBarry Smith levelcnt[level[i] - 1]++; 104242eaa7f3SBarry Smith } 1043a297a907SKarl Rupp for (i = 0; i < nlevels; i++) levelmax = PetscMax(levelmax, levelcnt[i]); 104442eaa7f3SBarry Smith 104542eaa7f3SBarry Smith /* for each level sort the ids by the parent id */ 10469566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(levelmax, &workid, levelmax, &workparentid)); 10479566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nmask, &idbylevel)); 104842eaa7f3SBarry Smith for (j = 1; j <= nlevels; j++) { 104942eaa7f3SBarry Smith cnt = 0; 105042eaa7f3SBarry Smith for (i = 0; i < n; i++) { 105142eaa7f3SBarry Smith if (mask[i]) continue; 105242eaa7f3SBarry Smith if (level[i] != j) continue; 105342eaa7f3SBarry Smith workid[cnt] = i; 105442eaa7f3SBarry Smith workparentid[cnt++] = parentid[i]; 105542eaa7f3SBarry Smith } 105642eaa7f3SBarry Smith /* PetscIntView(cnt,workparentid,0); 105742eaa7f3SBarry Smith PetscIntView(cnt,workid,0); 10589566063dSJacob Faibussowitsch PetscCall(PetscSortIntWithArray(cnt,workparentid,workid)); 105942eaa7f3SBarry Smith PetscIntView(cnt,workparentid,0); 106042eaa7f3SBarry Smith PetscIntView(cnt,workid,0);*/ 10619566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(idbylevel + tcnt, workid, cnt)); 106242eaa7f3SBarry Smith tcnt += cnt; 106342eaa7f3SBarry Smith } 106408401ef6SPierre Jolivet PetscCheck(tcnt == nmask, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent count of unmasked nodes"); 10659566063dSJacob Faibussowitsch PetscCall(PetscFree2(workid, workparentid)); 106642eaa7f3SBarry Smith 106742eaa7f3SBarry Smith /* for each node list its column */ 10689566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &column)); 106942eaa7f3SBarry Smith cnt = 0; 107042eaa7f3SBarry Smith for (j = 0; j < nlevels; j++) { 10719371c9d4SSatish Balay for (i = 0; i < levelcnt[j]; i++) { column[idbylevel[cnt++]] = i; } 107242eaa7f3SBarry Smith } 107342eaa7f3SBarry Smith 107442eaa7f3SBarry Smith *Nlevels = nlevels; 107542eaa7f3SBarry Smith *Level = level; 107642eaa7f3SBarry Smith *Levelcnt = levelcnt; 107742eaa7f3SBarry Smith *Idbylevel = idbylevel; 107842eaa7f3SBarry Smith *Column = column; 107942eaa7f3SBarry Smith PetscFunctionReturn(0); 108042eaa7f3SBarry Smith } 1081ce605777SToby Isaac 1082ce605777SToby Isaac /*@ 1083ce605777SToby Isaac PetscParallelSortedInt - Check whether an integer array, distributed over a communicator, is globally sorted. 1084ce605777SToby Isaac 1085ce605777SToby Isaac Collective 1086ce605777SToby Isaac 1087ce605777SToby Isaac Input Parameters: 1088ce605777SToby Isaac + comm - the MPI communicator 1089ce605777SToby Isaac . n - the local number of integers 1090ce605777SToby Isaac - keys - the local array of integers 1091ce605777SToby Isaac 1092ce605777SToby Isaac Output Parameters: 1093ce605777SToby Isaac . is_sorted - whether the array is globally sorted 1094ce605777SToby Isaac 1095ce605777SToby Isaac Level: developer 1096ce605777SToby Isaac 1097db781477SPatrick Sanan .seealso: `PetscParallelSortInt()` 1098ce605777SToby Isaac @*/ 10999371c9d4SSatish Balay PetscErrorCode PetscParallelSortedInt(MPI_Comm comm, PetscInt n, const PetscInt keys[], PetscBool *is_sorted) { 1100ce605777SToby Isaac PetscBool sorted; 1101ce605777SToby Isaac PetscInt i, min, max, prevmax; 11022a1da528SToby Isaac PetscMPIInt rank; 1103ce605777SToby Isaac 1104ce605777SToby Isaac PetscFunctionBegin; 1105ce605777SToby Isaac sorted = PETSC_TRUE; 1106ce605777SToby Isaac min = PETSC_MAX_INT; 1107ce605777SToby Isaac max = PETSC_MIN_INT; 1108ce605777SToby Isaac if (n) { 1109ce605777SToby Isaac min = keys[0]; 1110ce605777SToby Isaac max = keys[0]; 1111ce605777SToby Isaac } 1112ce605777SToby Isaac for (i = 1; i < n; i++) { 1113ce605777SToby Isaac if (keys[i] < keys[i - 1]) break; 1114ce605777SToby Isaac min = PetscMin(min, keys[i]); 1115ce605777SToby Isaac max = PetscMax(max, keys[i]); 1116ce605777SToby Isaac } 1117ce605777SToby Isaac if (i < n) sorted = PETSC_FALSE; 1118ce605777SToby Isaac prevmax = PETSC_MIN_INT; 11199566063dSJacob Faibussowitsch PetscCallMPI(MPI_Exscan(&max, &prevmax, 1, MPIU_INT, MPI_MAX, comm)); 11209566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 1121dd400576SPatrick Sanan if (rank == 0) prevmax = PETSC_MIN_INT; 1122ce605777SToby Isaac if (prevmax > min) sorted = PETSC_FALSE; 11239566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(&sorted, is_sorted, 1, MPIU_BOOL, MPI_LAND, comm)); 1124ce605777SToby Isaac PetscFunctionReturn(0); 1125ce605777SToby Isaac } 1126