Mercurial > hg > octave-lyh
annotate liboctave/intNDArray.cc @ 11700:a255ceb8e416 release-3-0-x
Chop trailing singletons in min/max functions
author | David Bateman <dbateman@free.fr> |
---|---|
date | Tue, 18 Mar 2008 20:47:40 -0400 |
parents | e8d953d03f6a |
children | 72830070a17b |
rev | line source |
---|---|
4902 | 1 // N-D Array manipulations. |
2 /* | |
3 | |
7017 | 4 Copyright (C) 2004, 2005, 2006, 2007 John W. Eaton |
4902 | 5 |
6 This file is part of Octave. | |
7 | |
8 Octave is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
7016 | 10 Free Software Foundation; either version 3 of the License, or (at your |
11 option) any later version. | |
4902 | 12 |
13 Octave is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
7016 | 19 along with Octave; see the file COPYING. If not, see |
20 <http://www.gnu.org/licenses/>. | |
4902 | 21 |
22 */ | |
23 | |
24 #ifdef HAVE_CONFIG_H | |
25 #include <config.h> | |
26 #endif | |
27 | |
28 #include "Array-util.h" | |
29 #include "mx-base.h" | |
30 #include "lo-ieee.h" | |
31 | |
32 // unary operations | |
33 | |
34 template <class T> | |
35 boolNDArray | |
36 intNDArray<T>::operator ! (void) const | |
37 { | |
4932 | 38 boolNDArray b (this->dims ()); |
4902 | 39 |
5275 | 40 for (octave_idx_type i = 0; i < this->length (); i++) |
4932 | 41 b.elem (i) = ! this->elem (i); |
4902 | 42 |
43 return b; | |
44 } | |
45 | |
5943 | 46 template <class T> |
47 bool | |
48 intNDArray<T>::any_element_not_one_or_zero (void) const | |
49 { | |
50 octave_idx_type nel = this->nelem (); | |
51 | |
52 for (octave_idx_type i = 0; i < nel; i++) | |
53 { | |
54 T val = this->elem (i); | |
55 | |
56 if (val != 0.0 && val != 1.0) | |
57 return true; | |
58 } | |
59 | |
60 return false; | |
61 } | |
62 | |
6979 | 63 |
64 template <class T> | |
65 intNDArray<T> | |
66 intNDArray<T>::diag (void) const | |
67 { | |
68 return diag (0); | |
69 } | |
70 | |
71 template <class T> | |
72 intNDArray<T> | |
73 intNDArray<T>::diag (octave_idx_type k) const | |
74 { | |
75 dim_vector dv = this->dims (); | |
76 octave_idx_type nd = dv.length (); | |
77 | |
78 if (nd > 2) | |
79 { | |
80 (*current_liboctave_error_handler) ("Matrix must be 2-dimensional"); | |
81 return intNDArray<T>(); | |
82 } | |
83 else | |
84 { | |
85 octave_idx_type nnr = dv (0); | |
86 octave_idx_type nnc = dv (1); | |
87 | |
88 if (k > 0) | |
89 nnc -= k; | |
90 else if (k < 0) | |
91 nnr += k; | |
92 | |
93 intNDArray<T> d; | |
94 | |
95 if (nnr > 0 && nnc > 0) | |
96 { | |
97 octave_idx_type ndiag = (nnr < nnc) ? nnr : nnc; | |
98 | |
99 d.resize (dim_vector (ndiag, 1)); | |
100 | |
101 if (k > 0) | |
102 { | |
103 for (octave_idx_type i = 0; i < ndiag; i++) | |
104 d.xelem (i) = this->elem (i, i+k); | |
105 } | |
106 else if (k < 0) | |
107 { | |
108 for (octave_idx_type i = 0; i < ndiag; i++) | |
109 d.xelem (i) = this->elem (i-k, i); | |
110 } | |
111 else | |
112 { | |
113 for (octave_idx_type i = 0; i < ndiag; i++) | |
114 d.xelem (i) = this->elem (i, i); | |
115 } | |
116 } | |
117 else | |
118 (*current_liboctave_error_handler) | |
119 ("diag: requested diagonal out of range"); | |
120 | |
121 return d; | |
122 } | |
123 } | |
124 | |
5775 | 125 // FIXME -- this is not quite the right thing. |
4902 | 126 |
127 template <class T> | |
128 boolNDArray | |
129 intNDArray<T>::all (int dim) const | |
130 { | |
4932 | 131 MX_ND_ANY_ALL_REDUCTION (MX_ND_ALL_EVAL (this->elem (iter_idx) == T (0)), true); |
4902 | 132 } |
133 | |
134 template <class T> | |
135 boolNDArray | |
136 intNDArray<T>::any (int dim) const | |
137 { | |
4932 | 138 MX_ND_ANY_ALL_REDUCTION (MX_ND_ALL_EVAL (this->elem (iter_idx) == T (0)), false); |
4902 | 139 } |
140 | |
141 template <class T> | |
142 void | |
5275 | 143 intNDArray<T>::increment_index (Array<octave_idx_type>& ra_idx, |
4902 | 144 const dim_vector& dimensions, |
145 int start_dimension) | |
146 { | |
147 ::increment_index (ra_idx, dimensions, start_dimension); | |
148 } | |
149 | |
150 template <class T> | |
5275 | 151 octave_idx_type |
152 intNDArray<T>::compute_index (Array<octave_idx_type>& ra_idx, | |
4902 | 153 const dim_vector& dimensions) |
154 { | |
155 return ::compute_index (ra_idx, dimensions); | |
156 } | |
157 | |
4915 | 158 template <class T> |
5073 | 159 intNDArray<T> |
5275 | 160 intNDArray<T>::concat (const intNDArray<T>& rb, const Array<octave_idx_type>& ra_idx) |
5073 | 161 { |
6482 | 162 if (rb.numel () > 0) |
5073 | 163 insert (rb, ra_idx); |
164 return *this; | |
165 } | |
166 | |
167 template <class T> | |
4915 | 168 intNDArray<T>& |
5275 | 169 intNDArray<T>::insert (const intNDArray<T>& a, octave_idx_type r, octave_idx_type c) |
4915 | 170 { |
171 Array<T>::insert (a, r, c); | |
172 return *this; | |
173 } | |
174 | |
175 template <class T> | |
176 intNDArray<T>& | |
5275 | 177 intNDArray<T>::insert (const intNDArray<T>& a, const Array<octave_idx_type>& ra_idx) |
4915 | 178 { |
179 Array<T>::insert (a, ra_idx); | |
180 return *this; | |
181 } | |
182 | |
4902 | 183 // This contains no information on the array structure !!! |
184 | |
185 template <class T> | |
186 std::ostream& | |
187 operator << (std::ostream& os, const intNDArray<T>& a) | |
188 { | |
5275 | 189 octave_idx_type nel = a.nelem (); |
4902 | 190 |
5275 | 191 for (octave_idx_type i = 0; i < nel; i++) |
4902 | 192 os << " " << a.elem (i) << "\n"; |
193 | |
194 return os; | |
195 } | |
196 | |
197 template <class T> | |
198 std::istream& | |
199 operator >> (std::istream& is, intNDArray<T>& a) | |
200 { | |
5275 | 201 octave_idx_type nel = a.nelem (); |
4902 | 202 |
203 if (nel < 1 ) | |
204 is.clear (std::ios::badbit); | |
205 else | |
206 { | |
207 T tmp; | |
208 | |
5275 | 209 for (octave_idx_type i = 0; i < nel; i++) |
4902 | 210 { |
211 is >> tmp; | |
212 | |
213 if (is) | |
214 a.elem (i) = tmp; | |
215 else | |
216 goto done; | |
217 } | |
218 } | |
219 | |
220 done: | |
221 | |
222 return is; | |
223 } | |
224 | |
7113 | 225 template <class T> |
226 intNDArray<T> | |
227 intNDArray<T>::sum (int dim) const | |
228 { | |
229 MX_ND_REDUCTION (retval(result_idx) += intNDArray<T>::elem (iter_idx), 0, intNDArray<T>); | |
230 } | |
231 | |
7189 | 232 template <class T> |
233 intNDArray<T> | |
234 intNDArray<T>::max (int dim) const | |
235 { | |
236 ArrayN<octave_idx_type> dummy_idx; | |
237 return max (dummy_idx, dim); | |
238 } | |
239 | |
240 template <class T> | |
241 intNDArray<T> | |
242 intNDArray<T>::max (ArrayN<octave_idx_type>& idx_arg, int dim) const | |
243 { | |
244 dim_vector dv = this->dims (); | |
245 dim_vector dr = this->dims (); | |
246 | |
247 if (dv.numel () == 0 || dim > dv.length () || dim < 0) | |
248 return intNDArray<T> (); | |
249 | |
250 dr(dim) = 1; | |
251 | |
252 intNDArray<T> result (dr); | |
253 idx_arg.resize (dr); | |
254 | |
255 octave_idx_type x_stride = 1; | |
256 octave_idx_type x_len = dv(dim); | |
257 for (int i = 0; i < dim; i++) | |
258 x_stride *= dv(i); | |
259 | |
260 for (octave_idx_type i = 0; i < dr.numel (); i++) | |
261 { | |
262 octave_idx_type x_offset; | |
263 if (x_stride == 1) | |
264 x_offset = i * x_len; | |
265 else | |
266 { | |
267 octave_idx_type x_offset2 = 0; | |
268 x_offset = i; | |
269 while (x_offset >= x_stride) | |
270 { | |
271 x_offset -= x_stride; | |
272 x_offset2++; | |
273 } | |
274 x_offset += x_offset2 * x_stride * x_len; | |
275 } | |
276 | |
277 octave_idx_type idx_j = 0; | |
278 | |
279 T tmp_max = this->elem (x_offset); | |
280 | |
281 for (octave_idx_type j = 1; j < x_len; j++) | |
282 { | |
283 T tmp = this->elem (j * x_stride + x_offset); | |
284 | |
285 if (tmp > tmp_max) | |
286 { | |
287 idx_j = j; | |
288 tmp_max = tmp; | |
289 } | |
290 } | |
291 | |
292 result.elem (i) = tmp_max; | |
293 idx_arg.elem (i) = idx_j; | |
294 } | |
295 | |
11700
a255ceb8e416
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7189
diff
changeset
|
296 result.chop_trailing_singletons (); |
a255ceb8e416
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7189
diff
changeset
|
297 idx_arg.chop_trailing_singletons (); |
a255ceb8e416
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7189
diff
changeset
|
298 |
7189 | 299 return result; |
300 } | |
301 | |
302 template <class T> | |
303 intNDArray<T> | |
304 intNDArray<T>::min (int dim) const | |
305 { | |
306 ArrayN<octave_idx_type> dummy_idx; | |
307 return min (dummy_idx, dim); | |
308 } | |
309 | |
310 template <class T> | |
311 intNDArray<T> | |
312 intNDArray<T>::min (ArrayN<octave_idx_type>& idx_arg, int dim) const | |
313 { | |
314 dim_vector dv = this->dims (); | |
315 dim_vector dr = this->dims (); | |
316 | |
317 if (dv.numel () == 0 || dim > dv.length () || dim < 0) | |
318 return intNDArray<T> (); | |
319 | |
320 dr(dim) = 1; | |
321 | |
322 intNDArray<T> result (dr); | |
323 idx_arg.resize (dr); | |
324 | |
325 octave_idx_type x_stride = 1; | |
326 octave_idx_type x_len = dv(dim); | |
327 for (int i = 0; i < dim; i++) | |
328 x_stride *= dv(i); | |
329 | |
330 for (octave_idx_type i = 0; i < dr.numel (); i++) | |
331 { | |
332 octave_idx_type x_offset; | |
333 if (x_stride == 1) | |
334 x_offset = i * x_len; | |
335 else | |
336 { | |
337 octave_idx_type x_offset2 = 0; | |
338 x_offset = i; | |
339 while (x_offset >= x_stride) | |
340 { | |
341 x_offset -= x_stride; | |
342 x_offset2++; | |
343 } | |
344 x_offset += x_offset2 * x_stride * x_len; | |
345 } | |
346 | |
347 octave_idx_type idx_j = 0; | |
348 | |
349 T tmp_min = this->elem (x_offset); | |
350 | |
351 for (octave_idx_type j = 1; j < x_len; j++) | |
352 { | |
353 T tmp = this->elem (j * x_stride + x_offset); | |
354 | |
355 if (tmp < tmp_min) | |
356 { | |
357 idx_j = j; | |
358 tmp_min = tmp; | |
359 } | |
360 } | |
361 | |
362 result.elem (i) = tmp_min; | |
363 idx_arg.elem (i) = idx_j; | |
364 } | |
365 | |
11700
a255ceb8e416
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7189
diff
changeset
|
366 result.chop_trailing_singletons (); |
a255ceb8e416
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7189
diff
changeset
|
367 idx_arg.chop_trailing_singletons (); |
a255ceb8e416
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7189
diff
changeset
|
368 |
7189 | 369 return result; |
370 } | |
371 | |
4902 | 372 /* |
373 ;;; Local Variables: *** | |
374 ;;; mode: C++ *** | |
375 ;;; End: *** | |
376 */ |