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 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027
00028 #include <iostream>
00029
00030 #include "dim-vector.h"
00031
00032
00033
00034
00035
00036 octave_idx_type
00037 dim_vector::dim_max (void)
00038 {
00039 return std::numeric_limits<octave_idx_type>::max () - 1;
00040 }
00041
00042 void
00043 dim_vector::chop_all_singletons (void)
00044 {
00045 make_unique ();
00046
00047 int j = 0;
00048 int l = ndims();
00049
00050 for (int i = 0; i < l; i++)
00051 {
00052 if (rep[i] != 1)
00053 rep[j++] = rep[i];
00054 }
00055
00056 if (j == 1)
00057 rep[1] = 1;
00058
00059 ndims () = j > 2 ? j : 2;
00060 }
00061
00062 std::string
00063 dim_vector::str (char sep) const
00064 {
00065 std::ostringstream buf;
00066
00067 for (int i = 0; i < length (); i++)
00068 {
00069 buf << elem (i);
00070
00071 if (i < length () - 1)
00072 buf << sep;
00073 }
00074
00075 std::string retval = buf.str ();
00076
00077 return retval;
00078 }
00079
00080 int
00081 dim_vector::num_ones (void) const
00082 {
00083 int retval = 0;
00084
00085 for (int i = 0; i < length (); i++)
00086 if (elem (i) == 1)
00087 retval++;
00088
00089 return retval;
00090 }
00091
00092 octave_idx_type
00093 dim_vector::safe_numel (void) const
00094 {
00095 octave_idx_type idx_max = dim_max ();
00096 octave_idx_type n = 1;
00097 int n_dims = length ();
00098
00099 for (int i = 0; i < n_dims; i++)
00100 {
00101 n *= rep[i];
00102 if (rep[i] != 0)
00103 idx_max /= rep[i];
00104 if (idx_max <= 0)
00105 throw std::bad_alloc ();
00106 }
00107
00108 return n;
00109 }
00110
00111 dim_vector
00112 dim_vector::squeeze (void) const
00113 {
00114 dim_vector new_dims = *this;
00115
00116 bool dims_changed = 1;
00117
00118 int k = 0;
00119
00120 for (int i = 0; i < length (); i++)
00121 {
00122 if (elem (i) == 1)
00123 dims_changed = true;
00124 else
00125 new_dims(k++) = elem (i);
00126 }
00127
00128 if (dims_changed)
00129 {
00130 if (k == 0)
00131 new_dims = dim_vector (1, 1);
00132 else if (k == 1)
00133 {
00134
00135
00136
00137 if (elem (0) == 1)
00138 {
00139
00140
00141
00142 octave_idx_type tmp = new_dims(0);
00143
00144 new_dims.resize (2);
00145
00146 new_dims(0) = 1;
00147 new_dims(1) = tmp;
00148 }
00149 else
00150 {
00151
00152
00153
00154 new_dims.resize (2);
00155
00156 new_dims(1) = 1;
00157 }
00158 }
00159 else
00160 new_dims.resize(k);
00161 }
00162
00163 return new_dims;
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 bool
00177 dim_vector::concat (const dim_vector& dvb, int dim)
00178 {
00179 int orig_nd = ndims (), ndb = dvb.ndims ();
00180 int new_nd = dim < ndb ? ndb : dim + 1;
00181 if (new_nd > orig_nd)
00182 resize (new_nd, 1);
00183 else
00184 new_nd = orig_nd;
00185
00186 make_unique ();
00187
00188 bool match = true;
00189
00190 for (int i = 0; i < ndb; i++)
00191 {
00192 if (i != dim && rep[i] != dvb(i))
00193 {
00194 match = false;
00195 break;
00196 }
00197 }
00198
00199 for (int i = ndb; i < new_nd; i++)
00200 {
00201 if (i != dim && rep[i] != 1)
00202 {
00203 match = false;
00204 break;
00205 }
00206 }
00207
00208 if (match)
00209 rep[dim] += (dim < ndb ? dvb(dim) : 1);
00210 else
00211 {
00212
00213
00214 if (ndb == 2 && dvb(0) == 0 && dvb(1) == 0)
00215 match = true;
00216 else if (orig_nd == 2 && rep[0] == 0 && rep[1] == 0)
00217 {
00218 *this = dvb;
00219 match = true;
00220 }
00221 }
00222
00223 chop_trailing_singletons ();
00224
00225 return match;
00226 }
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 bool
00240 dim_vector::hvcat (const dim_vector& dvb, int dim)
00241 {
00242 if (concat (dvb, dim))
00243 return true;
00244 else if (length () == 2 && dvb.length () == 2)
00245 {
00246 bool e2dv = rep[0] + rep[1] == 1;
00247 bool e2dvb = dvb(0) + dvb(1) == 1;
00248 if (e2dvb)
00249 {
00250 if (e2dv)
00251 *this = dim_vector ();
00252 return true;
00253 }
00254 else if (e2dv)
00255 {
00256 *this = dvb;
00257 return true;
00258 }
00259 }
00260
00261 return false;
00262 }
00263
00264 dim_vector
00265 dim_vector::redim (int n) const
00266 {
00267 int n_dims = length ();
00268
00269 if (n_dims == n)
00270 return *this;
00271 else if (n_dims < n)
00272 {
00273 dim_vector retval = alloc (n);
00274
00275 for (int i = 0; i < n_dims; i++)
00276 retval.rep[i] = rep[i];
00277
00278 for (int i = n_dims; i < n; i++)
00279 retval.rep[i] = 1;
00280
00281 return retval;
00282 }
00283 else
00284 {
00285 if (n < 1) n = 1;
00286
00287 dim_vector retval = alloc (n);
00288
00289 retval.rep[1] = 1;
00290
00291 for (int i = 0; i < n-1; i++)
00292 retval.rep[i] = rep[i];
00293
00294 int k = rep[n-1];
00295 for (int i = n; i < n_dims; i++)
00296 k *= rep[i];
00297
00298 retval.rep[n-1] = k;
00299
00300 return retval;
00301 }
00302 }