OpenWalnut
1.4.0
|
00001 //--------------------------------------------------------------------------- 00002 // 00003 // Project: OpenWalnut ( http://www.openwalnut.org ) 00004 // 00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS 00006 // For more information see http://www.openwalnut.org/copying 00007 // 00008 // This file is part of OpenWalnut. 00009 // 00010 // OpenWalnut is free software: you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as published by 00012 // the Free Software Foundation, either version 3 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // OpenWalnut is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public License 00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>. 00022 // 00023 //--------------------------------------------------------------------------- 00024 00025 #ifndef WDATASETVECTOR_TEST_H 00026 #define WDATASETVECTOR_TEST_H 00027 00028 #include <vector> 00029 #include <cmath> 00030 00031 #include <boost/array.hpp> 00032 00033 #include <cxxtest/TestSuite.h> 00034 00035 #include "../../common/WLogger.h" 00036 #include "../WDataSetVector.h" 00037 00038 /** 00039 * Test basic functionality of WDataSetVector. 00040 */ 00041 class WDataSetVectorTest : public CxxTest::TestSuite 00042 { 00043 public: 00044 /** 00045 * Constructs unit test environment. 00046 */ 00047 void setUp( void ) 00048 { 00049 WLogger::startup(); 00050 } 00051 00052 /** 00053 * An interpolate of an vector is as if every components were interpolated 00054 */ 00055 void testInterpolate( void ) 00056 { 00057 boost::shared_ptr< WGridRegular3D > grid( new WGridRegular3D( 2, 2, 2 ) ); 00058 boost::array< WPosition, 8 > d = { { WPosition( 0, 1, 2 ), WPosition( 3, 4, 5 ), WPosition( 6, 7, 8 ), // NOLINT braces 00059 WPosition( 9,10,11 ), WPosition( 12,13,14 ), WPosition( 15,16,17 ), WPosition( 18,19,20 ), WPosition( 21,22,23 ) } }; // NOLINT braces 00060 00061 boost::shared_ptr< std::vector< double > > data( new std::vector< double > ); 00062 for( size_t i = 0; i < grid->size() * 3; ++i ) 00063 { 00064 data->push_back( i ); 00065 } 00066 00067 double almost1 = 1 - wlimits::DBL_EPS; 00068 boost::array< WPosition, 8 > gridPos = { { WPosition( 0, 0, 0 ), WPosition( almost1, 0, 0 ), WPosition( 0, almost1, 0 ), // NOLINT braces 00069 WPosition( almost1, almost1, 0 ), WPosition( 0, 0, almost1 ), WPosition( almost1, 0, almost1 ), 00070 WPosition( 0, almost1, almost1 ), WPosition( almost1, almost1, almost1 ) } }; // NOLINT braces 00071 00072 boost::shared_ptr< WValueSet< double > > valueSet( new WValueSet< double >( 1, 3, data, W_DT_DOUBLE ) ); 00073 WDataSetVector ds( valueSet, grid ); 00074 00075 bool success = false; 00076 for( size_t i = 0; i < 8; ++i ) 00077 { 00078 if( !delta( ds.interpolate( gridPos[i], &success ), d[i], 1e-9 ) ) 00079 { 00080 std::stringstream ss; 00081 ss << "i:" << i << " gridPos(i):" << gridPos[i] << " d(i):" << d[i] << " interpol:" << ds.interpolate( gridPos[i], &success ) << "\n"; 00082 TS_FAIL( ss.str() ); 00083 } 00084 TS_ASSERT( success ); 00085 } 00086 00087 TS_ASSERT( delta( ds.interpolate( WPosition( 0.3, 0.4, 0.5 ), &success ), WPosition( 9.3, 10.3, 11.3 ), 1e-9 ) ); 00088 TS_ASSERT( success ); 00089 TS_ASSERT( delta( ds.interpolate( WPosition( 0.5, 0.5, 0.5 ), &success ), WPosition( 10.5, 11.5, 12.5 ), 1e-9 ) ); 00090 TS_ASSERT( success ); 00091 } 00092 00093 /** 00094 * Checks if the reorientation of the vectors is applied in eigenVectorInterpolate(). 00095 \verbatim 00096 v_6( 1, 0, 0 ) v_7( 1, 0, 0 ) 00097 /----------------------------/ 00098 z A /| /| 00099 | / | / | 00100 |/ | / | 00101 /---+------------------------/ | 00102 v_4( 1, 0, 0 ) v_5( 1, 0, 0 ) 00103 | | | | 00104 | | | | 00105 | | | | 00106 | | y | | 00107 | | / | | 00108 | | / | | 00109 | | / | | 00110 | | v_2( 1, 0, 0 ) | | v_3( 1, 0, 0 ) 00111 | /------------------------+---/ 00112 | / | / 00113 | / | / 00114 |/ |/ 00115 /----------------------------/------------------> x 00116 v_0( -1, 0, 0) v_1( 1, 0, 0 ) 00117 00118 \endverbatim 00119 */ 00120 void testEigenVectorInterpolate( void ) 00121 { 00122 boost::shared_ptr< WGrid > grid( new WGridRegular3D( 2, 2, 2 ) ); 00123 boost::shared_ptr< std::vector< double > > data( new std::vector< double > ); 00124 boost::array< WPosition, 8 > d = { { WPosition( -1, 0, 0 ), // NOLINT braces 00125 WPosition( 1, 0, 0 ), 00126 WPosition( 1, 0, 0 ), 00127 WPosition( 1, 0, 0 ), 00128 WPosition( 1, 0, 0 ), 00129 WPosition( 1, 0, 0 ), 00130 WPosition( 1, 0, 0 ), 00131 WPosition( 1, 0, 0 ) } }; // NOLINT braces 00132 00133 for( size_t i = 0; i < grid->size(); ++i ) 00134 { 00135 data->push_back( d[i][0] ); 00136 data->push_back( d[i][1] ); 00137 data->push_back( d[i][2] ); 00138 } 00139 boost::shared_ptr< WValueSet< double > > valueSet( new WValueSet< double >( 1, 3, data, W_DT_DOUBLE ) ); 00140 WDataSetVector ds( valueSet, grid ); 00141 00142 bool success = false; 00143 TS_ASSERT_EQUALS( ds.interpolate( WPosition( 0.0, 0.0, 0.0 ), &success ), d[0] ); 00144 TS_ASSERT( success ); 00145 TS_ASSERT( delta( ds.interpolate( WPosition( 0.9999, 0.9999, 0.9999 ), &success ), d[7], 1e-9 ) ); 00146 TS_ASSERT( success ); 00147 TS_ASSERT_EQUALS( ds.interpolate( WPosition( 0.5, 0.5, 0.5 ), &success ), WPosition( 0.75, 0.0, 0.0 ) ); 00148 TS_ASSERT( success ); 00149 TS_ASSERT_EQUALS( ds.eigenVectorInterpolate( WPosition( 0.0, 0.0, 0.0 ), &success ), d[0] ); 00150 TS_ASSERT( success ); 00151 TS_ASSERT( delta( ds.eigenVectorInterpolate( WPosition( 0.9999, 0.9999, 0.9999 ), &success ), WPosition( -1.0, 0.0, 0.0 ), 1e-9 ) ); 00152 TS_ASSERT( success ); 00153 TS_ASSERT_EQUALS( ds.eigenVectorInterpolate( WPosition( 0.5, 0.5, 0.5 ), &success ), WPosition( -1.0, 0.0, 0.0 ) ); 00154 TS_ASSERT( success ); 00155 } 00156 00157 /** 00158 * Using interpolate on Positions on the boundary of the grid the success flag is true but there should not be any segfaults. 00159 * See ticket #313 for more informations. 00160 */ 00161 void testBoundary_ticket313( void ) 00162 { 00163 boost::shared_ptr< WGridRegular3D > grid( new WGridRegular3D( 3, 4, 5 ) ); 00164 bool success = false; 00165 boost::shared_ptr< std::vector< double > > data( new std::vector< double >( grid->size() * 3 ) ); 00166 for( size_t i = 0; i < grid->size() * 3; ++i ) 00167 { 00168 ( *data )[i] = i; 00169 } 00170 boost::shared_ptr< WValueSet< double > > valueSet( new WValueSet< double >( 1, 3, data, W_DT_DOUBLE ) ); 00171 WDataSetVector ds( valueSet, grid ); 00172 ds.interpolate( WPosition( 2.0, 3.0, 4.0 ), &success ); 00173 TS_ASSERT( !success ); 00174 } 00175 00176 /** 00177 * When the grid for this dataset was rotated the interpolation should still work. 00178 */ 00179 void testRotatedGridInterpolate( void ) 00180 { 00181 // rotation around z with 45 degrees 00182 WMatrix< double > mat( 4, 4 ); 00183 mat.makeIdentity(); 00184 mat( 0, 0 ) = 1.0 / sqrt( 2.0 ); 00185 mat( 0, 1 ) = 1.0 / sqrt( 2.0 ); 00186 mat( 1, 0 ) = -1.0 / sqrt( 2.0 ); 00187 mat( 1, 1 ) = 1.0 / sqrt( 2.0 ); 00188 00189 WGridTransformOrtho v( mat ); 00190 00191 boost::shared_ptr< WGridRegular3D > grid( new WGridRegular3D( 2, 2, 2, v ) ); 00192 boost::shared_ptr< std::vector< double > > data( new std::vector< double > ); 00193 boost::array< WPosition, 8 > d = { { WPosition( -1, 0, 0 ), // NOLINT braces 00194 WPosition( 1, 0, 0 ), 00195 WPosition( 1, 0, 0 ), 00196 WPosition( 1, 0, 0 ), 00197 WPosition( 1, 0, 0 ), 00198 WPosition( 1, 0, 0 ), 00199 WPosition( 1, 0, 0 ), 00200 WPosition( 1, 0, 0 ) } }; // NOLINT braces 00201 00202 for( size_t i = 0; i < grid->size(); ++i ) 00203 { 00204 data->push_back( d[i][0] ); 00205 data->push_back( d[i][1] ); 00206 data->push_back( d[i][2] ); 00207 } 00208 boost::shared_ptr< WValueSet< double > > valueSet( new WValueSet< double >( 1, 3, data, W_DT_DOUBLE ) ); 00209 WDataSetVector ds( valueSet, grid ); 00210 00211 bool success = false; 00212 WPosition pos = grid->getTransform().positionToWorldSpace( WPosition( 0.0, 0.0, 0.0 ) ); 00213 TS_ASSERT_EQUALS( ds.interpolate( pos, &success ), d[0] ); 00214 TS_ASSERT( success ); 00215 pos = grid->getTransform().positionToWorldSpace( WPosition( 0.9999, 0.9999, 0.9999 ) ); 00216 TS_ASSERT( delta( ds.interpolate( pos, &success ), d[7], 1e-9 ) ); 00217 TS_ASSERT( success ); 00218 pos = grid->getTransform().positionToWorldSpace( WPosition( 0.5, 0.5, 0.5 ) ); 00219 TS_ASSERT_EQUALS( ds.interpolate( pos, &success ), WPosition( 0.75, 0.0, 0.0 ) ); 00220 TS_ASSERT( success ); 00221 pos = grid->getTransform().positionToWorldSpace( WPosition( 0.0, 0.0, 0.0 ) ); 00222 TS_ASSERT_EQUALS( ds.eigenVectorInterpolate( pos, &success ), d[0] ); 00223 TS_ASSERT( success ); 00224 pos = grid->getTransform().positionToWorldSpace( WPosition( 0.9999, 0.9999, 0.9999 ) ); 00225 TS_ASSERT( delta( ds.eigenVectorInterpolate( pos, &success ), WPosition( -1.0, 0.0, 0.0 ), 1e-9 ) ); 00226 TS_ASSERT( success ); 00227 pos = grid->getTransform().positionToWorldSpace( WPosition( 0.5, 0.5, 0.5 ) ); 00228 TS_ASSERT_EQUALS( ds.eigenVectorInterpolate( pos, &success ), WPosition( -1.0, 0.0, 0.0 ) ); 00229 TS_ASSERT( success ); 00230 } 00231 00232 private: 00233 /** 00234 * Computes if both vectors are almost similar and their components do not differ from a certain given delta. 00235 * 00236 * \param lhs First vector 00237 * \param rhs Second vector 00238 * \param d The given delta 00239 * 00240 * \return True if and only if all components differing at most by the given delta. 00241 */ 00242 bool delta( WVector3d lhs, WVector3d rhs, double d ) 00243 { 00244 bool result = true; 00245 for( int i = 0; result && ( i < 3 ); ++i ) 00246 { 00247 result = result && ( std::abs( lhs[i] - rhs[i] ) <= d ); 00248 if( !result ) 00249 { 00250 std::cout.precision( 10 ); 00251 std::cout.setf( std::ios::fixed, std::ios::floatfield ); 00252 std::cout << "delta failed! => lhs:" << lhs << " rhs:" << rhs << " failed: abs(lhs[" << i << "] - rhs[" 00253 << i << "])=" << std::abs( lhs[i] - rhs[i] ) << ", but should be: " << d << "\n"; 00254 } 00255 } 00256 return result; 00257 } 00258 }; 00259 00260 #endif // WDATASETVECTOR_TEST_H