Changeset 789 for trunk


Ignore:
Timestamp:
Mar 10, 2007, 9:07:13 PM (16 years ago)
Author:
Jari Häkkinen
Message:

Addresses #193. vector now works as outlined here. Added some
functionality. Added a clone function that facilitates resizing of
vectors. clone is needed since assignement operator functionality is
changed.

Location:
trunk
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/test/matrix_test.cc

    r774 r789  
    186186    *error << "error sub-vector test 5" << std::endl;
    187187  }
    188   // Checking that vector::operator= indeed makes a view to become a
    189   // "normal" vector.
    190   v5subrow=utility::vector(23,22);
    191   double m5_sum6=0;
    192   for (size_t i=0; i<m5.rows(); ++i)
    193     for (size_t j=0; j<m5.columns(); ++j)
    194       m5_sum6+=m5(i,j);
    195   if (m5_sum6-m5_sum5>1e-13) {
    196     ok=false;
    197     *error << "error sub-vector test 6" << std::endl;
    198   }
    199188
    200189  // Checking that the memberfunction matrixwrapper::row() returns a
  • trunk/test/regression_test.cc

    r775 r789  
    502502  rl.fit(10, 100);
    503503
    504   utility::vector y = rl.y_predicted();
     504  utility::vector y(rl.y_predicted());
    505505  for (size_t i=0; i<y.size(); i++)
    506506    if (y(i)!=10.0){
  • trunk/test/vector_test.cc

    r786 r789  
    4343int main(const int argc,const char* argv[])
    4444
    45   bool print = (argc>1 && argv[1]==std::string("-p"));
     45  std::ostream* message;
     46  if (argc>1 && argv[1]==std::string("-v"))
     47    message = &std::cerr;
     48  else {
     49    message = new std::ofstream("/dev/null");
     50    if (argc>1)
     51      std::cout << argv[0] << " -v : for printing extra "  << "information\n";
     52  }
     53  *message << "testing vector" << std::endl;
    4654  bool ok = true;
    4755
     
    5159
    5260  // checking that shuffle works
     61  *message << "shuffle" << std::endl;
    5362  double sum_before = utility::sum(vec);
    5463  shuffle(vec);
    5564  double sum_after = utility::sum(vec);
    56   if (sum_after != sum_before)
    57     ok = false;
     65  ok &= (sum_after==sum_before);
    5866
    5967  // checking that view works
     68  *message << "view" << std::endl;
    6069  sum_before=0;
    6170  for (unsigned int i=0; i<vec.size(); i+=2)
     
    6372  utility::vector vec_view(vec,0,6,2);
    6473  sum_after=utility::sum(vec_view);
    65   if (sum_after != sum_before)
    66     ok = false;
     74  ok &= (sum_after==sum_before);
    6775  vec[0]=0;
    6876  vec_view[0]=24;
    69   if (vec[0]!=vec_view[0])
    70     ok=false;
    71 
    72   // checking that copy constructor creates an independent object
    73   utility::vector vec2(vec);
    74   if (vec.size()!=vec2.size())
    75     ok=false;
    76   if (&vec2 == &vec)
    77     ok=false;
    78   if (vec2.isview())
    79     ok=false;
     77  ok &= (vec[0]==vec_view[0]);
     78
     79  // Test of const view implementation (make sure no zero pointer is
     80  // used). Here we use the bad style of not making the view const!
     81  {
     82    *message << "const view implementation" << std::endl;
     83    const utility::vector vv(10,3.0);
     84    utility::vector vview(vv,0,5,1);
     85    // const utility::vector vview(vv,0,5,1); // this is the proper line
     86    utility::vector vv2(5,2.0);
     87    vv2.mul(vview); // should work even without const since const arg passing
     88    vv2.div(vview); // should work even without const since const arg passing
     89    ok &= (vview*vview == 3.0*3.0*vview.size());
     90  }
    8091
    8192  // checking that copy constructor creates an independent object when
    82   // copying a view
    83   vec2=vec_view;
    84   if (vec_view.size()!=vec2.size())
    85     ok=false;
    86   if ((&vec2 == &vec_view) || (&vec2 == &vec))
    87     ok=false;
    88   if (vec2.isview())
    89     ok=false;
    90   vec2[0]=0;
    91   vec_view[0]=24;
    92   if (vec2[0]==vec_view[0])
    93     ok=false;
     93  // a non-view vector is copied
     94  {
     95    *message << "copy constructor" << std::endl;
     96    utility::vector vec2(vec);
     97    ok &= (vec.size()==vec2.size());
     98    ok &= (vec2==vec);
     99    ok &= (&vec2 != &vec);
     100    ok &= !vec2.isview();
     101  }
     102
     103  // checking that copy constructor creates an independent object when
     104  // a view vector is copied
     105  {
     106    *message << "copy contructor on view" << std::endl;
     107    utility::vector vec3(vec_view);
     108    ok &= (vec_view.size()==vec3.size());
     109    ok &= (vec3 == vec_view);
     110    ok &= (&vec3 != &vec_view);
     111    ok &= !vec3.isview();
     112  }
     113
     114  // checking that assignment operator throws an exception if vectors
     115  // differ in size
     116  {
     117    *message << "assignment operator" << std::endl;
     118    bool exception_happens=false;
     119    try {
     120      utility::vector v(vec_view.size()+1,0.0);
     121      v=vec_view;
     122    } catch (utility::GSL_error& err) {
     123      exception_happens=true;
     124    }
     125    if (!exception_happens) {
     126      *message << "Vector assignment operator did not throw expected exception"
     127               << std::endl;
     128      ok=false;
     129    }
     130  }
     131
     132  // checking that assignment operator changes the underlying object when
     133  // a view is changed.
     134  {
     135    *message << "assignment operator on view" << std::endl;
     136    vec[3]=vec[4]=vec[5]=13;
     137    utility::vector vec_view(vec,3,3,1);
     138    utility::vector vec2(3,123.0);
     139    vec_view=vec2;
     140    if (vec[3]!=vec_view[0] || vec[4]!=vec_view[1] || vec[5]!=vec_view[2])
     141      ok=false;
     142  }
     143
     144  // checking clone functionality
     145  {
     146    *message << "clone functionality" << std::endl;
     147    bool this_ok=true;
     148    *message << "\tcloning normal vector" << std::endl;
     149    utility::vector vec2(3,123.0);
     150    vec2.clone(vec);
     151    if (vec.size()!=vec2.size())
     152      this_ok=false;
     153    else
     154      for (unsigned int i=0; i<vec.size(); ++i)
     155        if (vec(i)!=vec2(i))
     156          this_ok=false;
     157    if (vec.gsl_vector_p()==vec2.gsl_vector_p())
     158      this_ok=false;
     159    *message << "\tcloning vector view" << std::endl;
     160    utility::vector* vec_view=new utility::vector(vec,3,3,1);
     161    utility::vector vec_view2;
     162    vec_view2.clone(*vec_view);
     163    if (!vec_view2.isview())
     164      this_ok=false;
     165    if (vec_view->size()!=vec_view2.size())
     166      this_ok=false;
     167    else
     168      for (u_int i=0; i<vec_view2.size(); ++i)
     169        if ((*vec_view)(i)!=vec_view2(i))
     170          this_ok=false;
     171    *message << "\tcloned vector view independence" << std::endl;
     172    delete vec_view;
     173    if (vec[3]!=vec_view2[0] || vec[4]!=vec_view2[1] || vec[5]!=vec_view2[2])
     174      this_ok=false;
     175
     176    if (!this_ok) {
     177      *message << "FAIL: clone test" << std::endl;
     178      ok=false;
     179    }
     180  }
    94181
    95182  // checking that reading vectors from properly formatted files works
    96183  try {
     184    *message << "stream" << std::endl;
    97185    std::string data1("data/vector1.data");
    98186    std::string data2("data/vector2.data");
     
    107195    std::ifstream data_stream3(data3.c_str());
    108196    std::ifstream data_stream4(data4.c_str());
    109     vec=utility::vector(data_stream1);
    110     if (vec.size()!=9)
    111       ok=false;
    112     vec=utility::vector(data_stream2);
    113     if (vec.size()!=9)
    114       ok=false;
    115     vec=utility::vector(data_stream3);
    116     if (vec.size()!=12)
    117       ok=false;
    118     vec=utility::vector(data_stream4);
    119     if (vec.size()!=12)
    120       ok=false;
    121   } catch (utility::IO_error& err) {
    122     if (print)
    123       std::cerr << err.what() << std::endl;
     197    utility::vector vec1(data_stream1);
     198    ok &= (vec1.size()==9);
     199    vec1=utility::vector(data_stream2);
     200    ok &= (vec1.size()==9);
     201    utility::vector vec2(data_stream3);
     202    ok &= (vec2.size()==12);
     203    vec2=utility::vector(data_stream4);
     204    ok &= (vec2.size()==12);
     205  } catch (utility::IO_error& err) {
     206    *message << err.what() << std::endl;
    124207    ok=false;
    125208  }
     
    127210  // Checking that vector stream input operator can read whatever
    128211  // vector stream output operator produces.
    129   std::stringstream s;
    130   s << vec;
    131   vec2=utility::vector(s);
    132   if (!(vec==vec2))
    133     ok=false;
     212  {
     213    *message << "checking that output stream is valid as an input stream"
     214             << std::endl;
     215    std::stringstream s;
     216    s << vec;
     217    utility::vector vec2(s);
     218    ok &= (vec==vec2);
     219  }
    134220
    135221  // Checking that badly formatted files are not accepted, or at least
    136222  // throws an exception for the programmer to catch.
     223  *message << "checking that bad stream are rejected" << std::endl;
    137224  bool this_ok=false;
    138225  // Checking that unexpected characters in a stream gives error.
     
    141228    check_file_access(data5);
    142229    std::ifstream data_stream5(data5.c_str());
    143     vec=utility::vector(data_stream5); // this will give an exception
    144   } catch (utility::IO_error& err) {
    145     if (print)
    146       std::cerr << err.what() << std::endl;
     230    utility::vector dummy(data_stream5); // this will give an exception
     231  } catch (utility::IO_error& err) {
     232    *message << err.what() << std::endl;
    147233    this_ok=true; // good, exceoption thrown, test passed
    148234  }
     
    151237    check_file_access(data);
    152238    std::ifstream data_stream(data.c_str());
    153     vec=utility::vector(data_stream); // this will give an exception
    154   } catch (utility::IO_error& err) {
    155     if (print)
    156       std::cerr << err.what() << std::endl;
     239    utility::vector dummy(data_stream); // this will give an exception
     240  } catch (utility::IO_error& err) {
     241    *message << err.what() << std::endl;
    157242    this_ok=true; // good, exceoption thrown, test passed
    158243  }
    159   if (!this_ok)
    160     ok=false;
     244  ok &= this_ok;
     245
    161246  this_ok=false;
    162247  try {
     
    166251    vec=utility::vector(data_stream); // this will give an exception
    167252  } catch (utility::IO_error& err) {
    168     if (print)
    169       std::cerr << err.what() << std::endl;
     253    *message << err.what() << std::endl;
    170254    this_ok=true; // good, exceoption thrown, test passed
    171255  }
    172 
    173   if (!this_ok)
    174     ok=false;
    175 
    176   // test of const view implementation (make sure no zero pointer used.
    177   const utility::vector vv(10,3.0);
    178   const utility::vector vview(vv,0,5,1);
    179   utility::vector vv2(5,2.0);
    180   vv2.mul(vview); // should work without an abort due to zero pointer in mul
    181   vv2.div(vview); // should work without an abort due to zero pointer in mul
    182 
    183   if (vview*vview!= 3.0*3.0*vview.size())
    184     ok = false;
    185 
    186   if (print && !ok)
    187     std::cout << "vector_test failed" << std::endl;
    188 
    189  
     256  ok &= this_ok;
     257
     258  if (!ok)
     259    *message << "vector test failed" << std::endl;
    190260
    191261  return (ok ? 0 : -1);
  • trunk/yat/classifier/IGP.cc

    r680 r789  
    4545   
    4646    // Calculate IGP for each class
    47     igp_=utility::vector(target_.nof_classes());
     47    igp_.clone(utility::vector(target_.nof_classes()));
    4848    for(u_int i=0; i<target_.size(); i++) {
    4949      u_int neighbor=i;
  • trunk/yat/classifier/NCC.cc

    r722 r789  
    110110                    utility::vector& prediction) const
    111111  {
    112     prediction=utility::vector(centroids_.columns());   
     112    prediction.clone(utility::vector(centroids_.columns()));
    113113
    114114    utility::vector value(input.size(),0);
  • trunk/yat/classifier/utility.cc

    r779 r789  
    3434  void convert(const DataLookup1D& lookup, utility::vector& vector)
    3535  {
    36     vector=utility::vector(lookup.size());
     36    vector.clone(utility::vector(lookup.size()));
    3737    for(u_int i=0; i<lookup.size(); i++)
    3838      vector(i)=lookup(i);
     
    4343  {
    4444   
    45     value=utility::vector(lookup.size());
    46     weight=utility::vector(lookup.size());
     45    value.clone(utility::vector(lookup.size()));
     46    weight.clone(utility::vector(lookup.size()));
    4747    for(u_int i=0; i<lookup.size(); i++){
    4848      value(i)=lookup.data(i);
  • trunk/yat/regression/Local.cc

    r767 r789  
    5858
    5959    size_t nof_fits=data_.size()/step_size;
    60     x_= utility::vector(nof_fits);
    61     y_predicted_ = utility::vector(x_.size());
    62     y_err_ = utility::vector(x_.size());
     60    x_.clone(utility::vector(nof_fits));
     61    y_predicted_.clone(utility::vector(x_.size()));
     62    y_err_.clone(utility::vector(x_.size()));
    6363    sort(data_.begin(), data_.end());
    6464
  • trunk/yat/regression/MultiDimensional.cc

    r750 r789  
    5757    assert(x.rows()==y.size());
    5858    covariance_=utility::matrix(x.columns(),x.columns());
    59     fit_parameters_=utility::vector(x.columns());
     59    fit_parameters_.clone(utility::vector(x.columns()));
    6060    if (work_)
    6161      gsl_multifit_linear_free(work_);
  • trunk/yat/regression/MultiDimensionalWeighted.cc

    r750 r789  
    5959
    6060    covariance_=utility::matrix(x.columns(),x.columns());
    61     fit_parameters_=utility::vector(x.columns());
     61    fit_parameters_.clone(utility::vector(x.columns()));
    6262    if (work_)
    6363      gsl_multifit_linear_free(work_);
     
    8585  }
    8686
     87
    8788  double MultiDimensionalWeighted::predict(const utility::vector& x) const
    8889  {
     
    9091    return fit_parameters_ * x;
    9192  }
     93
    9294
    9395  double MultiDimensionalWeighted::prediction_error2(const utility::vector& x,
  • trunk/yat/statistics/Score.cc

    r779 r789  
    5454  {
    5555    assert(target.size()==value.size());
    56     utility::vector a;
     56    utility::vector a(value.size());
    5757    classifier::convert(value,a);
    5858    return score(target,a);
     
    6464  {
    6565    assert(target.size()==value.size());
    66     utility::vector a;
    67     utility::vector b;
     66    utility::vector a(value.size());
     67    utility::vector b(value.size());
    6868    classifier::convert(value,a,b);
    6969    return score(target,a,b);
     
    7575                      const classifier::DataLookup1D& weight) const
    7676  {
    77     utility::vector a;
     77    utility::vector a(value.size());
    7878    classifier::convert(value,a);
    79     utility::vector b;
     79    utility::vector b(value.size());
    8080    classifier::convert(weight,a);
    8181    return score(target,a,b);
  • trunk/yat/utility/PCA.cc

    r782 r789  
    6969    eigenvectors_ = U;
    7070    eigenvectors_ .transpose();
    71     eigenvalues_ = pSVD->s();
     71    eigenvalues_.clone(pSVD->s());
    7272
    7373    // T
     
    109109    eigenvectors_=V;
    110110    eigenvectors_.transpose();
    111     eigenvalues_ = pSVD->s();
     111    eigenvalues_.clone(pSVD->s());
    112112
    113113    // Transform back when done with SVD!
     
    139139  void PCA::row_center(utility::matrix& A_center)
    140140  {
    141     meanvalues_ = utility::vector( A_.rows() );
     141    meanvalues_.clone(utility::vector(A_.rows()));
    142142    utility::vector A_row_sum(A_.rows());
    143143    for (size_t i=0; i<A_row_sum.size(); ++i)
  • trunk/yat/utility/vector.cc

    r787 r789  
    3030
    3131#include <cassert>
     32#include <cmath>
    3233#include <iostream>
    3334#include <sstream>
     
    8384      throw utility::GSL_error("vector::vector failed to setup view");
    8485    proxy_v_ = &(view_const_->vector);
    85     const_cast<const gsl_vector*>(proxy_v_);
    8686  }
    8787
     
    210210
    211211
     212  const vector& vector::clone(const vector& other)
     213  {
     214    if (this!=&other) {
     215
     216      if (view_)
     217        delete view_;
     218      else if (view_const_)
     219        delete view_const_;
     220      else if (v_)
     221        gsl_vector_free(v_);
     222
     223      if (other.view_) {
     224        view_ = new gsl_vector_view(*other.view_);
     225        proxy_v_ = v_ = &(view_->vector);
     226      }
     227      else if (other.view_const_) {
     228        view_const_ = new gsl_vector_const_view(*other.view_const_);
     229        proxy_v_ = &(view_const_->vector);
     230        v_=NULL;
     231      }
     232      else if (other.v_)
     233        proxy_v_ = v_ = other.create_gsl_vector_copy();
     234
     235    }
     236    return *this;
     237  }
     238
     239
    212240  void vector::div(const vector& other)
    213241  {
     
    216244    if (status)
    217245      throw utility::GSL_error(std::string("vector::div",status));
     246  }
     247
     248
     249  bool vector::equal(const vector& other, const double d) const
     250  {
     251    if (this==&other)
     252      return true;
     253    if (size()!=other.size())
     254      return false;
     255    // if gsl error handler disabled, out of bounds index will not
     256    // abort the program.
     257    for (size_t i=0; i<size(); ++i)
     258      // The two last condition checks are needed for NaN detection
     259      if (fabs( (*this)(i)-other(i) ) > d ||
     260          (*this)(i)!=(*this)(i) || other(i)!=other(i))
     261        return false;
     262    return true;
    218263  }
    219264
     
    316361
    317362
    318   bool vector::operator==(const vector& a) const
    319   {
    320     if (size()!=a.size())
    321       return false;
    322     // if gsl error handler disabled, out of bounds index will not
    323     // abort the program.
    324     for (size_t i=0; i<size(); ++i)
    325       if (gsl_vector_get(proxy_v_,i)!=a(i))
    326         return false;
    327     return true;
     363  bool vector::operator==(const vector& other) const
     364  {
     365    return equal(other);
     366  }
     367
     368
     369  bool vector::operator!=(const vector& other) const
     370  {
     371    return !equal(other);
    328372  }
    329373
     
    341385  {
    342386    if( this != &other ) {
    343       if (view_)
    344         delete view_;
    345       else if (view_const_)
    346         delete view_const_;
    347       else if ( v_ )
    348         gsl_vector_free( v_ );
    349       proxy_v_ = v_ = other.create_gsl_vector_copy();
     387      if (size()!=other.size())
     388        throw utility::GSL_error("vector::operator= vector sizes differ");
     389      for (size_t i=0; i<size(); ++i)
     390        gsl_vector_set(v_, i, other(i));
    350391    }
    351392    return *this;
  • trunk/yat/utility/vector.h

    r787 r789  
    219219
    220220    /**
     221       \brief Make a copy of \a other.
     222
     223       This function will make a deep copy of \a other. Memory is
     224       resized and view state is changed if needed.
     225    */
     226    const vector& clone(const vector& other);
     227
     228    /**
    221229       \brief This function performs element-wise division, \f$ this_i =
    222230       this_i/other_i \; \forall i \f$.
     
    225233    */
    226234    void div(const vector& other);
     235
     236    /**
     237       \brief Check whether vectors are equal within a user defined
     238       precision, set by \a precision.
     239
     240       \return True if each element deviates less or equal than \a
     241       d. If any vector contain a NaN, false is always returned.
     242
     243       \see operator== and operator!=
     244    */
     245    bool equal(const vector&, const double precision=0) const;
    227246
    228247    ///
     
    321340    const double& operator[](size_t i) const;
    322341
    323     ///
    324     /// Comparison operator. Takes linear time.
    325     ///
    326     /// @return True if the sequence of the elements in the vectors
    327     /// are element/wise equal.
    328     ///
     342    /**
     343       \brief Comparison operator. Takes linear time.
     344
     345       Checks are performed with exact matching, i.e., rounding off
     346       effects may destroy comparison. Use the equal function for
     347       comparing elements within a user defined precision.
     348
     349       \return True if all elements are equal otherwise false.
     350
     351       \see equal
     352    */
    329353    bool operator==(const vector&) const;
     354
     355    /**
     356       \brief Comparison operator. Takes linear time.
     357
     358       Checks are performed with exact matching, i.e., rounding off
     359       effects may destroy comparison. Use the equal function for
     360       comparing elements within a user defined precision.
     361
     362       \return False if all elements are equal otherwise true.
     363
     364       \see equal
     365    */
     366    bool operator!=(const vector&) const;
    330367
    331368    ///
Note: See TracChangeset for help on using the changeset viewer.