00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #if !defined (octave_Array_h)
00025 #define octave_Array_h 1
00026
00027 #if defined (__GNUG__) && defined (USE_PRAGMA_INTERFACE_IMPLEMENTATION)
00028 #pragma interface
00029 #endif
00030
00031 #include <cassert>
00032 #include <cstddef>
00033
00034 #include <iostream>
00035
00036 #include "dim-vector.h"
00037 #include "lo-utils.h"
00038
00039 class idx_vector;
00040
00041
00042
00043
00044 template <class T>
00045 T
00046 resize_fill_value (const T& x)
00047 {
00048 return x;
00049 }
00050
00051 template <class T>
00052 class
00053 Array
00054 {
00055 protected:
00056
00057
00058
00059
00060
00061 class ArrayRep
00062 {
00063 public:
00064
00065 T *data;
00066 int len;
00067 int count;
00068
00069 ArrayRep (T *d, int l) : data (d), len (l), count (1) { }
00070
00071 ArrayRep (void) : data (0), len (0), count (1) { }
00072
00073 explicit ArrayRep (int n) : data (new T [n]), len (n), count (1) { }
00074
00075 explicit ArrayRep (int n, const T& val)
00076 : data (new T [n]), len (n), count (1)
00077 {
00078 fill (val);
00079 }
00080
00081 ArrayRep (const ArrayRep& a)
00082 : data (new T [a.len]), len (a.len), count (1)
00083 {
00084 for (int i = 0; i < len; i++)
00085 data[i] = a.data[i];
00086 }
00087
00088 ~ArrayRep (void) { delete [] data; }
00089
00090 int length (void) const { return len; }
00091
00092 void fill (const T& val)
00093 {
00094 for (int i = 0; i < len; i++)
00095 data[i] = val;
00096 }
00097
00098 T& elem (int n) { return data[n]; }
00099
00100 T elem (int n) const { return data[n]; }
00101
00102 void qsort (int (*compare) (const void *, const void *))
00103 {
00104 octave_qsort (data, static_cast<size_t> (len), sizeof (T), compare);
00105 }
00106
00107 private:
00108
00109
00110
00111 ArrayRep& operator = (const ArrayRep& a);
00112 };
00113
00114
00115
00116 void make_unique (void)
00117 {
00118 if (rep->count > 1)
00119 {
00120 --rep->count;
00121 rep = new ArrayRep (*rep);
00122 }
00123 }
00124
00125 void make_unique (const T& val)
00126 {
00127 if (rep->count > 1)
00128 {
00129 --rep->count;
00130 rep = new ArrayRep (rep->length (), val);
00131 }
00132 else
00133 rep->fill (val);
00134 }
00135
00136 public:
00137
00138
00139
00140
00141 typename Array<T>::ArrayRep *rep;
00142
00143 dim_vector dimensions;
00144
00145 protected:
00146
00147 idx_vector *idx;
00148 int idx_count;
00149
00150 Array (T *d, int n)
00151 : rep (new typename Array<T>::ArrayRep (d, n)), dimensions (n),
00152 idx (0), idx_count (0) { }
00153
00154 Array (T *d, const dim_vector& dv)
00155 : rep (new typename Array<T>::ArrayRep (d, get_size (dv))),
00156 dimensions (dv), idx (0), idx_count (0) { }
00157
00158 private:
00159
00160 typename Array<T>::ArrayRep *nil_rep (void) const
00161 {
00162 static typename Array<T>::ArrayRep *nr
00163 = new typename Array<T>::ArrayRep ();
00164
00165 return nr;
00166 }
00167
00168 template <class U>
00169 T *
00170 coerce (const U *a, int len)
00171 {
00172 T *retval = new T [len];
00173
00174 for (int i = 0; i < len; i++)
00175 retval[i] = T (a[i]);
00176
00177 return retval;
00178 }
00179
00180 public:
00181
00182 Array (void)
00183 : rep (nil_rep ()), dimensions (),
00184 idx (0), idx_count (0) { rep->count++; }
00185
00186 explicit Array (int n)
00187 : rep (new typename Array<T>::ArrayRep (n)), dimensions (n),
00188 idx (0), idx_count (0) { }
00189
00190 explicit Array (int n, const T& val)
00191 : rep (new typename Array<T>::ArrayRep (n)), dimensions (n),
00192 idx (0), idx_count (0)
00193 {
00194 fill (val);
00195 }
00196
00197
00198 template <class U>
00199 Array (const Array<U>& a)
00200 : rep (new typename Array<T>::ArrayRep (coerce (a.data (), a.length ()), a.length ())),
00201 dimensions (a.dimensions), idx (0), idx_count (0)
00202 {
00203 }
00204
00205
00206 Array (const Array<T>& a)
00207 : rep (a.rep), dimensions (a.dimensions), idx (0), idx_count (0)
00208 {
00209 rep->count++;
00210 }
00211
00212 public:
00213
00214 Array (const dim_vector& dv)
00215 : rep (new typename Array<T>::ArrayRep (get_size (dv))),
00216 dimensions (dv), idx (0), idx_count (0) { }
00217
00218 Array (const dim_vector& dv, const T& val)
00219 : rep (new typename Array<T>::ArrayRep (get_size (dv))),
00220 dimensions (dv), idx (0), idx_count (0)
00221 {
00222 fill (val);
00223 }
00224
00225 Array (const Array<T>& a, const dim_vector& dv);
00226
00227 virtual ~Array (void);
00228
00229 Array<T>& operator = (const Array<T>& a)
00230 {
00231 if (this != &a)
00232 {
00233 if (--rep->count <= 0)
00234 delete rep;
00235
00236 rep = a.rep;
00237 rep->count++;
00238
00239 dimensions = a.dimensions;
00240 }
00241
00242 idx_count = 0;
00243 idx = 0;
00244
00245 return *this;
00246 }
00247
00248 void fill (const T& val) { make_unique (val); }
00249
00250 int capacity (void) const { return rep->length (); }
00251 int length (void) const { return capacity (); }
00252 int nelem (void) const { return capacity (); }
00253 int numel (void) const { return nelem (); }
00254
00255 int dim1 (void) const { return dimensions(0); }
00256 int dim2 (void) const { return dimensions(1); }
00257 int dim3 (void) const { return dimensions(2); }
00258
00259 int rows (void) const { return dim1 (); }
00260 int cols (void) const { return dim2 (); }
00261 int columns (void) const { return dim2 (); }
00262 int pages (void) const { return dim3 (); }
00263
00264 size_t byte_size (void) const { return numel () * sizeof (T); }
00265
00266 dim_vector dims (void) const { return dimensions; }
00267
00268 Array<T> squeeze (void) const;
00269
00270 void chop_trailing_singletons (void)
00271 { dimensions.chop_trailing_singletons (); }
00272
00273 static int get_size (int r, int c);
00274 static int get_size (int r, int c, int p);
00275 static int get_size (const dim_vector& dv);
00276
00277 int compute_index (const Array<int>& ra_idx) const;
00278
00279 T range_error (const char *fcn, int n) const;
00280 T& range_error (const char *fcn, int n);
00281
00282 T range_error (const char *fcn, int i, int j) const;
00283 T& range_error (const char *fcn, int i, int j);
00284
00285 T range_error (const char *fcn, int i, int j, int k) const;
00286 T& range_error (const char *fcn, int i, int j, int k);
00287
00288 T range_error (const char *fcn, const Array<int>& ra_idx) const;
00289 T& range_error (const char *fcn, const Array<int>& ra_idx);
00290
00291
00292
00293 T& xelem (int n) { return rep->elem (n); }
00294 T xelem (int n) const { return rep->elem (n); }
00295
00296 T& xelem (int i, int j) { return xelem (dim1()*j+i); }
00297 T xelem (int i, int j) const { return xelem (dim1()*j+i); }
00298
00299 T& xelem (int i, int j, int k) { return xelem (i, dim2()*k+j); }
00300 T xelem (int i, int j, int k) const { return xelem (i, dim2()*k+j); }
00301
00302 T& xelem (const Array<int>& ra_idx)
00303 { return xelem (compute_index (ra_idx)); }
00304
00305 T xelem (const Array<int>& ra_idx) const
00306 { return xelem (compute_index (ra_idx)); }
00307
00308
00309
00310
00311
00312 T& checkelem (int n)
00313 {
00314 if (n < 0 || n >= rep->length ())
00315 return range_error ("T& Array<T>::checkelem", n);
00316 else
00317 {
00318 make_unique ();
00319 return xelem (n);
00320 }
00321 }
00322
00323 T& checkelem (int i, int j)
00324 {
00325 if (i < 0 || j < 0 || i >= dim1 () || j >= dim2 ())
00326 return range_error ("T& Array<T>::checkelem", i, j);
00327 else
00328 return elem (dim1()*j+i);
00329 }
00330
00331 T& checkelem (int i, int j, int k)
00332 {
00333 if (i < 0 || j < 0 || k < 0 || i >= dim1 () || j >= dim2 () || k >= dim3 ())
00334 return range_error ("T& Array<T>::checkelem", i, j, k);
00335 else
00336 return elem (i, dim2()*k+j);
00337 }
00338
00339 T& checkelem (const Array<int>& ra_idx)
00340 {
00341 int i = compute_index (ra_idx);
00342
00343 if (i < 0)
00344 return range_error ("T& Array<T>::checkelem", ra_idx);
00345 else
00346 return elem (i);
00347 }
00348
00349 T& elem (int n)
00350 {
00351 make_unique ();
00352 return xelem (n);
00353 }
00354
00355 T& elem (int i, int j) { return elem (dim1()*j+i); }
00356
00357 T& elem (int i, int j, int k) { return elem (i, dim2()*k+j); }
00358
00359 T& elem (const Array<int>& ra_idx)
00360 { return Array<T>::elem (compute_index (ra_idx)); }
00361
00362 #if defined (BOUNDS_CHECKING)
00363 T& operator () (int n) { return checkelem (n); }
00364 T& operator () (int i, int j) { return checkelem (i, j); }
00365 T& operator () (int i, int j, int k) { return checkelem (i, j, k); }
00366 T& operator () (const Array<int>& ra_idx) { return checkelem (ra_idx); }
00367 #else
00368 T& operator () (int n) { return elem (n); }
00369 T& operator () (int i, int j) { return elem (i, j); }
00370 T& operator () (int i, int j, int k) { return elem (i, j, k); }
00371 T& operator () (const Array<int>& ra_idx) { return elem (ra_idx); }
00372 #endif
00373
00374 T checkelem (int n) const
00375 {
00376 if (n < 0 || n >= rep->length ())
00377 return range_error ("T Array<T>::checkelem", n);
00378 else
00379 return xelem (n);
00380 }
00381
00382 T checkelem (int i, int j) const
00383 {
00384 if (i < 0 || j < 0 || i >= dim1 () || j >= dim2 ())
00385 return range_error ("T Array<T>::checkelem", i, j);
00386 else
00387 return elem (dim1()*j+i);
00388 }
00389
00390 T checkelem (int i, int j, int k) const
00391 {
00392 if (i < 0 || j < 0 || k < 0 || i >= dim1 () || j >= dim2 () || k >= dim3 ())
00393 return range_error ("T Array<T>::checkelem", i, j, k);
00394 else
00395 return Array<T>::elem (i, Array<T>::dim1()*k+j);
00396 }
00397
00398 T checkelem (const Array<int>& ra_idx) const
00399 {
00400 int i = compute_index (ra_idx);
00401
00402 if (i < 0)
00403 return range_error ("T Array<T>::checkelem", ra_idx);
00404 else
00405 return Array<T>::elem (i);
00406 }
00407
00408 T elem (int n) const { return xelem (n); }
00409
00410 T elem (int i, int j) const { return elem (dim1()*j+i); }
00411
00412 T elem (int i, int j, int k) const { return elem (i, dim2()*k+j); }
00413
00414 T elem (const Array<int>& ra_idx) const
00415 { return Array<T>::elem (compute_index (ra_idx)); }
00416
00417 #if defined (BOUNDS_CHECKING)
00418 T operator () (int n) const { return checkelem (n); }
00419 T operator () (int i, int j) const { return checkelem (i, j); }
00420 T operator () (int i, int j, int k) const { return checkelem (i, j, k); }
00421 T operator () (const Array<int>& ra_idx) const { return checkelem (ra_idx); }
00422 #else
00423 T operator () (int n) const { return elem (n); }
00424 T operator () (int i, int j) const { return elem (i, j); }
00425 T operator () (int i, int j, int k) const { return elem (i, j, k); }
00426 T operator () (const Array<int>& ra_idx) const { return elem (ra_idx); }
00427 #endif
00428
00429 Array<T> reshape (const dim_vector& new_dims) const;
00430
00431 Array<T> permute (const Array<int>& vec, bool inv = false) const;
00432 Array<T> ipermute (const Array<int>& vec) const
00433 { return permute (vec, true); }
00434
00435 void resize_no_fill (int n);
00436 void resize_and_fill (int n, const T& val);
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446 void resize_no_fill (int r, int c);
00447 void resize_and_fill (int r, int c, const T& val);
00448
00449 void resize_no_fill (int r, int c, int p);
00450 void resize_and_fill (int r, int c, int p, const T& val);
00451
00452 void resize_no_fill (const dim_vector& dv);
00453 void resize_and_fill (const dim_vector& dv, const T& val);
00454
00455 public:
00456
00457 void resize (int n) { resize_no_fill (n); }
00458
00459 void resize (int n, const T& val) { resize_and_fill (n, val); }
00460
00461 void resize (const dim_vector& dv) { resize_no_fill (dv); }
00462
00463 void resize (const dim_vector& dv, const T& val)
00464 { resize_and_fill (dv, val); }
00465
00466 Array<T>& insert (const Array<T>& a, int r, int c);
00467 Array<T>& insert2 (const Array<T>& a, int r, int c);
00468 Array<T>& insertN (const Array<T>& a, int r, int c);
00469
00470 Array<T>& insert (const Array<T>& a, const Array<int>& idx);
00471
00472 bool is_square (void) const { return (dim1 () == dim2 ()); }
00473
00474 bool is_empty (void) const { return numel () == 0; }
00475
00476 Array<T> transpose (void) const;
00477
00478 const T *data (void) const { return rep->data; }
00479
00480 const T *fortran_vec (void) const { return data (); }
00481
00482 T *fortran_vec (void);
00483
00484 Array<T>& qsort (int (*compare) (const void *, const void *))
00485 {
00486 make_unique ();
00487
00488 rep->qsort (compare);
00489
00490 return *this;
00491 }
00492
00493 int ndims (void) const { return dimensions.length (); }
00494
00495 void maybe_delete_dims (void);
00496
00497 void clear_index (void);
00498
00499 void set_index (const idx_vector& i);
00500
00501 int index_count (void) const { return idx_count; }
00502
00503 idx_vector *get_idx (void) const { return idx; }
00504
00505 void maybe_delete_elements (idx_vector& i);
00506
00507 void maybe_delete_elements_1 (idx_vector& i);
00508
00509 void maybe_delete_elements_2 (idx_vector& i);
00510
00511 void maybe_delete_elements (idx_vector& i, idx_vector& j);
00512
00513 void maybe_delete_elements (idx_vector& i, idx_vector& j, idx_vector& k);
00514
00515 void maybe_delete_elements (Array<idx_vector>& ra_idx, const T& rfv);
00516
00517 Array<T> value (void);
00518
00519 Array<T> index (idx_vector& i, int resize_ok = 0,
00520 const T& rfv = resize_fill_value (T ())) const;
00521
00522 Array<T> index1 (idx_vector& i, int resize_ok = 0,
00523 const T& rfv = resize_fill_value (T ())) const;
00524
00525 Array<T> index2 (idx_vector& i, int resize_ok = 0,
00526 const T& rfv = resize_fill_value (T ())) const;
00527
00528 Array<T> indexN (idx_vector& i, int resize_ok = 0,
00529 const T& rfv = resize_fill_value (T ())) const;
00530
00531 Array<T> index (idx_vector& i, idx_vector& j, int resize_ok = 0,
00532 const T& rfv = resize_fill_value (T ())) const;
00533
00534 Array<T> index (Array<idx_vector>& ra_idx, int resize_ok = 0,
00535 const T& rfv = resize_fill_value (T ())) const;
00536
00537
00538
00539 void print_info (std::ostream& os, const std::string& prefix) const;
00540 };
00541
00542
00543
00544
00545
00546 template <class LT, class RT>
00547 int
00548 assign (Array<LT>& lhs, const Array<RT>& rhs, const LT& rfv);
00549
00550 template <class LT, class RT>
00551 int
00552 assign1 (Array<LT>& lhs, const Array<RT>& rhs, const LT& rfv);
00553
00554 template <class LT, class RT>
00555 int
00556 assign2 (Array<LT>& lhs, const Array<RT>& rhs, const LT& rfv);
00557
00558 template <class LT, class RT>
00559 int
00560 assignN (Array<LT>& lhs, const Array<RT>& rhs, const LT& rfv);
00561
00562 template <class LT, class RT>
00563 int
00564 assign (Array<LT>& lhs, const Array<RT>& rhs)
00565 {
00566 return assign (lhs, rhs, resize_fill_value (LT ()));
00567 }
00568
00569 #define INSTANTIATE_ARRAY_ASSIGN(LT, RT) \
00570 template int assign (Array<LT>&, const Array<RT>&, const LT&); \
00571 template int assign1 (Array<LT>&, const Array<RT>&, const LT&); \
00572 template int assign2 (Array<LT>&, const Array<RT>&, const LT&); \
00573 template int assignN (Array<LT>&, const Array<RT>&, const LT&); \
00574 template int assign (Array<LT>&, const Array<RT>&)
00575
00576
00577 #define INSTANTIATE_ARRAY(T) \
00578 template class Array<T>; \
00579 template T resize_fill_value (const T&); \
00580
00581 #define INSTANTIATE_ARRAY_AND_ASSIGN(T) \
00582 INSTANTIATE_ARRAY (T); \
00583 INSTANTIATE_ARRAY_ASSIGN (T, T)
00584
00585 #endif
00586
00587
00588
00589
00590
00591