source: trunk/test/vector_test.cc @ 1261

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

changing some u_int to size_t

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.5 KB
Line 
1// $Id: vector_test.cc 1261 2008-04-08 14:01:33Z 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, 2008 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 "Suite.h"
28
29#include "yat/utility/Exception.h"
30#include "yat/utility/FileUtil.h"
31#include "yat/utility/utility.h"
32#include "yat/utility/Vector.h"
33#include "yat/utility/VectorConstView.h"
34#include "yat/utility/VectorView.h"
35
36#include <cstddef>
37#include <fstream>
38#include <sstream>
39
40using namespace theplu::yat;
41
42void check_file_access(std::string& str)
43{
44 
45  if (utility::FileUtil(str).permissions("r")) {
46    std::cerr << "test_nni: Cannot access file " << str << std::endl;
47    exit(-1);
48  }
49}
50
51int main(int argc,char* argv[])
52{ 
53  test::Suite suite(argc, argv);
54  suite.err() << "testing vector" << std::endl;
55
56  utility::Vector vec(12);
57  for (size_t i=0; i<vec.size(); i++) 
58    vec(i)=i;
59
60  // checking that shuffle works
61  suite.err() << "shuffle" << std::endl;
62  double sum_before = utility::sum(vec);
63  shuffle(vec);
64  double sum_after = utility::sum(vec);
65  if (sum_after!=sum_before){
66    suite.err() << "shuffle failed" << std::endl;
67    suite.add(false);
68  }
69
70  // checking that view works
71  suite.err() << "view" << std::endl;
72  sum_before=0;
73  for (size_t i=0; i<vec.size(); i+=2) 
74    sum_before+=vec(i);
75  utility::VectorView vec_view(vec,0,6,2);
76  sum_after=utility::sum(vec_view);
77  suite.add(suite.equal(sum_after, sum_before));
78  vec(0)=0;
79  vec_view(0)=24;
80  suite.add(suite.equal(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    suite.err() << "const view implementation" << std::endl;
88    const utility::Vector vv(10,3.0);
89    utility::VectorConstView 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    suite.add(suite.equal(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    suite.err() << "copy constructor" << std::endl;
101    utility::Vector vec2(vec);
102    suite.add(vec.size()==vec2.size());
103    suite.add(suite.equal_range(vec2.begin(), vec2.end(), vec.begin()));
104    suite.add(&vec2 != &vec);
105    suite.add(!vec2.isview());
106  }
107
108  // checking that copy constructor creates an independent object when
109  // a view vector is copied
110  {
111    suite.err() << "copy contructor on view" << std::endl;
112    utility::Vector vec3(vec_view);
113    suite.add(vec_view.size()==vec3.size());
114    suite.add(suite.equal_range(vec3.begin(), vec3.end(), vec_view.begin()));
115    suite.add(!vec3.isview());
116  }
117
118  // checking that assignment operator throws an exception if vectors
119  // differ in size
120  {
121    suite.err() << "assignment operator" << std::endl;
122    // GSL will catch the error in this test there for the GSL error
123    // handling must be disabled until after the exception is
124    // catched. The GSL error handler is reinstated after the
125    // try-catch construct.
126    gsl_error_handler_t* err_handler=gsl_set_error_handler_off();
127    bool exception_happens=false;
128    try {
129      utility::Vector v(vec_view.size()+1,0.0);
130      vec_view=v;
131    } catch (utility::GSL_error& err) {
132      exception_happens=true;
133    }
134    if (!exception_happens) {
135      suite.err() << "Vector assignment operator did not throw expected exception"
136               << std::endl;
137      suite.add(false);
138    }
139    gsl_set_error_handler(err_handler);
140  }
141
142  // checking that assignment operator changes the underlying object when
143  // a view is changed.
144  {
145    suite.err() << "assignment operator on view" << std::endl;
146    vec(3)=vec(4)=vec(5)=13;
147    utility::VectorView vec_view(vec,3,3,1);
148    utility::Vector vec2(3,123.0);
149    vec_view=vec2;
150    if (vec(3)!=vec_view(0) || vec(4)!=vec_view(1) || vec(5)!=vec_view(2)){
151      suite.err() << " failed\n";
152      suite.add(false);
153    }
154  }
155
156  // checking clone functionality
157  {
158    suite.err() << "clone functionality" << std::endl;
159    bool this_ok=true;
160    suite.err() << "\tcloning normal vector" << std::endl;
161    utility::Vector vec2(3,123.0);
162    vec2 = 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    suite.err() << "\tcloning vector view" << std::endl;
172    utility::VectorView* vec_view=new utility::VectorView(vec,3,3,1);
173    utility::VectorView vec_view2(*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 (size_t i=0; i<vec_view2.size(); ++i)
180        if ((*vec_view)(i)!=vec_view2(i))
181          this_ok=false;
182    suite.err() << "\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      suite.err() << "FAIL: clone test" << std::endl;
189      suite.add(false);
190    }
191  }
192
193  // checking that reading vectors from properly formatted files works
194  try {
195    suite.err() << "stream" << std::endl;
196    std::string data1(test::filename("data/vector1.data"));
197    std::string data2(test::filename("data/vector2.data"));
198    std::string data3(test::filename("data/vector3.data"));
199    std::string data4(test::filename("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    suite.add(vec1.size()==9);
210    vec1=utility::Vector(data_stream2);
211    suite.add(vec1.size()==9);
212    utility::Vector vec2(data_stream3);
213    suite.add(vec2.size()==12);
214    vec2=utility::Vector(data_stream4);
215    suite.add(vec2.size()==12);
216  } catch (utility::IO_error& err) {
217    suite.err() << err.what() << std::endl;
218    suite.add(false);
219  }
220
221  // Checking that vector stream input operator can read whatever
222  // vector stream output operator produces.
223  {
224    suite.err() << "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    suite.add(suite.equal_range(vec.begin(), vec.end(), vec2.begin()));
230  }
231
232  // Checking that badly formatted files are not accepted, or at least
233  // throws an exception for the programmer to catch.
234  suite.err() << "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(test::filename("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    suite.err() << err.what() << std::endl;
244    this_ok=true; // good, exception thrown, test passed
245  }
246  try {
247    std::string data(test::filename("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    suite.err() << err.what() << std::endl;
253    this_ok=true; // good, exceoption thrown, test passed
254  }
255  suite.add(this_ok);
256
257  this_ok=false;
258  try {
259    std::string data(test::filename("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    suite.err() << err.what() << std::endl;
265    this_ok=true; // good, exceoption thrown, test passed
266  }
267  suite.add(this_ok);
268
269
270  // Test sort algorithms
271  {
272    std::string data3(test::filename("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      suite.add(false);
281      suite.err() << "Vector of sorted indices has incorrect size" << std::endl;
282    }
283    if(dummy[0]!=11 || dummy[dummy.size()-1]!=8) {
284      suite.add(false);
285      suite.err() << "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      suite.add(false);
292      suite.err() << "Vector of sorted smallest indices has incorrect size" << std::endl;
293    }
294    if(dummy[0]!=11 || dummy[dummy.size()-1]!=9) {
295      suite.add(false);
296      suite.err() << "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      suite.add(false);
303      suite.err() << "Vector of sorted largest indices has incorrect size" << std::endl;
304    }
305    if(dummy[0]!=8 || dummy[dummy.size()-1]!=5) {
306      suite.add(false);
307      suite.err() << "Vector of sorted largest indices incorrect" << std::endl;
308    }
309  }
310
311  {
312    utility::Vector vec(10, 2.3);
313    utility::VectorView vv(vec);
314    vec = vv;
315    if (vec.size()!=10){
316      suite.err() << "indirect self-assignment failed - size should be 10\n";
317      suite.add(false);
318    }
319    if (vec(0)!=2.3){
320      suite.err() << "indirect self-assignment failed - vec(0) should be 2.3\n";
321      suite.add(false);
322    }
323    utility::VectorView vv2(vec, 0, 5);
324    vec = vv2;
325    if (vec.size()!=5){
326      suite.err() << "indirect self-assignment failed - size should be 5\n";
327      suite.add(false);
328    }
329    if (vec(0)!=2.3){
330      suite.err() << "indirect self-assignment failed - vec(0) should be 2.3\n";
331      suite.add(false);
332    }
333  }
334
335  // test for ticket:285
336  {
337    theplu::yat::utility::Vector vec(10);
338    theplu::yat::utility::Vector vec2;
339    vec2 = vec;
340  }
341
342  return suite.return_value();
343}
Note: See TracBrowser for help on using the repository browser.