max@0
|
1 // Copyright (C) 2010 NICTA (www.nicta.com.au)
|
max@0
|
2 // Copyright (C) 2010 Conrad Sanderson
|
max@0
|
3 // Copyright (C) 2010 Dimitrios Bouzas
|
max@0
|
4 //
|
max@0
|
5 // This file is part of the Armadillo C++ library.
|
max@0
|
6 // It is provided without any warranty of fitness
|
max@0
|
7 // for any purpose. You can redistribute this file
|
max@0
|
8 // and/or modify it under the terms of the GNU
|
max@0
|
9 // Lesser General Public License (LGPL) as published
|
max@0
|
10 // by the Free Software Foundation, either version 3
|
max@0
|
11 // of the License or (at your option) any later version.
|
max@0
|
12 // (see http://www.opensource.org/licenses for more info)
|
max@0
|
13
|
max@0
|
14
|
max@0
|
15
|
max@0
|
16 //! \addtogroup op_find
|
max@0
|
17 //! @{
|
max@0
|
18
|
max@0
|
19
|
max@0
|
20
|
max@0
|
21 template<typename T1>
|
max@0
|
22 inline
|
max@0
|
23 uword
|
max@0
|
24 op_find::helper
|
max@0
|
25 (
|
max@0
|
26 Mat<uword>& indices,
|
max@0
|
27 const Base<typename T1::elem_type, T1>& X
|
max@0
|
28 )
|
max@0
|
29 {
|
max@0
|
30 arma_extra_debug_sigprint();
|
max@0
|
31
|
max@0
|
32 typedef typename T1::elem_type eT;
|
max@0
|
33 typedef typename Proxy<T1>::ea_type ea_type;
|
max@0
|
34
|
max@0
|
35 const Proxy<T1> A(X.get_ref());
|
max@0
|
36
|
max@0
|
37 ea_type PA = A.get_ea();
|
max@0
|
38 const uword n_elem = A.get_n_elem();
|
max@0
|
39
|
max@0
|
40 indices.set_size(n_elem, 1);
|
max@0
|
41
|
max@0
|
42 uword* indices_mem = indices.memptr();
|
max@0
|
43 uword n_nz = 0;
|
max@0
|
44
|
max@0
|
45 for(uword i=0; i<n_elem; ++i)
|
max@0
|
46 {
|
max@0
|
47 if(PA[i] != eT(0))
|
max@0
|
48 {
|
max@0
|
49 indices_mem[n_nz] = i;
|
max@0
|
50 ++n_nz;
|
max@0
|
51 }
|
max@0
|
52 }
|
max@0
|
53
|
max@0
|
54 return n_nz;
|
max@0
|
55 }
|
max@0
|
56
|
max@0
|
57
|
max@0
|
58
|
max@0
|
59 template<typename T1, typename op_type>
|
max@0
|
60 inline
|
max@0
|
61 uword
|
max@0
|
62 op_find::helper
|
max@0
|
63 (
|
max@0
|
64 Mat<uword>& indices,
|
max@0
|
65 const mtOp<uword, T1, op_type>& X,
|
max@0
|
66 const typename arma_op_rel_only<op_type>::result junk1,
|
max@0
|
67 const typename arma_not_cx<typename T1::elem_type>::result junk2
|
max@0
|
68 )
|
max@0
|
69 {
|
max@0
|
70 arma_extra_debug_sigprint();
|
max@0
|
71 arma_ignore(junk1);
|
max@0
|
72 arma_ignore(junk2);
|
max@0
|
73
|
max@0
|
74 typedef typename T1::elem_type eT;
|
max@0
|
75 typedef typename Proxy<T1>::ea_type ea_type;
|
max@0
|
76
|
max@0
|
77 const eT val = X.aux;
|
max@0
|
78
|
max@0
|
79 const Proxy<T1> A(X.m);
|
max@0
|
80
|
max@0
|
81 ea_type PA = A.get_ea();
|
max@0
|
82 const uword n_elem = A.get_n_elem();
|
max@0
|
83
|
max@0
|
84 indices.set_size(n_elem, 1);
|
max@0
|
85
|
max@0
|
86 uword* indices_mem = indices.memptr();
|
max@0
|
87 uword n_nz = 0;
|
max@0
|
88
|
max@0
|
89 for(uword i=0; i<n_elem; ++i)
|
max@0
|
90 {
|
max@0
|
91 const eT tmp = PA[i];
|
max@0
|
92
|
max@0
|
93 bool not_zero;
|
max@0
|
94
|
max@0
|
95 if(is_same_type<op_type, op_rel_lt_pre >::value == true) { not_zero = (val < tmp); }
|
max@0
|
96 else if(is_same_type<op_type, op_rel_lt_post >::value == true) { not_zero = (tmp < val); }
|
max@0
|
97 else if(is_same_type<op_type, op_rel_gt_pre >::value == true) { not_zero = (val > tmp); }
|
max@0
|
98 else if(is_same_type<op_type, op_rel_gt_post >::value == true) { not_zero = (tmp > val); }
|
max@0
|
99 else if(is_same_type<op_type, op_rel_lteq_pre >::value == true) { not_zero = (val <= tmp); }
|
max@0
|
100 else if(is_same_type<op_type, op_rel_lteq_post>::value == true) { not_zero = (tmp <= val); }
|
max@0
|
101 else if(is_same_type<op_type, op_rel_gteq_pre >::value == true) { not_zero = (val >= tmp); }
|
max@0
|
102 else if(is_same_type<op_type, op_rel_gteq_post>::value == true) { not_zero = (tmp >= val); }
|
max@0
|
103 else if(is_same_type<op_type, op_rel_eq >::value == true) { not_zero = (tmp == val); }
|
max@0
|
104 else if(is_same_type<op_type, op_rel_noteq >::value == true) { not_zero = (tmp != val); }
|
max@0
|
105 else not_zero = false;
|
max@0
|
106
|
max@0
|
107 if(not_zero == true)
|
max@0
|
108 {
|
max@0
|
109 indices_mem[n_nz] = i;
|
max@0
|
110 ++n_nz;
|
max@0
|
111 }
|
max@0
|
112 }
|
max@0
|
113
|
max@0
|
114 return n_nz;
|
max@0
|
115 }
|
max@0
|
116
|
max@0
|
117
|
max@0
|
118
|
max@0
|
119 template<typename T1, typename op_type>
|
max@0
|
120 inline
|
max@0
|
121 uword
|
max@0
|
122 op_find::helper
|
max@0
|
123 (
|
max@0
|
124 Mat<uword>& indices,
|
max@0
|
125 const mtOp<uword, T1, op_type>& X,
|
max@0
|
126 const typename arma_op_rel_only<op_type>::result junk1,
|
max@0
|
127 const typename arma_cx_only<typename T1::elem_type>::result junk2
|
max@0
|
128 )
|
max@0
|
129 {
|
max@0
|
130 arma_extra_debug_sigprint();
|
max@0
|
131 arma_ignore(junk1);
|
max@0
|
132 arma_ignore(junk2);
|
max@0
|
133
|
max@0
|
134 typedef typename T1::elem_type eT;
|
max@0
|
135 typedef typename Proxy<T1>::ea_type ea_type;
|
max@0
|
136
|
max@0
|
137 const eT val = X.aux;
|
max@0
|
138
|
max@0
|
139 const Proxy<T1> A(X.m);
|
max@0
|
140
|
max@0
|
141 ea_type PA = A.get_ea();
|
max@0
|
142 const uword n_elem = A.get_n_elem();
|
max@0
|
143
|
max@0
|
144 indices.set_size(n_elem, 1);
|
max@0
|
145
|
max@0
|
146 uword* indices_mem = indices.memptr();
|
max@0
|
147 uword n_nz = 0;
|
max@0
|
148
|
max@0
|
149 for(uword i=0; i<n_elem; ++i)
|
max@0
|
150 {
|
max@0
|
151 const eT tmp = PA[i];
|
max@0
|
152
|
max@0
|
153 bool not_zero;
|
max@0
|
154
|
max@0
|
155 if(is_same_type<op_type, op_rel_eq >::value == true) { not_zero = (tmp == val); }
|
max@0
|
156 else if(is_same_type<op_type, op_rel_noteq>::value == true) { not_zero = (tmp != val); }
|
max@0
|
157 else not_zero = false;
|
max@0
|
158
|
max@0
|
159 if(not_zero == true)
|
max@0
|
160 {
|
max@0
|
161 indices_mem[n_nz] = i;
|
max@0
|
162 ++n_nz;
|
max@0
|
163 }
|
max@0
|
164 }
|
max@0
|
165
|
max@0
|
166 return n_nz;
|
max@0
|
167 }
|
max@0
|
168
|
max@0
|
169
|
max@0
|
170
|
max@0
|
171 template<typename T1, typename T2, typename glue_type>
|
max@0
|
172 inline
|
max@0
|
173 uword
|
max@0
|
174 op_find::helper
|
max@0
|
175 (
|
max@0
|
176 Mat<uword>& indices,
|
max@0
|
177 const mtGlue<uword, T1, T2, glue_type>& X,
|
max@0
|
178 const typename arma_glue_rel_only<glue_type>::result junk1,
|
max@0
|
179 const typename arma_not_cx<typename T1::elem_type>::result junk2,
|
max@0
|
180 const typename arma_not_cx<typename T2::elem_type>::result junk3
|
max@0
|
181 )
|
max@0
|
182 {
|
max@0
|
183 arma_extra_debug_sigprint();
|
max@0
|
184 arma_ignore(junk1);
|
max@0
|
185 arma_ignore(junk2);
|
max@0
|
186 arma_ignore(junk3);
|
max@0
|
187
|
max@0
|
188 typedef typename T1::elem_type eT1;
|
max@0
|
189 typedef typename T2::elem_type eT2;
|
max@0
|
190
|
max@0
|
191 typedef typename Proxy<T1>::ea_type ea_type1;
|
max@0
|
192 typedef typename Proxy<T2>::ea_type ea_type2;
|
max@0
|
193
|
max@0
|
194 const Proxy<T1> A(X.A);
|
max@0
|
195 const Proxy<T2> B(X.B);
|
max@0
|
196
|
max@0
|
197 arma_debug_assert_same_size(A, B, "relational operator");
|
max@0
|
198
|
max@0
|
199 ea_type1 PA = A.get_ea();
|
max@0
|
200 ea_type2 PB = B.get_ea();
|
max@0
|
201 const uword n_elem = B.get_n_elem();
|
max@0
|
202
|
max@0
|
203 indices.set_size(n_elem, 1);
|
max@0
|
204
|
max@0
|
205 uword* indices_mem = indices.memptr();
|
max@0
|
206 uword n_nz = 0;
|
max@0
|
207
|
max@0
|
208 for(uword i=0; i<n_elem; ++i)
|
max@0
|
209 {
|
max@0
|
210 const eT1 tmp1 = PA[i];
|
max@0
|
211 const eT2 tmp2 = PB[i];
|
max@0
|
212
|
max@0
|
213 bool not_zero;
|
max@0
|
214
|
max@0
|
215 if(is_same_type<glue_type, glue_rel_lt >::value == true) { not_zero = (tmp1 < tmp2); }
|
max@0
|
216 else if(is_same_type<glue_type, glue_rel_gt >::value == true) { not_zero = (tmp1 > tmp2); }
|
max@0
|
217 else if(is_same_type<glue_type, glue_rel_lteq >::value == true) { not_zero = (tmp1 <= tmp2); }
|
max@0
|
218 else if(is_same_type<glue_type, glue_rel_gteq >::value == true) { not_zero = (tmp1 >= tmp2); }
|
max@0
|
219 else if(is_same_type<glue_type, glue_rel_eq >::value == true) { not_zero = (tmp1 == tmp2); }
|
max@0
|
220 else if(is_same_type<glue_type, glue_rel_noteq >::value == true) { not_zero = (tmp1 != tmp2); }
|
max@0
|
221 else not_zero = false;
|
max@0
|
222
|
max@0
|
223 if(not_zero == true)
|
max@0
|
224 {
|
max@0
|
225 indices_mem[n_nz] = i;
|
max@0
|
226 ++n_nz;
|
max@0
|
227 }
|
max@0
|
228 }
|
max@0
|
229
|
max@0
|
230 return n_nz;
|
max@0
|
231 }
|
max@0
|
232
|
max@0
|
233
|
max@0
|
234
|
max@0
|
235 template<typename T1, typename T2, typename glue_type>
|
max@0
|
236 inline
|
max@0
|
237 uword
|
max@0
|
238 op_find::helper
|
max@0
|
239 (
|
max@0
|
240 Mat<uword>& indices,
|
max@0
|
241 const mtGlue<uword, T1, T2, glue_type>& X,
|
max@0
|
242 const typename arma_glue_rel_only<glue_type>::result junk1,
|
max@0
|
243 const typename arma_cx_only<typename T1::elem_type>::result junk2,
|
max@0
|
244 const typename arma_cx_only<typename T2::elem_type>::result junk3
|
max@0
|
245 )
|
max@0
|
246 {
|
max@0
|
247 arma_extra_debug_sigprint();
|
max@0
|
248 arma_ignore(junk1);
|
max@0
|
249 arma_ignore(junk2);
|
max@0
|
250 arma_ignore(junk3);
|
max@0
|
251
|
max@0
|
252 typedef typename Proxy<T1>::ea_type ea_type1;
|
max@0
|
253 typedef typename Proxy<T2>::ea_type ea_type2;
|
max@0
|
254
|
max@0
|
255 const Proxy<T1> A(X.A);
|
max@0
|
256 const Proxy<T2> B(X.B);
|
max@0
|
257
|
max@0
|
258 arma_debug_assert_same_size(A, B, "relational operator");
|
max@0
|
259
|
max@0
|
260 ea_type1 PA = A.get_ea();
|
max@0
|
261 ea_type2 PB = B.get_ea();
|
max@0
|
262 const uword n_elem = B.get_n_elem();
|
max@0
|
263
|
max@0
|
264 indices.set_size(n_elem, 1);
|
max@0
|
265
|
max@0
|
266 uword* indices_mem = indices.memptr();
|
max@0
|
267 uword n_nz = 0;
|
max@0
|
268
|
max@0
|
269 for(uword i=0; i<n_elem; ++i)
|
max@0
|
270 {
|
max@0
|
271 bool not_zero;
|
max@0
|
272
|
max@0
|
273 if(is_same_type<glue_type, glue_rel_eq >::value == true) { not_zero = (PA[i] == PB[i]); }
|
max@0
|
274 else if(is_same_type<glue_type, glue_rel_noteq >::value == true) { not_zero = (PA[i] != PB[i]); }
|
max@0
|
275 else not_zero = false;
|
max@0
|
276
|
max@0
|
277 if(not_zero == true)
|
max@0
|
278 {
|
max@0
|
279 indices_mem[n_nz] = i;
|
max@0
|
280 ++n_nz;
|
max@0
|
281 }
|
max@0
|
282 }
|
max@0
|
283
|
max@0
|
284 return n_nz;
|
max@0
|
285 }
|
max@0
|
286
|
max@0
|
287
|
max@0
|
288
|
max@0
|
289 template<typename T1>
|
max@0
|
290 inline
|
max@0
|
291 void
|
max@0
|
292 op_find::apply(Mat<uword>& out, const mtOp<uword, T1, op_find>& X)
|
max@0
|
293 {
|
max@0
|
294 arma_extra_debug_sigprint();
|
max@0
|
295
|
max@0
|
296 const uword k = X.aux_uword_a;
|
max@0
|
297 const uword type = X.aux_uword_b;
|
max@0
|
298
|
max@0
|
299 Mat<uword> indices;
|
max@0
|
300 const uword n_nz = op_find::helper(indices, X.m);
|
max@0
|
301
|
max@0
|
302 if(n_nz > 0)
|
max@0
|
303 {
|
max@0
|
304 if(type == 0) // "first"
|
max@0
|
305 {
|
max@0
|
306 out = (k > 0 && k <= n_nz) ? indices.rows(0, k-1 ) : indices.rows(0, n_nz-1);
|
max@0
|
307 }
|
max@0
|
308 else // "last"
|
max@0
|
309 {
|
max@0
|
310 out = (k > 0 && k <= n_nz) ? indices.rows(n_nz-k, n_nz-1) : indices.rows(0, n_nz-1);
|
max@0
|
311 }
|
max@0
|
312 }
|
max@0
|
313 else
|
max@0
|
314 {
|
max@0
|
315 out.reset();
|
max@0
|
316 }
|
max@0
|
317 }
|
max@0
|
318
|
max@0
|
319
|
max@0
|
320
|
max@0
|
321 //! @}
|