source: branches/peter-dev/test/vector_test.cc @ 995

Last change on this file since 995 was 995, checked in by Peter, 15 years ago

Splitting vector class into three different classes for vector, view and const_view, and adding abstract classes appropriately. NOTE, the tests are not going through, not even compiling; sorry about that

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