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 #ifndef Q_MOC_RUN
32 #include <boost/array.hpp>
33 #endif
34 
35 #include <cxxtest/TestSuite.h>
36 
37 #include "../../common/WLogger.h"
38 #include "../WDataSetVector.h"
39 
40 /**
41  * Test basic functionality of WDataSetVector.
42  */
43 class WDataSetVectorTest : public CxxTest::TestSuite
44 {
45 public:
46  /**
47  * Constructs unit test environment.
48  */
49  void setUp( void )
50  {
52  }
53 
54  /**
55  * An interpolate of an vector is as if every components were interpolated
56  */
57  void testInterpolate( void )
58  {
59  boost::shared_ptr< WGridRegular3D > grid( new WGridRegular3D( 2, 2, 2 ) );
60  boost::array< WPosition, 8 > d = { { WPosition( 0, 1, 2 ), WPosition( 3, 4, 5 ), WPosition( 6, 7, 8 ), // NOLINT braces
61  WPosition( 9,10,11 ), WPosition( 12,13,14 ), WPosition( 15,16,17 ), WPosition( 18,19,20 ), WPosition( 21,22,23 ) } }; // NOLINT braces
62 
63  boost::shared_ptr< std::vector< double > > data( new std::vector< double > );
64  for( size_t i = 0; i < grid->size() * 3; ++i )
65  {
66  data->push_back( i );
67  }
68 
69  double almost1 = 1 - wlimits::DBL_EPS;
70  boost::array< WPosition, 8 > gridPos = { { WPosition( 0, 0, 0 ), WPosition( almost1, 0, 0 ), WPosition( 0, almost1, 0 ), // NOLINT braces
71  WPosition( almost1, almost1, 0 ), WPosition( 0, 0, almost1 ), WPosition( almost1, 0, almost1 ),
72  WPosition( 0, almost1, almost1 ), WPosition( almost1, almost1, almost1 ) } }; // NOLINT braces
73 
74  boost::shared_ptr< WValueSet< double > > valueSet( new WValueSet< double >( 1, 3, data, W_DT_DOUBLE ) );
75  WDataSetVector ds( valueSet, grid );
76 
77  bool success = false;
78  for( size_t i = 0; i < 8; ++i )
79  {
80  if( !delta( ds.interpolate( gridPos[i], &success ), d[i], 1e-9 ) )
81  {
82  std::stringstream ss;
83  ss << "i:" << i << " gridPos(i):" << gridPos[i] << " d(i):" << d[i] << " interpol:" << ds.interpolate( gridPos[i], &success ) << "\n";
84  TS_FAIL( ss.str() );
85  }
86  TS_ASSERT( success );
87  }
88 
89  TS_ASSERT( delta( ds.interpolate( WPosition( 0.3, 0.4, 0.5 ), &success ), WPosition( 9.3, 10.3, 11.3 ), 1e-9 ) );
90  TS_ASSERT( success );
91  TS_ASSERT( delta( ds.interpolate( WPosition( 0.5, 0.5, 0.5 ), &success ), WPosition( 10.5, 11.5, 12.5 ), 1e-9 ) );
92  TS_ASSERT( success );
93  }
94 
95  /**
96  * Checks if the reorientation of the vectors is applied in eigenVectorInterpolate().
97  \verbatim
98  v_6( 1, 0, 0 ) v_7( 1, 0, 0 )
99  /----------------------------/
100  z A /| /|
101  | / | / |
102  |/ | / |
103  /---+------------------------/ |
104  v_4( 1, 0, 0 ) v_5( 1, 0, 0 )
105  | | | |
106  | | | |
107  | | | |
108  | | y | |
109  | | / | |
110  | | / | |
111  | | / | |
112  | | v_2( 1, 0, 0 ) | | v_3( 1, 0, 0 )
113  | /------------------------+---/
114  | / | /
115  | / | /
116  |/ |/
117  /----------------------------/------------------> x
118  v_0( -1, 0, 0) v_1( 1, 0, 0 )
119 
120  \endverbatim
121  */
123  {
124  boost::shared_ptr< WGrid > grid( new WGridRegular3D( 2, 2, 2 ) );
125  boost::shared_ptr< std::vector< double > > data( new std::vector< double > );
126  boost::array< WPosition, 8 > d = { { WPosition( -1, 0, 0 ), // NOLINT braces
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 ),
132  WPosition( 1, 0, 0 ),
133  WPosition( 1, 0, 0 ) } }; // NOLINT braces
134 
135  for( size_t i = 0; i < grid->size(); ++i )
136  {
137  data->push_back( d[i][0] );
138  data->push_back( d[i][1] );
139  data->push_back( d[i][2] );
140  }
141  boost::shared_ptr< WValueSet< double > > valueSet( new WValueSet< double >( 1, 3, data, W_DT_DOUBLE ) );
142  WDataSetVector ds( valueSet, grid );
143 
144  bool success = false;
145  TS_ASSERT_EQUALS( ds.interpolate( WPosition( 0.0, 0.0, 0.0 ), &success ), d[0] );
146  TS_ASSERT( success );
147  TS_ASSERT( delta( ds.interpolate( WPosition( 0.9999, 0.9999, 0.9999 ), &success ), d[7], 1e-9 ) );
148  TS_ASSERT( success );
149  TS_ASSERT_EQUALS( ds.interpolate( WPosition( 0.5, 0.5, 0.5 ), &success ), WPosition( 0.75, 0.0, 0.0 ) );
150  TS_ASSERT( success );
151  TS_ASSERT_EQUALS( ds.eigenVectorInterpolate( WPosition( 0.0, 0.0, 0.0 ), &success ), d[0] );
152  TS_ASSERT( success );
153  TS_ASSERT( delta( ds.eigenVectorInterpolate( WPosition( 0.9999, 0.9999, 0.9999 ), &success ), WPosition( -1.0, 0.0, 0.0 ), 1e-9 ) );
154  TS_ASSERT( success );
155  TS_ASSERT_EQUALS( ds.eigenVectorInterpolate( WPosition( 0.5, 0.5, 0.5 ), &success ), WPosition( -1.0, 0.0, 0.0 ) );
156  TS_ASSERT( success );
157  }
158 
159  /**
160  * Using interpolate on Positions on the boundary of the grid the success flag is true but there should not be any segfaults.
161  * See ticket #313 for more informations.
162  */
164  {
165  boost::shared_ptr< WGridRegular3D > grid( new WGridRegular3D( 3, 4, 5 ) );
166  bool success = false;
167  boost::shared_ptr< std::vector< double > > data( new std::vector< double >( grid->size() * 3 ) );
168  for( size_t i = 0; i < grid->size() * 3; ++i )
169  {
170  ( *data )[i] = i;
171  }
172  boost::shared_ptr< WValueSet< double > > valueSet( new WValueSet< double >( 1, 3, data, W_DT_DOUBLE ) );
173  WDataSetVector ds( valueSet, grid );
174  ds.interpolate( WPosition( 2.0, 3.0, 4.0 ), &success );
175  TS_ASSERT( !success );
176  }
177 
178  /**
179  * When the grid for this dataset was rotated the interpolation should still work.
180  */
182  {
183  // rotation around z with 45 degrees
184  WMatrix< double > mat( 4, 4 );
185  mat.makeIdentity();
186  mat( 0, 0 ) = 1.0 / sqrt( 2.0 );
187  mat( 0, 1 ) = 1.0 / sqrt( 2.0 );
188  mat( 1, 0 ) = -1.0 / sqrt( 2.0 );
189  mat( 1, 1 ) = 1.0 / sqrt( 2.0 );
190 
191  WGridTransformOrtho v( mat );
192 
193  boost::shared_ptr< WGridRegular3D > grid( new WGridRegular3D( 2, 2, 2, v ) );
194  boost::shared_ptr< std::vector< double > > data( new std::vector< double > );
195  boost::array< WPosition, 8 > d = { { WPosition( -1, 0, 0 ), // NOLINT braces
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 ),
201  WPosition( 1, 0, 0 ),
202  WPosition( 1, 0, 0 ) } }; // NOLINT braces
203 
204  for( size_t i = 0; i < grid->size(); ++i )
205  {
206  data->push_back( d[i][0] );
207  data->push_back( d[i][1] );
208  data->push_back( d[i][2] );
209  }
210  boost::shared_ptr< WValueSet< double > > valueSet( new WValueSet< double >( 1, 3, data, W_DT_DOUBLE ) );
211  WDataSetVector ds( valueSet, grid );
212 
213  bool success = false;
214  WPosition pos = grid->getTransform().positionToWorldSpace( WPosition( 0.0, 0.0, 0.0 ) );
215  TS_ASSERT_EQUALS( ds.interpolate( pos, &success ), d[0] );
216  TS_ASSERT( success );
217  pos = grid->getTransform().positionToWorldSpace( WPosition( 0.9999, 0.9999, 0.9999 ) );
218  TS_ASSERT( delta( ds.interpolate( pos, &success ), d[7], 1e-9 ) );
219  TS_ASSERT( success );
220  pos = grid->getTransform().positionToWorldSpace( WPosition( 0.5, 0.5, 0.5 ) );
221  TS_ASSERT_EQUALS( ds.interpolate( pos, &success ), WPosition( 0.75, 0.0, 0.0 ) );
222  TS_ASSERT( success );
223  pos = grid->getTransform().positionToWorldSpace( WPosition( 0.0, 0.0, 0.0 ) );
224  TS_ASSERT_EQUALS( ds.eigenVectorInterpolate( pos, &success ), d[0] );
225  TS_ASSERT( success );
226  pos = grid->getTransform().positionToWorldSpace( WPosition( 0.9999, 0.9999, 0.9999 ) );
227  TS_ASSERT( delta( ds.eigenVectorInterpolate( pos, &success ), WPosition( -1.0, 0.0, 0.0 ), 1e-9 ) );
228  TS_ASSERT( success );
229  pos = grid->getTransform().positionToWorldSpace( WPosition( 0.5, 0.5, 0.5 ) );
230  TS_ASSERT_EQUALS( ds.eigenVectorInterpolate( pos, &success ), WPosition( -1.0, 0.0, 0.0 ) );
231  TS_ASSERT( success );
232  }
233 
234 private:
235  /**
236  * Computes if both vectors are almost similar and their components do not differ from a certain given delta.
237  *
238  * \param lhs First vector
239  * \param rhs Second vector
240  * \param d The given delta
241  *
242  * \return True if and only if all components differing at most by the given delta.
243  */
244  bool delta( WVector3d lhs, WVector3d rhs, double d )
245  {
246  bool result = true;
247  for( int i = 0; result && ( i < 3 ); ++i )
248  {
249  result = result && ( std::abs( lhs[i] - rhs[i] ) <= d );
250  if( !result )
251  {
252  std::cout.precision( 10 );
253  std::cout.setf( std::ios::fixed, std::ios::floatfield );
254  std::cout << "delta failed! => lhs:" << lhs << " rhs:" << rhs << " failed: abs(lhs[" << i << "] - rhs["
255  << i << "])=" << std::abs( lhs[i] - rhs[i] ) << ", but should be: " << d << "\n";
256  }
257  }
258  return result;
259  }
260 };
261 
262 #endif // WDATASETVECTOR_TEST_H
This data set type contains vectors as values.
A grid that has parallelepiped cells which all have the same proportion.
WMatrix & makeIdentity()
Makes the matrix contain the identity matrix, i.e.
Definition: WMatrix.h:352
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:48
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.