Go to the documentation of this file.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_dim_vector_h)
00025 #define octave_dim_vector_h 1
00026
00027 #include <cassert>
00028 #include <limits>
00029
00030 #include <sstream>
00031 #include <string>
00032
00033 #include "lo-error.h"
00034 #include "lo-macros.h"
00035 #include "oct-refcount.h"
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 class
00054 OCTAVE_API
00055 dim_vector
00056 {
00057 private:
00058
00059 octave_idx_type *rep;
00060
00061 octave_idx_type& ndims (void) const { return rep[-1]; }
00062
00063 octave_idx_type& count (void) const { return rep[-2]; }
00064
00065
00066
00067 static octave_idx_type *newrep (int ndims)
00068 {
00069 octave_idx_type *r = new octave_idx_type[ndims + 2];
00070
00071 *r++ = 1;
00072 *r++ = ndims;
00073
00074 return r;
00075 }
00076
00077
00078
00079 octave_idx_type *clonerep (void)
00080 {
00081 int l = ndims ();
00082
00083 octave_idx_type *r = new octave_idx_type[l + 2];
00084
00085 *r++ = 1;
00086 *r++ = l;
00087
00088 for (int i = 0; i < l; i++)
00089 r[i] = rep[i];
00090
00091 return r;
00092 }
00093
00094
00095
00096 octave_idx_type *resizerep (int n, octave_idx_type fill_value)
00097 {
00098 int l = ndims ();
00099
00100 if (n < 2)
00101 n = 2;
00102
00103 octave_idx_type *r = new octave_idx_type[n + 2];
00104
00105 *r++ = 1;
00106 *r++ = n;
00107
00108 if (l > n)
00109 l = n;
00110
00111 int j;
00112 for (j = 0; j < l; j++)
00113 r[j] = rep[j];
00114 for (; j < n; j++)
00115 r[j] = fill_value;
00116
00117 return r;
00118 }
00119
00120
00121
00122 void freerep (void)
00123 {
00124 assert (count () == 0);
00125 delete [] (rep - 2);
00126 }
00127
00128 void make_unique (void)
00129 {
00130 if (count () > 1)
00131 {
00132 octave_idx_type *new_rep = clonerep ();
00133
00134 if (OCTREFCOUNT_ATOMIC_DECREMENT(&(count())) == 0)
00135 freerep ();
00136
00137 rep = new_rep;
00138 }
00139 }
00140
00141 public:
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 explicit dim_vector (octave_idx_type n) GCC_ATTR_DEPRECATED
00158 : rep (newrep (2))
00159 {
00160 rep[0] = n;
00161 rep[1] = 1;
00162 }
00163
00164 #define ASSIGN_REP(i) rep[i] = d ## i;
00165 #define DIM_VECTOR_CTOR(N) \
00166 dim_vector (OCT_MAKE_DECL_LIST (octave_idx_type, d, N)) \
00167 : rep (newrep (N)) \
00168 { \
00169 OCT_ITERATE_MACRO (ASSIGN_REP, N) \
00170 }
00171
00172
00173 DIM_VECTOR_CTOR (2)
00174 DIM_VECTOR_CTOR (3)
00175 DIM_VECTOR_CTOR (4)
00176 DIM_VECTOR_CTOR (5)
00177 DIM_VECTOR_CTOR (6)
00178 DIM_VECTOR_CTOR (7)
00179
00180 #undef ASSIGN_REP
00181 #undef DIM_VECTOR_CTOR
00182
00183 octave_idx_type& elem (int i)
00184 {
00185 #ifdef BOUNDS_CHECKING
00186 assert (i >= 0 && i < ndims ());
00187 #endif
00188 make_unique ();
00189 return rep[i];
00190 }
00191
00192 octave_idx_type elem (int i) const
00193 {
00194 #ifdef BOUNDS_CHECKING
00195 assert (i >= 0 && i < ndims ());
00196 #endif
00197 return rep[i];
00198 }
00199
00200 void chop_trailing_singletons (void)
00201 {
00202 int l = ndims ();
00203 if (l > 2 && rep[l-1] == 1)
00204 {
00205 make_unique ();
00206 do
00207 l--;
00208 while (l > 2 && rep[l-1] == 1);
00209 ndims () = l;
00210 }
00211 }
00212
00213 void chop_all_singletons (void);
00214
00215 private:
00216
00217 static octave_idx_type *nil_rep (void)
00218 {
00219 static dim_vector zv (0, 0);
00220 return zv.rep;
00221 }
00222
00223 explicit dim_vector (octave_idx_type *r)
00224 : rep (r) { }
00225
00226 public:
00227
00228 static octave_idx_type dim_max (void);
00229
00230 explicit dim_vector (void) : rep (nil_rep ())
00231 { OCTREFCOUNT_ATOMIC_INCREMENT (&(count())); }
00232
00233 dim_vector (const dim_vector& dv) : rep (dv.rep)
00234 { OCTREFCOUNT_ATOMIC_INCREMENT (&(count())); }
00235
00236 static dim_vector alloc (int n)
00237 {
00238 return dim_vector (newrep (n < 2 ? 2 : n));
00239 }
00240
00241 dim_vector& operator = (const dim_vector& dv)
00242 {
00243 if (&dv != this)
00244 {
00245 if (OCTREFCOUNT_ATOMIC_DECREMENT (&(count())) == 0)
00246 freerep ();
00247
00248 rep = dv.rep;
00249 OCTREFCOUNT_ATOMIC_INCREMENT (&(count()));
00250 }
00251
00252 return *this;
00253 }
00254
00255 ~dim_vector (void)
00256 {
00257 if (OCTREFCOUNT_ATOMIC_DECREMENT (&(count())) == 0)
00258 freerep ();
00259 }
00260
00261 int length (void) const { return ndims (); }
00262
00263 octave_idx_type& operator () (int i) { return elem (i); }
00264
00265 octave_idx_type operator () (int i) const { return elem (i); }
00266
00267 void resize (int n, int fill_value = 0)
00268 {
00269 int len = length ();
00270
00271 if (n != len)
00272 {
00273 octave_idx_type *r = resizerep (n, fill_value);
00274
00275 if (OCTREFCOUNT_ATOMIC_DECREMENT (&(count())) == 0)
00276 freerep ();
00277
00278 rep = r;
00279 }
00280 }
00281
00282 std::string str (char sep = 'x') const;
00283
00284 bool all_zero (void) const
00285 {
00286 bool retval = true;
00287
00288 for (int i = 0; i < length (); i++)
00289 {
00290 if (elem (i) != 0)
00291 {
00292 retval = false;
00293 break;
00294 }
00295 }
00296
00297 return retval;
00298 }
00299
00300 bool empty_2d (void) const
00301 {
00302 return length () == 2 && (elem (0) == 0 || elem (1) == 0);
00303 }
00304
00305
00306 bool zero_by_zero (void) const
00307 {
00308 return length () == 2 && elem (0) == 0 && elem (1) == 0;
00309 }
00310
00311 bool any_zero (void) const
00312 {
00313 bool retval = false;
00314
00315 for (int i = 0; i < length (); i++)
00316 {
00317 if (elem (i) == 0)
00318 {
00319 retval = true;
00320 break;
00321 }
00322 }
00323
00324 return retval;
00325 }
00326
00327 int num_ones (void) const;
00328
00329 bool all_ones (void) const
00330 {
00331 return (num_ones () == length ());
00332 }
00333
00334
00335
00336
00337
00338 octave_idx_type numel (int n = 0) const
00339 {
00340 int n_dims = length ();
00341
00342 octave_idx_type retval = 1;
00343
00344 for (int i = n; i < n_dims; i++)
00345 retval *= elem (i);
00346
00347 return retval;
00348 }
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 octave_idx_type safe_numel (void) const;
00359
00360 bool any_neg (void) const
00361 {
00362 int n_dims = length ();
00363 int i;
00364
00365 for (i = 0; i < n_dims; i++)
00366 if (elem (i) < 0)
00367 break;
00368
00369 return i < n_dims;
00370 }
00371
00372 dim_vector squeeze (void) const;
00373
00374
00375 bool concat (const dim_vector& dvb, int dim);
00376
00377
00378
00379 bool hvcat (const dim_vector& dvb, int dim);
00380
00381
00382
00383
00384
00385
00386 dim_vector redim (int n) const;
00387
00388 dim_vector as_column (void) const
00389 {
00390 if (length () == 2 && elem (1) == 1)
00391 return *this;
00392 else
00393 return dim_vector (numel (), 1);
00394 }
00395
00396 dim_vector as_row (void) const
00397 {
00398 if (length () == 2 && elem (0) == 1)
00399 return *this;
00400 else
00401 return dim_vector (1, numel ());
00402 }
00403
00404 bool is_vector (void) const
00405 {
00406 return (length () == 2 && (elem (0) == 1 || elem (1) == 1));
00407 }
00408
00409 int first_non_singleton (int def = 0) const
00410 {
00411 for (int i = 0; i < length (); i++)
00412 {
00413 if (elem (i) != 1)
00414 return i;
00415 }
00416
00417 return def;
00418 }
00419
00420
00421
00422 octave_idx_type compute_index (const octave_idx_type *idx) const
00423 {
00424 octave_idx_type k = 0;
00425 for (int i = length () - 1; i >= 0; i--)
00426 k = k * rep[i] + idx[i];
00427
00428 return k;
00429 }
00430
00431
00432
00433 octave_idx_type compute_index (const octave_idx_type *idx, int nidx) const
00434 {
00435 octave_idx_type k = 0;
00436 for (int i = nidx - 1; i >= 0; i--)
00437 k = k * rep[i] + idx[i];
00438
00439 return k;
00440 }
00441
00442
00443
00444
00445
00446 int increment_index (octave_idx_type *idx, int start = 0) const
00447 {
00448 int i;
00449 for (i = start; i < length (); i++)
00450 {
00451 if (++(*idx) == rep[i])
00452 *idx++ = 0;
00453 else
00454 break;
00455 }
00456 return i;
00457 }
00458
00459
00460
00461 dim_vector cumulative (void) const
00462 {
00463 int nd = length ();
00464 dim_vector retval = alloc (nd);
00465
00466 octave_idx_type k = 1;
00467 for (int i = 0; i < nd; i++)
00468 retval.rep[i] = k *= rep[i];
00469
00470 return retval;
00471 }
00472
00473
00474
00475
00476 octave_idx_type cum_compute_index (const octave_idx_type *idx) const
00477 {
00478 octave_idx_type k = idx[0];
00479
00480 for (int i = 1; i < length (); i++)
00481 k += rep[i-1] * idx[i];
00482
00483 return k;
00484 }
00485
00486
00487 friend bool operator == (const dim_vector& a, const dim_vector& b);
00488 };
00489
00490 inline bool
00491 operator == (const dim_vector& a, const dim_vector& b)
00492 {
00493
00494 if (a.rep == b.rep)
00495 return true;
00496
00497 bool retval = true;
00498
00499 int a_len = a.length ();
00500 int b_len = b.length ();
00501
00502 if (a_len != b_len)
00503 retval = false;
00504 else
00505 {
00506 for (int i = 0; i < a_len; i++)
00507 {
00508 if (a(i) != b(i))
00509 {
00510 retval = false;
00511 break;
00512 }
00513 }
00514 }
00515
00516 return retval;
00517 }
00518
00519 inline bool
00520 operator != (const dim_vector& a, const dim_vector& b)
00521 {
00522 return ! operator == (a, b);
00523 }
00524
00525 #endif