source: trunk/test/vector_test.cc @ 1009

Last change on this file since 1009 was 1009, checked in by Peter, 13 years ago

merging branch peter-dev into trunk delta 1008:994

  • 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 1009 2008-02-01 04:15:44Z 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/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#include "yat/utility/vectorView.h"
32
33#include <fstream>
34#include <sstream>
35
36using namespace theplu::yat;
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::vectorView 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::vectorView 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.isview();
117  }
118
119  /* different sizes are allowed in new design
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
145  // checking that assignment operator changes the underlying object when
146  // a view is changed.
147  {
148    *message << "assignment operator on view" << std::endl;
149    vec[3]=vec[4]=vec[5]=13;
150    utility::vectorView vec_view(vec,3,3,1);
151    utility::vector vec2(3,123.0);
152    vec_view=vec2;
153    if (vec[3]!=vec_view[0] || vec[4]!=vec_view[1] || vec[5]!=vec_view[2]){
154      *message << " failed\n";
155      ok=false;
156    }
157  }
158
159  // checking clone functionality
160  {
161    *message << "clone functionality" << std::endl;
162    bool this_ok=true;
163    *message << "\tcloning normal vector" << std::endl;
164    utility::vector vec2(3,123.0);
165    vec2 = vec;
166    if (vec.size()!=vec2.size())
167      this_ok=false;
168    else
169      for (size_t i=0; i<vec.size(); ++i)
170        if (vec(i)!=vec2(i))
171          this_ok=false;
172    if (vec.gsl_vector_p()==vec2.gsl_vector_p())
173      this_ok=false;
174    *message << "\tcloning vector view" << std::endl;
175    utility::vectorView* vec_view=new utility::vectorView(vec,3,3,1);
176    utility::vectorView vec_view2(*vec_view);
177    if (!vec_view2.isview())
178      this_ok=false;
179    if (vec_view->size()!=vec_view2.size())
180      this_ok=false;
181    else
182      for (u_int i=0; i<vec_view2.size(); ++i)
183        if ((*vec_view)(i)!=vec_view2(i))
184          this_ok=false;
185    *message << "\tcloned vector view independence" << std::endl;
186    delete vec_view;
187    if (vec[3]!=vec_view2[0] || vec[4]!=vec_view2[1] || vec[5]!=vec_view2[2])
188      this_ok=false;
189
190    if (!this_ok) {
191      *message << "FAIL: clone test" << std::endl;
192      ok=false;
193    }
194  }
195
196  // checking that reading vectors from properly formatted files works
197  try {
198    *message << "stream" << std::endl;
199    std::string data1("data/vector1.data");
200    std::string data2("data/vector2.data");
201    std::string data3("data/vector3.data");
202    std::string data4("data/vector4.data");
203    check_file_access(data1);
204    check_file_access(data2);
205    check_file_access(data3);
206    check_file_access(data4);
207    std::ifstream data_stream1(data1.c_str());
208    std::ifstream data_stream2(data2.c_str());
209    std::ifstream data_stream3(data3.c_str());
210    std::ifstream data_stream4(data4.c_str());
211    utility::vector vec1(data_stream1);
212    ok &= (vec1.size()==9);
213    vec1=utility::vector(data_stream2);
214    ok &= (vec1.size()==9);
215    utility::vector vec2(data_stream3);
216    ok &= (vec2.size()==12);
217    vec2=utility::vector(data_stream4);
218    ok &= (vec2.size()==12);
219  } catch (utility::IO_error& err) {
220    *message << err.what() << std::endl;
221    ok=false;
222  }
223
224  // Checking that vector stream input operator can read whatever
225  // vector stream output operator produces.
226  {
227    *message << "checking that output stream is valid as an input stream"
228             << std::endl;
229    std::stringstream s;
230    s << vec;
231    utility::vector vec2(s);
232    ok &= (vec==vec2);
233  }
234
235  // Checking that badly formatted files are not accepted, or at least
236  // throws an exception for the programmer to catch.
237  *message << "checking that bad stream are rejected" << std::endl;
238  bool this_ok=false;
239  // Checking that unexpected characters in a stream gives error.
240  try {
241    std::string data5("data/vector5.data");
242    check_file_access(data5);
243    std::ifstream data_stream5(data5.c_str());
244    utility::vector dummy(data_stream5); // this will give an exception
245  } catch (utility::IO_error& err) {
246    *message << err.what() << std::endl;
247    this_ok=true; // good, exception thrown, test passed
248  }
249  try {
250    std::string data("data/vector6.data");
251    check_file_access(data);
252    std::ifstream data_stream(data.c_str());
253    utility::vector dummy(data_stream); // this will give an exception
254  } catch (utility::IO_error& err) {
255    *message << err.what() << std::endl;
256    this_ok=true; // good, exceoption thrown, test passed
257  }
258  ok &= this_ok;
259
260  this_ok=false;
261  try {
262    std::string data("data/vector7.data");
263    check_file_access(data);
264    std::ifstream data_stream(data.c_str());
265    vec=utility::vector(data_stream); // this will give an exception
266  } catch (utility::IO_error& err) {
267    *message << err.what() << std::endl;
268    this_ok=true; // good, exceoption thrown, test passed
269  }
270  ok &= this_ok;
271
272
273  // Test sort algorithms
274  {
275    std::string data3("data/vector3.data");
276    std::ifstream data_stream3(data3.c_str());
277    utility::vector vec3(data_stream3);
278    std::vector<size_t> dummy;
279    dummy.push_back(100); // To make sure it works starting with a non-empty vector
280
281    utility::sort_index(dummy,vec3);
282    if(dummy.size()!=vec3.size()) {
283      ok=false;
284      *message << "Vector of sorted indices has incorrect size" << std::endl;
285    }
286    if(dummy[0]!=11 || dummy[dummy.size()-1]!=8) {
287      ok=false;
288      *message << "Vector of sorted indices incorrect" << std::endl;
289    }
290    size_t k=3;
291
292    utility::sort_smallest_index(dummy,k,vec3);
293    if(dummy.size()!=k) {
294      ok=false;
295      *message << "Vector of sorted smallest indices has incorrect size" << std::endl;
296    }
297    if(dummy[0]!=11 || dummy[dummy.size()-1]!=9) {
298      ok=false;
299      *message << "Vector of sorted smallest indices incorrect" << std::endl;
300    }
301
302    k=4;
303    utility::sort_largest_index(dummy,k,vec3);
304    if(dummy.size()!=k) {
305      ok=false;
306      *message << "Vector of sorted largest indices has incorrect size" << std::endl;
307    }
308    if(dummy[0]!=8 || dummy[dummy.size()-1]!=5) {
309      ok=false;
310      *message << "Vector of sorted largest indices incorrect" << std::endl;
311    }
312  }
313
314  if (!ok)
315    *message << "vector test failed" << std::endl;
316
317  if (message!=&std::cerr)
318    delete message;
319
320  return (ok ? 0 : -1);
321}
Note: See TracBrowser for help on using the repository browser.