source: trunk/test/vector_test.cc @ 885

Last change on this file since 885 was 885, checked in by Peter, 16 years ago

adding some cleaning

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.4 KB
Line 
1// $Id: vector_test.cc 885 2007-09-23 00:23:39Z peter $
2
3/*
4  Copyright (C) 2004 Peter Johansson
5  Copyright (C) 2005 Jari Häkkinen, Markus Ringnér, Peter Johansson
6  Copyright (C) 2006 Jari Häkkinen
7  Copyright (C) 2007 Jari Häkkinen, Peter Johansson
8
9  This file is part of the yat library, http://trac.thep.lu.se/trac/yat
10
11  The yat library is free software; you can redistribute it and/or
12  modify it under the terms of the GNU General Public License as
13  published by the Free Software Foundation; either version 2 of the
14  License, or (at your option) any later version.
15
16  The yat library is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  General Public License for more details.
20
21  You should have received a copy of the GNU General Public License
22  along with this program; if not, write to the Free Software
23  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
24  02111-1307, USA.
25*/
26
27#include "yat/utility/Exception.h"
28#include "yat/utility/FileUtil.h"
29#include "yat/utility/utility.h"
30#include "yat/utility/vector.h"
31
32#include <fstream>
33#include <sstream>
34
35using namespace theplu::yat;
36
37void check_file_access(std::string& str)
38{
39 
40  if (utility::FileUtil(str).permissions("r")) {
41    std::cerr << "test_nni: Cannot access file " << str << std::endl;
42    exit(-1);
43  }
44}
45
46int main(const int argc,const char* argv[])
47{ 
48  std::ostream* message;
49  if (argc>1 && argv[1]==std::string("-v"))
50    message = &std::cerr;
51  else {
52    message = new std::ofstream("/dev/null");
53    if (argc>1)
54      std::cout << "vector_test -v : for printing extra "  << "information\n";
55  }
56  *message << "testing vector" << std::endl;
57  bool ok = true;
58
59  utility::vector vec(12);
60  for (unsigned int i=0; i<vec.size(); i++) 
61    vec(i)=i;
62
63  // checking that shuffle works
64  *message << "shuffle" << std::endl;
65  double sum_before = utility::sum(vec);
66  shuffle(vec);
67  double sum_after = utility::sum(vec);
68  ok &= (sum_after==sum_before);
69
70  // checking that view works
71  *message << "view" << std::endl;
72  sum_before=0;
73  for (unsigned int i=0; i<vec.size(); i+=2) 
74    sum_before+=vec[i];
75  utility::vector vec_view(vec,0,6,2);
76  sum_after=utility::sum(vec_view);
77  ok &= (sum_after==sum_before);
78  vec[0]=0;
79  vec_view[0]=24;
80  ok &= (vec[0]==vec_view[0]);
81
82  // Test of const view implementation (make sure no zero pointer is
83  // used). Here we use the bad style of not making the view const!
84  // If test fails with a null pointer exception it is an uncatchable
85  // core dump!
86  {
87    *message << "const view implementation" << std::endl;
88    const utility::vector vv(10,3.0);
89    utility::vector vview(vv,0,5,1);
90    // const utility::vector vview(vv,0,5,1); // this is the proper line
91    utility::vector vv2(5,2.0);
92    vv2.mul(vview); // should work even without const since const arg passing
93    vv2.div(vview); // should work even without const since const arg passing
94    ok &= (vview*vview == 3.0*3.0*vview.size());
95  }
96
97  // checking that copy constructor creates an independent object when
98  // a non-view vector is copied
99  {
100    *message << "copy constructor" << std::endl;
101    utility::vector vec2(vec);
102    ok &= (vec.size()==vec2.size());
103    ok &= (vec2==vec);
104    ok &= (&vec2 != &vec);
105    ok &= !vec2.isview();
106  }
107
108  // checking that copy constructor creates an independent object when
109  // a view vector is copied
110  {
111    *message << "copy contructor on view" << std::endl;
112    utility::vector vec3(vec_view);
113    ok &= (vec_view.size()==vec3.size());
114    ok &= (vec3 == vec_view);
115    ok &= (&vec3 != &vec_view);
116    ok &= !vec3.isview();
117  }
118
119  // checking that assignment operator throws an exception if vectors
120  // differ in size
121  {
122    *message << "assignment operator" << std::endl;
123    // GSL will catch the error in this test there for the GSL error
124    // handling must be disabled until after the exception is
125    // catched. The GSL error handler is reinstated after the
126    // try-catch construct.
127    gsl_error_handler_t* err_handler=gsl_set_error_handler_off();
128    bool exception_happens=false;
129    try {
130      utility::vector v(vec_view.size()+1,0.0);
131      v=vec_view;
132    } catch (utility::GSL_error& err) {
133      exception_happens=true;
134    }
135    if (!exception_happens) {
136      *message << "Vector assignment operator did not throw expected exception"
137               << std::endl;
138      ok=false;
139    }
140    gsl_set_error_handler(err_handler);
141  }
142
143  // checking that assignment operator changes the underlying object when
144  // a view is changed.
145  {
146    *message << "assignment operator on view" << std::endl;
147    vec[3]=vec[4]=vec[5]=13;
148    utility::vector vec_view(vec,3,3,1);
149    utility::vector vec2(3,123.0);
150    vec_view=vec2;
151    if (vec[3]!=vec_view[0] || vec[4]!=vec_view[1] || vec[5]!=vec_view[2])
152      ok=false;
153  }
154
155  // checking clone functionality
156  {
157    *message << "clone functionality" << std::endl;
158    bool this_ok=true;
159    *message << "\tcloning normal vector" << std::endl;
160    utility::vector vec2(3,123.0);
161    vec2.clone(vec);
162    if (vec.size()!=vec2.size())
163      this_ok=false;
164    else
165      for (unsigned int i=0; i<vec.size(); ++i)
166        if (vec(i)!=vec2(i))
167          this_ok=false;
168    if (vec.gsl_vector_p()==vec2.gsl_vector_p())
169      this_ok=false;
170    *message << "\tcloning vector view" << std::endl;
171    utility::vector* vec_view=new utility::vector(vec,3,3,1);
172    utility::vector vec_view2;
173    vec_view2.clone(*vec_view);
174    if (!vec_view2.isview())
175      this_ok=false;
176    if (vec_view->size()!=vec_view2.size())
177      this_ok=false;
178    else
179      for (u_int i=0; i<vec_view2.size(); ++i)
180        if ((*vec_view)(i)!=vec_view2(i))
181          this_ok=false;
182    *message << "\tcloned vector view independence" << std::endl;
183    delete vec_view;
184    if (vec[3]!=vec_view2[0] || vec[4]!=vec_view2[1] || vec[5]!=vec_view2[2])
185      this_ok=false;
186
187    if (!this_ok) {
188      *message << "FAIL: clone test" << std::endl;
189      ok=false;
190    }
191  }
192
193  // checking that reading vectors from properly formatted files works
194  try {
195    *message << "stream" << std::endl;
196    std::string data1("data/vector1.data");
197    std::string data2("data/vector2.data");
198    std::string data3("data/vector3.data");
199    std::string data4("data/vector4.data");
200    check_file_access(data1);
201    check_file_access(data2);
202    check_file_access(data3);
203    check_file_access(data4);
204    std::ifstream data_stream1(data1.c_str());
205    std::ifstream data_stream2(data2.c_str());
206    std::ifstream data_stream3(data3.c_str());
207    std::ifstream data_stream4(data4.c_str());
208    utility::vector vec1(data_stream1);
209    ok &= (vec1.size()==9);
210    vec1=utility::vector(data_stream2);
211    ok &= (vec1.size()==9);
212    utility::vector vec2(data_stream3);
213    ok &= (vec2.size()==12);
214    vec2=utility::vector(data_stream4);
215    ok &= (vec2.size()==12);
216  } catch (utility::IO_error& err) {
217    *message << err.what() << std::endl;
218    ok=false;
219  }
220
221  // Checking that vector stream input operator can read whatever
222  // vector stream output operator produces.
223  {
224    *message << "checking that output stream is valid as an input stream"
225             << std::endl;
226    std::stringstream s;
227    s << vec;
228    utility::vector vec2(s);
229    ok &= (vec==vec2);
230  }
231
232  // Checking that badly formatted files are not accepted, or at least
233  // throws an exception for the programmer to catch.
234  *message << "checking that bad stream are rejected" << std::endl;
235  bool this_ok=false;
236  // Checking that unexpected characters in a stream gives error.
237  try {
238    std::string data5("data/vector5.data");
239    check_file_access(data5);
240    std::ifstream data_stream5(data5.c_str());
241    utility::vector dummy(data_stream5); // this will give an exception
242  } catch (utility::IO_error& err) {
243    *message << err.what() << std::endl;
244    this_ok=true; // good, exception thrown, test passed
245  }
246  try {
247    std::string data("data/vector6.data");
248    check_file_access(data);
249    std::ifstream data_stream(data.c_str());
250    utility::vector dummy(data_stream); // this will give an exception
251  } catch (utility::IO_error& err) {
252    *message << err.what() << std::endl;
253    this_ok=true; // good, exceoption thrown, test passed
254  }
255  ok &= this_ok;
256
257  this_ok=false;
258  try {
259    std::string data("data/vector7.data");
260    check_file_access(data);
261    std::ifstream data_stream(data.c_str());
262    vec=utility::vector(data_stream); // this will give an exception
263  } catch (utility::IO_error& err) {
264    *message << err.what() << std::endl;
265    this_ok=true; // good, exceoption thrown, test passed
266  }
267  ok &= this_ok;
268
269
270  // Test sort algorithms
271  {
272    std::string data3("data/vector3.data");
273    std::ifstream data_stream3(data3.c_str());
274    utility::vector vec3(data_stream3);
275    std::vector<size_t> dummy;
276    dummy.push_back(100); // To make sure it works starting with a non-empty vector
277
278    utility::sort_index(dummy,vec3);
279    if(dummy.size()!=vec3.size()) {
280      ok=false;
281      *message << "Vector of sorted indices has incorrect size" << std::endl;
282    }
283    if(dummy[0]!=11 || dummy[dummy.size()-1]!=8) {
284      ok=false;
285      *message << "Vector of sorted indices incorrect" << std::endl;
286    }
287    size_t k=3;
288
289    utility::sort_smallest_index(dummy,k,vec3);
290    if(dummy.size()!=k) {
291      ok=false;
292      *message << "Vector of sorted smallest indices has incorrect size" << std::endl;
293    }
294    if(dummy[0]!=11 || dummy[dummy.size()-1]!=9) {
295      ok=false;
296      *message << "Vector of sorted smallest indices incorrect" << std::endl;
297    }
298
299    k=4;
300    utility::sort_largest_index(dummy,k,vec3);
301    if(dummy.size()!=k) {
302      ok=false;
303      *message << "Vector of sorted largest indices has incorrect size" << std::endl;
304    }
305    if(dummy[0]!=8 || dummy[dummy.size()-1]!=5) {
306      ok=false;
307      *message << "Vector of sorted largest indices incorrect" << std::endl;
308    }
309  }
310
311  if (!ok)
312    *message << "vector test failed" << std::endl;
313
314  if (message!=&std::cerr)
315    delete message;
316
317  return (ok ? 0 : -1);
318}
Note: See TracBrowser for help on using the repository browser.