Changeset 686 for trunk/yat


Ignore:
Timestamp:
Oct 17, 2006, 1:33:46 AM (17 years ago)
Author:
Jari Häkkinen
Message:

Fixes #17. Constness of vectors and views are stricltly
maintained. Improper use of const view vectors will cause runtime
error. See vector class documentation for more information.

Location:
trunk/yat/utility
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/yat/utility/vector.cc

    r680 r686  
    4040
    4141
     42  vector::vector(void)
     43    : v_(NULL), v_const_(NULL), view_(NULL), view_const_(NULL), proxy_v_(NULL)
     44  {
     45  }
     46
     47
     48  vector::vector(size_t n, double init_value)
     49    : v_(gsl_vector_alloc(n)), v_const_(NULL), view_(NULL), view_const_(NULL),
     50      proxy_v_(v_)
     51  {
     52    set_all(init_value);
     53  }
     54
     55
     56  vector::vector(const vector& other)
     57    : v_(other.create_gsl_vector_copy()), v_const_(NULL), view_(NULL),
     58      view_const_(NULL), proxy_v_(v_)
     59  {
     60  }
     61
    4262
    4363  vector::vector(vector& v, size_t offset, size_t n, size_t stride)
    44     : const_view_(NULL)
     64    : v_const_(NULL), view_const_(NULL)
    4565  {
    4666    // Jari, exception handling needed here. Failure in setting up a
     
    4969    view_ = new gsl_vector_view(gsl_vector_subvector_with_stride(v.v_,offset,
    5070                                                                 stride,n));
    51     v_ = &(view_->vector);
    52   }
    53 
     71    proxy_v_ = v_ = &(view_->vector);
     72  }
    5473
    5574
    5675  vector::vector(const vector& v, size_t offset, size_t n, size_t stride)
    57     : view_(NULL)
     76    : v_(NULL), view_(NULL)
    5877  {
    5978    // Jari, exception handling needed here. Failure in setting up a
    6079    // proper gsl_vector_view is communicated by NULL pointer in the
    6180    // view structure (cf. GSL manual). How about GSL error state?
    62     const_view_ = new gsl_vector_const_view(
     81    view_const_ = new gsl_vector_const_view(
    6382                   gsl_vector_const_subvector_with_stride(v.v_,offset,stride,n));
    64     v_ = const_cast<gsl_vector*>(&(const_view_->vector));
    65   }
    66 
     83    proxy_v_ = v_const_ = &(view_const_->vector);
     84  }
    6785
    6886
    6987  vector::vector(matrix& m, size_t i, bool row)
    70     : const_view_(NULL)
     88    : v_const_(NULL), view_const_(NULL)
    7189  {
    7290    view_=new gsl_vector_view(row ?
    7391                              gsl_matrix_row   (m.gsl_matrix_p(),i) :
    7492                              gsl_matrix_column(m.gsl_matrix_p(),i)  );
    75     v_ = &(view_->vector);
    76   }
    77 
     93    proxy_v_ = v_ = &(view_->vector);
     94  }
    7895
    7996
    8097  vector::vector(const matrix& m, size_t i, bool row)
    81     : view_(NULL)
    82   {
    83     const_view_ = new gsl_vector_const_view(row ?
     98    : v_(NULL), view_(NULL)
     99  {
     100    view_const_ = new gsl_vector_const_view(row ?
    84101                                   gsl_matrix_const_row   (m.gsl_matrix_p(),i) :
    85102                                   gsl_matrix_const_column(m.gsl_matrix_p(),i) );
    86     v_ = const_cast<gsl_vector*>(&(const_view_->vector));
    87   }
    88 
    89 
    90 
    91   vector::vector(std::istream& is, char sep)
    92     throw (utility::IO_error,std::exception)
    93     : view_(NULL), const_view_(NULL)
     103    proxy_v_ = v_const_ = &(view_const_->vector);
     104  }
     105
     106
     107  vector::vector(std::istream& is, char sep)
     108    throw (utility::IO_error, std::exception)
     109    : v_const_(NULL), view_(NULL), view_const_(NULL)
    94110  {
    95111    // read the data file and store in stl vectors (dynamically
     
    104120          continue;
    105121      nof_rows++;
    106      
     122
    107123      std::vector<double> v;
    108124      std::string element;
     
    154170    is.clear(std::ios::goodbit);
    155171    // convert the data to a gsl vector
    156     v_ = gsl_vector_alloc(nof_rows*nof_columns);
     172    proxy_v_ = v_ = gsl_vector_alloc(nof_rows*nof_columns);
    157173    size_t n=0;
    158174    for (size_t i=0; i<nof_rows; i++)
     
    162178
    163179
    164 
    165180  vector::~vector(void)
    166181  {
    167182    if (view_)
    168183      delete view_;
    169     else if (const_view_)
    170       delete const_view_;
     184    else if (view_const_)
     185      delete view_const_;
    171186    else if (v_)
    172187      gsl_vector_free(v_);
    173     v_=NULL;
    174   }
    175 
     188  }
    176189
    177190
     
    179192  {
    180193    gsl_vector* vec = gsl_vector_alloc(size());
    181     gsl_vector_memcpy(vec,v_);
     194    gsl_vector_memcpy(vec, proxy_v_);
    182195    return vec;
    183196  }
    184197
    185198
    186 
    187199  std::pair<double,double> vector::minmax(void) const
    188200  {
    189201    double min, max;
    190     gsl_vector_minmax(v_,&min,&max);
     202    gsl_vector_minmax(proxy_v_, &min, &max);
    191203    return std::pair<double,double>(min,max);
    192204  }
    193205
    194206
    195 
    196207  std::pair<size_t,size_t> vector::minmax_index(void) const
    197208  {
    198209    size_t min_index, max_index;
    199     gsl_vector_minmax_index(v_,&min_index,&max_index);
     210    gsl_vector_minmax_index(proxy_v_, &min_index, &max_index);
    200211    return std::pair<size_t,size_t>(min_index,max_index);
    201212  }
    202 
    203213
    204214
     
    209219      sum += (*this)(i);
    210220    return( sum );
    211   } 
     221  }
     222
    212223
    213224  bool vector::operator==(const vector& a) const
     
    216227      return false;
    217228    for (size_t i=0; i<size(); ++i)
    218       if (gsl_vector_get(v_,i)!=a(i))
     229      if (gsl_vector_get(proxy_v_,i)!=a(i))
    219230        return false;
    220231    return true;
    221232  }
    222 
    223233
    224234
     
    232242
    233243
    234 
    235   const vector& vector::operator=( const vector& other )
     244  const vector& vector::operator=( const vector& other )
    236245  {
    237246    if( this != &other ) {
    238247      if (view_)
    239248        delete view_;
    240       else if (const_view_)
    241         delete const_view_;
     249      else if (view_const_)
     250        delete view_const_;
    242251      else if ( v_ )
    243252        gsl_vector_free( v_ );
    244       v_ = other.create_gsl_vector_copy();
    245     }
     253      v_const_=NULL;
     254      proxy_v_ = v_ = other.create_gsl_vector_copy();
     255    }
    246256    return *this;
    247257  }
    248 
    249258
    250259
     
    258267        s << s.fill();
    259268    }
    260 
    261269    return s;
    262270  }
    263271
    264 
    265 }}} // of namespace utility, yat and thep
     272}}} // of namespace utility, yat, and thep
  • trunk/yat/utility/vector.h

    r680 r686  
    4343  class matrix;
    4444
    45   ///
    46   /// This is the yat interface to GSL vector. 'double' is the
    47   /// only type supported, maybe we should add a 'complex' type as
    48   /// well in the future.
    49   ///
    50   /// \par[File streams] Reading and writing vectors to file streams
    51   /// are of course supported. These are implemented without using GSL
    52   /// functionality, and thus binary read and write to streams are not
    53   /// supported.
    54   ///
    55   /// \par[Vector views] GSL vector views are supported and these are
    56   /// disguised as ordinary utility::vectors. A support function is
    57   /// added, utility::vector::isview(), that can be used to check if a
    58   /// vector object is a view. Note that view vectors do not own the
    59   /// undelying data, and a view is not valid if the vector owning the
    60   /// data is deallocated.
    61   ///
    62   /// @note Missing support to underlying GSL vector features can in
    63   /// principle be included to this class if requested by the user
    64   /// community.
    65   ///
     45  /**
     46     This is the yat interface to GSL vector. 'double' is the only
     47     type supported, maybe we should add a 'complex' type as well in
     48     the future.
     49
     50     \par File streams:
     51     Reading and writing vectors to file streams are of course
     52     supported. These are implemented without using GSL functionality,
     53     and thus binary read and write to streams are not supported.
     54
     55     \par Vector views:
     56     GSL vector views are supported and these are disguised as
     57     ordinary utility::vectors. A support function is added,
     58     utility::vector::isview(), that can be used to check if a vector
     59     object is a view. Note that view vectors do not own the
     60     underlying data, and a view is not valid if the vector owing the
     61     data is deallocated.
     62
     63     \par
     64     Currently there is no restriction on how a vector is used in
     65     cases when the vector is a const view into another vector or
     66     matrix. To avoid unexpected runtime errors, the programmer must
     67     declare const view vectors as const in order to get compile time
     68     diagnostics about improper use of a const view vector object. An
     69     example of improper use of a const view vector is assignment of
     70     values to an element in the object. If the const view object was
     71     declared const the assigment will be caught by the compiler
     72     whereas it will cause a (un-catchable) runtime error. Example:
     73     @code
     74  const vector vm(13,1.0);
     75  vector v1(vm,2,4);       // bad code!
     76  v1(0)=-123;              // accepted by compiler, runtime failure will occur
     77  const vector v2(vm,2,4);
     78  v2(0)=-123;              // not acceptable for the compiler
     79     @endcode
     80
     81     @note Missing support to underlying GSL vector features can in
     82     principle be included to this class if requested by the user
     83     community.
     84  */
     85
    6686  class vector
    6787  {
     
    7191    /// The default constructor.
    7292    ///
    73     inline vector(void) : v_(NULL), view_(NULL), const_view_(NULL) {}
     93    vector(void);
    7494
    7595    ///
     
    7797    /// sets all elements to \a init_value.
    7898    ///
    79     inline vector(const size_t n,const double init_value=0)
    80       : view_(NULL), const_view_(NULL)
    81       { v_ = gsl_vector_alloc(n); set_all(init_value); }
     99    vector(size_t n, double init_value=0);
    82100
    83101    ///
     
    87105    /// of the view will be copied, i.e. the view is not copied.
    88106    ///
    89     inline vector(const vector& other) : view_(NULL), const_view_(NULL)
    90       { v_ = other.create_gsl_vector_copy(); }
     107    vector(const vector& other);
    91108
    92109    ///
     
    178195    /// end of input to the vector is at end of file marker.
    179196    ///
    180     explicit vector(std::istream &, char sep='\0') throw (utility::IO_error,std::exception);
    181 
     197    explicit vector(std::istream &, char sep='\0')
     198      throw(utility::IO_error, std::exception);
    182199
    183200    ///
     
    215232    /// @return A const pointer to the internal GSL vector,
    216233    ///
    217     inline const gsl_vector* gsl_vector_p(void) const { return v_; }
     234    inline const gsl_vector* gsl_vector_p(void) const { return proxy_v_; }
    218235
    219236    ///
     
    226243    /// othwerwise;
    227244    ///
    228     inline bool isnull(void) const { return gsl_vector_isnull(v_); }
     245    inline bool isnull(void) const { return gsl_vector_isnull(proxy_v_); }
    229246
    230247    ///
     
    234251    /// @return True if the object is a view, false othwerwise.
    235252    ///
    236     inline bool isview(void) const { return view_ || const_view_; }
     253    inline bool isview(void) const { return view_ || view_const_; }
    237254
    238255    ///
     
    240257    ///
    241258    // Jari, doxygen group as Finding maximum and minimum elements
    242     inline double max(void) const { return gsl_vector_max(v_); }
     259    inline double max(void) const { return gsl_vector_max(proxy_v_); }
    243260
    244261    ///
     
    247264    ///
    248265    // Jari, doxygen group as Finding maximum and minimum elements
    249     inline size_t max_index(void) const { return gsl_vector_max_index(v_); }
     266    inline size_t
     267    max_index(void) const { return gsl_vector_max_index(proxy_v_); }
    250268
    251269    ///
     
    253271    ///
    254272    // Jari, doxygen group as Finding maximum and minimum elements
    255     inline double min(void) const { return gsl_vector_min(v_); }
     273    inline double min(void) const { return gsl_vector_min(proxy_v_); }
    256274
    257275    ///
     
    260278    ///
    261279    // Jari, doxygen group as Finding maximum and minimum elements
    262     inline size_t min_index(void) const { return gsl_vector_min_index(v_); }
     280    inline size_t
     281    min_index(void) const { return gsl_vector_min_index(proxy_v_); }
    263282
    264283    ///
     
    338357    /// @return the number of elements in the vector.
    339358    ///
    340     inline size_t size(void) const { return v_->size; }
     359    inline size_t size(void) const { return proxy_v_->size; }
    341360
    342361    ///
     
    346365    ///
    347366    // Markus to Jari, doxygen group as Exchanging elements ????
    348     inline void sort(void) { gsl_sort_vector(v_);}
    349 
     367    inline void sort(void) { gsl_sort_vector(v_); }
    350368
    351369    ///
     
    396414    // Jari, doxygen group as Accessing vector elements
    397415    inline const double&
    398     operator()(size_t i) const { return *gsl_vector_const_ptr(v_,i); }
     416    operator()(size_t i) const { return *gsl_vector_const_ptr(proxy_v_,i); }
    399417
    400418    ///
     
    413431    // Jari, doxygen group as Accessing vector elements
    414432    inline const double&
    415     operator[](size_t i) const { return *gsl_vector_const_ptr(v_,i); }
     433    operator[](size_t i) const { return *gsl_vector_const_ptr(proxy_v_,i); }
    416434
    417435    ///
     
    481499
    482500    gsl_vector* v_;
     501    const gsl_vector* v_const_;
    483502    gsl_vector_view* view_;
    484     gsl_vector_const_view* const_view_;
     503    gsl_vector_const_view* view_const_;
     504    const gsl_vector* proxy_v_;
    485505  };
    486506
     
    491511
    492512
    493 }}} // of namespace utility, yat and theplu
     513}}} // of namespace utility, yat, and theplu
    494514
    495515#endif
Note: See TracChangeset for help on using the changeset viewer.