Chris@49
|
1 // Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
|
Chris@49
|
2 // Copyright (C) 2009-2012 Conrad Sanderson
|
Chris@49
|
3 //
|
Chris@49
|
4 // This Source Code Form is subject to the terms of the Mozilla Public
|
Chris@49
|
5 // License, v. 2.0. If a copy of the MPL was not distributed with this
|
Chris@49
|
6 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
Chris@49
|
7
|
Chris@49
|
8
|
Chris@49
|
9 //! \addtogroup fn_sort_index
|
Chris@49
|
10 //! @{
|
Chris@49
|
11
|
Chris@49
|
12
|
Chris@49
|
13
|
Chris@49
|
14
|
Chris@49
|
15 template<typename T1, typename T2>
|
Chris@49
|
16 struct arma_sort_index_packet
|
Chris@49
|
17 {
|
Chris@49
|
18 T1 val;
|
Chris@49
|
19 T2 index;
|
Chris@49
|
20 };
|
Chris@49
|
21
|
Chris@49
|
22
|
Chris@49
|
23
|
Chris@49
|
24 class arma_sort_index_helper_ascend
|
Chris@49
|
25 {
|
Chris@49
|
26 public:
|
Chris@49
|
27
|
Chris@49
|
28 template<typename T1, typename T2>
|
Chris@49
|
29 arma_inline
|
Chris@49
|
30 bool
|
Chris@49
|
31 operator() (const arma_sort_index_packet<T1,T2>& A, const arma_sort_index_packet<T1,T2>& B) const
|
Chris@49
|
32 {
|
Chris@49
|
33 return (A.val < B.val);
|
Chris@49
|
34 }
|
Chris@49
|
35 };
|
Chris@49
|
36
|
Chris@49
|
37
|
Chris@49
|
38
|
Chris@49
|
39 class arma_sort_index_helper_descend
|
Chris@49
|
40 {
|
Chris@49
|
41 public:
|
Chris@49
|
42
|
Chris@49
|
43 template<typename T1, typename T2>
|
Chris@49
|
44 arma_inline
|
Chris@49
|
45 bool
|
Chris@49
|
46 operator() (const arma_sort_index_packet<T1,T2>& A, const arma_sort_index_packet<T1,T2>& B) const
|
Chris@49
|
47 {
|
Chris@49
|
48 return (A.val > B.val);
|
Chris@49
|
49 }
|
Chris@49
|
50 };
|
Chris@49
|
51
|
Chris@49
|
52
|
Chris@49
|
53
|
Chris@49
|
54 template<typename umat_elem_type, typename eT, const uword sort_direction, const uword sort_type>
|
Chris@49
|
55 void
|
Chris@49
|
56 inline
|
Chris@49
|
57 sort_index_helper(umat_elem_type* out_mem, const eT* in_mem, const uword n_elem)
|
Chris@49
|
58 {
|
Chris@49
|
59 arma_extra_debug_sigprint();
|
Chris@49
|
60
|
Chris@49
|
61 std::vector< arma_sort_index_packet<eT, umat_elem_type> > packet_vec(n_elem);
|
Chris@49
|
62
|
Chris@49
|
63 for(uword i=0; i<n_elem; ++i)
|
Chris@49
|
64 {
|
Chris@49
|
65 packet_vec[i].val = in_mem[i];
|
Chris@49
|
66 packet_vec[i].index = i;
|
Chris@49
|
67 }
|
Chris@49
|
68
|
Chris@49
|
69
|
Chris@49
|
70 if(sort_direction == 0)
|
Chris@49
|
71 {
|
Chris@49
|
72 // ascend
|
Chris@49
|
73
|
Chris@49
|
74 arma_sort_index_helper_ascend comparator;
|
Chris@49
|
75
|
Chris@49
|
76 if(sort_type == 0)
|
Chris@49
|
77 {
|
Chris@49
|
78 std::sort( packet_vec.begin(), packet_vec.end(), comparator );
|
Chris@49
|
79 }
|
Chris@49
|
80 else
|
Chris@49
|
81 {
|
Chris@49
|
82 std::stable_sort( packet_vec.begin(), packet_vec.end(), comparator );
|
Chris@49
|
83 }
|
Chris@49
|
84 }
|
Chris@49
|
85 else
|
Chris@49
|
86 {
|
Chris@49
|
87 // descend
|
Chris@49
|
88
|
Chris@49
|
89 arma_sort_index_helper_descend comparator;
|
Chris@49
|
90
|
Chris@49
|
91 if(sort_type == 0)
|
Chris@49
|
92 {
|
Chris@49
|
93 std::sort( packet_vec.begin(), packet_vec.end(), comparator );
|
Chris@49
|
94 }
|
Chris@49
|
95 else
|
Chris@49
|
96 {
|
Chris@49
|
97 std::stable_sort( packet_vec.begin(), packet_vec.end(), comparator );
|
Chris@49
|
98 }
|
Chris@49
|
99 }
|
Chris@49
|
100
|
Chris@49
|
101
|
Chris@49
|
102 for(uword i=0; i<n_elem; ++i)
|
Chris@49
|
103 {
|
Chris@49
|
104 out_mem[i] = packet_vec[i].index;
|
Chris@49
|
105 }
|
Chris@49
|
106 }
|
Chris@49
|
107
|
Chris@49
|
108
|
Chris@49
|
109
|
Chris@49
|
110 template<typename T1>
|
Chris@49
|
111 inline
|
Chris@49
|
112 umat
|
Chris@49
|
113 sort_index
|
Chris@49
|
114 (
|
Chris@49
|
115 const Base<typename T1::elem_type,T1>& X,
|
Chris@49
|
116 const uword sort_direction = 0,
|
Chris@49
|
117 const typename arma_not_cx<typename T1::elem_type>::result* junk = 0
|
Chris@49
|
118 )
|
Chris@49
|
119 {
|
Chris@49
|
120 arma_extra_debug_sigprint();
|
Chris@49
|
121 arma_ignore(junk);
|
Chris@49
|
122
|
Chris@49
|
123 typedef typename T1::elem_type eT;
|
Chris@49
|
124
|
Chris@49
|
125 const unwrap<T1> tmp(X.get_ref());
|
Chris@49
|
126 const Mat<eT>& A = tmp.M;
|
Chris@49
|
127
|
Chris@49
|
128 if(A.is_empty() == true)
|
Chris@49
|
129 {
|
Chris@49
|
130 return umat();
|
Chris@49
|
131 }
|
Chris@49
|
132
|
Chris@49
|
133 arma_debug_check( (A.is_vec() == false), "sort_index(): currently only handles vectors");
|
Chris@49
|
134
|
Chris@49
|
135 typedef typename umat::elem_type out_elem_type;
|
Chris@49
|
136
|
Chris@49
|
137 umat out(A.n_rows, A.n_cols);
|
Chris@49
|
138
|
Chris@49
|
139 if(sort_direction == 0)
|
Chris@49
|
140 {
|
Chris@49
|
141 sort_index_helper<out_elem_type, eT, 0, 0>(out.memptr(), A.mem, A.n_elem);
|
Chris@49
|
142 }
|
Chris@49
|
143 else
|
Chris@49
|
144 {
|
Chris@49
|
145 sort_index_helper<out_elem_type, eT, 1, 0>(out.memptr(), A.mem, A.n_elem);
|
Chris@49
|
146 }
|
Chris@49
|
147
|
Chris@49
|
148 return out;
|
Chris@49
|
149 }
|
Chris@49
|
150
|
Chris@49
|
151
|
Chris@49
|
152
|
Chris@49
|
153 template<typename T1>
|
Chris@49
|
154 inline
|
Chris@49
|
155 umat
|
Chris@49
|
156 stable_sort_index
|
Chris@49
|
157 (
|
Chris@49
|
158 const Base<typename T1::elem_type,T1>& X,
|
Chris@49
|
159 const uword sort_direction = 0,
|
Chris@49
|
160 const typename arma_not_cx<typename T1::elem_type>::result* junk = 0
|
Chris@49
|
161 )
|
Chris@49
|
162 {
|
Chris@49
|
163 arma_extra_debug_sigprint();
|
Chris@49
|
164 arma_ignore(junk);
|
Chris@49
|
165
|
Chris@49
|
166 typedef typename T1::elem_type eT;
|
Chris@49
|
167
|
Chris@49
|
168 const unwrap<T1> tmp(X.get_ref());
|
Chris@49
|
169 const Mat<eT>& A = tmp.M;
|
Chris@49
|
170
|
Chris@49
|
171 if(A.is_empty() == true)
|
Chris@49
|
172 {
|
Chris@49
|
173 return umat();
|
Chris@49
|
174 }
|
Chris@49
|
175
|
Chris@49
|
176 arma_debug_check( (A.is_vec() == false), "stable_sort_index(): currently only handles vectors");
|
Chris@49
|
177
|
Chris@49
|
178 typedef typename umat::elem_type out_elem_type;
|
Chris@49
|
179
|
Chris@49
|
180 umat out(A.n_rows, A.n_cols);
|
Chris@49
|
181
|
Chris@49
|
182 if(sort_direction == 0)
|
Chris@49
|
183 {
|
Chris@49
|
184 sort_index_helper<out_elem_type, eT, 0, 1>(out.memptr(), A.mem, A.n_elem);
|
Chris@49
|
185 }
|
Chris@49
|
186 else
|
Chris@49
|
187 {
|
Chris@49
|
188 sort_index_helper<out_elem_type, eT, 1, 1>(out.memptr(), A.mem, A.n_elem);
|
Chris@49
|
189 }
|
Chris@49
|
190
|
Chris@49
|
191 return out;
|
Chris@49
|
192 }
|
Chris@49
|
193
|
Chris@49
|
194
|
Chris@49
|
195
|
Chris@49
|
196 //! @}
|