source: trunk/test/vector_test.cc @ 1056

Last change on this file since 1056 was 1056, checked in by Peter, 14 years ago

fixes ticket:285

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