00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #if !defined (octave_dim_vector_h)
00024 #define octave_dim_vector_h 1
00025
00026 #if defined (__GNUG__) && defined (USE_PRAGMA_INTERFACE_IMPLEMENTATION)
00027 #pragma interface
00028 #endif
00029
00030 #include <cassert>
00031 #include <string>
00032
00033 #include "lo-sstream.h"
00034
00035 class
00036 dim_vector
00037 {
00038 protected:
00039
00040 class dim_vector_rep
00041 {
00042 public:
00043
00044 int *dims;
00045 int ndims;
00046 int count;
00047
00048 dim_vector_rep (void) : dims (0), ndims (0), count (1) { }
00049
00050 dim_vector_rep (int n) : dims (new int [1]), ndims (1), count (1)
00051 {
00052 dims[0] = n;
00053 }
00054
00055 dim_vector_rep (int r, int c) : dims (new int [2]), ndims (2), count (1)
00056 {
00057 dims[0] = r;
00058 dims[1] = c;
00059 }
00060
00061 dim_vector_rep (int r, int c, int p)
00062 : dims (new int [3]), ndims (3), count (1)
00063 {
00064 dims[0] = r;
00065 dims[1] = c;
00066 dims[2] = p;
00067 }
00068
00069 dim_vector_rep (const dim_vector_rep& dv)
00070 : dims (dv.ndims > 0 ? new int [dv.ndims] : 0),
00071 ndims (dv.ndims > 0 ? dv.ndims : 0), count (1)
00072 {
00073 if (dims)
00074 {
00075 for (int i = 0; i < ndims; i++)
00076 dims[i] = dv.dims[i];
00077 }
00078 }
00079
00080 dim_vector_rep (int n, const dim_vector_rep *dv, int fill_value = 0)
00081 : dims ((dv && n > 0) ? new int [n] : 0),
00082 ndims (n > 0 ? n : 0), count (1)
00083 {
00084 if (dims)
00085 {
00086 int dv_ndims = dv ? dv->ndims : 0;
00087
00088 int min_len = n < dv_ndims ? n : dv_ndims;
00089
00090 for (int i = 0; i < min_len; i++)
00091 dims[i] = dv->dims[i];
00092
00093 for (int i = dv_ndims; i < n; i++)
00094 dims[i] = fill_value;
00095 }
00096 }
00097
00098 ~dim_vector_rep (void) { delete [] dims; }
00099
00100 int length (void) const { return ndims; }
00101
00102 int& elem (int i)
00103 {
00104 assert (i >= 0 && i < ndims);
00105 return dims[i];
00106 }
00107
00108 int elem (int i) const
00109 {
00110 assert (i >= 0 && i < ndims);
00111 return dims[i];
00112 }
00113
00114 void chop_trailing_singletons (void)
00115 {
00116 for (int i = ndims - 1; i > 1; i--)
00117 {
00118 if (dims[i] == 1)
00119 ndims--;
00120 else
00121 break;
00122 }
00123 }
00124
00125 private:
00126
00127
00128
00129 dim_vector_rep& operator = (const dim_vector_rep& dv);
00130 };
00131
00132 dim_vector_rep *rep;
00133
00134 void make_unique (void)
00135 {
00136 if (rep->count > 1)
00137 {
00138 --rep->count;
00139 rep = new dim_vector_rep (*rep);
00140 }
00141 }
00142
00143 private:
00144
00145 dim_vector_rep *nil_rep (void) const
00146 {
00147 static dim_vector_rep *nr = new dim_vector_rep ();
00148
00149 return nr;
00150 }
00151
00152 public:
00153
00154 explicit dim_vector (void)
00155 : rep (nil_rep ()) { rep->count++; }
00156
00157 explicit dim_vector (int n)
00158 : rep (new dim_vector_rep (n)) { }
00159
00160 explicit dim_vector (int r, int c)
00161 : rep (new dim_vector_rep (r, c)) { }
00162
00163 explicit dim_vector (int r, int c, int p)
00164 : rep (new dim_vector_rep (r, c, p)) { }
00165
00166 dim_vector (const dim_vector& dv)
00167 : rep (dv.rep) { rep->count++; }
00168
00169 dim_vector& operator = (const dim_vector& dv)
00170 {
00171 if (&dv != this)
00172 {
00173 if (--rep->count <= 0)
00174 delete rep;
00175
00176 rep = dv.rep;
00177 rep->count++;
00178 }
00179
00180 return *this;
00181 }
00182
00183 ~dim_vector (void)
00184 {
00185 if (--rep->count <= 0)
00186 delete rep;
00187 }
00188
00189 int length (void) const { return rep->length (); }
00190
00191 int& elem (int i) { make_unique (); return rep->elem (i); }
00192
00193 int elem (int i) const { return rep->elem (i); }
00194
00195 int& operator () (int i) { return elem (i); }
00196
00197 int operator () (int i) const { return elem (i); }
00198
00199 void resize (int n, int fill_value = 0)
00200 {
00201 int len = length ();
00202
00203 if (n != len)
00204 {
00205 dim_vector_rep *old_rep = rep;
00206
00207 rep = new dim_vector_rep (n, old_rep, fill_value);
00208
00209 if (--old_rep->count <= 0)
00210 delete old_rep;
00211 }
00212 }
00213
00214 std::string str (char sep = 'x') const
00215 {
00216 OSSTREAM buf;
00217
00218 for (int i = 0; i < length (); i++)
00219 {
00220 buf << elem (i);
00221
00222 if (i < length () - 1)
00223 buf << sep;
00224 }
00225
00226 buf << OSSTREAM_ENDS;
00227
00228 std::string retval = OSSTREAM_STR (buf);
00229
00230 OSSTREAM_FREEZE (buf);
00231
00232 return retval;
00233 }
00234
00235 bool all_zero (void) const
00236 {
00237 bool retval = true;
00238
00239 for (int i = 0; i < length (); i++)
00240 {
00241 if (elem (i) != 0)
00242 {
00243 retval = false;
00244 break;
00245 }
00246 }
00247
00248 return retval;
00249 }
00250
00251 bool any_zero (void) const
00252 {
00253 bool retval = false;
00254
00255 for (int i = 0; i < length (); i++)
00256 {
00257 if (elem (i) == 0)
00258 {
00259 retval = true;
00260 break;
00261 }
00262 }
00263
00264 return retval;
00265 }
00266
00267 int
00268 num_ones (void) const
00269 {
00270 int retval = 0;
00271
00272 for (int i = 0; i < length (); i++)
00273 if (elem (i) == 1)
00274 retval++;
00275
00276 return retval;
00277 }
00278
00279 bool
00280 all_ones (void) const
00281 {
00282 return (num_ones () == length ());
00283 }
00284
00285
00286
00287
00288
00289 int numel (void) const
00290 {
00291 int n_dims = length ();
00292
00293 int retval = n_dims > 0 ? elem (0) : 0;
00294
00295 for (int i = 1; i < n_dims; i++)
00296 retval *= elem (i);
00297
00298 return retval;
00299 }
00300
00301 void chop_trailing_singletons (void)
00302 {
00303 make_unique ();
00304 rep->chop_trailing_singletons ();
00305 }
00306
00307 dim_vector squeeze (void) const
00308 {
00309 dim_vector new_dims = *this;
00310
00311 bool dims_changed = 1;
00312
00313 int k = 0;
00314
00315 for (int i = 0; i < length (); i++)
00316 {
00317 if (elem (i) == 1)
00318 dims_changed = true;
00319 else
00320 new_dims(k++) = elem (i);
00321 }
00322
00323 if (dims_changed)
00324 {
00325 if (k == 0)
00326 new_dims = dim_vector (1, 1);
00327 else if (k == 1)
00328 {
00329
00330
00331
00332 if (elem (0) == 1)
00333 {
00334
00335
00336
00337 int tmp = new_dims(0);
00338
00339 new_dims.resize (2);
00340
00341 new_dims(0) = 1;
00342 new_dims(1) = tmp;
00343 }
00344 else
00345 {
00346
00347
00348
00349 new_dims.resize (2);
00350
00351 new_dims(1) = 1;
00352 }
00353 }
00354 else
00355 new_dims.resize(k);
00356 }
00357
00358 return new_dims;
00359 }
00360
00361 bool concat (const dim_vector& dvb, int dim = 0)
00362 {
00363 if (all_zero ())
00364 {
00365 *this = dvb;
00366 return true;
00367 }
00368
00369 if (dvb.all_zero ())
00370 return true;
00371
00372 int na = length ();
00373 int nb = dvb.length ();
00374
00375
00376 int n_max = na > nb ? na : nb;
00377 int n_min = na < nb ? na : nb;
00378
00379
00380
00381
00382
00383 for (int i = 0; i < n_min; i++)
00384 {
00385 if (elem(i) != dvb(i) && dim != i)
00386 return false;
00387 }
00388
00389
00390 for (int i = n_min; i < n_max; i++)
00391 {
00392 if (na > n_min)
00393 {
00394 if (elem(i) != 1 && dim != i)
00395 return false;
00396 }
00397 else
00398 {
00399 if (dvb(i) != 1 && dim != i)
00400 return false;
00401 }
00402 }
00403
00404
00405
00406
00407
00408 n_max = n_max > (dim + 1) ? n_max : (dim + 1);
00409
00410
00411
00412 if (n_max > na)
00413 {
00414 dim_vector_rep *old_rep = rep;
00415
00416 rep = new dim_vector_rep (n_max, old_rep, 1);
00417
00418 if (--old_rep->count <= 0)
00419 delete old_rep;
00420 }
00421
00422
00423
00424 if (dim >= nb)
00425 elem (dim)++;
00426 else
00427 elem (dim) += dvb(dim);
00428
00429 return true;
00430 }
00431 };
00432
00433 static inline bool
00434 operator == (const dim_vector& a, const dim_vector& b)
00435 {
00436 bool retval = true;
00437
00438 int a_len = a.length ();
00439 int b_len = b.length ();
00440
00441 if (a_len != b_len)
00442 retval = false;
00443 else
00444 {
00445 for (int i = 0; i < a_len; i++)
00446 {
00447 if (a(i) != b(i))
00448 {
00449 retval = false;
00450 break;
00451 }
00452 }
00453 }
00454
00455 return retval;
00456 }
00457
00458 static inline bool
00459 operator != (const dim_vector& a, const dim_vector& b)
00460 {
00461 return ! operator == (a, b);
00462 }
00463
00464 #endif
00465
00466
00467
00468
00469
00470