max@0
|
1 // Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
|
max@0
|
2 // Copyright (C) 2008-2011 Conrad Sanderson
|
max@0
|
3 //
|
max@0
|
4 // This file is part of the Armadillo C++ library.
|
max@0
|
5 // It is provided without any warranty of fitness
|
max@0
|
6 // for any purpose. You can redistribute this file
|
max@0
|
7 // and/or modify it under the terms of the GNU
|
max@0
|
8 // Lesser General Public License (LGPL) as published
|
max@0
|
9 // by the Free Software Foundation, either version 3
|
max@0
|
10 // of the License or (at your option) any later version.
|
max@0
|
11 // (see http://www.opensource.org/licenses for more info)
|
max@0
|
12
|
max@0
|
13
|
max@0
|
14 //! \addtogroup op_sort
|
max@0
|
15 //! @{
|
max@0
|
16
|
max@0
|
17
|
max@0
|
18
|
max@0
|
19 template<typename eT>
|
max@0
|
20 class arma_ascend_sort_helper
|
max@0
|
21 {
|
max@0
|
22 public:
|
max@0
|
23
|
max@0
|
24 arma_inline
|
max@0
|
25 bool
|
max@0
|
26 operator() (eT a, eT b) const
|
max@0
|
27 {
|
max@0
|
28 return (a < b);
|
max@0
|
29 }
|
max@0
|
30 };
|
max@0
|
31
|
max@0
|
32
|
max@0
|
33
|
max@0
|
34 template<typename eT>
|
max@0
|
35 class arma_descend_sort_helper
|
max@0
|
36 {
|
max@0
|
37 public:
|
max@0
|
38
|
max@0
|
39 arma_inline
|
max@0
|
40 bool
|
max@0
|
41 operator() (eT a, eT b) const
|
max@0
|
42 {
|
max@0
|
43 return (a > b);
|
max@0
|
44 }
|
max@0
|
45 };
|
max@0
|
46
|
max@0
|
47
|
max@0
|
48
|
max@0
|
49 template<typename T>
|
max@0
|
50 class arma_ascend_sort_helper< std::complex<T> >
|
max@0
|
51 {
|
max@0
|
52 public:
|
max@0
|
53
|
max@0
|
54 typedef typename std::complex<T> eT;
|
max@0
|
55
|
max@0
|
56 inline
|
max@0
|
57 bool
|
max@0
|
58 operator() (const eT& a, const eT& b) const
|
max@0
|
59 {
|
max@0
|
60 return (std::abs(a) < std::abs(b));
|
max@0
|
61 }
|
max@0
|
62 };
|
max@0
|
63
|
max@0
|
64
|
max@0
|
65
|
max@0
|
66 template<typename T>
|
max@0
|
67 class arma_descend_sort_helper< std::complex<T> >
|
max@0
|
68 {
|
max@0
|
69 public:
|
max@0
|
70
|
max@0
|
71 typedef typename std::complex<T> eT;
|
max@0
|
72
|
max@0
|
73 inline
|
max@0
|
74 bool
|
max@0
|
75 operator() (const eT& a, const eT& b) const
|
max@0
|
76 {
|
max@0
|
77 return (std::abs(a) > std::abs(b));
|
max@0
|
78 }
|
max@0
|
79 };
|
max@0
|
80
|
max@0
|
81
|
max@0
|
82
|
max@0
|
83 template<typename eT>
|
max@0
|
84 inline
|
max@0
|
85 void
|
max@0
|
86 op_sort::direct_sort(eT* X, const uword n_elem, const uword sort_type)
|
max@0
|
87 {
|
max@0
|
88 arma_extra_debug_sigprint();
|
max@0
|
89
|
max@0
|
90 if(sort_type == 0)
|
max@0
|
91 {
|
max@0
|
92 arma_ascend_sort_helper<eT> comparator;
|
max@0
|
93
|
max@0
|
94 std::sort(&X[0], &X[n_elem], comparator);
|
max@0
|
95 }
|
max@0
|
96 else
|
max@0
|
97 {
|
max@0
|
98 arma_descend_sort_helper<eT> comparator;
|
max@0
|
99
|
max@0
|
100 std::sort(&X[0], &X[n_elem], comparator);
|
max@0
|
101 }
|
max@0
|
102 }
|
max@0
|
103
|
max@0
|
104
|
max@0
|
105
|
max@0
|
106 template<typename eT>
|
max@0
|
107 inline
|
max@0
|
108 void
|
max@0
|
109 op_sort::copy_row(eT* X, const Mat<eT>& A, const uword row)
|
max@0
|
110 {
|
max@0
|
111 const uword N = A.n_cols;
|
max@0
|
112
|
max@0
|
113 uword i,j;
|
max@0
|
114
|
max@0
|
115 for(i=0, j=1; j<N; i+=2, j+=2)
|
max@0
|
116 {
|
max@0
|
117 X[i] = A.at(row,i);
|
max@0
|
118 X[j] = A.at(row,j);
|
max@0
|
119 }
|
max@0
|
120
|
max@0
|
121 if(i < N)
|
max@0
|
122 {
|
max@0
|
123 X[i] = A.at(row,i);
|
max@0
|
124 }
|
max@0
|
125 }
|
max@0
|
126
|
max@0
|
127
|
max@0
|
128
|
max@0
|
129 template<typename eT>
|
max@0
|
130 inline
|
max@0
|
131 void
|
max@0
|
132 op_sort::copy_row(Mat<eT>& A, const eT* X, const uword row)
|
max@0
|
133 {
|
max@0
|
134 const uword N = A.n_cols;
|
max@0
|
135
|
max@0
|
136 uword i,j;
|
max@0
|
137
|
max@0
|
138 for(i=0, j=1; j<N; i+=2, j+=2)
|
max@0
|
139 {
|
max@0
|
140 A.at(row,i) = X[i];
|
max@0
|
141 A.at(row,j) = X[j];
|
max@0
|
142 }
|
max@0
|
143
|
max@0
|
144 if(i < N)
|
max@0
|
145 {
|
max@0
|
146 A.at(row,i) = X[i];
|
max@0
|
147 }
|
max@0
|
148 }
|
max@0
|
149
|
max@0
|
150
|
max@0
|
151
|
max@0
|
152 template<typename T1>
|
max@0
|
153 inline
|
max@0
|
154 void
|
max@0
|
155 op_sort::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_sort>& in)
|
max@0
|
156 {
|
max@0
|
157 arma_extra_debug_sigprint();
|
max@0
|
158
|
max@0
|
159 typedef typename T1::elem_type eT;
|
max@0
|
160
|
max@0
|
161 const unwrap<T1> tmp(in.m);
|
max@0
|
162 const Mat<eT>& X = tmp.M;
|
max@0
|
163
|
max@0
|
164 const uword sort_type = in.aux_uword_a;
|
max@0
|
165 const uword dim = in.aux_uword_b;
|
max@0
|
166
|
max@0
|
167 arma_debug_check( (sort_type > 1), "sort(): incorrect usage. sort_type must be 0 or 1");
|
max@0
|
168 arma_debug_check( (dim > 1), "sort(): incorrect usage. dim must be 0 or 1" );
|
max@0
|
169 arma_debug_check( (X.is_finite() == false), "sort(): given object has non-finite elements" );
|
max@0
|
170
|
max@0
|
171 if( (X.n_rows * X.n_cols) <= 1 )
|
max@0
|
172 {
|
max@0
|
173 out = X;
|
max@0
|
174 return;
|
max@0
|
175 }
|
max@0
|
176
|
max@0
|
177
|
max@0
|
178 if(dim == 0) // sort the contents of each column
|
max@0
|
179 {
|
max@0
|
180 arma_extra_debug_print("op_sort::apply(), dim = 0");
|
max@0
|
181
|
max@0
|
182 out = X;
|
max@0
|
183
|
max@0
|
184 const uword n_rows = out.n_rows;
|
max@0
|
185 const uword n_cols = out.n_cols;
|
max@0
|
186
|
max@0
|
187 for(uword col=0; col < n_cols; ++col)
|
max@0
|
188 {
|
max@0
|
189 op_sort::direct_sort( out.colptr(col), n_rows, sort_type );
|
max@0
|
190 }
|
max@0
|
191 }
|
max@0
|
192 else
|
max@0
|
193 if(dim == 1) // sort the contents of each row
|
max@0
|
194 {
|
max@0
|
195 if(X.n_rows == 1) // a row vector
|
max@0
|
196 {
|
max@0
|
197 arma_extra_debug_print("op_sort::apply(), dim = 1, vector specific");
|
max@0
|
198
|
max@0
|
199 out = X;
|
max@0
|
200 op_sort::direct_sort(out.memptr(), out.n_elem, sort_type);
|
max@0
|
201 }
|
max@0
|
202 else // not a row vector
|
max@0
|
203 {
|
max@0
|
204 arma_extra_debug_print("op_sort::apply(), dim = 1, generic");
|
max@0
|
205
|
max@0
|
206 out.copy_size(X);
|
max@0
|
207
|
max@0
|
208 const uword n_rows = out.n_rows;
|
max@0
|
209 const uword n_cols = out.n_cols;
|
max@0
|
210
|
max@0
|
211 podarray<eT> tmp_array(n_cols);
|
max@0
|
212
|
max@0
|
213 for(uword row=0; row < n_rows; ++row)
|
max@0
|
214 {
|
max@0
|
215 op_sort::copy_row(tmp_array.memptr(), X, row);
|
max@0
|
216
|
max@0
|
217 op_sort::direct_sort( tmp_array.memptr(), n_cols, sort_type );
|
max@0
|
218
|
max@0
|
219 op_sort::copy_row(out, tmp_array.memptr(), row);
|
max@0
|
220 }
|
max@0
|
221 }
|
max@0
|
222 }
|
max@0
|
223
|
max@0
|
224 }
|
max@0
|
225
|
max@0
|
226
|
max@0
|
227 //! @}
|