Actual source code: sortd.c
petsc-3.3-p7 2013-05-11
2: /*
3: This file contains routines for sorting doubles. Values are sorted in place.
4: These are provided because the general sort routines incur a great deal
5: of overhead in calling the comparision routines.
7: */
8: #include <petscsys.h> /*I "petscsys.h" I*/
10: #define SWAP(a,b,t) {t=a;a=b;b=t;}
11:
14: /* A simple version of quicksort; taken from Kernighan and Ritchie, page 87 */
15: static PetscErrorCode PetscSortReal_Private(PetscReal *v,PetscInt right)
16: {
17: PetscInt i,last;
18: PetscReal vl,tmp;
19:
21: if (right <= 1) {
22: if (right == 1) {
23: if (v[0] > v[1]) SWAP(v[0],v[1],tmp);
24: }
25: return(0);
26: }
27: SWAP(v[0],v[right/2],tmp);
28: vl = v[0];
29: last = 0;
30: for (i=1; i<=right; i++) {
31: if (v[i] < vl) {last++; SWAP(v[last],v[i],tmp);}
32: }
33: SWAP(v[0],v[last],tmp);
34: PetscSortReal_Private(v,last-1);
35: PetscSortReal_Private(v+last+1,right-(last+1));
36: return(0);
37: }
41: /*@
42: PetscSortReal - Sorts an array of doubles in place in increasing order.
44: Not Collective
46: Input Parameters:
47: + n - number of values
48: - v - array of doubles
50: Level: intermediate
52: Concepts: sorting^doubles
54: .seealso: PetscSortInt(), PetscSortRealWithPermutation()
55: @*/
56: PetscErrorCode PetscSortReal(PetscInt n,PetscReal v[])
57: {
58: PetscInt j,k;
59: PetscReal tmp,vk;
62: if (n<8) {
63: for (k=0; k<n; k++) {
64: vk = v[k];
65: for (j=k+1; j<n; j++) {
66: if (vk > v[j]) {
67: SWAP(v[k],v[j],tmp);
68: vk = v[k];
69: }
70: }
71: }
72: } else {
73: PetscSortReal_Private(v,n-1);
74: }
75: return(0);
76: }
80: /*@
81: PetscSortSplit - Quick-sort split of an array of PetscScalars in place.
83: Not Collective
85: Input Parameters:
86: + ncut - splitig index
87: . n - number of values to sort
88: . a - array of values
89: - idx - index for array a
91: Output Parameters:
92: + a - permuted array of values such that its elements satisfy:
93: abs(a[i]) >= abs(a[ncut-1]) for i < ncut and
94: abs(a[i]) <= abs(a[ncut-1]) for i >= ncut
95: - idx - permuted index of array a
97: Level: intermediate
99: Concepts: sorting^doubles
101: .seealso: PetscSortInt(), PetscSortRealWithPermutation()
102: @*/
103: PetscErrorCode PetscSortSplit(PetscInt ncut,PetscInt n,PetscScalar a[],PetscInt idx[])
104: {
105: PetscInt i,mid,last,itmp,j,first;
106: PetscScalar d,tmp;
107: PetscReal abskey;
110: first = 0;
111: last = n-1;
112: if (ncut < first || ncut > last) return(0);
114: while (1){
115: mid = first;
116: abskey = (d = a[mid],PetscAbsScalar(d));
117: i = last;
118: for (j = first + 1; j <= i; ++j) {
119: if ((d = a[j],PetscAbsScalar(d)) >= abskey) {
120: ++mid;
121: /* interchange */
122: tmp = a[mid]; itmp = idx[mid];
123: a[mid] = a[j]; idx[mid] = idx[j];
124: a[j] = tmp; idx[j] = itmp;
125: }
126: }
127:
128: /* interchange */
129: tmp = a[mid]; itmp = idx[mid];
130: a[mid] = a[first]; idx[mid] = idx[first];
131: a[first] = tmp; idx[first] = itmp;
133: /* test for while loop */
134: if (mid == ncut) {
135: break;
136: } else if (mid > ncut){
137: last = mid - 1;
138: } else {
139: first = mid + 1;
140: }
141: }
142: return(0);
143: }
147: /*@
148: PetscSortSplitReal - Quick-sort split of an array of PetscReals in place.
150: Not Collective
152: Input Parameters:
153: + ncut - splitig index
154: . n - number of values to sort
155: . a - array of values in PetscReal
156: - idx - index for array a
158: Output Parameters:
159: + a - permuted array of real values such that its elements satisfy:
160: abs(a[i]) >= abs(a[ncut-1]) for i < ncut and
161: abs(a[i]) <= abs(a[ncut-1]) for i >= ncut
162: - idx - permuted index of array a
164: Level: intermediate
166: Concepts: sorting^doubles
168: .seealso: PetscSortInt(), PetscSortRealWithPermutation()
169: @*/
170: PetscErrorCode PetscSortSplitReal(PetscInt ncut,PetscInt n,PetscReal a[],PetscInt idx[])
171: {
172: PetscInt i,mid,last,itmp,j,first;
173: PetscReal d,tmp;
174: PetscReal abskey;
177: first = 0;
178: last = n-1;
179: if (ncut < first || ncut > last) return(0);
181: while (1){
182: mid = first;
183: abskey = (d = a[mid],PetscAbsReal(d));
184: i = last;
185: for (j = first + 1; j <= i; ++j) {
186: if ((d = a[j],PetscAbsReal(d)) >= abskey) {
187: ++mid;
188: /* interchange */
189: tmp = a[mid]; itmp = idx[mid];
190: a[mid] = a[j]; idx[mid] = idx[j];
191: a[j] = tmp; idx[j] = itmp;
192: }
193: }
194:
195: /* interchange */
196: tmp = a[mid]; itmp = idx[mid];
197: a[mid] = a[first]; idx[mid] = idx[first];
198: a[first] = tmp; idx[first] = itmp;
200: /* test for while loop */
201: if (mid == ncut) {
202: break;
203: } else if (mid > ncut){
204: last = mid - 1;
205: } else {
206: first = mid + 1;
207: }
208: }
209: return(0);
210: }