Mercurial > hg > octave-nkf
annotate liboctave/Array-util.cc @ 7924:4976f66d469b
miscellaneous cleanup
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 11 Jul 2008 17:59:28 -0400 |
parents | 935be827eaf8 |
children | 7cbe01c21986 |
rev | line source |
---|---|
4588 | 1 /* |
2 | |
7017 | 3 Copyright (C) 2003, 2004, 2005, 2006, 2007 John W. Eaton |
4588 | 4 |
5 This file is part of Octave. | |
6 | |
7 Octave is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
7016 | 9 Free Software Foundation; either version 3 of the License, or (at your |
10 option) any later version. | |
4588 | 11 |
12 Octave is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
7016 | 18 along with Octave; see the file COPYING. If not, see |
19 <http://www.gnu.org/licenses/>. | |
4588 | 20 |
21 */ | |
22 | |
23 #ifdef HAVE_CONFIG_H | |
24 #include <config.h> | |
25 #endif | |
26 | |
27 #include "Array-util.h" | |
4669 | 28 #include "dim-vector.h" |
29 #include "lo-error.h" | |
4588 | 30 |
31 bool | |
5275 | 32 index_in_bounds (const Array<octave_idx_type>& ra_idx, const dim_vector& dimensions) |
4588 | 33 { |
34 bool retval = true; | |
35 | |
36 int n = ra_idx.length (); | |
37 | |
38 if (n == dimensions.length ()) | |
39 { | |
40 for (int i = 0; i < n; i++) | |
41 { | |
4747 | 42 if (ra_idx(i) < 0 || ra_idx(i) >= dimensions(i)) |
4588 | 43 { |
44 retval = false; | |
45 break; | |
46 } | |
47 } | |
48 } | |
49 else | |
50 retval = false; | |
51 | |
52 return retval; | |
53 } | |
54 | |
55 void | |
5275 | 56 increment_index (Array<octave_idx_type>& ra_idx, const dim_vector& dimensions, |
4588 | 57 int start_dimension) |
58 { | |
59 ra_idx(start_dimension)++; | |
60 | |
61 int n = ra_idx.length () - 1; | |
6868 | 62 int nda = dimensions.length (); |
4588 | 63 |
64 for (int i = start_dimension; i < n; i++) | |
65 { | |
6868 | 66 if (ra_idx(i) < (i < nda ? dimensions(i) : 1)) |
4588 | 67 break; |
68 else | |
69 { | |
70 ra_idx(i) = 0; | |
71 ra_idx(i+1)++; | |
72 } | |
73 } | |
74 } | |
75 | |
5275 | 76 octave_idx_type |
77 get_scalar_idx (Array<octave_idx_type>& idx, dim_vector& dims) | |
4588 | 78 { |
5275 | 79 octave_idx_type retval (-1); |
4588 | 80 |
81 int n = idx.length (); | |
82 | |
83 if (n > 0) | |
84 { | |
85 retval = idx(--n); | |
86 | |
87 while (--n >= 0) | |
88 { | |
89 retval *= dims (n); | |
90 | |
91 retval += idx(n); | |
92 } | |
93 } | |
94 return retval; | |
95 } | |
96 | |
5275 | 97 octave_idx_type |
98 num_ones (const Array<octave_idx_type>& ra_idx) | |
4588 | 99 { |
5275 | 100 octave_idx_type retval = 0; |
4635 | 101 |
5275 | 102 for (octave_idx_type i = 0; i < ra_idx.length (); i++) |
4588 | 103 { |
104 if (ra_idx (i) == 1) | |
105 retval++; | |
106 } | |
4635 | 107 |
4588 | 108 return retval; |
109 } | |
110 | |
111 bool | |
112 is_scalar (const dim_vector& dim) | |
113 { | |
114 bool retval = true; | |
115 | |
116 int n = dim.length (); | |
117 | |
118 if (n == 0) | |
119 { | |
120 retval = false; | |
121 } | |
122 else | |
123 { | |
124 for (int i = 0; i < n; i ++) | |
125 { | |
126 if (dim (i) != 1) | |
127 { | |
128 retval = false; | |
129 | |
130 break; | |
131 } | |
132 } | |
133 } | |
134 return retval; | |
135 } | |
136 | |
137 bool | |
7642
9a4541c622b5
refactor Array::assignN dimensioning code for empty initial matrices
David Bateman <dbateman@free.fr>
parents:
7241
diff
changeset
|
138 is_vector (const dim_vector& dim) |
9a4541c622b5
refactor Array::assignN dimensioning code for empty initial matrices
David Bateman <dbateman@free.fr>
parents:
7241
diff
changeset
|
139 { |
9a4541c622b5
refactor Array::assignN dimensioning code for empty initial matrices
David Bateman <dbateman@free.fr>
parents:
7241
diff
changeset
|
140 int m = 0; |
9a4541c622b5
refactor Array::assignN dimensioning code for empty initial matrices
David Bateman <dbateman@free.fr>
parents:
7241
diff
changeset
|
141 int n = dim.length (); |
9a4541c622b5
refactor Array::assignN dimensioning code for empty initial matrices
David Bateman <dbateman@free.fr>
parents:
7241
diff
changeset
|
142 |
9a4541c622b5
refactor Array::assignN dimensioning code for empty initial matrices
David Bateman <dbateman@free.fr>
parents:
7241
diff
changeset
|
143 if (n == 0) |
9a4541c622b5
refactor Array::assignN dimensioning code for empty initial matrices
David Bateman <dbateman@free.fr>
parents:
7241
diff
changeset
|
144 m = 2; |
9a4541c622b5
refactor Array::assignN dimensioning code for empty initial matrices
David Bateman <dbateman@free.fr>
parents:
7241
diff
changeset
|
145 else |
9a4541c622b5
refactor Array::assignN dimensioning code for empty initial matrices
David Bateman <dbateman@free.fr>
parents:
7241
diff
changeset
|
146 { |
9a4541c622b5
refactor Array::assignN dimensioning code for empty initial matrices
David Bateman <dbateman@free.fr>
parents:
7241
diff
changeset
|
147 for (int i = 0; i < n; i ++) |
9a4541c622b5
refactor Array::assignN dimensioning code for empty initial matrices
David Bateman <dbateman@free.fr>
parents:
7241
diff
changeset
|
148 if (dim (i) > 1) |
9a4541c622b5
refactor Array::assignN dimensioning code for empty initial matrices
David Bateman <dbateman@free.fr>
parents:
7241
diff
changeset
|
149 m++; |
9a4541c622b5
refactor Array::assignN dimensioning code for empty initial matrices
David Bateman <dbateman@free.fr>
parents:
7241
diff
changeset
|
150 else if (dim(i) < 1) |
9a4541c622b5
refactor Array::assignN dimensioning code for empty initial matrices
David Bateman <dbateman@free.fr>
parents:
7241
diff
changeset
|
151 m += 2; |
9a4541c622b5
refactor Array::assignN dimensioning code for empty initial matrices
David Bateman <dbateman@free.fr>
parents:
7241
diff
changeset
|
152 } |
7924 | 153 |
7642
9a4541c622b5
refactor Array::assignN dimensioning code for empty initial matrices
David Bateman <dbateman@free.fr>
parents:
7241
diff
changeset
|
154 return (m < 2); |
9a4541c622b5
refactor Array::assignN dimensioning code for empty initial matrices
David Bateman <dbateman@free.fr>
parents:
7241
diff
changeset
|
155 } |
9a4541c622b5
refactor Array::assignN dimensioning code for empty initial matrices
David Bateman <dbateman@free.fr>
parents:
7241
diff
changeset
|
156 |
9a4541c622b5
refactor Array::assignN dimensioning code for empty initial matrices
David Bateman <dbateman@free.fr>
parents:
7241
diff
changeset
|
157 bool |
5275 | 158 any_ones (const Array<octave_idx_type>& arr) |
4588 | 159 { |
160 bool retval = false; | |
161 | |
5275 | 162 for (octave_idx_type i = 0; i < arr.length (); i++) |
4588 | 163 { |
164 if (arr (i) == 1) | |
165 { | |
166 retval = true; | |
167 | |
168 break; | |
169 } | |
170 } | |
171 return retval; | |
172 } | |
173 | |
5275 | 174 octave_idx_type |
175 compute_index (const Array<octave_idx_type>& ra_idx, const dim_vector& dims) | |
4588 | 176 { |
5275 | 177 octave_idx_type retval = -1; |
4588 | 178 |
179 int n = dims.length (); | |
180 | |
181 if (n > 0 && n == ra_idx.length ()) | |
182 { | |
183 retval = ra_idx(--n); | |
184 | |
185 while (--n >= 0) | |
186 { | |
187 retval *= dims(n); | |
188 | |
189 retval += ra_idx(n); | |
190 } | |
191 } | |
192 else | |
193 (*current_liboctave_error_handler) | |
194 ("ArrayN<T>::compute_index: invalid ra_idxing operation"); | |
195 | |
196 return retval; | |
197 } | |
198 | |
5275 | 199 Array<octave_idx_type> |
4588 | 200 conv_to_int_array (const Array<idx_vector>& a) |
201 { | |
5275 | 202 Array<octave_idx_type> retval (a.length ()); |
4588 | 203 |
5275 | 204 for (octave_idx_type i = 0; i < a.length (); i++) |
4588 | 205 retval (i) = a(i).elem (0); |
206 | |
207 return retval; | |
208 } | |
209 | |
210 Array<idx_vector> | |
5275 | 211 conv_to_array (const idx_vector *tmp, const octave_idx_type len) |
4588 | 212 { |
213 Array<idx_vector> retval (len); | |
214 | |
5275 | 215 for (octave_idx_type i = 0; i < len; i++) |
4588 | 216 retval (i) = tmp[i]; |
217 | |
218 return retval; | |
219 } | |
220 | |
221 dim_vector | |
222 freeze (Array<idx_vector>& ra_idx, const dim_vector& dimensions, int resize_ok) | |
223 { | |
224 dim_vector retval; | |
225 | |
226 int n = ra_idx.length (); | |
227 | |
228 assert (n == dimensions.length ()); | |
229 | |
230 retval.resize (n); | |
231 | |
5136 | 232 static const char *tag[3] = { "row", "column", 0 }; |
233 | |
4588 | 234 for (int i = 0; i < n; i++) |
5136 | 235 retval(i) = ra_idx(i).freeze (dimensions(i), tag[i < 2 ? i : 3], |
236 resize_ok); | |
4588 | 237 |
238 return retval; | |
239 } | |
240 | |
241 bool | |
5519 | 242 vector_equivalent (const dim_vector& dv) |
4588 | 243 { |
5519 | 244 int n = dv.length (); |
4588 | 245 |
246 bool found_first = false; | |
247 | |
5519 | 248 for (int i = 0; i < n; i++) |
4588 | 249 { |
5519 | 250 if (dv(i) != 1) |
4588 | 251 { |
252 if (! found_first) | |
253 found_first = true; | |
254 else | |
255 return false; | |
256 } | |
257 } | |
258 | |
259 return true; | |
260 } | |
261 | |
262 bool | |
263 all_ok (const Array<idx_vector>& ra_idx) | |
264 { | |
265 bool retval = true; | |
266 | |
5275 | 267 octave_idx_type n = ra_idx.length (); |
4588 | 268 |
5275 | 269 for (octave_idx_type i = 0; i < n; i++) |
4588 | 270 { |
271 if (! ra_idx(i)) | |
272 { | |
273 retval = false; | |
274 break; | |
275 } | |
276 } | |
277 | |
278 return retval; | |
279 } | |
280 | |
281 bool | |
282 any_orig_empty (const Array<idx_vector>& ra_idx) | |
283 { | |
284 bool retval = false; | |
285 | |
5275 | 286 octave_idx_type n = ra_idx.length (); |
4588 | 287 |
5275 | 288 for (octave_idx_type i = 0; i < n; i++) |
4588 | 289 { |
290 if (ra_idx(i).orig_empty ()) | |
291 { | |
292 retval = true; | |
293 break; | |
294 } | |
295 } | |
296 | |
297 return retval; | |
298 } | |
299 | |
300 bool | |
301 all_colon_equiv (const Array<idx_vector>& ra_idx, | |
302 const dim_vector& frozen_lengths) | |
303 { | |
304 bool retval = true; | |
305 | |
5275 | 306 octave_idx_type idx_n = ra_idx.length (); |
4588 | 307 |
308 int n = frozen_lengths.length (); | |
309 | |
310 assert (idx_n == n); | |
311 | |
5275 | 312 for (octave_idx_type i = 0; i < n; i++) |
4588 | 313 { |
314 if (! ra_idx(i).is_colon_equiv (frozen_lengths(i))) | |
315 { | |
316 retval = false; | |
317 break; | |
318 } | |
319 } | |
320 | |
321 return retval; | |
322 } | |
323 | |
324 bool | |
5275 | 325 is_in (octave_idx_type num, const idx_vector& idx) |
4588 | 326 { |
5275 | 327 octave_idx_type n = idx.capacity (); |
4588 | 328 |
5275 | 329 for (octave_idx_type i = 0; i < n; i++) |
4588 | 330 if (idx.elem (i) == num) |
331 return true; | |
332 | |
333 return false; | |
334 } | |
335 | |
5275 | 336 octave_idx_type |
337 how_many_lgt (const octave_idx_type num, idx_vector& idxv) | |
4588 | 338 { |
5275 | 339 octave_idx_type retval = 0; |
4588 | 340 |
5275 | 341 octave_idx_type n = idxv.capacity (); |
4588 | 342 |
5275 | 343 for (octave_idx_type i = 0; i < n; i++) |
4588 | 344 { |
345 if (num > idxv.elem (i)) | |
346 retval++; | |
347 } | |
348 | |
349 return retval; | |
350 } | |
351 | |
352 bool | |
5275 | 353 all_ones (const Array<octave_idx_type>& arr) |
4588 | 354 { |
355 bool retval = true; | |
356 | |
5275 | 357 for (octave_idx_type i = 0; i < arr.length (); i++) |
4588 | 358 { |
359 if (arr(i) != 1) | |
360 { | |
361 retval = false; | |
362 break; | |
363 } | |
364 } | |
365 | |
366 return retval; | |
367 } | |
368 | |
5275 | 369 Array<octave_idx_type> |
370 get_elt_idx (const Array<idx_vector>& ra_idx, const Array<octave_idx_type>& result_idx) | |
4588 | 371 { |
5275 | 372 octave_idx_type n = ra_idx.length (); |
4588 | 373 |
5275 | 374 Array<octave_idx_type> retval (n); |
4588 | 375 |
5275 | 376 for (octave_idx_type i = 0; i < n; i++) |
4588 | 377 retval(i) = ra_idx(i).elem (result_idx(i)); |
378 | |
379 return retval; | |
380 } | |
381 | |
5275 | 382 Array<octave_idx_type> |
383 get_ra_idx (octave_idx_type idx, const dim_vector& dims) | |
4588 | 384 { |
5275 | 385 Array<octave_idx_type> retval; |
4588 | 386 |
387 int n_dims = dims.length (); | |
388 | |
389 retval.resize (n_dims); | |
390 | |
391 for (int i = 0; i < n_dims; i++) | |
392 retval(i) = 0; | |
393 | |
4747 | 394 assert (idx > 0 || idx < dims.numel ()); |
4588 | 395 |
5275 | 396 for (octave_idx_type i = 0; i < idx; i++) |
4588 | 397 increment_index (retval, dims); |
398 | |
5775 | 399 // FIXME -- the solution using increment_index is not |
4588 | 400 // efficient. |
401 | |
402 #if 0 | |
5275 | 403 octave_idx_type var = 1; |
4588 | 404 for (int i = 0; i < n_dims; i++) |
405 { | |
406 std::cout << "idx: " << idx << ", var: " << var << ", dims(" << i << "): " << dims(i) <<"\n"; | |
407 retval(i) = ((int)floor(((idx) / (double)var))) % dims(i); | |
408 idx -= var * retval(i); | |
409 var = dims(i); | |
410 } | |
411 #endif | |
412 | |
413 return retval; | |
414 } | |
415 | |
416 dim_vector | |
417 short_freeze (Array<idx_vector>& ra_idx, const dim_vector& dimensions, | |
418 int resize_ok) | |
419 { | |
420 dim_vector retval; | |
421 | |
422 int n = ra_idx.length (); | |
423 | |
424 int n_dims = dimensions.length (); | |
425 | |
426 if (n == n_dims) | |
427 { | |
428 retval = freeze (ra_idx, dimensions, resize_ok); | |
429 } | |
430 else if (n < n_dims) | |
431 { | |
432 retval.resize (n); | |
433 | |
434 for (int i = 0; i < n - 1; i++) | |
435 retval(i) = ra_idx(i).freeze (dimensions(i), "dimension", resize_ok); | |
436 | |
437 int size_left = 1; | |
438 | |
439 for (int i = n - 1; i < n_dims; i++) | |
440 size_left *= dimensions(i); | |
441 | |
442 if (ra_idx(n-1).is_colon()) | |
443 { | |
444 retval(n-1) = size_left; | |
445 } | |
446 else | |
447 { | |
5275 | 448 octave_idx_type last_ra_idx = ra_idx(n-1)(0); |
449 for (octave_idx_type i = 1; i < ra_idx (n - 1).capacity (); i++) | |
4887 | 450 last_ra_idx = (last_ra_idx > ra_idx(n-1)(i) ? last_ra_idx : |
451 ra_idx(n-1)(i)); | |
4588 | 452 |
4887 | 453 if (last_ra_idx < size_left) |
4588 | 454 { |
4887 | 455 retval(n-1) = ra_idx(n-1).freeze (size_left, |
456 "dimension", resize_ok); | |
4588 | 457 } |
458 else | |
459 { | |
4887 | 460 // Make it larger than it should be to get an error |
461 // later. | |
4588 | 462 |
4887 | 463 retval.resize (n_dims+1); |
464 | |
465 (*current_liboctave_error_handler) | |
466 ("index exceeds N-d array dimensions"); | |
4588 | 467 } |
468 } | |
469 } | |
470 | |
471 return retval; | |
472 } | |
473 | |
7241 | 474 int |
475 permute_vector_compare (const void *a, const void *b) | |
476 { | |
477 const permute_vector *pva = static_cast<const permute_vector *> (a); | |
478 const permute_vector *pvb = static_cast<const permute_vector *> (b); | |
479 | |
480 return pva->pidx > pvb->pidx; | |
481 } | |
482 | |
7922
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7642
diff
changeset
|
483 void |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7642
diff
changeset
|
484 gripe_nan_to_logical_conversion (void) |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7642
diff
changeset
|
485 { |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7642
diff
changeset
|
486 (*current_liboctave_error_handler) ("invalid conversion of NaN to logical"); |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7642
diff
changeset
|
487 } |
7241 | 488 |
4669 | 489 void |
490 gripe_nonconformant (const char *op, int op1_len, int op2_len) | |
491 { | |
492 (*current_liboctave_error_handler) | |
493 ("%s: nonconformant arguments (op1 len: %d, op2 len: %d)", | |
494 op, op1_len, op2_len); | |
495 } | |
496 | |
497 void | |
498 gripe_nonconformant (const char *op, int op1_nr, int op1_nc, | |
499 int op2_nr, int op2_nc) | |
500 { | |
501 (*current_liboctave_error_handler) | |
502 ("%s: nonconformant arguments (op1 is %dx%d, op2 is %dx%d)", | |
503 op, op1_nr, op1_nc, op2_nr, op2_nc); | |
504 } | |
505 | |
506 void | |
507 gripe_nonconformant (const char *op, dim_vector& op1_dims, | |
508 dim_vector& op2_dims) | |
509 { | |
510 std::string op1_dims_str = op1_dims.str (); | |
511 std::string op2_dims_str = op2_dims.str (); | |
512 | |
513 (*current_liboctave_error_handler) | |
514 ("%s: nonconformant arguments (op1 is %s, op2 is %s)", | |
515 op, op1_dims_str.c_str (), op2_dims_str.c_str ()); | |
516 } | |
517 | |
4588 | 518 /* |
519 ;;; Local Variables: *** | |
520 ;;; mode: C++ *** | |
521 ;;; End: *** | |
522 */ |