OpenWalnut  1.3.1
WDataSetVector_test.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WDATASETVECTOR_TEST_H
26 #define WDATASETVECTOR_TEST_H
27 
28 #include <vector>
29 #include <cmath>
30 
31 #include <boost/array.hpp>
32 
33 #include <cxxtest/TestSuite.h>
34 
35 #include "../../common/WLogger.h"
36 #include "../WDataSetVector.h"
37 
38 /**
39  * Test basic functionality of WDataSetVector.
40  */
41 class WDataSetVectorTest : public CxxTest::TestSuite
42 {
43 public:
44  /**
45  * Constructs unit test environment.
46  */
47  void setUp( void )
48  {
50  }
51 
52  /**
53  * An interpolate of an vector is as if every components were interpolated
54  */
55  void testInterpolate( void )
56  {
57  boost::shared_ptr< WGridRegular3D > grid( new WGridRegular3D( 2, 2, 2 ) );
58  boost::array< WPosition, 8 > d = { { WPosition( 0, 1, 2 ), WPosition( 3, 4, 5 ), WPosition( 6, 7, 8 ), // NOLINT braces
59  WPosition( 9,10,11 ), WPosition( 12,13,14 ), WPosition( 15,16,17 ), WPosition( 18,19,20 ), WPosition( 21,22,23 ) } }; // NOLINT braces
60 
61  boost::shared_ptr< std::vector< double > > data( new std::vector< double > );
62  for( size_t i = 0; i < grid->size() * 3; ++i )
63  {
64  data->push_back( i );
65  }
66 
67  double almost1 = 1 - wlimits::DBL_EPS;
68  boost::array< WPosition, 8 > gridPos = { { WPosition( 0, 0, 0 ), WPosition( almost1, 0, 0 ), WPosition( 0, almost1, 0 ), // NOLINT braces
69  WPosition( almost1, almost1, 0 ), WPosition( 0, 0, almost1 ), WPosition( almost1, 0, almost1 ),
70  WPosition( 0, almost1, almost1 ), WPosition( almost1, almost1, almost1 ) } }; // NOLINT braces
71 
72  boost::shared_ptr< WValueSet< double > > valueSet( new WValueSet< double >( 1, 3, data, W_DT_DOUBLE ) );
73  WDataSetVector ds( valueSet, grid );
74 
75  bool success = false;
76  for( size_t i = 0; i < 8; ++i )
77  {
78  if( !delta( ds.interpolate( gridPos[i], &success ), d[i], 1e-9 ) )
79  {
80  std::stringstream ss;
81  ss << "i:" << i << " gridPos(i):" << gridPos[i] << " d(i):" << d[i] << " interpol:" << ds.interpolate( gridPos[i], &success ) << "\n";
82  TS_FAIL( ss.str() );
83  }
84  TS_ASSERT( success );
85  }
86 
87  TS_ASSERT( delta( ds.interpolate( WPosition( 0.3, 0.4, 0.5 ), &success ), WPosition( 9.3, 10.3, 11.3 ), 1e-9 ) );
88  TS_ASSERT( success );
89  TS_ASSERT( delta( ds.interpolate( WPosition( 0.5, 0.5, 0.5 ), &success ), WPosition( 10.5, 11.5, 12.5 ), 1e-9 ) );
90  TS_ASSERT( success );
91  }
92 
93  /**
94  * Checks if the reorientation of the vectors is applied in eigenVectorInterpolate().
95  \verbatim
96  v_6( 1, 0, 0 ) v_7( 1, 0, 0 )
97  /----------------------------/
98  z A /| /|
99  | / | / |
100  |/ | / |
101  /---+------------------------/ |
102  v_4( 1, 0, 0 ) v_5( 1, 0, 0 )
103  | | | |
104  | | | |
105  | | | |
106  | | y | |
107  | | / | |
108  | | / | |
109  | | / | |
110  | | v_2( 1, 0, 0 ) | | v_3( 1, 0, 0 )
111  | /------------------------+---/
112  | / | /
113  | / | /
114  |/ |/
115  /----------------------------/------------------> x
116  v_0( -1, 0, 0) v_1( 1, 0, 0 )
117 
118  \endverbatim
119  */
121  {
122  boost::shared_ptr< WGrid > grid = boost::shared_ptr< WGrid >( new WGridRegular3D( 2, 2, 2 ) );
123  boost::shared_ptr< std::vector< double > > data( new std::vector< double > );
124  boost::array< WPosition, 8 > d = { { WPosition( -1, 0, 0 ), // NOLINT braces
125  WPosition( 1, 0, 0 ),
126  WPosition( 1, 0, 0 ),
127  WPosition( 1, 0, 0 ),
128  WPosition( 1, 0, 0 ),
129  WPosition( 1, 0, 0 ),
130  WPosition( 1, 0, 0 ),
131  WPosition( 1, 0, 0 ) } }; // NOLINT braces
132 
133  for( size_t i = 0; i < grid->size(); ++i )
134  {
135  data->push_back( d[i][0] );
136  data->push_back( d[i][1] );
137  data->push_back( d[i][2] );
138  }
139  boost::shared_ptr< WValueSet< double > > valueSet( new WValueSet< double >( 1, 3, data, W_DT_DOUBLE ) );
140  WDataSetVector ds( valueSet, grid );
141 
142  bool success = false;
143  TS_ASSERT_EQUALS( ds.interpolate( WPosition( 0.0, 0.0, 0.0 ), &success ), d[0] );
144  TS_ASSERT( success );
145  TS_ASSERT( delta( ds.interpolate( WPosition( 0.9999, 0.9999, 0.9999 ), &success ), d[7], 1e-9 ) );
146  TS_ASSERT( success );
147  TS_ASSERT_EQUALS( ds.interpolate( WPosition( 0.5, 0.5, 0.5 ), &success ), WPosition( 0.75, 0.0, 0.0 ) );
148  TS_ASSERT( success );
149  TS_ASSERT_EQUALS( ds.eigenVectorInterpolate( WPosition( 0.0, 0.0, 0.0 ), &success ), d[0] );
150  TS_ASSERT( success );
151  TS_ASSERT( delta( ds.eigenVectorInterpolate( WPosition( 0.9999, 0.9999, 0.9999 ), &success ), WPosition( -1.0, 0.0, 0.0 ), 1e-9 ) );
152  TS_ASSERT( success );
153  TS_ASSERT_EQUALS( ds.eigenVectorInterpolate( WPosition( 0.5, 0.5, 0.5 ), &success ), WPosition( -1.0, 0.0, 0.0 ) );
154  TS_ASSERT( success );
155  }
156 
157  /**
158  * Using interpolate on Positions on the boundary of the grid the success flag is true but there should not be any segfaults.
159  * See ticket #313 for more informations.
160  */
162  {
163  boost::shared_ptr< WGridRegular3D > grid = boost::shared_ptr< WGridRegular3D >( new WGridRegular3D( 3, 4, 5 ) );
164  bool success = false;
165  boost::shared_ptr< std::vector< double > > data = boost::shared_ptr< std::vector< double > >( new std::vector< double >( grid->size() * 3 ) );
166  for( size_t i = 0; i < grid->size() * 3; ++i )
167  {
168  ( *data )[i] = i;
169  }
170  boost::shared_ptr< WValueSet< double > > valueSet( new WValueSet< double >( 1, 3, data, W_DT_DOUBLE ) );
171  WDataSetVector ds( valueSet, grid );
172  ds.interpolate( WPosition( 2.0, 3.0, 4.0 ), &success );
173  TS_ASSERT( !success );
174  }
175 
176  /**
177  * When the grid for this dataset was rotated the interpolation should still work.
178  */
180  {
181  // rotation around z with 45 degrees
182  WMatrix< double > mat( 4, 4 );
183  mat.makeIdentity();
184  mat( 0, 0 ) = 1.0 / sqrt( 2.0 );
185  mat( 0, 1 ) = 1.0 / sqrt( 2.0 );
186  mat( 1, 0 ) = -1.0 / sqrt( 2.0 );
187  mat( 1, 1 ) = 1.0 / sqrt( 2.0 );
188 
189  WGridTransformOrtho v( mat );
190 
191  boost::shared_ptr< WGridRegular3D > grid( new WGridRegular3D( 2, 2, 2, v ) );
192  boost::shared_ptr< std::vector< double > > data( new std::vector< double > );
193  boost::array< WPosition, 8 > d = { { WPosition( -1, 0, 0 ), // NOLINT braces
194  WPosition( 1, 0, 0 ),
195  WPosition( 1, 0, 0 ),
196  WPosition( 1, 0, 0 ),
197  WPosition( 1, 0, 0 ),
198  WPosition( 1, 0, 0 ),
199  WPosition( 1, 0, 0 ),
200  WPosition( 1, 0, 0 ) } }; // NOLINT braces
201 
202  for( size_t i = 0; i < grid->size(); ++i )
203  {
204  data->push_back( d[i][0] );
205  data->push_back( d[i][1] );
206  data->push_back( d[i][2] );
207  }
208  boost::shared_ptr< WValueSet< double > > valueSet( new WValueSet< double >( 1, 3, data, W_DT_DOUBLE ) );
209  WDataSetVector ds( valueSet, grid );
210 
211  bool success = false;
212  WPosition pos = grid->getTransform().positionToWorldSpace( WPosition( 0.0, 0.0, 0.0 ) );
213  TS_ASSERT_EQUALS( ds.interpolate( pos, &success ), d[0] );
214  TS_ASSERT( success );
215  pos = grid->getTransform().positionToWorldSpace( WPosition( 0.9999, 0.9999, 0.9999 ) );
216  TS_ASSERT( delta( ds.interpolate( pos, &success ), d[7], 1e-9 ) );
217  TS_ASSERT( success );
218  pos = grid->getTransform().positionToWorldSpace( WPosition( 0.5, 0.5, 0.5 ) );
219  TS_ASSERT_EQUALS( ds.interpolate( pos, &success ), WPosition( 0.75, 0.0, 0.0 ) );
220  TS_ASSERT( success );
221  pos = grid->getTransform().positionToWorldSpace( WPosition( 0.0, 0.0, 0.0 ) );
222  TS_ASSERT_EQUALS( ds.eigenVectorInterpolate( pos, &success ), d[0] );
223  TS_ASSERT( success );
224  pos = grid->getTransform().positionToWorldSpace( WPosition( 0.9999, 0.9999, 0.9999 ) );
225  TS_ASSERT( delta( ds.eigenVectorInterpolate( pos, &success ), WPosition( -1.0, 0.0, 0.0 ), 1e-9 ) );
226  TS_ASSERT( success );
227  pos = grid->getTransform().positionToWorldSpace( WPosition( 0.5, 0.5, 0.5 ) );
228  TS_ASSERT_EQUALS( ds.eigenVectorInterpolate( pos, &success ), WPosition( -1.0, 0.0, 0.0 ) );
229  TS_ASSERT( success );
230  }
231 
232 private:
233  /**
234  * Computes if both vectors are almost similar and their components do not differ from a certain given delta.
235  *
236  * \param lhs First vector
237  * \param rhs Second vector
238  * \param d The given delta
239  *
240  * \return True if and only if all components differing at most by the given delta.
241  */
242  bool delta( WVector3d lhs, WVector3d rhs, double d )
243  {
244  bool result = true;
245  for( int i = 0; result && ( i < 3 ); ++i )
246  {
247  result = result && ( std::abs( lhs[i] - rhs[i] ) <= d );
248  if( !result )
249  {
250  std::cout.precision( 10 );
251  std::cout.setf( std::ios::fixed, std::ios::floatfield );
252  std::cout << "delta failed! => lhs:" << lhs << " rhs:" << rhs << " failed: abs(lhs[" << i << "] - rhs["
253  << i << "])=" << std::abs( lhs[i] - rhs[i] ) << ", but should be: " << d << "\n";
254  }
255  }
256  return result;
257  }
258 };
259 
260 #endif // WDATASETVECTOR_TEST_H