Mercurial > octave-nkf
annotate liboctave/intNDArray.cc @ 7503:8c32f95c2639
convert mapper functions to new format
author | David Bateman <dbateman@free.fr> |
---|---|
date | Wed, 20 Feb 2008 04:22:50 -0500 |
parents | aab45fbcd71f |
children | 24abf5a702d9 |
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 { | |
7457 | 138 MX_ND_ANY_ALL_REDUCTION (MX_ND_ANY_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 | |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
225 // FIXME -- should abs and signum just be mapper functions? |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
226 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
227 template <class T> |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
228 intNDArray<T> |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
229 intNDArray<T>::abs (void) const |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
230 { |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
231 octave_idx_type nel = this->nelem (); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
232 intNDArray<T> ret (*this); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
233 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
234 for (octave_idx_type i = 0; i < nel; i++) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
235 { |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
236 T val = this->elem (i); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
237 ret.xelem (i) = val.abs (); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
238 } |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
239 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
240 return ret; |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
241 } |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
242 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
243 template <class T> |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
244 intNDArray<T> |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
245 intNDArray<T>::signum (void) const |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
246 { |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
247 octave_idx_type nel = this->nelem (); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
248 intNDArray<T> ret (*this); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
249 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
250 for (octave_idx_type i = 0; i < nel; i++) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
251 { |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
252 T val = this->elem (i); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
253 ret.xelem (i) = val.signum (); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
254 } |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
255 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
256 return ret; |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
257 } |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7457
diff
changeset
|
258 |
7113 | 259 template <class T> |
260 intNDArray<T> | |
261 intNDArray<T>::sum (int dim) const | |
262 { | |
263 MX_ND_REDUCTION (retval(result_idx) += intNDArray<T>::elem (iter_idx), 0, intNDArray<T>); | |
264 } | |
265 | |
7189 | 266 template <class T> |
267 intNDArray<T> | |
268 intNDArray<T>::max (int dim) const | |
269 { | |
270 ArrayN<octave_idx_type> dummy_idx; | |
271 return max (dummy_idx, dim); | |
272 } | |
273 | |
274 template <class T> | |
275 intNDArray<T> | |
276 intNDArray<T>::max (ArrayN<octave_idx_type>& idx_arg, int dim) const | |
277 { | |
278 dim_vector dv = this->dims (); | |
279 dim_vector dr = this->dims (); | |
280 | |
281 if (dv.numel () == 0 || dim > dv.length () || dim < 0) | |
282 return intNDArray<T> (); | |
283 | |
284 dr(dim) = 1; | |
285 | |
286 intNDArray<T> result (dr); | |
287 idx_arg.resize (dr); | |
288 | |
289 octave_idx_type x_stride = 1; | |
290 octave_idx_type x_len = dv(dim); | |
291 for (int i = 0; i < dim; i++) | |
292 x_stride *= dv(i); | |
293 | |
294 for (octave_idx_type i = 0; i < dr.numel (); i++) | |
295 { | |
296 octave_idx_type x_offset; | |
297 if (x_stride == 1) | |
298 x_offset = i * x_len; | |
299 else | |
300 { | |
301 octave_idx_type x_offset2 = 0; | |
302 x_offset = i; | |
303 while (x_offset >= x_stride) | |
304 { | |
305 x_offset -= x_stride; | |
306 x_offset2++; | |
307 } | |
308 x_offset += x_offset2 * x_stride * x_len; | |
309 } | |
310 | |
311 octave_idx_type idx_j = 0; | |
312 | |
313 T tmp_max = this->elem (x_offset); | |
314 | |
315 for (octave_idx_type j = 1; j < x_len; j++) | |
316 { | |
317 T tmp = this->elem (j * x_stride + x_offset); | |
318 | |
319 if (tmp > tmp_max) | |
320 { | |
321 idx_j = j; | |
322 tmp_max = tmp; | |
323 } | |
324 } | |
325 | |
326 result.elem (i) = tmp_max; | |
327 idx_arg.elem (i) = idx_j; | |
328 } | |
329 | |
330 return result; | |
331 } | |
332 | |
333 template <class T> | |
334 intNDArray<T> | |
335 intNDArray<T>::min (int dim) const | |
336 { | |
337 ArrayN<octave_idx_type> dummy_idx; | |
338 return min (dummy_idx, dim); | |
339 } | |
340 | |
341 template <class T> | |
342 intNDArray<T> | |
343 intNDArray<T>::min (ArrayN<octave_idx_type>& idx_arg, int dim) const | |
344 { | |
345 dim_vector dv = this->dims (); | |
346 dim_vector dr = this->dims (); | |
347 | |
348 if (dv.numel () == 0 || dim > dv.length () || dim < 0) | |
349 return intNDArray<T> (); | |
350 | |
351 dr(dim) = 1; | |
352 | |
353 intNDArray<T> result (dr); | |
354 idx_arg.resize (dr); | |
355 | |
356 octave_idx_type x_stride = 1; | |
357 octave_idx_type x_len = dv(dim); | |
358 for (int i = 0; i < dim; i++) | |
359 x_stride *= dv(i); | |
360 | |
361 for (octave_idx_type i = 0; i < dr.numel (); i++) | |
362 { | |
363 octave_idx_type x_offset; | |
364 if (x_stride == 1) | |
365 x_offset = i * x_len; | |
366 else | |
367 { | |
368 octave_idx_type x_offset2 = 0; | |
369 x_offset = i; | |
370 while (x_offset >= x_stride) | |
371 { | |
372 x_offset -= x_stride; | |
373 x_offset2++; | |
374 } | |
375 x_offset += x_offset2 * x_stride * x_len; | |
376 } | |
377 | |
378 octave_idx_type idx_j = 0; | |
379 | |
380 T tmp_min = this->elem (x_offset); | |
381 | |
382 for (octave_idx_type j = 1; j < x_len; j++) | |
383 { | |
384 T tmp = this->elem (j * x_stride + x_offset); | |
385 | |
386 if (tmp < tmp_min) | |
387 { | |
388 idx_j = j; | |
389 tmp_min = tmp; | |
390 } | |
391 } | |
392 | |
393 result.elem (i) = tmp_min; | |
394 idx_arg.elem (i) = idx_j; | |
395 } | |
396 | |
397 return result; | |
398 } | |
399 | |
4902 | 400 /* |
401 ;;; Local Variables: *** | |
402 ;;; mode: C++ *** | |
403 ;;; End: *** | |
404 */ |