source: trunk/test/vector_test.cc @ 790

Last change on this file since 790 was 790, checked in by Jari Häkkinen, 15 years ago

Addresses #193. Fixing doxygen docs, and operator=.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.9 KB
Line 
1// $Id: vector_test.cc 790 2007-03-10 20:49:31Z jari $
2
3/*
4  Copyright (C) The authors contributing to this file.
5
6  This file is part of the yat library, http://lev.thep.lu.se/trac/yat
7
8  The yat library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2 of the
11  License, or (at your option) any later version.
12
13  The yat library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21  02111-1307, USA.
22*/
23
24#include "yat/utility/Exception.h"
25#include "yat/utility/FileUtil.h"
26#include "yat/utility/utility.h"
27#include "yat/utility/vector.h"
28
29#include <fstream>
30#include <sstream>
31
32using namespace theplu::yat;
33
34void check_file_access(std::string& str)
35{
36 
37  if (utility::FileUtil(str).permissions("r")) {
38    std::cerr << "test_nni: Cannot access file " << str << std::endl;
39    exit(-1);
40  }
41}
42
43int main(const int argc,const char* argv[])
44{ 
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;
54  bool ok = true;
55
56  utility::vector vec(12);
57  for (unsigned int i=0; i<vec.size(); i++) 
58    vec(i)=i;
59
60  // checking that shuffle works
61  *message << "shuffle" << std::endl;
62  double sum_before = utility::sum(vec);
63  shuffle(vec);
64  double sum_after = utility::sum(vec);
65  ok &= (sum_after==sum_before);
66
67  // checking that view works
68  *message << "view" << std::endl;
69  sum_before=0;
70  for (unsigned int i=0; i<vec.size(); i+=2) 
71    sum_before+=vec[i];
72  utility::vector vec_view(vec,0,6,2);
73  sum_after=utility::sum(vec_view);
74  ok &= (sum_after==sum_before);
75  vec[0]=0;
76  vec_view[0]=24;
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  }
91
92  // checking that copy constructor creates an independent object when
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    // GSL will catch the error in this test there for the GSL error
119    // handling must be disabled until after the exception is
120    // catched. The GSL error handler is reinstated after the
121    // try-catch construct.
122    gsl_error_handler_t* err_handler=gsl_set_error_handler_off();
123    bool exception_happens=false;
124    try {
125      utility::vector v(vec_view.size()+1,0.0);
126      v=vec_view;
127    } catch (utility::GSL_error& err) {
128      exception_happens=true;
129    }
130    if (!exception_happens) {
131      *message << "Vector assignment operator did not throw expected exception"
132               << std::endl;
133      ok=false;
134    }
135    gsl_set_error_handler(err_handler);
136  }
137
138  // checking that assignment operator changes the underlying object when
139  // a view is changed.
140  {
141    *message << "assignment operator on view" << std::endl;
142    vec[3]=vec[4]=vec[5]=13;
143    utility::vector vec_view(vec,3,3,1);
144    utility::vector vec2(3,123.0);
145    vec_view=vec2;
146    if (vec[3]!=vec_view[0] || vec[4]!=vec_view[1] || vec[5]!=vec_view[2])
147      ok=false;
148  }
149
150  // checking clone functionality
151  {
152    *message << "clone functionality" << std::endl;
153    bool this_ok=true;
154    *message << "\tcloning normal vector" << std::endl;
155    utility::vector vec2(3,123.0);
156    vec2.clone(vec);
157    if (vec.size()!=vec2.size())
158      this_ok=false;
159    else
160      for (unsigned int i=0; i<vec.size(); ++i)
161        if (vec(i)!=vec2(i))
162          this_ok=false;
163    if (vec.gsl_vector_p()==vec2.gsl_vector_p())
164      this_ok=false;
165    *message << "\tcloning vector view" << std::endl;
166    utility::vector* vec_view=new utility::vector(vec,3,3,1);
167    utility::vector vec_view2;
168    vec_view2.clone(*vec_view);
169    if (!vec_view2.isview())
170      this_ok=false;
171    if (vec_view->size()!=vec_view2.size())
172      this_ok=false;
173    else
174      for (u_int i=0; i<vec_view2.size(); ++i)
175        if ((*vec_view)(i)!=vec_view2(i))
176          this_ok=false;
177    *message << "\tcloned vector view independence" << std::endl;
178    delete vec_view;
179    if (vec[3]!=vec_view2[0] || vec[4]!=vec_view2[1] || vec[5]!=vec_view2[2])
180      this_ok=false;
181
182    if (!this_ok) {
183      *message << "FAIL: clone test" << std::endl;
184      ok=false;
185    }
186  }
187
188  // checking that reading vectors from properly formatted files works
189  try {
190    *message << "stream" << std::endl;
191    std::string data1("data/vector1.data");
192    std::string data2("data/vector2.data");
193    std::string data3("data/vector3.data");
194    std::string data4("data/vector4.data");
195    check_file_access(data1);
196    check_file_access(data2);
197    check_file_access(data3);
198    check_file_access(data4);
199    std::ifstream data_stream1(data1.c_str());
200    std::ifstream data_stream2(data2.c_str());
201    std::ifstream data_stream3(data3.c_str());
202    std::ifstream data_stream4(data4.c_str());
203    utility::vector vec1(data_stream1);
204    ok &= (vec1.size()==9);
205    vec1=utility::vector(data_stream2);
206    ok &= (vec1.size()==9);
207    utility::vector vec2(data_stream3);
208    ok &= (vec2.size()==12);
209    vec2=utility::vector(data_stream4);
210    ok &= (vec2.size()==12);
211  } catch (utility::IO_error& err) {
212    *message << err.what() << std::endl;
213    ok=false;
214  }
215
216  // Checking that vector stream input operator can read whatever
217  // vector stream output operator produces.
218  {
219    *message << "checking that output stream is valid as an input stream"
220             << std::endl;
221    std::stringstream s;
222    s << vec;
223    utility::vector vec2(s);
224    ok &= (vec==vec2);
225  }
226
227  // Checking that badly formatted files are not accepted, or at least
228  // throws an exception for the programmer to catch.
229  *message << "checking that bad stream are rejected" << std::endl;
230  bool this_ok=false;
231  // Checking that unexpected characters in a stream gives error.
232  try {
233    std::string data5("data/vector5.data");
234    check_file_access(data5);
235    std::ifstream data_stream5(data5.c_str());
236    utility::vector dummy(data_stream5); // this will give an exception
237  } catch (utility::IO_error& err) {
238    *message << err.what() << std::endl;
239    this_ok=true; // good, exceoption thrown, test passed
240  }
241  try {
242    std::string data("data/vector6.data");
243    check_file_access(data);
244    std::ifstream data_stream(data.c_str());
245    utility::vector dummy(data_stream); // this will give an exception
246  } catch (utility::IO_error& err) {
247    *message << err.what() << std::endl;
248    this_ok=true; // good, exceoption thrown, test passed
249  }
250  ok &= this_ok;
251
252  this_ok=false;
253  try {
254    std::string data("data/vector7.data");
255    check_file_access(data);
256    std::ifstream data_stream(data.c_str());
257    vec=utility::vector(data_stream); // this will give an exception
258  } catch (utility::IO_error& err) {
259    *message << err.what() << std::endl;
260    this_ok=true; // good, exceoption thrown, test passed
261  }
262  ok &= this_ok;
263
264  if (!ok)
265    *message << "vector test failed" << std::endl;
266
267  return (ok ? 0 : -1);
268}
Note: See TracBrowser for help on using the repository browser.