Mercurial > hg > octave-nkf
annotate liboctave/Array.h @ 7793:96ba591be50f
Add some more support for single precision to libcruft functions
author | David Bateman <dbateman@free.fr> |
---|---|
date | Sun, 11 May 2008 22:51:50 +0200 |
parents | 82be108cc558 |
children | 311c9b36df8f |
rev | line source |
---|---|
1993 | 1 // Template array classes |
228 | 2 /* |
3 | |
7017 | 4 Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2003, |
5 2004, 2005, 2006, 2007 John W. Eaton | |
228 | 6 |
7 This file is part of Octave. | |
8 | |
9 Octave is free software; you can redistribute it and/or modify it | |
10 under the terms of the GNU General Public License as published by the | |
7016 | 11 Free Software Foundation; either version 3 of the License, or (at your |
12 option) any later version. | |
228 | 13 |
14 Octave is distributed in the hope that it will be useful, but WITHOUT | |
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
17 for more details. | |
18 | |
19 You should have received a copy of the GNU General Public License | |
7016 | 20 along with Octave; see the file COPYING. If not, see |
21 <http://www.gnu.org/licenses/>. | |
228 | 22 |
23 */ | |
24 | |
382 | 25 #if !defined (octave_Array_h) |
26 #define octave_Array_h 1 | |
27 | |
1366 | 28 #include <cassert> |
4152 | 29 #include <cstddef> |
3613 | 30 |
3933 | 31 #include <iostream> |
32 | |
4513 | 33 #include "dim-vector.h" |
3613 | 34 #include "lo-utils.h" |
7433 | 35 #include "oct-sort.h" |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
36 #include "quit.h" |
7433 | 37 |
1560 | 38 class idx_vector; |
39 | |
1359 | 40 // One dimensional array class. Handles the reference counting for |
41 // all the derived classes. | |
238 | 42 |
228 | 43 template <class T> |
4459 | 44 T |
45 resize_fill_value (const T& x) | |
46 { | |
47 return x; | |
48 } | |
49 | |
50 template <class T> | |
3585 | 51 class |
52 Array | |
228 | 53 { |
3504 | 54 protected: |
1619 | 55 |
4513 | 56 //-------------------------------------------------------------------- |
57 // The real representation of all arrays. | |
58 //-------------------------------------------------------------------- | |
1735 | 59 |
60 class ArrayRep | |
61 { | |
62 public: | |
63 | |
64 T *data; | |
5275 | 65 octave_idx_type len; |
1735 | 66 int count; |
67 | |
5275 | 68 ArrayRep (T *d, octave_idx_type l) : data (d), len (l), count (1) { } |
1735 | 69 |
70 ArrayRep (void) : data (0), len (0), count (1) { } | |
71 | |
5275 | 72 explicit ArrayRep (octave_idx_type n) : data (new T [n]), len (n), count (1) { } |
1735 | 73 |
5275 | 74 explicit ArrayRep (octave_idx_type n, const T& val) |
4513 | 75 : data (new T [n]), len (n), count (1) |
76 { | |
77 fill (val); | |
78 } | |
79 | |
1735 | 80 ArrayRep (const ArrayRep& a) |
81 : data (new T [a.len]), len (a.len), count (1) | |
4513 | 82 { |
5275 | 83 for (octave_idx_type i = 0; i < len; i++) |
4513 | 84 data[i] = a.data[i]; |
85 } | |
4517 | 86 |
1735 | 87 ~ArrayRep (void) { delete [] data; } |
88 | |
5275 | 89 octave_idx_type length (void) const { return len; } |
1735 | 90 |
4513 | 91 void fill (const T& val) |
92 { | |
5275 | 93 for (octave_idx_type i = 0; i < len; i++) |
4513 | 94 data[i] = val; |
95 } | |
96 | |
5275 | 97 T& elem (octave_idx_type n) { return data[n]; } |
1735 | 98 |
5275 | 99 T elem (octave_idx_type n) const { return data[n]; } |
1756 | 100 |
101 void qsort (int (*compare) (const void *, const void *)) | |
102 { | |
3613 | 103 octave_qsort (data, static_cast<size_t> (len), sizeof (T), compare); |
1756 | 104 } |
4517 | 105 |
106 private: | |
107 | |
108 // No assignment! | |
109 | |
110 ArrayRep& operator = (const ArrayRep& a); | |
1735 | 111 }; |
112 | |
4513 | 113 //-------------------------------------------------------------------- |
114 | |
6884 | 115 public: |
116 | |
117 // !!! WARNING !!! -- these should be protected, not public. You | |
118 // should not access these methods directly! | |
119 | |
2006 | 120 void make_unique (void) |
121 { | |
122 if (rep->count > 1) | |
123 { | |
124 --rep->count; | |
125 rep = new ArrayRep (*rep); | |
126 } | |
127 } | |
128 | |
4513 | 129 void make_unique (const T& val) |
130 { | |
131 if (rep->count > 1) | |
132 { | |
133 --rep->count; | |
134 rep = new ArrayRep (rep->length (), val); | |
135 } | |
136 else | |
137 rep->fill (val); | |
138 } | |
238 | 139 |
5900 | 140 typedef T element_type; |
141 | |
4902 | 142 // !!! WARNING !!! -- these should be protected, not public. You |
143 // should not access these data members directly! | |
144 | |
145 typename Array<T>::ArrayRep *rep; | |
4518 | 146 |
4513 | 147 dim_vector dimensions; |
148 | |
4518 | 149 protected: |
150 | |
6881 | 151 mutable idx_vector *idx; |
152 mutable int idx_count; | |
4513 | 153 |
5275 | 154 Array (T *d, octave_idx_type n) |
4513 | 155 : rep (new typename Array<T>::ArrayRep (d, n)), dimensions (n), |
156 idx (0), idx_count (0) { } | |
1619 | 157 |
4587 | 158 Array (T *d, const dim_vector& dv) |
159 : rep (new typename Array<T>::ArrayRep (d, get_size (dv))), | |
160 dimensions (dv), idx (0), idx_count (0) { } | |
4513 | 161 |
162 private: | |
163 | |
4585 | 164 typename Array<T>::ArrayRep *nil_rep (void) const |
4513 | 165 { |
166 static typename Array<T>::ArrayRep *nr | |
167 = new typename Array<T>::ArrayRep (); | |
168 | |
169 return nr; | |
1550 | 170 } |
238 | 171 |
4902 | 172 template <class U> |
173 T * | |
174 coerce (const U *a, int len) | |
175 { | |
176 T *retval = new T [len]; | |
177 | |
178 for (int i = 0; i < len; i++) | |
179 retval[i] = T (a[i]); | |
180 | |
181 return retval; | |
182 } | |
183 | |
228 | 184 public: |
238 | 185 |
1550 | 186 Array (void) |
4513 | 187 : rep (nil_rep ()), dimensions (), |
188 idx (0), idx_count (0) { rep->count++; } | |
1550 | 189 |
5275 | 190 explicit Array (octave_idx_type n) |
4513 | 191 : rep (new typename Array<T>::ArrayRep (n)), dimensions (n), |
192 idx (0), idx_count (0) { } | |
1619 | 193 |
5275 | 194 explicit Array (octave_idx_type n, const T& val) |
4513 | 195 : rep (new typename Array<T>::ArrayRep (n)), dimensions (n), |
196 idx (0), idx_count (0) | |
197 { | |
198 fill (val); | |
199 } | |
200 | |
4902 | 201 // Type conversion case. |
202 template <class U> | |
203 Array (const Array<U>& a) | |
204 : rep (new typename Array<T>::ArrayRep (coerce (a.data (), a.length ()), a.length ())), | |
205 dimensions (a.dimensions), idx (0), idx_count (0) | |
206 { | |
207 } | |
208 | |
209 // No type conversion case. | |
4513 | 210 Array (const Array<T>& a) |
211 : rep (a.rep), dimensions (a.dimensions), idx (0), idx_count (0) | |
212 { | |
213 rep->count++; | |
1550 | 214 } |
215 | |
4513 | 216 public: |
217 | |
4587 | 218 Array (const dim_vector& dv) |
219 : rep (new typename Array<T>::ArrayRep (get_size (dv))), | |
220 dimensions (dv), idx (0), idx_count (0) { } | |
238 | 221 |
4587 | 222 Array (const dim_vector& dv, const T& val) |
223 : rep (new typename Array<T>::ArrayRep (get_size (dv))), | |
224 dimensions (dv), idx (0), idx_count (0) | |
1550 | 225 { |
4513 | 226 fill (val); |
227 } | |
228 | |
4834 | 229 Array (const Array<T>& a, const dim_vector& dv); |
228 | 230 |
4979 | 231 virtual ~Array (void); |
228 | 232 |
7717
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
233 Array<T>& operator = (const Array<T>& a); |
4513 | 234 |
235 void fill (const T& val) { make_unique (val); } | |
238 | 236 |
5275 | 237 octave_idx_type capacity (void) const { return rep->length (); } |
238 octave_idx_type length (void) const { return capacity (); } | |
239 octave_idx_type nelem (void) const { return capacity (); } | |
240 octave_idx_type numel (void) const { return nelem (); } | |
4513 | 241 |
5275 | 242 octave_idx_type dim1 (void) const { return dimensions(0); } |
243 octave_idx_type dim2 (void) const { return dimensions(1); } | |
244 octave_idx_type dim3 (void) const { return dimensions(2); } | |
4513 | 245 |
5275 | 246 octave_idx_type rows (void) const { return dim1 (); } |
247 octave_idx_type cols (void) const { return dim2 (); } | |
248 octave_idx_type columns (void) const { return dim2 (); } | |
249 octave_idx_type pages (void) const { return dim3 (); } | |
4513 | 250 |
4902 | 251 size_t byte_size (void) const { return numel () * sizeof (T); } |
252 | |
4513 | 253 dim_vector dims (void) const { return dimensions; } |
254 | |
4532 | 255 Array<T> squeeze (void) const; |
4703 | 256 |
257 void chop_trailing_singletons (void) | |
258 { dimensions.chop_trailing_singletons (); } | |
259 | |
5275 | 260 static octave_idx_type get_size (octave_idx_type r, octave_idx_type c); |
261 static octave_idx_type get_size (octave_idx_type r, octave_idx_type c, octave_idx_type p); | |
262 static octave_idx_type get_size (const dim_vector& dv); | |
228 | 263 |
5275 | 264 octave_idx_type compute_index (const Array<octave_idx_type>& ra_idx) const; |
4517 | 265 |
5275 | 266 T range_error (const char *fcn, octave_idx_type n) const; |
267 T& range_error (const char *fcn, octave_idx_type n); | |
3665 | 268 |
5275 | 269 T range_error (const char *fcn, octave_idx_type i, octave_idx_type j) const; |
270 T& range_error (const char *fcn, octave_idx_type i, octave_idx_type j); | |
4513 | 271 |
5275 | 272 T range_error (const char *fcn, octave_idx_type i, octave_idx_type j, octave_idx_type k) const; |
273 T& range_error (const char *fcn, octave_idx_type i, octave_idx_type j, octave_idx_type k); | |
4513 | 274 |
6867 | 275 T range_error (const char *fcn, const Array<octave_idx_type>& ra_idx) const; |
276 T& range_error (const char *fcn, const Array<octave_idx_type>& ra_idx); | |
4513 | 277 |
2108 | 278 // No checking, even for multiple references, ever. |
279 | |
5275 | 280 T& xelem (octave_idx_type n) { return rep->elem (n); } |
281 T xelem (octave_idx_type n) const { return rep->elem (n); } | |
2108 | 282 |
5275 | 283 T& xelem (octave_idx_type i, octave_idx_type j) { return xelem (dim1()*j+i); } |
284 T xelem (octave_idx_type i, octave_idx_type j) const { return xelem (dim1()*j+i); } | |
4513 | 285 |
5275 | 286 T& xelem (octave_idx_type i, octave_idx_type j, octave_idx_type k) { return xelem (i, dim2()*k+j); } |
287 T xelem (octave_idx_type i, octave_idx_type j, octave_idx_type k) const { return xelem (i, dim2()*k+j); } | |
4513 | 288 |
6867 | 289 T& xelem (const Array<octave_idx_type>& ra_idx) |
4513 | 290 { return xelem (compute_index (ra_idx)); } |
291 | |
6867 | 292 T xelem (const Array<octave_idx_type>& ra_idx) const |
4513 | 293 { return xelem (compute_index (ra_idx)); } |
294 | |
5775 | 295 // FIXME -- would be nice to fix this so that we don't |
2006 | 296 // unnecessarily force a copy, but that is not so easy, and I see no |
297 // clean way to do it. | |
298 | |
5275 | 299 T& checkelem (octave_idx_type n) |
2006 | 300 { |
301 if (n < 0 || n >= rep->length ()) | |
2109 | 302 return range_error ("T& Array<T>::checkelem", n); |
2006 | 303 else |
2108 | 304 { |
305 make_unique (); | |
306 return xelem (n); | |
307 } | |
2006 | 308 } |
309 | |
5275 | 310 T& checkelem (octave_idx_type i, octave_idx_type j) |
4513 | 311 { |
312 if (i < 0 || j < 0 || i >= dim1 () || j >= dim2 ()) | |
313 return range_error ("T& Array<T>::checkelem", i, j); | |
314 else | |
315 return elem (dim1()*j+i); | |
316 } | |
317 | |
5275 | 318 T& checkelem (octave_idx_type i, octave_idx_type j, octave_idx_type k) |
4513 | 319 { |
320 if (i < 0 || j < 0 || k < 0 || i >= dim1 () || j >= dim2 () || k >= dim3 ()) | |
321 return range_error ("T& Array<T>::checkelem", i, j, k); | |
322 else | |
323 return elem (i, dim2()*k+j); | |
324 } | |
325 | |
6867 | 326 T& checkelem (const Array<octave_idx_type>& ra_idx) |
4513 | 327 { |
5275 | 328 octave_idx_type i = compute_index (ra_idx); |
4513 | 329 |
330 if (i < 0) | |
331 return range_error ("T& Array<T>::checkelem", ra_idx); | |
332 else | |
333 return elem (i); | |
334 } | |
335 | |
5275 | 336 T& elem (octave_idx_type n) |
2108 | 337 { |
338 make_unique (); | |
2109 | 339 return xelem (n); |
2108 | 340 } |
2306 | 341 |
5275 | 342 T& elem (octave_idx_type i, octave_idx_type j) { return elem (dim1()*j+i); } |
4513 | 343 |
5275 | 344 T& elem (octave_idx_type i, octave_idx_type j, octave_idx_type k) { return elem (i, dim2()*k+j); } |
4513 | 345 |
6867 | 346 T& elem (const Array<octave_idx_type>& ra_idx) |
4513 | 347 { return Array<T>::elem (compute_index (ra_idx)); } |
348 | |
2306 | 349 #if defined (BOUNDS_CHECKING) |
5275 | 350 T& operator () (octave_idx_type n) { return checkelem (n); } |
351 T& operator () (octave_idx_type i, octave_idx_type j) { return checkelem (i, j); } | |
352 T& operator () (octave_idx_type i, octave_idx_type j, octave_idx_type k) { return checkelem (i, j, k); } | |
6867 | 353 T& operator () (const Array<octave_idx_type>& ra_idx) { return checkelem (ra_idx); } |
2306 | 354 #else |
5275 | 355 T& operator () (octave_idx_type n) { return elem (n); } |
356 T& operator () (octave_idx_type i, octave_idx_type j) { return elem (i, j); } | |
357 T& operator () (octave_idx_type i, octave_idx_type j, octave_idx_type k) { return elem (i, j, k); } | |
6867 | 358 T& operator () (const Array<octave_idx_type>& ra_idx) { return elem (ra_idx); } |
2006 | 359 #endif |
360 | |
5275 | 361 T checkelem (octave_idx_type n) const |
2006 | 362 { |
363 if (n < 0 || n >= rep->length ()) | |
2109 | 364 return range_error ("T Array<T>::checkelem", n); |
2049 | 365 else |
2108 | 366 return xelem (n); |
2006 | 367 } |
1989 | 368 |
5275 | 369 T checkelem (octave_idx_type i, octave_idx_type j) const |
4513 | 370 { |
371 if (i < 0 || j < 0 || i >= dim1 () || j >= dim2 ()) | |
372 return range_error ("T Array<T>::checkelem", i, j); | |
373 else | |
374 return elem (dim1()*j+i); | |
375 } | |
376 | |
5275 | 377 T checkelem (octave_idx_type i, octave_idx_type j, octave_idx_type k) const |
4513 | 378 { |
379 if (i < 0 || j < 0 || k < 0 || i >= dim1 () || j >= dim2 () || k >= dim3 ()) | |
380 return range_error ("T Array<T>::checkelem", i, j, k); | |
381 else | |
382 return Array<T>::elem (i, Array<T>::dim1()*k+j); | |
383 } | |
384 | |
6867 | 385 T checkelem (const Array<octave_idx_type>& ra_idx) const |
4513 | 386 { |
5275 | 387 octave_idx_type i = compute_index (ra_idx); |
4513 | 388 |
389 if (i < 0) | |
390 return range_error ("T Array<T>::checkelem", ra_idx); | |
391 else | |
392 return Array<T>::elem (i); | |
393 } | |
394 | |
5275 | 395 T elem (octave_idx_type n) const { return xelem (n); } |
2306 | 396 |
5275 | 397 T elem (octave_idx_type i, octave_idx_type j) const { return elem (dim1()*j+i); } |
4513 | 398 |
5275 | 399 T elem (octave_idx_type i, octave_idx_type j, octave_idx_type k) const { return elem (i, dim2()*k+j); } |
4513 | 400 |
6867 | 401 T elem (const Array<octave_idx_type>& ra_idx) const |
4513 | 402 { return Array<T>::elem (compute_index (ra_idx)); } |
403 | |
2108 | 404 #if defined (BOUNDS_CHECKING) |
5275 | 405 T operator () (octave_idx_type n) const { return checkelem (n); } |
406 T operator () (octave_idx_type i, octave_idx_type j) const { return checkelem (i, j); } | |
407 T operator () (octave_idx_type i, octave_idx_type j, octave_idx_type k) const { return checkelem (i, j, k); } | |
6867 | 408 T operator () (const Array<octave_idx_type>& ra_idx) const { return checkelem (ra_idx); } |
2006 | 409 #else |
5275 | 410 T operator () (octave_idx_type n) const { return elem (n); } |
411 T operator () (octave_idx_type i, octave_idx_type j) const { return elem (i, j); } | |
412 T operator () (octave_idx_type i, octave_idx_type j, octave_idx_type k) const { return elem (i, j, k); } | |
6867 | 413 T operator () (const Array<octave_idx_type>& ra_idx) const { return elem (ra_idx); } |
2006 | 414 #endif |
415 | |
4567 | 416 Array<T> reshape (const dim_vector& new_dims) const; |
417 | |
5275 | 418 Array<T> permute (const Array<octave_idx_type>& vec, bool inv = false) const; |
419 Array<T> ipermute (const Array<octave_idx_type>& vec) const | |
4593 | 420 { return permute (vec, true); } |
421 | |
5275 | 422 void resize_no_fill (octave_idx_type n); |
423 void resize_and_fill (octave_idx_type n, const T& val); | |
4548 | 424 |
4518 | 425 // !!! WARNING !!! -- the following resize_no_fill and |
426 // resize_and_fill functions are public because template friends | |
427 // don't work properly with versions of gcc earlier than 3.3. You | |
428 // should use these functions only in classes that are derived | |
429 // from Array<T>. | |
430 | |
431 // protected: | |
4513 | 432 |
5275 | 433 void resize_no_fill (octave_idx_type r, octave_idx_type c); |
434 void resize_and_fill (octave_idx_type r, octave_idx_type c, const T& val); | |
4513 | 435 |
5275 | 436 void resize_no_fill (octave_idx_type r, octave_idx_type c, octave_idx_type p); |
437 void resize_and_fill (octave_idx_type r, octave_idx_type c, octave_idx_type p, const T& val); | |
4513 | 438 |
4587 | 439 void resize_no_fill (const dim_vector& dv); |
440 void resize_and_fill (const dim_vector& dv, const T& val); | |
4513 | 441 |
442 public: | |
443 | |
5392 | 444 void resize (octave_idx_type n) { resize_no_fill (n); } |
4513 | 445 |
5392 | 446 void resize (octave_idx_type n, const T& val) { resize_and_fill (n, val); } |
4513 | 447 |
4587 | 448 void resize (const dim_vector& dv) { resize_no_fill (dv); } |
4513 | 449 |
4587 | 450 void resize (const dim_vector& dv, const T& val) |
451 { resize_and_fill (dv, val); } | |
4513 | 452 |
5275 | 453 Array<T>& insert (const Array<T>& a, octave_idx_type r, octave_idx_type c); |
454 Array<T>& insert2 (const Array<T>& a, octave_idx_type r, octave_idx_type c); | |
455 Array<T>& insertN (const Array<T>& a, octave_idx_type r, octave_idx_type c); | |
4513 | 456 |
5275 | 457 Array<T>& insert (const Array<T>& a, const Array<octave_idx_type>& idx); |
4513 | 458 |
459 bool is_square (void) const { return (dim1 () == dim2 ()); } | |
460 | |
4559 | 461 bool is_empty (void) const { return numel () == 0; } |
462 | |
4513 | 463 Array<T> transpose (void) const; |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
464 Array<T> hermitian (T (*fcn) (const T&) = 0) const; |
238 | 465 |
1550 | 466 const T *data (void) const { return rep->data; } |
228 | 467 |
3952 | 468 const T *fortran_vec (void) const { return data (); } |
469 | |
238 | 470 T *fortran_vec (void); |
1560 | 471 |
1781 | 472 Array<T>& qsort (int (*compare) (const void *, const void *)) |
1756 | 473 { |
2347 | 474 make_unique (); |
1756 | 475 |
476 rep->qsort (compare); | |
1781 | 477 |
478 return *this; | |
1756 | 479 } |
480 | |
4513 | 481 int ndims (void) const { return dimensions.length (); } |
1560 | 482 |
4517 | 483 void maybe_delete_dims (void); |
484 | |
6881 | 485 void clear_index (void) const; |
1560 | 486 |
6881 | 487 void set_index (const idx_vector& i) const; |
1560 | 488 |
1619 | 489 int index_count (void) const { return idx_count; } |
1560 | 490 |
1619 | 491 idx_vector *get_idx (void) const { return idx; } |
1560 | 492 |
493 void maybe_delete_elements (idx_vector& i); | |
494 | |
4513 | 495 void maybe_delete_elements_1 (idx_vector& i); |
496 | |
497 void maybe_delete_elements_2 (idx_vector& i); | |
498 | |
499 void maybe_delete_elements (idx_vector& i, idx_vector& j); | |
500 | |
501 void maybe_delete_elements (idx_vector& i, idx_vector& j, idx_vector& k); | |
502 | |
503 void maybe_delete_elements (Array<idx_vector>& ra_idx, const T& rfv); | |
504 | |
6881 | 505 Array<T> value (void) const; |
2382 | 506 |
3933 | 507 Array<T> index (idx_vector& i, int resize_ok = 0, |
4459 | 508 const T& rfv = resize_fill_value (T ())) const; |
3933 | 509 |
4513 | 510 Array<T> index1 (idx_vector& i, int resize_ok = 0, |
511 const T& rfv = resize_fill_value (T ())) const; | |
512 | |
513 Array<T> index2 (idx_vector& i, int resize_ok = 0, | |
514 const T& rfv = resize_fill_value (T ())) const; | |
515 | |
4530 | 516 Array<T> indexN (idx_vector& i, int resize_ok = 0, |
517 const T& rfv = resize_fill_value (T ())) const; | |
518 | |
4513 | 519 Array<T> index (idx_vector& i, idx_vector& j, int resize_ok = 0, |
520 const T& rfv = resize_fill_value (T ())) const; | |
521 | |
522 Array<T> index (Array<idx_vector>& ra_idx, int resize_ok = 0, | |
523 const T& rfv = resize_fill_value (T ())) const; | |
3928 | 524 |
4459 | 525 // static T resize_fill_value (void) { return T (); } |
3933 | 526 |
4517 | 527 void print_info (std::ostream& os, const std::string& prefix) const; |
5900 | 528 |
529 // Unsafe. This function exists to support the MEX interface. | |
530 // You should not use it anywhere else. | |
531 void *mex_get_data (void) const { return const_cast<T *> (data ()); } | |
7433 | 532 |
7463
2467639bd8c0
eliminate UNDEFINED sort mode
John W. Eaton <jwe@octave.org>
parents:
7433
diff
changeset
|
533 Array<T> sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const; |
7433 | 534 Array<T> sort (Array<octave_idx_type> &sidx, octave_idx_type dim = 0, |
7463
2467639bd8c0
eliminate UNDEFINED sort mode
John W. Eaton <jwe@octave.org>
parents:
7433
diff
changeset
|
535 sortmode mode = ASCENDING) const; |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
536 |
7620
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
537 Array<T> diag (octave_idx_type k = 0) const; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
538 |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
539 template <class U, class F> |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
540 Array<U> |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
541 map (F fcn) const |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
542 { |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
543 octave_idx_type len = length (); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
544 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
545 const T *m = data (); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
546 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
547 Array<U> result (dims ()); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
548 U *p = result.fortran_vec (); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
549 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
550 for (octave_idx_type i = 0; i < len; i++) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
551 { |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
552 OCTAVE_QUIT; |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
553 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
554 p[i] = fcn (m[i]); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
555 } |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
556 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
557 return result; |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7463
diff
changeset
|
558 } |
4513 | 559 }; |
4459 | 560 |
4518 | 561 // NOTE: these functions should be friends of the Array<T> class and |
562 // Array<T>::dimensions should be protected, not public, but we can't | |
563 // do that because of bugs in gcc prior to 3.3. | |
564 | |
565 template <class LT, class RT> | |
566 /* friend */ int | |
567 assign (Array<LT>& lhs, const Array<RT>& rhs, const LT& rfv); | |
568 | |
569 template <class LT, class RT> | |
570 /* friend */ int | |
571 assign1 (Array<LT>& lhs, const Array<RT>& rhs, const LT& rfv); | |
572 | |
573 template <class LT, class RT> | |
574 /* friend */ int | |
575 assign2 (Array<LT>& lhs, const Array<RT>& rhs, const LT& rfv); | |
576 | |
577 template <class LT, class RT> | |
578 /* friend */ int | |
579 assignN (Array<LT>& lhs, const Array<RT>& rhs, const LT& rfv); | |
580 | |
3836 | 581 template <class LT, class RT> |
582 int | |
583 assign (Array<LT>& lhs, const Array<RT>& rhs) | |
584 { | |
4459 | 585 return assign (lhs, rhs, resize_fill_value (LT ())); |
3836 | 586 } |
1560 | 587 |
6708 | 588 #define INSTANTIATE_ARRAY_ASSIGN(LT, RT, API) \ |
589 template API int assign (Array<LT>&, const Array<RT>&, const LT&); \ | |
590 template API int assign1 (Array<LT>&, const Array<RT>&, const LT&); \ | |
591 template API int assign2 (Array<LT>&, const Array<RT>&, const LT&); \ | |
592 template API int assignN (Array<LT>&, const Array<RT>&, const LT&); \ | |
593 template API int assign (Array<LT>&, const Array<RT>&) | |
4594 | 594 |
4762 | 595 |
6708 | 596 #define INSTANTIATE_ARRAY(T, API) \ |
597 template class API Array<T>; \ | |
598 template API T resize_fill_value (const T&); \ | |
4762 | 599 |
6708 | 600 #define INSTANTIATE_ARRAY_AND_ASSIGN(T, API) \ |
601 INSTANTIATE_ARRAY (T, API); \ | |
602 INSTANTIATE_ARRAY_ASSIGN (T, T, API) | |
4594 | 603 |
7433 | 604 #define INSTANTIATE_ARRAY_SORT(T) \ |
605 template class octave_sort<T>; \ | |
606 template class vec_index<T>; \ | |
607 template class octave_sort<vec_index<T> *>; | |
608 | |
609 #define NO_INSTANTIATE_ARRAY_SORT(T) \ | |
610 template class vec_index<T>; \ | |
611 template <> bool ascending_compare (T, T) { return true; } \ | |
612 template <> bool ascending_compare (vec_index<T> *, vec_index<T> *) \ | |
613 { return true; } \ | |
614 template <> bool descending_compare (T, T) { return true; } \ | |
615 template <> bool descending_compare (vec_index<T> *, vec_index<T> *) \ | |
616 { return true; } \ | |
617 template <> Array<T> Array<T>::sort \ | |
618 (octave_idx_type, sortmode) const { return *this; } \ | |
619 template <> Array<T> Array<T>::sort (Array<octave_idx_type> &sidx, \ | |
620 octave_idx_type, sortmode) const \ | |
621 { sidx = Array<octave_idx_type> (); return *this; } | |
622 | |
228 | 623 #endif |
624 | |
625 /* | |
626 ;;; Local Variables: *** | |
627 ;;; mode: C++ *** | |
628 ;;; End: *** | |
629 */ |