source: trunk/test/vector_test.cc @ 1251

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

make distcheck works - fixes ticket:217

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