00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026
00027 #include "Array-util.h"
00028 #include "dim-vector.h"
00029 #include "lo-error.h"
00030
00031 bool
00032 index_in_bounds (const Array<int>& ra_idx, const dim_vector& dimensions)
00033 {
00034 bool retval = true;
00035
00036 int n = ra_idx.length ();
00037
00038 if (n == dimensions.length ())
00039 {
00040 for (int i = 0; i < n; i++)
00041 {
00042 if (ra_idx(i) < 0 || ra_idx(i) >= dimensions(i))
00043 {
00044 retval = false;
00045 break;
00046 }
00047 }
00048 }
00049 else
00050 retval = false;
00051
00052 return retval;
00053 }
00054
00055 void
00056 increment_index (Array<int>& ra_idx, const dim_vector& dimensions,
00057 int start_dimension)
00058 {
00059 ra_idx(start_dimension)++;
00060
00061 int n = ra_idx.length () - 1;
00062
00063 for (int i = start_dimension; i < n; i++)
00064 {
00065 if (ra_idx(i) < dimensions(i))
00066 break;
00067 else
00068 {
00069 ra_idx(i) = 0;
00070 ra_idx(i+1)++;
00071 }
00072 }
00073 }
00074
00075 int
00076 get_scalar_idx (Array<int>& idx, dim_vector& dims)
00077 {
00078 int retval (-1);
00079
00080 int n = idx.length ();
00081
00082 if (n > 0)
00083 {
00084 retval = idx(--n);
00085
00086 while (--n >= 0)
00087 {
00088 retval *= dims (n);
00089
00090 retval += idx(n);
00091 }
00092 }
00093 return retval;
00094 }
00095
00096 int
00097 num_ones (const Array<int>& ra_idx)
00098 {
00099 int retval = 0;
00100
00101 for (int i = 0; i < ra_idx.length (); i++)
00102 {
00103 if (ra_idx (i) == 1)
00104 retval++;
00105 }
00106
00107 return retval;
00108 }
00109
00110 bool
00111 is_scalar (const dim_vector& dim)
00112 {
00113 bool retval = true;
00114
00115 int n = dim.length ();
00116
00117 if (n == 0)
00118 {
00119 retval = false;
00120 }
00121 else
00122 {
00123 for (int i = 0; i < n; i ++)
00124 {
00125 if (dim (i) != 1)
00126 {
00127 retval = false;
00128
00129 break;
00130 }
00131 }
00132 }
00133 return retval;
00134 }
00135
00136 bool
00137 any_ones (const Array<int>& arr)
00138 {
00139 bool retval = false;
00140
00141 for (int i = 0; i < arr.length (); i++)
00142 {
00143 if (arr (i) == 1)
00144 {
00145 retval = true;
00146
00147 break;
00148 }
00149 }
00150 return retval;
00151 }
00152
00153 int
00154 compute_index (const Array<int>& ra_idx, const dim_vector& dims)
00155 {
00156 int retval = -1;
00157
00158 int n = dims.length ();
00159
00160 if (n > 0 && n == ra_idx.length ())
00161 {
00162 retval = ra_idx(--n);
00163
00164 while (--n >= 0)
00165 {
00166 retval *= dims(n);
00167
00168 retval += ra_idx(n);
00169 }
00170 }
00171 else
00172 (*current_liboctave_error_handler)
00173 ("ArrayN<T>::compute_index: invalid ra_idxing operation");
00174
00175 return retval;
00176 }
00177
00178 Array<int>
00179 conv_to_int_array (const Array<idx_vector>& a)
00180 {
00181 Array<int> retval (a.length ());
00182
00183 for (int i = 0; i < a.length (); i++)
00184 retval (i) = a(i).elem (0);
00185
00186 return retval;
00187 }
00188
00189 Array<idx_vector>
00190 conv_to_array (const idx_vector *tmp, const int len)
00191 {
00192 Array<idx_vector> retval (len);
00193
00194 for (int i = 0; i < len; i++)
00195 retval (i) = tmp[i];
00196
00197 return retval;
00198 }
00199
00200 dim_vector
00201 freeze (Array<idx_vector>& ra_idx, const dim_vector& dimensions, int resize_ok)
00202 {
00203 dim_vector retval;
00204
00205 int n = ra_idx.length ();
00206
00207 assert (n == dimensions.length ());
00208
00209 retval.resize (n);
00210
00211 for (int i = 0; i < n; i++)
00212 retval(i) = ra_idx(i).freeze (dimensions(i), "XXX FIXME XXX", resize_ok);
00213
00214 return retval;
00215 }
00216
00217 bool
00218 vector_equivalent (const Array<int>& ra_idx)
00219 {
00220 int n = ra_idx.length ();
00221
00222 bool found_first = false;
00223
00224 for (int i = 0; i < n; i++)
00225 {
00226 if (ra_idx(i) != 1)
00227 {
00228 if (! found_first)
00229 found_first = true;
00230 else
00231 return false;
00232 }
00233 }
00234
00235 return true;
00236 }
00237
00238 bool
00239 all_ok (const Array<idx_vector>& ra_idx)
00240 {
00241 bool retval = true;
00242
00243 int n = ra_idx.length ();
00244
00245 for (int i = 0; i < n; i++)
00246 {
00247 if (! ra_idx(i))
00248 {
00249 retval = false;
00250 break;
00251 }
00252 }
00253
00254 return retval;
00255 }
00256
00257 bool
00258 any_orig_empty (const Array<idx_vector>& ra_idx)
00259 {
00260 bool retval = false;
00261
00262 int n = ra_idx.length ();
00263
00264 for (int i = 0; i < n; i++)
00265 {
00266 if (ra_idx(i).orig_empty ())
00267 {
00268 retval = true;
00269 break;
00270 }
00271 }
00272
00273 return retval;
00274 }
00275
00276 bool
00277 all_colon_equiv (const Array<idx_vector>& ra_idx,
00278 const dim_vector& frozen_lengths)
00279 {
00280 bool retval = true;
00281
00282 int idx_n = ra_idx.length ();
00283
00284 int n = frozen_lengths.length ();
00285
00286 assert (idx_n == n);
00287
00288 for (int i = 0; i < n; i++)
00289 {
00290 if (! ra_idx(i).is_colon_equiv (frozen_lengths(i)))
00291 {
00292 retval = false;
00293 break;
00294 }
00295 }
00296
00297 return retval;
00298 }
00299
00300 bool
00301 is_in (int num, const idx_vector& idx)
00302 {
00303 int n = idx.capacity ();
00304
00305 for (int i = 0; i < n; i++)
00306 if (idx.elem (i) == num)
00307 return true;
00308
00309 return false;
00310 }
00311
00312 int
00313 how_many_lgt (const int num, idx_vector& idxv)
00314 {
00315 int retval = 0;
00316
00317 int n = idxv.capacity ();
00318
00319 for (int i = 0; i < n; i++)
00320 {
00321 if (num > idxv.elem (i))
00322 retval++;
00323 }
00324
00325 return retval;
00326 }
00327
00328 bool
00329 all_ones (const Array<int>& arr)
00330 {
00331 bool retval = true;
00332
00333 for (int i = 0; i < arr.length (); i++)
00334 {
00335 if (arr(i) != 1)
00336 {
00337 retval = false;
00338 break;
00339 }
00340 }
00341
00342 return retval;
00343 }
00344
00345 Array<int>
00346 get_elt_idx (const Array<idx_vector>& ra_idx, const Array<int>& result_idx)
00347 {
00348 int n = ra_idx.length ();
00349
00350 Array<int> retval (n);
00351
00352 for (int i = 0; i < n; i++)
00353 retval(i) = ra_idx(i).elem (result_idx(i));
00354
00355 return retval;
00356 }
00357
00358 Array<int>
00359 get_ra_idx (int idx, const dim_vector& dims)
00360 {
00361 Array<int> retval;
00362
00363 int n_dims = dims.length ();
00364
00365 retval.resize (n_dims);
00366
00367 for (int i = 0; i < n_dims; i++)
00368 retval(i) = 0;
00369
00370 assert (idx > 0 || idx < dims.numel ());
00371
00372 for (int i = 0; i < idx; i++)
00373 increment_index (retval, dims);
00374
00375
00376
00377
00378 #if 0
00379 int var = 1;
00380 for (int i = 0; i < n_dims; i++)
00381 {
00382 std::cout << "idx: " << idx << ", var: " << var << ", dims(" << i << "): " << dims(i) <<"\n";
00383 retval(i) = ((int)floor(((idx) / (double)var))) % dims(i);
00384 idx -= var * retval(i);
00385 var = dims(i);
00386 }
00387 #endif
00388
00389 return retval;
00390 }
00391
00392 dim_vector
00393 short_freeze (Array<idx_vector>& ra_idx, const dim_vector& dimensions,
00394 int resize_ok)
00395 {
00396 dim_vector retval;
00397
00398 int n = ra_idx.length ();
00399
00400 int n_dims = dimensions.length ();
00401
00402 if (n == n_dims)
00403 {
00404 retval = freeze (ra_idx, dimensions, resize_ok);
00405 }
00406 else if (n < n_dims)
00407 {
00408 retval.resize (n);
00409
00410 for (int i = 0; i < n - 1; i++)
00411 retval(i) = ra_idx(i).freeze (dimensions(i), "dimension", resize_ok);
00412
00413 int size_left = 1;
00414
00415 for (int i = n - 1; i < n_dims; i++)
00416 size_left *= dimensions(i);
00417
00418 if (ra_idx(n-1).is_colon())
00419 {
00420 retval(n-1) = size_left;
00421 }
00422 else
00423 {
00424 int last_ra_idx = ra_idx(n-1)(0);
00425 for (int i = 1; i < ra_idx (n - 1).capacity (); i++)
00426 last_ra_idx = (last_ra_idx > ra_idx(n-1)(i) ? last_ra_idx :
00427 ra_idx(n-1)(i));
00428
00429 if (last_ra_idx < size_left)
00430 {
00431 retval(n-1) = ra_idx(n-1).freeze (size_left,
00432 "dimension", resize_ok);
00433 }
00434 else
00435 {
00436
00437
00438
00439 retval.resize (n_dims+1);
00440
00441 (*current_liboctave_error_handler)
00442 ("index exceeds N-d array dimensions");
00443 }
00444 }
00445 }
00446
00447 return retval;
00448 }
00449
00450 Array<int>
00451 calc_permutated_idx (const Array<int>& old_idx,
00452 const Array<int>& perm_vec, bool inv)
00453 {
00454 int n_el = old_idx.length ();
00455
00456 Array<int> retval (n_el);
00457
00458 for (int i = 0; i < n_el; i++)
00459 {
00460 if (inv)
00461 retval(perm_vec(i)-1) = old_idx(i);
00462 else
00463 retval(i) = old_idx(perm_vec(i)-1);
00464 }
00465
00466 return retval;
00467 }
00468
00469 void
00470 gripe_nonconformant (const char *op, int op1_len, int op2_len)
00471 {
00472 (*current_liboctave_error_handler)
00473 ("%s: nonconformant arguments (op1 len: %d, op2 len: %d)",
00474 op, op1_len, op2_len);
00475 }
00476
00477 void
00478 gripe_nonconformant (const char *op, int op1_nr, int op1_nc,
00479 int op2_nr, int op2_nc)
00480 {
00481 (*current_liboctave_error_handler)
00482 ("%s: nonconformant arguments (op1 is %dx%d, op2 is %dx%d)",
00483 op, op1_nr, op1_nc, op2_nr, op2_nc);
00484 }
00485
00486 void
00487 gripe_nonconformant (const char *op, dim_vector& op1_dims,
00488 dim_vector& op2_dims)
00489 {
00490 std::string op1_dims_str = op1_dims.str ();
00491 std::string op2_dims_str = op2_dims.str ();
00492
00493 (*current_liboctave_error_handler)
00494 ("%s: nonconformant arguments (op1 is %s, op2 is %s)",
00495 op, op1_dims_str.c_str (), op2_dims_str.c_str ());
00496 }
00497
00498
00499
00500
00501
00502