Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/util/newmat/sort.cpp @ 4565

Last change on this file since 4565 was 4565, checked in by patrick, 19 years ago

orxonox/trunk: added the newmat library to the project. needs some translation in directory, temp under util/newmat. is needed by the collision detection engine to perform lin alg operations such as eigenvector decomposition. perhaps we will make our own library to do that later.

File size: 7.3 KB
Line 
1//$$ sort.cpp                            Sorting
2
3// Copyright (C) 1991,2,3,4: R B Davies
4
5#define WANT_MATH
6
7#include "include.h"
8
9#include "newmatap.h"
10
11#ifdef use_namespace
12namespace 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
35static void MyQuickSortDescending(Real* first, Real* last, int depth);
36static void InsertionSortDescending(Real* first, const int length,
37   int guard);
38static Real SortThreeDescending(Real* a, Real* b, Real* c);
39
40static void MyQuickSortAscending(Real* first, Real* last, int depth);
41static void InsertionSortAscending(Real* first, const int length,
42   int guard);
43
44
45void SortDescending(GeneralMatrix& GM)
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
57static 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
71static 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
96static 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
121void SortAscending(GeneralMatrix& GM)
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
133static 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}
157static 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
190void 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
224void 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
Note: See TracBrowser for help on using the repository browser.