Mercurial > hg > octave-nkf
comparison liboctave/array/Array.h @ 19198:96751a74bbbb
Start doxygenising sources
* Screen.cpp Screen.h Vt102Emulation.cpp files-dock-widget.h
main-window.h octave-qt-link.h parser.h: Reformat existing Doxygen
commands to use @ instead of \ to start a command.
* Array.h: Convert existing comments into Doxygen comments.
author | Jordi Gutiérrez Hermoso <jordigh@octave.org> |
---|---|
date | Tue, 12 Aug 2014 15:27:16 -0400 |
parents | 49a5a4be04a1 |
children | 5b263e517c95 |
comparison
equal
deleted
inserted
replaced
19195:d00f6b09258f | 19198:96751a74bbbb |
---|---|
39 #include "oct-sort.h" | 39 #include "oct-sort.h" |
40 #include "quit.h" | 40 #include "quit.h" |
41 #include "oct-mem.h" | 41 #include "oct-mem.h" |
42 #include "oct-refcount.h" | 42 #include "oct-refcount.h" |
43 | 43 |
44 // One dimensional array class. Handles the reference counting for | 44 //! One dimensional array class. Handles the reference counting for |
45 // all the derived classes. | 45 //! all the derived classes. |
46 | 46 |
47 template <class T> | 47 template <class T> |
48 class | 48 class |
49 Array | 49 Array |
50 { | 50 { |
51 protected: | 51 protected: |
52 | 52 |
53 //-------------------------------------------------------------------- | 53 //! The real representation of all arrays. |
54 // The real representation of all arrays. | |
55 //-------------------------------------------------------------------- | |
56 | |
57 class ArrayRep | 54 class ArrayRep |
58 { | 55 { |
59 public: | 56 public: |
60 | 57 |
61 T *data; | 58 T *data; |
142 // need to be properly updated. | 139 // need to be properly updated. |
143 | 140 |
144 T* slice_data; | 141 T* slice_data; |
145 octave_idx_type slice_len; | 142 octave_idx_type slice_len; |
146 | 143 |
147 // slice constructor | 144 //! slice constructor |
148 Array (const Array<T>& a, const dim_vector& dv, | 145 Array (const Array<T>& a, const dim_vector& dv, |
149 octave_idx_type l, octave_idx_type u) | 146 octave_idx_type l, octave_idx_type u) |
150 : dimensions (dv), rep(a.rep), slice_data (a.slice_data+l), slice_len (u-l) | 147 : dimensions (dv), rep(a.rep), slice_data (a.slice_data+l), slice_len (u-l) |
151 { | 148 { |
152 rep->count++; | 149 rep->count++; |
165 return &nr; | 162 return &nr; |
166 } | 163 } |
167 | 164 |
168 protected: | 165 protected: |
169 | 166 |
170 // For jit support | 167 //! For jit support |
171 Array (T *sdata, octave_idx_type slen, octave_idx_type *adims, void *arep) | 168 Array (T *sdata, octave_idx_type slen, octave_idx_type *adims, void *arep) |
172 : dimensions (adims), | 169 : dimensions (adims), |
173 rep (reinterpret_cast<typename Array<T>::ArrayRep *> (arep)), | 170 rep (reinterpret_cast<typename Array<T>::ArrayRep *> (arep)), |
174 slice_data (sdata), slice_len (slen) { } | 171 slice_data (sdata), slice_len (slen) { } |
175 | 172 |
176 public: | 173 public: |
177 | 174 |
178 // Empty ctor (0x0). | 175 //! Empty ctor (0 by 0). |
179 | |
180 Array (void) | 176 Array (void) |
181 : dimensions (), rep (nil_rep ()), slice_data (rep->data), | 177 : dimensions (), rep (nil_rep ()), slice_data (rep->data), |
182 slice_len (rep->len) | 178 slice_len (rep->len) |
183 { | 179 { |
184 rep->count++; | 180 rep->count++; |
185 } | 181 } |
186 | 182 |
187 // Obsolete 1D ctor (there are no 1D arrays). | 183 //! Obsolete 1D ctor (there are no 1D arrays). |
188 explicit Array (octave_idx_type n) GCC_ATTR_DEPRECATED | 184 explicit Array (octave_idx_type n) GCC_ATTR_DEPRECATED |
189 : dimensions (n, 1), rep (new typename Array<T>::ArrayRep (n)), | 185 : dimensions (n, 1), rep (new typename Array<T>::ArrayRep (n)), |
190 slice_data (rep->data), slice_len (rep->len) | 186 slice_data (rep->data), slice_len (rep->len) |
191 { } | 187 { } |
192 | 188 |
193 // Obsolete initialized 1D ctor (there are no 1D arrays). | 189 //! Obsolete initialized 1D ctor (there are no 1D arrays). |
194 explicit Array (octave_idx_type n, const T& val) GCC_ATTR_DEPRECATED | 190 explicit Array (octave_idx_type n, const T& val) GCC_ATTR_DEPRECATED |
195 : dimensions (n, 1), rep (new typename Array<T>::ArrayRep (n)), | 191 : dimensions (n, 1), rep (new typename Array<T>::ArrayRep (n)), |
196 slice_data (rep->data), slice_len (rep->len) | 192 slice_data (rep->data), slice_len (rep->len) |
197 { | 193 { |
198 fill (val); | 194 fill (val); |
199 } | 195 } |
200 | 196 |
201 // nD uninitialized ctor. | 197 //! nD uninitialized ctor. |
202 explicit Array (const dim_vector& dv) | 198 explicit Array (const dim_vector& dv) |
203 : dimensions (dv), | 199 : dimensions (dv), |
204 rep (new typename Array<T>::ArrayRep (dv.safe_numel ())), | 200 rep (new typename Array<T>::ArrayRep (dv.safe_numel ())), |
205 slice_data (rep->data), slice_len (rep->len) | 201 slice_data (rep->data), slice_len (rep->len) |
206 { | 202 { |
207 dimensions.chop_trailing_singletons (); | 203 dimensions.chop_trailing_singletons (); |
208 } | 204 } |
209 | 205 |
210 // nD initialized ctor. | 206 //! nD initialized ctor. |
211 explicit Array (const dim_vector& dv, const T& val) | 207 explicit Array (const dim_vector& dv, const T& val) |
212 : dimensions (dv), | 208 : dimensions (dv), |
213 rep (new typename Array<T>::ArrayRep (dv.safe_numel ())), | 209 rep (new typename Array<T>::ArrayRep (dv.safe_numel ())), |
214 slice_data (rep->data), slice_len (rep->len) | 210 slice_data (rep->data), slice_len (rep->len) |
215 { | 211 { |
216 fill (val); | 212 fill (val); |
217 dimensions.chop_trailing_singletons (); | 213 dimensions.chop_trailing_singletons (); |
218 } | 214 } |
219 | 215 |
220 // Reshape constructor. | 216 //! Reshape constructor. |
221 Array (const Array<T>& a, const dim_vector& dv); | 217 Array (const Array<T>& a, const dim_vector& dv); |
222 | 218 |
223 // Type conversion case. | 219 //! Type conversion case. |
224 template <class U> | 220 template <class U> |
225 Array (const Array<U>& a) | 221 Array (const Array<U>& a) |
226 : dimensions (a.dims ()), | 222 : dimensions (a.dims ()), |
227 rep (new typename Array<T>::ArrayRep (a.data (), a.length ())), | 223 rep (new typename Array<T>::ArrayRep (a.data (), a.length ())), |
228 slice_data (rep->data), slice_len (rep->len) | 224 slice_data (rep->data), slice_len (rep->len) |
229 { } | 225 { } |
230 | 226 |
231 // No type conversion case. | 227 //! No type conversion case. |
232 Array (const Array<T>& a) | 228 Array (const Array<T>& a) |
233 : dimensions (a.dimensions), rep (a.rep), slice_data (a.slice_data), | 229 : dimensions (a.dimensions), rep (a.rep), slice_data (a.slice_data), |
234 slice_len (a.slice_len) | 230 slice_len (a.slice_len) |
235 { | 231 { |
236 rep->count++; | 232 rep->count++; |
268 void clear (const dim_vector& dv); | 264 void clear (const dim_vector& dv); |
269 | 265 |
270 void clear (octave_idx_type r, octave_idx_type c) | 266 void clear (octave_idx_type r, octave_idx_type c) |
271 { clear (dim_vector (r, c)); } | 267 { clear (dim_vector (r, c)); } |
272 | 268 |
269 //@{ | |
270 //! Number of elements in the array. These are all synonyms. | |
273 octave_idx_type capacity (void) const { return slice_len; } | 271 octave_idx_type capacity (void) const { return slice_len; } |
274 octave_idx_type length (void) const { return capacity (); } | 272 octave_idx_type length (void) const { return capacity (); } |
275 octave_idx_type nelem (void) const { return capacity (); } | 273 octave_idx_type nelem (void) const { return capacity (); } |
276 octave_idx_type numel (void) const { return nelem (); } | 274 octave_idx_type numel (void) const { return nelem (); } |
277 | 275 //@} |
278 octave_idx_type dim1 (void) const { return dimensions(0); } | 276 |
279 octave_idx_type dim2 (void) const { return dimensions(1); } | 277 //! Return the array as a column vector. |
280 octave_idx_type dim3 (void) const { return dimensions(2); } | |
281 | |
282 // Return the array as a column vector. | |
283 Array<T> as_column (void) const | 278 Array<T> as_column (void) const |
284 { | 279 { |
285 Array<T> retval (*this); | 280 Array<T> retval (*this); |
286 if (dimensions.length () != 2 || dimensions(1) != 1) | 281 if (dimensions.length () != 2 || dimensions(1) != 1) |
287 retval.dimensions = dim_vector (numel (), 1); | 282 retval.dimensions = dim_vector (numel (), 1); |
288 | 283 |
289 return retval; | 284 return retval; |
290 } | 285 } |
291 | 286 |
292 // Return the array as a row vector. | 287 //! Return the array as a row vector. |
293 Array<T> as_row (void) const | 288 Array<T> as_row (void) const |
294 { | 289 { |
295 Array<T> retval (*this); | 290 Array<T> retval (*this); |
296 if (dimensions.length () != 2 || dimensions(0) != 1) | 291 if (dimensions.length () != 2 || dimensions(0) != 1) |
297 retval.dimensions = dim_vector (1, numel ()); | 292 retval.dimensions = dim_vector (1, numel ()); |
298 | 293 |
299 return retval; | 294 return retval; |
300 } | 295 } |
301 | 296 |
302 // Return the array as a matrix. | 297 //! Return the array as a matrix. |
303 Array<T> as_matrix (void) const | 298 Array<T> as_matrix (void) const |
304 { | 299 { |
305 Array<T> retval (*this); | 300 Array<T> retval (*this); |
306 if (dimensions.length () != 2) | 301 if (dimensions.length () != 2) |
307 retval.dimensions = dimensions.redim (2); | 302 retval.dimensions = dimensions.redim (2); |
308 | 303 |
309 return retval; | 304 return retval; |
310 } | 305 } |
311 | 306 |
307 //! @name First dimension | |
308 //! | |
309 //! Get the first dimension of the array (number of rows) | |
310 //@{ | |
311 octave_idx_type dim1 (void) const { return dimensions(0); } | |
312 octave_idx_type rows (void) const { return dim1 (); } | 312 octave_idx_type rows (void) const { return dim1 (); } |
313 //@} | |
314 | |
315 //! @name Second dimension | |
316 //! | |
317 //! Get the second dimension of the array (number of columns) | |
318 //@{ | |
319 octave_idx_type dim2 (void) const { return dimensions(1); } | |
313 octave_idx_type cols (void) const { return dim2 (); } | 320 octave_idx_type cols (void) const { return dim2 (); } |
314 octave_idx_type columns (void) const { return dim2 (); } | 321 octave_idx_type columns (void) const { return dim2 (); } |
322 //@} | |
323 | |
324 //! @name Third dimension | |
325 //! | |
326 //! Get the third dimension of the array (number of pages) | |
327 //@{ | |
328 octave_idx_type dim3 (void) const { return dimensions(2); } | |
315 octave_idx_type pages (void) const { return dim3 (); } | 329 octave_idx_type pages (void) const { return dim3 (); } |
330 //@} | |
316 | 331 |
317 size_t byte_size (void) const | 332 size_t byte_size (void) const |
318 { return static_cast<size_t> (numel ()) * sizeof (T); } | 333 { return static_cast<size_t> (numel ()) * sizeof (T); } |
319 | 334 |
320 // Return a const-reference so that dims ()(i) works efficiently. | 335 //! Return a const-reference so that dims ()(i) works efficiently. |
321 const dim_vector& dims (void) const { return dimensions; } | 336 const dim_vector& dims (void) const { return dimensions; } |
322 | 337 |
338 //! Chop off leading singleton dimensions | |
323 Array<T> squeeze (void) const; | 339 Array<T> squeeze (void) const; |
324 | 340 |
325 void chop_trailing_singletons (void) GCC_ATTR_DEPRECATED | 341 void chop_trailing_singletons (void) GCC_ATTR_DEPRECATED |
326 { dimensions.chop_trailing_singletons (); } | 342 { dimensions.chop_trailing_singletons (); } |
327 | 343 |
432 #endif | 448 #endif |
433 | 449 |
434 // Fast extractors. All of these produce shallow copies. | 450 // Fast extractors. All of these produce shallow copies. |
435 // Warning: none of these do check bounds, unless BOUNDS_CHECKING is on! | 451 // Warning: none of these do check bounds, unless BOUNDS_CHECKING is on! |
436 | 452 |
437 // Extract column: A(:,k+1). | 453 //! Extract column: A(:,k+1). |
438 Array<T> column (octave_idx_type k) const; | 454 Array<T> column (octave_idx_type k) const; |
439 // Extract page: A(:,:,k+1). | 455 //! Extract page: A(:,:,k+1). |
440 Array<T> page (octave_idx_type k) const; | 456 Array<T> page (octave_idx_type k) const; |
441 | 457 |
442 // Extract a slice from this array as a column vector: A(:)(lo+1:up). | 458 //! Extract a slice from this array as a column vector: A(:)(lo+1:up). |
443 // Must be 0 <= lo && up <= numel. May be up < lo. | 459 //! Must be 0 <= lo && up <= numel. May be up < lo. |
444 Array<T> linear_slice (octave_idx_type lo, octave_idx_type up) const; | 460 Array<T> linear_slice (octave_idx_type lo, octave_idx_type up) const; |
445 | 461 |
446 Array<T> reshape (octave_idx_type nr, octave_idx_type nc) const | 462 Array<T> reshape (octave_idx_type nr, octave_idx_type nc) const |
447 { return Array<T> (*this, dim_vector (nr, nc)); } | 463 { return Array<T> (*this, dim_vector (nr, nc)); } |
448 | 464 |
470 | 486 |
471 bool is_shared (void) { return rep->count > 1; } | 487 bool is_shared (void) { return rep->count > 1; } |
472 | 488 |
473 int ndims (void) const { return dimensions.length (); } | 489 int ndims (void) const { return dimensions.length (); } |
474 | 490 |
475 // Indexing without resizing. | 491 //@{ |
476 | 492 //! Indexing without resizing. |
477 Array<T> index (const idx_vector& i) const; | 493 Array<T> index (const idx_vector& i) const; |
478 | 494 |
479 Array<T> index (const idx_vector& i, const idx_vector& j) const; | 495 Array<T> index (const idx_vector& i, const idx_vector& j) const; |
480 | 496 |
481 Array<T> index (const Array<idx_vector>& ia) const; | 497 Array<T> index (const Array<idx_vector>& ia) const; |
498 //@} | |
482 | 499 |
483 virtual T resize_fill_value (void) const; | 500 virtual T resize_fill_value (void) const; |
484 | 501 |
485 // Resizing (with fill). | 502 //@{ |
486 | 503 //! Resizing (with fill). |
487 void resize1 (octave_idx_type n, const T& rfv); | 504 void resize1 (octave_idx_type n, const T& rfv); |
488 void resize1 (octave_idx_type n) { resize1 (n, resize_fill_value ()); } | 505 void resize1 (octave_idx_type n) { resize1 (n, resize_fill_value ()); } |
489 | 506 |
490 void resize (octave_idx_type n) GCC_ATTR_DEPRECATED { resize1 (n); } | 507 void resize (octave_idx_type n) GCC_ATTR_DEPRECATED { resize1 (n); } |
491 | 508 |
500 resize2 (nr, nc, resize_fill_value ()); | 517 resize2 (nr, nc, resize_fill_value ()); |
501 } | 518 } |
502 | 519 |
503 void resize (const dim_vector& dv, const T& rfv); | 520 void resize (const dim_vector& dv, const T& rfv); |
504 void resize (const dim_vector& dv) { resize (dv, resize_fill_value ()); } | 521 void resize (const dim_vector& dv) { resize (dv, resize_fill_value ()); } |
505 | 522 //@} |
506 // Indexing with possible resizing and fill | 523 |
507 // FIXME: this is really a corner case, that should better be | 524 //@{ |
525 //! Indexing with possible resizing and fill | |
526 | |
527 // FIXME -- this is really a corner case, that should better be | |
508 // handled directly in liboctinterp. | 528 // handled directly in liboctinterp. |
529 | |
509 | 530 |
510 Array<T> index (const idx_vector& i, bool resize_ok, const T& rfv) const; | 531 Array<T> index (const idx_vector& i, bool resize_ok, const T& rfv) const; |
511 Array<T> index (const idx_vector& i, bool resize_ok) const | 532 Array<T> index (const idx_vector& i, bool resize_ok) const |
512 { | 533 { |
513 return index (i, resize_ok, resize_fill_value ()); | 534 return index (i, resize_ok, resize_fill_value ()); |
525 const T& rfv) const; | 546 const T& rfv) const; |
526 Array<T> index (const Array<idx_vector>& ia, bool resize_ok) const | 547 Array<T> index (const Array<idx_vector>& ia, bool resize_ok) const |
527 { | 548 { |
528 return index (ia, resize_ok, resize_fill_value ()); | 549 return index (ia, resize_ok, resize_fill_value ()); |
529 } | 550 } |
530 | 551 //@} |
531 // Indexed assignment (always with resize & fill). | 552 |
532 | 553 |
554 //@{ | |
555 //! Indexed assignment (always with resize & fill). | |
533 void assign (const idx_vector& i, const Array<T>& rhs, const T& rfv); | 556 void assign (const idx_vector& i, const Array<T>& rhs, const T& rfv); |
534 void assign (const idx_vector& i, const Array<T>& rhs) | 557 void assign (const idx_vector& i, const Array<T>& rhs) |
535 { | 558 { |
536 assign (i, rhs, resize_fill_value ()); | 559 assign (i, rhs, resize_fill_value ()); |
537 } | 560 } |
546 void assign (const Array<idx_vector>& ia, const Array<T>& rhs, const T& rfv); | 569 void assign (const Array<idx_vector>& ia, const Array<T>& rhs, const T& rfv); |
547 void assign (const Array<idx_vector>& ia, const Array<T>& rhs) | 570 void assign (const Array<idx_vector>& ia, const Array<T>& rhs) |
548 { | 571 { |
549 assign (ia, rhs, resize_fill_value ()); | 572 assign (ia, rhs, resize_fill_value ()); |
550 } | 573 } |
551 | 574 //@} |
552 // Deleting elements. | 575 |
553 | 576 //@{ |
554 // A(I) = [] (with a single subscript) | 577 //! Deleting elements. |
578 | |
579 //! A(I) = [] (with a single subscript) | |
555 void delete_elements (const idx_vector& i); | 580 void delete_elements (const idx_vector& i); |
556 | 581 |
557 // A(:,...,I,...,:) = [] (>= 2 subscripts, one of them is non-colon) | 582 //! A(:,...,I,...,:) = [] (>= 2 subscripts, one of them is non-colon) |
558 void delete_elements (int dim, const idx_vector& i); | 583 void delete_elements (int dim, const idx_vector& i); |
559 | 584 |
560 // Dispatcher to the above two. | 585 //! Dispatcher to the above two. |
561 void delete_elements (const Array<idx_vector>& ia); | 586 void delete_elements (const Array<idx_vector>& ia); |
562 | 587 //@} |
563 // Insert an array into another at a specified position. | 588 |
564 // If size (a) is [d1 d2 ... dN] and idx is [i1 i2 ... iN], | 589 //! Insert an array into another at a specified position. If |
565 // this method is equivalent to | 590 //! size (a) is [d1 d2 ... dN] and idx is [i1 i2 ... iN], this |
566 // x(i1:i1+d1-1, i2:i2+d2-1, ... , iN:iN+dN-1) = a. | 591 //! method is equivalent to x(i1:i1+d1-1, i2:i2+d2-1, ... , |
592 //! iN:iN+dN-1) = a. | |
567 Array<T>& insert (const Array<T>& a, const Array<octave_idx_type>& idx); | 593 Array<T>& insert (const Array<T>& a, const Array<octave_idx_type>& idx); |
568 | 594 |
569 // This is just a special case for idx = [r c 0 ...] | 595 //! This is just a special case for idx = [r c 0 ...] |
570 Array<T>& insert (const Array<T>& a, octave_idx_type r, octave_idx_type c); | 596 Array<T>& insert (const Array<T>& a, octave_idx_type r, octave_idx_type c); |
571 | 597 |
572 void maybe_economize (void) | 598 void maybe_economize (void) |
573 { | 599 { |
574 if (rep->count == 1 && slice_len != rep->len) | 600 if (rep->count == 1 && slice_len != rep->len) |
580 } | 606 } |
581 } | 607 } |
582 | 608 |
583 void print_info (std::ostream& os, const std::string& prefix) const; | 609 void print_info (std::ostream& os, const std::string& prefix) const; |
584 | 610 |
585 // Unsafe. This function exists to support the MEX interface. | 611 //! Give a pointer to the data in mex format. Unsafe. This function |
586 // You should not use it anywhere else. | 612 //! exists to support the MEX interface. You should not use it |
613 //! anywhere else. | |
587 void *mex_get_data (void) const { return const_cast<T *> (data ()); } | 614 void *mex_get_data (void) const { return const_cast<T *> (data ()); } |
588 | 615 |
589 Array<T> sort (int dim = 0, sortmode mode = ASCENDING) const; | 616 Array<T> sort (int dim = 0, sortmode mode = ASCENDING) const; |
590 Array<T> sort (Array<octave_idx_type> &sidx, int dim = 0, | 617 Array<T> sort (Array<octave_idx_type> &sidx, int dim = 0, |
591 sortmode mode = ASCENDING) const; | 618 sortmode mode = ASCENDING) const; |
592 | 619 |
593 // Ordering is auto-detected or can be specified. | 620 //! Ordering is auto-detected or can be specified. |
594 sortmode is_sorted (sortmode mode = UNSORTED) const; | 621 sortmode is_sorted (sortmode mode = UNSORTED) const; |
595 | 622 |
596 // Sort by rows returns only indices. | 623 //! Sort by rows returns only indices. |
597 Array<octave_idx_type> sort_rows_idx (sortmode mode = ASCENDING) const; | 624 Array<octave_idx_type> sort_rows_idx (sortmode mode = ASCENDING) const; |
598 | 625 |
599 // Ordering is auto-detected or can be specified. | 626 //! Ordering is auto-detected or can be specified. |
600 sortmode is_sorted_rows (sortmode mode = UNSORTED) const; | 627 sortmode is_sorted_rows (sortmode mode = UNSORTED) const; |
601 | 628 |
602 // Do a binary lookup in a sorted array. Must not contain NaNs. | 629 //! @brief Do a binary lookup in a sorted array. Must not contain NaNs. |
603 // Mode can be specified or is auto-detected by comparing 1st and last element. | 630 //! Mode can be specified or is auto-detected by comparing 1st and last element. |
604 octave_idx_type lookup (const T& value, sortmode mode = UNSORTED) const; | 631 octave_idx_type lookup (const T& value, sortmode mode = UNSORTED) const; |
605 | 632 |
606 // Ditto, but for an array of values, specializing on the case when values | 633 //! Ditto, but for an array of values, specializing on the case when values |
607 // are sorted. NaNs get the value N. | 634 //! are sorted. NaNs get the value N. |
608 Array<octave_idx_type> lookup (const Array<T>& values, | 635 Array<octave_idx_type> lookup (const Array<T>& values, |
609 sortmode mode = UNSORTED) const; | 636 sortmode mode = UNSORTED) const; |
610 | 637 |
611 // Count nonzero elements. | 638 //! Count nonzero elements. |
612 octave_idx_type nnz (void) const; | 639 octave_idx_type nnz (void) const; |
613 | 640 |
614 // Find indices of (at most n) nonzero elements. If n is specified, backward | 641 //! Find indices of (at most n) nonzero elements. If n is specified, |
615 // specifies search from backward. | 642 //! backward specifies search from backward. |
616 Array<octave_idx_type> find (octave_idx_type n = -1, | 643 Array<octave_idx_type> find (octave_idx_type n = -1, bool backward = false) const; |
617 bool backward = false) const; | 644 |
618 | 645 //! Returns the n-th element in increasing order, using the same |
619 // Returns the n-th element in increasing order, using the same ordering as | 646 //! ordering as used for sort. n can either be a scalar index or a |
620 // used for sort. n can either be a scalar index or a contiguous range. | 647 //! contiguous range. |
621 Array<T> nth_element (const idx_vector& n, int dim = 0) const; | 648 Array<T> nth_element (const idx_vector& n, int dim = 0) const; |
622 | 649 |
650 //! Get the kth super or subdiagonal. The zeroth diagonal is the | |
651 //! ordinary diagonal. | |
623 Array<T> diag (octave_idx_type k = 0) const; | 652 Array<T> diag (octave_idx_type k = 0) const; |
624 | 653 |
625 Array<T> diag (octave_idx_type m, octave_idx_type n) const; | 654 Array<T> diag (octave_idx_type m, octave_idx_type n) const; |
626 | 655 |
627 // Concatenation along a specified (0-based) dimension, equivalent to cat(). | 656 //! Concatenation along a specified (0-based) dimension, equivalent |
628 // dim = -1 corresponds to dim = 0 and dim = -2 corresponds to dim = 1, | 657 //! to cat(). dim = -1 corresponds to dim = 0 and dim = -2 |
629 // but apply the looser matching rules of vertcat/horzcat. | 658 //! corresponds to dim = 1, but apply the looser matching rules of |
659 //! vertcat/horzcat. | |
630 static Array<T> | 660 static Array<T> |
631 cat (int dim, octave_idx_type n, const Array<T> *array_list); | 661 cat (int dim, octave_idx_type n, const Array<T> *array_list); |
632 | 662 |
663 //! Apply function fcn to each element of the Array<T>. This function | |
664 //! is optimised with a manually unrolled loop. | |
633 template <class U, class F> | 665 template <class U, class F> |
634 Array<U> | 666 Array<U> |
635 map (F fcn) const | 667 map (F fcn) const |
636 { | 668 { |
637 octave_idx_type len = length (); | 669 octave_idx_type len = length (); |
658 p[i] = fcn (m[i]); | 690 p[i] = fcn (m[i]); |
659 | 691 |
660 return result; | 692 return result; |
661 } | 693 } |
662 | 694 |
663 // Overloads for function references. | 695 //@{ |
696 //! Overloads for function references. | |
664 template <class U> | 697 template <class U> |
665 Array<U> | 698 Array<U> |
666 map (U (&fcn) (T)) const | 699 map (U (&fcn) (T)) const |
667 { return map<U, U (&) (T)> (fcn); } | 700 { return map<U, U (&) (T)> (fcn); } |
668 | 701 |
669 template <class U> | 702 template <class U> |
670 Array<U> | 703 Array<U> |
671 map (U (&fcn) (const T&)) const | 704 map (U (&fcn) (const T&)) const |
672 { return map<U, U (&) (const T&)> (fcn); } | 705 { return map<U, U (&) (const T&)> (fcn); } |
673 | 706 //@} |
674 // Generic any/all test functionality with arbitrary predicate. | 707 |
708 //! Generic any/all test functionality with arbitrary predicate. | |
675 template <class F, bool zero> | 709 template <class F, bool zero> |
676 bool test (F fcn) const | 710 bool test (F fcn) const |
677 { | 711 { |
678 return any_all_test<F, T, zero> (fcn, data (), length ()); | 712 return any_all_test<F, T, zero> (fcn, data (), length ()); |
679 } | 713 } |
680 | 714 |
681 // Simpler calls. | 715 //@{ |
716 //! Simpler calls. | |
682 template <class F> | 717 template <class F> |
683 bool test_any (F fcn) const | 718 bool test_any (F fcn) const |
684 { return test<F, false> (fcn); } | 719 { return test<F, false> (fcn); } |
685 | 720 |
686 template <class F> | 721 template <class F> |
687 bool test_all (F fcn) const | 722 bool test_all (F fcn) const |
688 { return test<F, true> (fcn); } | 723 { return test<F, true> (fcn); } |
689 | 724 //@} |
690 // Overloads for function references. | 725 |
726 //@{ | |
727 //! Overloads for function references. | |
691 bool test_any (bool (&fcn) (T)) const | 728 bool test_any (bool (&fcn) (T)) const |
692 { return test<bool (&) (T), false> (fcn); } | 729 { return test<bool (&) (T), false> (fcn); } |
693 | 730 |
694 bool test_any (bool (&fcn) (const T&)) const | 731 bool test_any (bool (&fcn) (const T&)) const |
695 { return test<bool (&) (const T&), false> (fcn); } | 732 { return test<bool (&) (const T&), false> (fcn); } |
697 bool test_all (bool (&fcn) (T)) const | 734 bool test_all (bool (&fcn) (T)) const |
698 { return test<bool (&) (T), true> (fcn); } | 735 { return test<bool (&) (T), true> (fcn); } |
699 | 736 |
700 bool test_all (bool (&fcn) (const T&)) const | 737 bool test_all (bool (&fcn) (const T&)) const |
701 { return test<bool (&) (const T&), true> (fcn); } | 738 { return test<bool (&) (const T&), true> (fcn); } |
739 //@} | |
702 | 740 |
703 template <class U> friend class Array; | 741 template <class U> friend class Array; |
704 | 742 |
705 // Returns true if this->dims () == dv, and if so, replaces this->dimensions | 743 //! Returns true if this->dims () == dv, and if so, replaces this->dimensions |
706 // by a shallow copy of dv. This is useful for maintaining several arrays with | 744 //! by a shallow copy of dv. This is useful for maintaining several arrays with |
707 // supposedly equal dimensions (e.g. structs in the interpreter). | 745 //! supposedly equal dimensions (e.g. structs in the interpreter). |
708 bool optimize_dimensions (const dim_vector& dv); | 746 bool optimize_dimensions (const dim_vector& dv); |
709 | 747 |
710 // WARNING: Only call these functions from jit | 748 //@{ |
711 | 749 //! WARNING: Only call these functions from jit |
750 | |
712 int *jit_ref_count (void) { return rep->count.get (); } | 751 int *jit_ref_count (void) { return rep->count.get (); } |
713 | 752 |
714 T *jit_slice_data (void) const { return slice_data; } | 753 T *jit_slice_data (void) const { return slice_data; } |
715 | 754 |
716 octave_idx_type *jit_dimensions (void) const { return dimensions.to_jit (); } | 755 octave_idx_type *jit_dimensions (void) const { return dimensions.to_jit (); } |
717 | 756 |
718 void *jit_array_rep (void) const { return rep; } | 757 void *jit_array_rep (void) const { return rep; } |
758 //@} | |
719 | 759 |
720 private: | 760 private: |
721 | 761 |
722 void resize2 (octave_idx_type nr, octave_idx_type nc, const T& rfv); | 762 void resize2 (octave_idx_type nr, octave_idx_type nc, const T& rfv); |
723 void resize2 (octave_idx_type nr, octave_idx_type nc) | 763 void resize2 (octave_idx_type nr, octave_idx_type nc) |
726 } | 766 } |
727 | 767 |
728 static void instantiation_guard (); | 768 static void instantiation_guard (); |
729 }; | 769 }; |
730 | 770 |
731 // This is a simple wrapper template that will subclass an Array<T> type or any | 771 //! This is a simple wrapper template that will subclass an Array<T> |
732 // later type derived from it and override the default non-const operator() to | 772 //! type or any later type derived from it and override the default |
733 // not check for the array's uniqueness. It is, however, the user's | 773 //! non-const operator() to not check for the array's uniqueness. It |
734 // responsibility to ensure the array is actually unaliased whenever elements | 774 //! is, however, the user's responsibility to ensure the array is |
735 // are accessed. | 775 //! actually unaliased whenever elements are accessed. |
736 | |
737 template<class ArrayClass> | 776 template<class ArrayClass> |
738 class NoAlias : public ArrayClass | 777 class NoAlias : public ArrayClass |
739 { | 778 { |
740 typedef typename ArrayClass::element_type T; | 779 typedef typename ArrayClass::element_type T; |
741 public: | 780 public: |