メインページ   クラス階層   構成   ファイル一覧   構成メンバ   ファイルメンバ  

idx-vector.cc

解説を見る。
00001 /*
00002 
00003 Copyright (C) 1996, 1997 John W. Eaton
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 2, or (at your option) any
00010 later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, write to the Free
00019 Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00020 
00021 */
00022 
00023 #if defined (__GNUG__) && defined (USE_PRAGMA_INTERFACE_IMPLEMENTATION)
00024 #pragma implementation
00025 #endif
00026 
00027 #ifdef HAVE_CONFIG_H
00028 #include <config.h>
00029 #endif
00030 
00031 #include <cstdlib>
00032 
00033 #include <iostream>
00034 
00035 #include "Range.h"
00036 #include "boolNDArray.h"
00037 #include "dColVector.h"
00038 #include "dNDArray.h"
00039 
00040 #include "idx-vector.h"
00041 #include "lo-error.h"
00042 #include "lo-mappers.h"
00043 
00044 #define IDX_VEC_REP idx_vector::idx_vector_rep
00045 
00046 IDX_VEC_REP::idx_vector_rep (const IDX_VEC_REP& a)
00047   : data (0), len (a.len), num_zeros (a.num_zeros), num_ones (a.num_ones),
00048     max_val (a.max_val), min_val (a.min_val),
00049     frozen_at_z_len (a.frozen_at_z_len), frozen_len (a.frozen_len),
00050     colon (a.colon), one_zero (a.one_zero), initialized (a.initialized),
00051     frozen (a.frozen), colon_equiv_checked (a.colon_equiv_checked),
00052     colon_equiv (a.colon_equiv), orig_dims (a.orig_dims)
00053 {
00054   if (len > 0)
00055     {
00056       data = new int [len];
00057       for (int i = 0; i < len; i++)
00058         data[i] = a.data[i];
00059     }
00060 }
00061 
00062 int
00063 IDX_VEC_REP::tree_to_mat_idx (double x, bool& conversion_error)
00064 {
00065   int retval = -1;
00066 
00067   conversion_error = false;
00068 
00069   if (D_NINT (x) != x)
00070     {
00071       (*current_liboctave_error_handler)
00072         ("expecting integer index, found %f", x);
00073 
00074       conversion_error = true;
00075     }
00076   else
00077     retval = static_cast<int> (x - 1);
00078 
00079   return retval;
00080 }
00081 
00082 static inline bool
00083 idx_is_inf_or_nan (double x)
00084 {
00085   bool retval = false;
00086 
00087   if (xisnan (x))
00088     {
00089       (*current_liboctave_error_handler) ("NaN invalid as index");
00090       retval = true;
00091     }
00092   else if (xisinf (x))
00093     {
00094       (*current_liboctave_error_handler) ("Inf invalid as index");
00095       retval = true;
00096     }
00097 
00098   return retval;
00099 }
00100 
00101 IDX_VEC_REP::idx_vector_rep (const ColumnVector& v)
00102   : data (0), len (v.length ()), num_zeros (0), num_ones (0), max_val (0),
00103     min_val (0), count (1), frozen_at_z_len (0), frozen_len (0),
00104     colon (0), one_zero (0), initialized (0), frozen (0),
00105     colon_equiv_checked (0), colon_equiv (0), orig_dims (len, 1)
00106 {
00107   if (len == 0)
00108     {
00109       initialized = 1;
00110       return;
00111     }
00112   else
00113     {
00114       data = new int [len];
00115 
00116       bool conversion_error = false;
00117 
00118       for (int i = 0; i < len; i++)
00119         {
00120           double d = v.elem (i);
00121 
00122           if (idx_is_inf_or_nan (d))
00123             return;
00124           else
00125             data[i] = tree_to_mat_idx (d, conversion_error);
00126 
00127           if (conversion_error)
00128             return;
00129         }
00130     }
00131 
00132   init_state ();
00133 }
00134 
00135 IDX_VEC_REP::idx_vector_rep (const NDArray& nda)
00136   : data (0), len (nda.length ()), num_zeros (0), num_ones (0),
00137     max_val (0), min_val (0), count (1), frozen_at_z_len (0),
00138     frozen_len (0), colon (0), one_zero (0), initialized (0),
00139     frozen (0), colon_equiv_checked (0), colon_equiv (0),
00140     orig_dims (nda.dims ())
00141 {
00142   if (len == 0)
00143     {
00144       initialized = 1;
00145       return;
00146     }
00147   else
00148     {
00149       int k = 0;
00150       data = new int [len];
00151 
00152       bool conversion_error = false;
00153 
00154       for (int i = 0; i < len; i++)
00155         {
00156           double d = nda.elem (i);
00157 
00158           if (idx_is_inf_or_nan (d))
00159             return;
00160           else
00161             data[k++] = tree_to_mat_idx (d, conversion_error);
00162 
00163           if (conversion_error)
00164             return;
00165         }
00166     }
00167 
00168   init_state ();
00169 }
00170 
00171 IDX_VEC_REP::idx_vector_rep (const Range& r)
00172   : data (0), len (r.nelem ()), num_zeros (0), num_ones (0),
00173     max_val (0), min_val (0), count (1), frozen_at_z_len (0),
00174     frozen_len (0), colon (0), one_zero (0), initialized (0),
00175     frozen (0), colon_equiv_checked (0), colon_equiv (0),
00176     orig_dims (1, len)
00177 {
00178   if (len < 0)
00179     {
00180       (*current_liboctave_error_handler) ("invalid range used as index");
00181       return;
00182     }
00183   else if (len == 0)
00184     {
00185       initialized = 1;
00186       return;
00187     }
00188 
00189   double b = r.base ();
00190   double step = r.inc ();
00191 
00192   data = new int [len];
00193 
00194   bool conversion_error = false;
00195 
00196   for (int i = 0; i < len; i++)
00197     {
00198       double val = b + i * step;
00199 
00200       if (idx_is_inf_or_nan (val))
00201         return;
00202       else
00203         data[i] = tree_to_mat_idx (val, conversion_error);
00204 
00205       if (conversion_error)
00206         return;
00207     }
00208 
00209   init_state ();
00210 }
00211 
00212 IDX_VEC_REP::idx_vector_rep (double d)
00213   : data (0), len (1), num_zeros (0), num_ones (0),
00214     max_val (0), min_val (0), count (1), frozen_at_z_len (0),
00215     frozen_len (0), colon (0), one_zero (0), initialized (0),
00216     frozen (0), colon_equiv_checked (0), colon_equiv (0),
00217     orig_dims (1, 1)
00218 {
00219   if (idx_is_inf_or_nan (d))
00220     return;
00221   else
00222     {
00223       data = new int [len];
00224 
00225       bool conversion_error = false;
00226 
00227       data[0] = tree_to_mat_idx (d, conversion_error);
00228 
00229       if (conversion_error)
00230         return;
00231     }
00232 
00233   init_state ();
00234 }
00235 
00236 IDX_VEC_REP::idx_vector_rep (int i)
00237   : data (0), len (1), num_zeros (0), num_ones (0),
00238     max_val (0), min_val (0), count (1), frozen_at_z_len (0),
00239     frozen_len (0), colon (0), one_zero (0), initialized (0),
00240     frozen (0), colon_equiv_checked (0), colon_equiv (0),
00241     orig_dims (1, 1)
00242 {
00243   data = new int [len];
00244 
00245   data[0] = tree_to_mat_idx (i);
00246 
00247   init_state ();
00248 }
00249 
00250 IDX_VEC_REP::idx_vector_rep (char c)
00251   : data (0), len (0), num_zeros (0), num_ones (0),
00252     max_val (0), min_val (0), count (1), frozen_at_z_len (0),
00253     frozen_len (0), colon (1), one_zero (0), initialized (0),
00254     frozen (0), colon_equiv_checked (0), colon_equiv (0),
00255     orig_dims (0, 0)
00256 {
00257   assert (c == ':');
00258 
00259   init_state ();
00260 }
00261 
00262 IDX_VEC_REP::idx_vector_rep (bool b)
00263   : data (0), len (1), num_zeros (0), num_ones (0),
00264     max_val (0), min_val (0), count (1), frozen_at_z_len (0),
00265     frozen_len (0), colon (0), one_zero (1), initialized (0),
00266     frozen (0), colon_equiv_checked (0), colon_equiv (0),
00267     orig_dims (1, 1)
00268 {
00269   data = new int [len];
00270 
00271   data[0] = tree_to_mat_idx (b);
00272 
00273   init_state ();
00274 }
00275 
00276 IDX_VEC_REP::idx_vector_rep (const boolNDArray& bnda)
00277   : data (0), len (bnda.length ()), num_zeros (0), num_ones (0),
00278     max_val (0), min_val (0), count (1), frozen_at_z_len (0),
00279     frozen_len (0), colon (0), one_zero (1), initialized (0),
00280     frozen (0), colon_equiv_checked (0), colon_equiv (0),
00281     orig_dims (bnda.dims ())
00282 {
00283   if (len == 0)
00284     {
00285       initialized = 1;
00286       return;
00287     }
00288   else
00289     {
00290       int k = 0;
00291       data = new int [len];
00292 
00293       for (int i = 0; i < len; i++)
00294         data[k++] = tree_to_mat_idx (bnda.elem (i));
00295     }
00296 
00297   init_state ();
00298 }
00299 
00300 IDX_VEC_REP&
00301 IDX_VEC_REP::operator = (const IDX_VEC_REP& a)
00302 {
00303   if (this != &a)
00304     {
00305       delete [] data;
00306       len = a.len;
00307       data = new int [len];
00308       for (int i = 0; i < len; i++)
00309         data[i] = a.data[i];
00310 
00311       num_zeros = a.num_zeros;
00312       num_ones = a.num_ones;
00313       max_val = a.max_val;
00314       min_val = a.min_val;
00315       frozen_at_z_len = a.frozen_at_z_len;
00316       frozen_len = a.frozen_len;
00317       colon = a.colon;
00318       one_zero = a.one_zero;
00319       initialized = a.initialized;
00320       frozen = a.frozen;
00321       colon_equiv_checked = a.colon_equiv_checked;
00322       colon_equiv = a.colon_equiv;
00323       orig_dims = a.orig_dims;
00324     }
00325 
00326   return *this;
00327 }
00328 
00329 void
00330 IDX_VEC_REP::init_state (void)
00331 {
00332   num_zeros = 0;
00333   num_ones = 0;
00334 
00335   if (colon)
00336     {
00337       min_val = 0;
00338       max_val = 0;
00339     }
00340   else
00341     {
00342       min_val = max_val = data[0];
00343 
00344       int i = 0;
00345       do
00346         {
00347           if (data[i] == -1)
00348             num_zeros++;
00349           else if (data[i] == 0)
00350             num_ones++;
00351 
00352           if (data[i] > max_val)
00353             max_val = data[i];
00354 
00355           if (data[i] < min_val)
00356             min_val = data[i];
00357         }
00358       while (++i < len);
00359     }
00360 
00361   initialized = 1;
00362 }
00363 
00364 void
00365 IDX_VEC_REP::maybe_convert_one_zero_to_idx (int z_len)
00366 {
00367   if (one_zero && (z_len == len || z_len == 0))
00368     {
00369       if (num_ones == 0)
00370         {
00371           len = 0;
00372           max_val = 0;
00373           min_val = 0;
00374           delete [] data;
00375           data = 0;
00376         }
00377       else
00378         {
00379           assert (num_ones + num_zeros == len);
00380 
00381           int *new_data = new int [num_ones];
00382           int k = 0;
00383           for (int i = 0; i < len; i++)
00384             if (data[i] == 0)
00385               new_data[k++] = i;
00386 
00387           delete [] data;
00388           len = num_ones;
00389           data = new_data;
00390 
00391           min_val = max_val = data[0];
00392 
00393           int i = 0;
00394           do
00395             {
00396               if (data[i] > max_val)
00397                 max_val = data[i];
00398 
00399               if (data[i] < min_val)
00400                 min_val = data[i];
00401             }
00402           while (++i < len);
00403         }
00404     }
00405 }
00406 
00407 int
00408 IDX_VEC_REP::checkelem (int n) const
00409 {
00410   if (n < 0 || n >= len)
00411     {
00412       (*current_liboctave_error_handler) ("idx-vector: index out of range");
00413       return 0;
00414     }
00415 
00416   return elem (n);
00417 }
00418 
00419 static inline int
00420 intcmp (const void *ii, const void *jj)
00421 {
00422   return (*(static_cast<const int *> (ii)) - *(static_cast<const int *> (jj)));
00423 }
00424 
00425 static inline void
00426 sort_data (int *d, int l)
00427 {
00428   qsort (d, l, sizeof (int), intcmp);
00429 }
00430 
00431 static inline int
00432 make_uniq (int *d, int l)
00433 {
00434   if (l < 2)
00435     return l;
00436 
00437   int k = 0;
00438   for (int ii = 1; ii < l; ii++)
00439     {
00440       if (d[ii] != d[k])
00441         {
00442           k++;
00443           d[k] = d[ii];
00444         }
00445     }
00446   return k+1;
00447 }
00448 
00449 static inline int *
00450 copy_data (const int *d, int l)
00451 {
00452   int *new_data = new int [l];
00453 
00454   for (int ii = 0; ii < l; ii++)
00455     new_data[ii] = d[ii];
00456 
00457   return new_data;
00458 }
00459 
00460 int
00461 IDX_VEC_REP::is_colon_equiv (int n, int sort_uniq)
00462 {
00463   if (! colon_equiv_checked)
00464     {
00465       if (colon)
00466         {
00467           colon_equiv = 1;
00468         }
00469       else if (len > 1)
00470         {
00471           if (one_zero)
00472             {
00473               colon_equiv = (len == n && ones_count () == n);
00474             }
00475           else if (sort_uniq)
00476             {
00477               int *tmp_data = copy_data (data, len);
00478 
00479               sort_data (tmp_data, len);
00480 
00481               int tmp_len = make_uniq (tmp_data, len);
00482 
00483               colon_equiv = (tmp_len == n
00484                              && tmp_data[0] == 0
00485                              && tmp_data[tmp_len-1] == tmp_len - 1);
00486 
00487               delete [] tmp_data;
00488             }
00489           else
00490             {
00491               if (len == n)
00492                 {
00493                   colon_equiv = 1;
00494 
00495                   for (int ii = 0; ii < n; ii++)
00496                     if (data[ii] != ii)
00497                       {
00498                         colon_equiv = 0;
00499                         break;
00500                       }
00501                 }
00502             }
00503         }
00504       else
00505         colon_equiv = (len == n && (n == 0 || (n == 1 && data[0] == 0)));
00506 
00507       colon_equiv_checked = 1;
00508     }
00509 
00510   return colon_equiv;
00511 }
00512 
00513 void
00514 IDX_VEC_REP::sort (bool uniq)
00515 {
00516   if (len > 1)
00517     {
00518       sort_data (data, len);
00519 
00520       if (uniq)
00521         len = make_uniq (data, len);
00522     }
00523 }
00524 
00525 void
00526 IDX_VEC_REP::shorten (int n)
00527 {
00528   if (n > 0 && n <= len)
00529     len = n;
00530   else
00531     (*current_liboctave_error_handler)
00532       ("idx_vector::shorten: internal error!");
00533 }
00534 
00535 std::ostream&
00536 IDX_VEC_REP::print (std::ostream& os) const
00537 {
00538   for (int ii = 0; ii < len; ii++)
00539     os << data[ii] << "\n";
00540   return os;
00541 }
00542 
00543 int
00544 IDX_VEC_REP::freeze (int z_len, const char *tag, bool resize_ok,
00545                      bool warn_resize)
00546 {
00547   if (frozen)
00548     return frozen_len;
00549 
00550   frozen_len = -1;
00551 
00552   if (colon)
00553     frozen_len = z_len;
00554   else
00555     {
00556       if (len == 0)
00557         frozen_len = 0;
00558       else
00559         {
00560           maybe_convert_one_zero_to_idx (z_len);
00561 
00562           max_val = max ();
00563           min_val = min ();
00564 
00565           if (min_val < 0)
00566             {
00567               if (tag)
00568                 (*current_liboctave_error_handler)
00569                   ("invalid %s index = %d", tag, min_val+1);
00570               else
00571                 (*current_liboctave_error_handler)
00572                   ("invalid index = %d", min_val+1);
00573 
00574               initialized = 0;
00575             }
00576           else if (! resize_ok && max_val >= z_len)
00577             {
00578               if (tag)
00579                 (*current_liboctave_error_handler)
00580                   ("invalid %s index = %d", tag, max_val+1);
00581               else
00582                 (*current_liboctave_error_handler)
00583                   ("invalid index = %d", max_val+1);
00584 
00585               initialized = 0;
00586             }
00587           else
00588             {
00589               if (warn_resize && max_val >= z_len)
00590                 {
00591                   if (tag)
00592                     (*current_liboctave_error_handler)
00593                       ("resizing object with %s index = %d out of bounds",
00594                        tag, max_val+1);
00595                   else
00596                     (*current_liboctave_error_handler)
00597                       ("resizing object with index = %d out of bounds",
00598                        max_val+1);
00599                 }
00600 
00601               frozen_len = length (z_len);
00602             }
00603         }
00604     }
00605 
00606   frozen = 1;
00607 
00608   frozen_at_z_len = z_len ? z_len : len;
00609 
00610   return frozen_len;
00611 }
00612 
00613 /*
00614 ;;; Local Variables: ***
00615 ;;; mode: C++ ***
00616 ;;; End: ***
00617 */

Wed Dec 29 11:51:36 2004に生成されました。 doxygen1.2.18
SEO [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送