OpenWalnut  1.4.0
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( 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( new WGridRegular3D( 3, 4, 5 ) );
164  bool success = false;
165  boost::shared_ptr< std::vector< double > > data( 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
WMatrix & makeIdentity()
Makes the matrix contain the identity matrix, i.e.
Definition: WMatrix.h:352
This data set type contains vectors as values.
A grid that has parallelepiped cells which all have the same proportion.
WVector3d interpolate(const WPosition &pos, bool *success) const
Interpolates the vector field at the given position.
void setUp(void)
Constructs unit test environment.
This only is a 3d double vector.
bool delta(WVector3d lhs, WVector3d rhs, double d)
Computes if both vectors are almost similar and their components do not differ from a certain given d...
void testRotatedGridInterpolate(void)
When the grid for this dataset was rotated the interpolation should still work.
static void startup(std::ostream &output=std::cout, LogLevel level=LL_DEBUG)
Create the first and only instance of the logger as it is a singleton.
Definition: WLogger.cpp:41
void testEigenVectorInterpolate(void)
Checks if the reorientation of the vectors is applied in eigenVectorInterpolate().
const double DBL_EPS
Smallest double such: 1.0 + DBL_EPS == 1.0 is still true.
Definition: WLimits.cpp:36
WVector3d eigenVectorInterpolate(const WPosition &pos, bool *success) const
Interpolates the very same way as interpolate but it assures that all vecs are aligned to point into ...
void testInterpolate(void)
An interpolate of an vector is as if every components were interpolated.
Base Class for all value set types.
Definition: WValueSet.h:46
Implements an orthogonal grid transformation.
void testBoundary_ticket313(void)
Using interpolate on Positions on the boundary of the grid the success flag is true but there should ...
Test basic functionality of WDataSetVector.