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