OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
sort.cpp
Go to the documentation of this file.
1 //$$ sort.cpp Sorting
2 
3 // Copyright (C) 1991,2,3,4: R B Davies
4 
5 #define WANT_MATH
6 
7 #include <ossim/matrix/include.h>
8 
10 
11 #ifdef use_namespace
12 namespace NEWMAT {
13 #endif
14 
15 #ifdef DO_REPORT
16 #define REPORT { static ExeCounter ExeCount(__LINE__,13); ++ExeCount; }
17 #else
18 #define REPORT {}
19 #endif
20 
21 /******************************** Quick sort ********************************/
22 
23 // Quicksort.
24 // Essentially the method described in Sedgewick s algorithms in C++
25 // My version is still partially recursive, unlike Segewick s, but the
26 // smallest segment of each split is used in the recursion, so it should
27 // not overlead the stack.
28 
29 // If the process does not seems to be converging an exception is thrown.
30 
31 
32 #define DoSimpleSort 17 // when to switch to insert sort
33 #define MaxDepth 50 // maximum recursion depth
34 
35 static void MyQuickSortDescending(Real* first, Real* last, int depth);
36 static void InsertionSortDescending(Real* first, const int length,
37  int guard);
38 static Real SortThreeDescending(Real* a, Real* b, Real* c);
39 
40 static void MyQuickSortAscending(Real* first, Real* last, int depth);
41 static void InsertionSortAscending(Real* first, const int length,
42  int guard);
43 
44 
46 {
47  REPORT
48  Tracer et("QuickSortDescending");
49 
50  Real* data = GM.Store(); int max = GM.Storage();
51 
52  if (max > DoSimpleSort) MyQuickSortDescending(data, data + max - 1, 0);
53  InsertionSortDescending(data, max, DoSimpleSort);
54 
55 }
56 
57 static Real SortThreeDescending(Real* a, Real* b, Real* c)
58 {
59  // sort *a, *b, *c; return *b; optimise for already sorted
60  if (*a >= *b)
61  {
62  if (*b >= *c) { REPORT return *b; }
63  else if (*a >= *c) { REPORT Real x = *c; *c = *b; *b = x; return x; }
64  else { REPORT Real x = *a; *a = *c; *c = *b; *b = x; return x; }
65  }
66  else if (*c >= *b) { REPORT Real x = *c; *c = *a; *a = x; return *b; }
67  else if (*a >= *c) { REPORT Real x = *a; *a = *b; *b = x; return x; }
68  else { REPORT Real x = *c; *c = *a; *a = *b; *b = x; return x; }
69 }
70 
71 static void InsertionSortDescending(Real* first, const int length,
72  int guard)
73 // guard gives the length of the sequence to scan to find first
74 // element (eg = length)
75 {
76  REPORT
77  if (length <= 1) return;
78 
79  // scan for first element
80  Real* f = first; Real v = *f; Real* h = f;
81  if (guard > length) { REPORT guard = length; }
82  int i = guard - 1;
83  while (i--) if (v < *(++f)) { v = *f; h = f; }
84  *h = *first; *first = v;
85 
86  // do the sort
87  i = length - 1; f = first;
88  while (i--)
89  {
90  Real* g = f++; h = f; v = *h;
91  while (*g < v) *h-- = *g--;
92  *h = v;
93  }
94 }
95 
96 static void MyQuickSortDescending(Real* first, Real* last, int depth)
97 {
98  REPORT
99  for (;;)
100  {
101  const int length = last - first + 1;
102  if (length < DoSimpleSort) { REPORT return; }
103  if (depth++ > MaxDepth)
104  Throw(ConvergenceException("QuickSortDescending fails: "));
105  Real* centre = first + length/2;
106  const Real test = SortThreeDescending(first, centre, last);
107  Real* f = first; Real* l = last;
108  for (;;)
109  {
110  while (*(++f) > test) {}
111  while (*(--l) < test) {}
112  if (l <= f) break;
113  const Real temp = *f; *f = *l; *l = temp;
114  }
115  if (f > centre)
116  { REPORT MyQuickSortDescending(l+1, last, depth); last = f-1; }
117  else { REPORT MyQuickSortDescending(first, f-1, depth); first = l+1; }
118  }
119 }
120 
122 {
123  REPORT
124  Tracer et("QuickSortAscending");
125 
126  Real* data = GM.Store(); int max = GM.Storage();
127 
128  if (max > DoSimpleSort) MyQuickSortAscending(data, data + max - 1, 0);
129  InsertionSortAscending(data, max, DoSimpleSort);
130 
131 }
132 
133 static void InsertionSortAscending(Real* first, const int length,
134  int guard)
135 // guard gives the length of the sequence to scan to find first
136 // element (eg guard = length)
137 {
138  REPORT
139  if (length <= 1) return;
140 
141  // scan for first element
142  Real* f = first; Real v = *f; Real* h = f;
143  if (guard > length) { REPORT guard = length; }
144  int i = guard - 1;
145  while (i--) if (v > *(++f)) { v = *f; h = f; }
146  *h = *first; *first = v;
147 
148  // do the sort
149  i = length - 1; f = first;
150  while (i--)
151  {
152  Real* g = f++; h = f; v = *h;
153  while (*g > v) *h-- = *g--;
154  *h = v;
155  }
156 }
157 static void MyQuickSortAscending(Real* first, Real* last, int depth)
158 {
159  REPORT
160  for (;;)
161  {
162  const int length = last - first + 1;
163  if (length < DoSimpleSort) { REPORT return; }
164  if (depth++ > MaxDepth)
165  Throw(ConvergenceException("QuickSortAscending fails: "));
166  Real* centre = first + length/2;
167  const Real test = SortThreeDescending(last, centre, first);
168  Real* f = first; Real* l = last;
169  for (;;)
170  {
171  while (*(++f) < test) {}
172  while (*(--l) > test) {}
173  if (l <= f) break;
174  const Real temp = *f; *f = *l; *l = temp;
175  }
176  if (f > centre)
177  { REPORT MyQuickSortAscending(l+1, last, depth); last = f-1; }
178  else { REPORT MyQuickSortAscending(first, f-1, depth); first = l+1; }
179  }
180 }
181 
182 //********* sort diagonal matrix & rearrange matrix columns ****************
183 
184 // used by SVD
185 
186 // these are for sorting singular values - should be updated with faster
187 // sorts that handle exchange of columns better
188 // however time is probably not significant compared with SVD time
189 
190 void SortSV(DiagonalMatrix& D, Matrix& U, bool ascending)
191 {
192  REPORT
193  Tracer trace("SortSV_DU");
194  int m = U.Nrows(); int n = U.Ncols();
195  if (n != D.Nrows()) Throw(IncompatibleDimensionsException(D,U));
196  Real* u = U.Store();
197  for (int i=0; i<n; i++)
198  {
199  int k = i; Real p = D.element(i);
200  if (ascending)
201  {
202  for (int j=i+1; j<n; j++)
203  { if (D.element(j) < p) { k = j; p = D.element(j); } }
204  }
205  else
206  {
207  for (int j=i+1; j<n; j++)
208  { if (D.element(j) > p) { k = j; p = D.element(j); } }
209  }
210  if (k != i)
211  {
212  D.element(k) = D.element(i); D.element(i) = p; int j = m;
213  Real* uji = u + i; Real* ujk = u + k;
214  if (j) for(;;)
215  {
216  p = *uji; *uji = *ujk; *ujk = p;
217  if (!(--j)) break;
218  uji += n; ujk += n;
219  }
220  }
221  }
222 }
223 
224 void SortSV(DiagonalMatrix& D, Matrix& U, Matrix& V, bool ascending)
225 {
226  REPORT
227  Tracer trace("SortSV_DUV");
228  int mu = U.Nrows(); int mv = V.Nrows(); int n = D.Nrows();
229  if (n != U.Ncols()) Throw(IncompatibleDimensionsException(D,U));
230  if (n != V.Ncols()) Throw(IncompatibleDimensionsException(D,V));
231  Real* u = U.Store(); Real* v = V.Store();
232  for (int i=0; i<n; i++)
233  {
234  int k = i; Real p = D.element(i);
235  if (ascending)
236  {
237  for (int j=i+1; j<n; j++)
238  { if (D.element(j) < p) { k = j; p = D.element(j); } }
239  }
240  else
241  {
242  for (int j=i+1; j<n; j++)
243  { if (D.element(j) > p) { k = j; p = D.element(j); } }
244  }
245  if (k != i)
246  {
247  D.element(k) = D.element(i); D.element(i) = p;
248  Real* uji = u + i; Real* ujk = u + k;
249  Real* vji = v + i; Real* vjk = v + k;
250  int j = mu;
251  if (j) for(;;)
252  {
253  p = *uji; *uji = *ujk; *ujk = p; if (!(--j)) break;
254  uji += n; ujk += n;
255  }
256  j = mv;
257  if (j) for(;;)
258  {
259  p = *vji; *vji = *vjk; *vjk = p; if (!(--j)) break;
260  vji += n; vjk += n;
261  }
262  }
263  }
264 }
265 
266 
267 
268 
269 #ifdef use_namespace
270 }
271 #endif
272 
ossim_uint32 x
double Real
Definition: include.h:57
void SortDescending(GeneralMatrix &GM)
Definition: sort.cpp:45
Real & element(int, int)
Definition: newmat6.cpp:725
void SortAscending(GeneralMatrix &GM)
Definition: sort.cpp:121
#define MaxDepth
Definition: sort.cpp:33
int Ncols() const
Definition: newmat.h:431
#define REPORT
Definition: sort.cpp:18
os2<< "> n<< " > nendobj n
Definition: newmat.h:543
#define DoSimpleSort
Definition: sort.cpp:32
void SortSV(DiagonalMatrix &D, Matrix &U, bool ascending)
Definition: sort.cpp:190
#define max(a, b)
Definition: auxiliary.h:76
int Storage() const
Definition: newmat.h:432
int Nrows() const
Definition: newmat.h:430
Real * Store() const
Definition: newmat.h:433