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 WVALUE_H 00026 #define WVALUE_H 00027 00028 #include <algorithm> 00029 #include <cmath> 00030 #include <vector> 00031 00032 #include <Eigen/Core> 00033 00034 #include "../WAssert.h" 00035 #include "../WStringUtils.h" 00036 00037 /** 00038 * Base class for all higher level values like tensors, vectors, matrices and so on. 00039 */ 00040 template< typename T > class WValue 00041 { 00042 template< typename S > friend class WValue; //!< All WValues are friends of each other. 00043 00044 // We exclude this from doxygen since they are documented already as functions and I don't want to duplicate that documentation 00045 // \cond Suppress_Doxygen 00046 template< typename U > friend std::ostream& operator<<( std::ostream& os, const WValue< U > &rhs ); 00047 template< typename U > friend std::istream& operator>>( std::istream& in, WValue< U >& rhs ); 00048 // \endcond 00049 public: 00050 /** 00051 * Create a WValue with the given number of components. 00052 * The components will be set to zero if T is a type representing numbers. 00053 * \param nbComponents Number of elements the WValue consists of. 00054 */ 00055 explicit WValue( size_t nbComponents ) 00056 : m_components( nbComponents ) 00057 { 00058 } 00059 00060 /** 00061 * Create a WValue as copy of the one given as parameter. 00062 * \param newValue The WValue to be copied. 00063 */ 00064 WValue( const WValue& newValue ) 00065 : m_components( newValue.m_components ) 00066 { 00067 } 00068 00069 /** 00070 * Create a WValue as copy of the one given as parameter but with another template type. 00071 * \param newValue The WValue to be copied. 00072 */ 00073 template< typename S > explicit WValue( const WValue< S >& newValue ) 00074 { 00075 m_components.resize( newValue.m_components.size() ); 00076 for( size_t i = 0; i < m_components.size(); ++i ) 00077 { 00078 m_components[i] = newValue.m_components[i]; 00079 } 00080 } 00081 00082 /** 00083 * Create a WValue from the given Eigen::VectorXd. 00084 * \param newValues The Eigen::VectorXd with the values.. 00085 */ 00086 explicit WValue( const Eigen::VectorXd& newValues ) 00087 : m_components( static_cast< std::size_t >( newValues.size() ) ) 00088 { 00089 copyFromEigenVector( newValues ); 00090 } 00091 00092 /** 00093 * Create a WValue from the given Eigen::VectorXf. 00094 * \param newValues The Eigen::VectorXf with the values.. 00095 */ 00096 explicit WValue( const Eigen::VectorXf& newValues ) 00097 : m_components( static_cast< std::size_t >( newValues.size() ) ) 00098 { 00099 copyFromEigenVector( newValues ); 00100 } 00101 00102 /** 00103 * Create a WValue from the given Eigen::VectorXi. 00104 * \param newValues The Eigen::VectorXi with the values.. 00105 */ 00106 explicit WValue( const Eigen::VectorXi& newValues ) 00107 : m_components( static_cast< std::size_t >( newValues.size() ) ) 00108 { 00109 copyFromEigenVector( newValues ); 00110 } 00111 00112 /** 00113 * Get number of components the value consists of. 00114 * \return The number of components the value consists of. 00115 */ 00116 size_t size() const 00117 { 00118 return m_components.size(); 00119 } 00120 00121 /** 00122 * Returns a reference to the i-th component in order 00123 * to provide access to the component. 00124 * \param i element id 00125 * \return A reference to the desired component. 00126 */ 00127 T& operator[]( size_t i ) 00128 { 00129 WAssert( i < m_components.size(), "Index out of bounds." ); 00130 return m_components[i]; 00131 } 00132 00133 /** 00134 * Returns a CONST reference to the i-th component in order 00135 * to provide read-only access to the component. 00136 * \param i element id 00137 * \return A CONST reference to the desired component 00138 */ 00139 const T& operator[]( size_t i ) const 00140 { 00141 WAssert( i < m_components.size(), "Index out of bounds." ); 00142 return m_components[i]; 00143 } 00144 00145 /** 00146 * Compares two WValues and returns true if they contain the same data. 00147 * \param rhs The right hand side of the comparison 00148 * \return The answer to whether both WValues contain the same data. 00149 */ 00150 bool operator==( const WValue& rhs ) const 00151 { 00152 return ( m_components == rhs.m_components ); 00153 } 00154 00155 /** 00156 * Compares two WValues and returns true if they contain the different data. 00157 * \param rhs The right hand side of the comparison 00158 * \return The answer to whether both WValues do NOT contain the same data. 00159 */ 00160 bool operator!=( const WValue& rhs ) const 00161 { 00162 return ( m_components != rhs.m_components ); 00163 } 00164 00165 /** 00166 * Assigns the contents of its argument to the contents of this WValue. 00167 * \param rhs The right hand side of the assignment 00168 * \return A reference to the left hand side of the assignment (i.e. the current object). 00169 */ 00170 WValue& operator=( const WValue& rhs ) 00171 { 00172 m_components = rhs.m_components; 00173 return *this; 00174 } 00175 00176 /** 00177 * Adds a the argument component-wise to the components of this WValue 00178 * \param rhs The right hand side of the assignment 00179 * \return A reference to the left hand side of the assignment (i.e. the current object). 00180 */ 00181 WValue& operator+=( const WValue& rhs ) 00182 { 00183 WAssert( m_components.size() == rhs.m_components.size(), "Incompatible sizes of lhs and rhs of operator." ); 00184 for( unsigned int i = 0; i < m_components.size(); ++i ) 00185 m_components[i] += rhs.m_components[i]; 00186 return *this; 00187 } 00188 00189 /** 00190 * Subtracts the argument component-wise from the components of this WValue 00191 * \param rhs The right hand side of the assignment 00192 * \return A reference to the left hand side of the assignment (i.e. the current object). 00193 */ 00194 WValue& operator-=( const WValue& rhs ) 00195 { 00196 WAssert( m_components.size() == rhs.m_components.size(), "Incompatible sizes of lhs and rhs of operator." ); 00197 for( unsigned int i = 0; i < m_components.size(); ++i ) 00198 m_components[i] -= rhs.m_components[i]; 00199 return *this; 00200 } 00201 00202 /** 00203 * Scales each component of this WValue with the given scalar argument 00204 * \param rhs The right hand side of the assignment 00205 * \return A reference to the left hand side of the assignment (i.e. the (scaled) current object). 00206 */ 00207 WValue& operator*=( double rhs ) 00208 { 00209 for( unsigned int i = 0; i < m_components.size(); ++i ) 00210 m_components[i] *= rhs; 00211 return *this; 00212 } 00213 00214 /** 00215 * Scales each component of this WValue with the corresponding 00216 * component of the given argument WValue 00217 * \param rhs The right hand side of the assignment 00218 * \return A reference to the left hand side of the assignment (i.e. the current (scaled) object). 00219 */ 00220 WValue& operator*=( const WValue& rhs ) 00221 { 00222 WAssert( m_components.size() == rhs.m_components.size(), "Incompatible sizes of lhs and rhs of operator." ); 00223 for( unsigned int i = 0; i < m_components.size(); ++i ) 00224 m_components[i] *= rhs.m_components[i]; 00225 return *this; 00226 } 00227 00228 /** 00229 * Scales each component of this WValue with the given scalar argument 00230 * \param rhs The right hand side of the assignment 00231 * \return A reference to the left hand side of the assignment (i.e. the current (scaled) object). 00232 */ 00233 WValue& operator/=( const double rhs ) 00234 { 00235 for( unsigned int i = 0; i < m_components.size(); ++i ) 00236 m_components[i] /= rhs; 00237 return *this; 00238 } 00239 00240 00241 /** 00242 * Component-wise addition. 00243 * \param summand2 The right hand side of the summation 00244 * \result The sum of the WValues. 00245 */ 00246 const WValue operator+( const WValue& summand2 ) const 00247 { 00248 WAssert( m_components.size() == summand2.m_components.size(), "Incompatible sizes of summands." ); 00249 WValue result( *this ); 00250 result += summand2; 00251 return result; 00252 } 00253 00254 /** 00255 * Component-wise subtraction. 00256 * \param subtrahend The right hand side of the subtraction 00257 * \result The difference of the WValues. 00258 */ 00259 const WValue operator-( const WValue& subtrahend ) const 00260 { 00261 WAssert( m_components.size() == subtrahend.m_components.size(), "Incompatible sizes of subtrahend and minuend." ); 00262 WValue result( *this ); 00263 result -= subtrahend; 00264 return result; 00265 } 00266 00267 /** 00268 * Component-wise multiplication. 00269 * \param factor2 The right hand side of the product 00270 * \return The vector of the product of the components. 00271 */ 00272 const WValue operator*( const WValue& factor2 ) const 00273 { 00274 WAssert( m_components.size() == factor2.m_components.size(), "Incompatible sizes of factors." ); 00275 WValue result( *this ); 00276 result *= factor2; 00277 return result; 00278 } 00279 00280 /** 00281 * Square root of sum of squares of elements. 00282 * This function returns double instead of T 00283 * because norm includes a square root and thus 00284 * its computation automatically results in a 00285 * floating point number. 00286 * \return Double-precision norm of the WValue. 00287 */ 00288 double norm() const 00289 { 00290 return sqrt( this->normSquare() ); 00291 } 00292 00293 /** 00294 * Sum of squares of elements. 00295 * This function returns double instead of T 00296 * because normSquare includes many squares and thus 00297 * might return large values that might not fit into 00298 * T's range of values. Double prevents an overflow. 00299 * Additionally this is consistent with norm(). 00300 * \return Double-precision squared norm of the WValue. 00301 */ 00302 double normSquare() const 00303 { 00304 double normSquare = 0.0; 00305 00306 for( unsigned int i = 0; i < m_components.size(); ++i ) 00307 { 00308 normSquare += m_components[i] * m_components[i]; 00309 } 00310 00311 return normSquare; 00312 } 00313 00314 /** 00315 * Make the norm of this WValue be 1 by dividing by WValue::norm() 00316 */ 00317 void normalize() 00318 { 00319 double currentNorm = norm(); 00320 for( unsigned int i = 0; i < m_components.size(); ++i ) 00321 { 00322 WAssert( currentNorm > 0.0, "Norm is non-positive!" ); 00323 m_components[i] /= currentNorm; 00324 } 00325 } 00326 00327 /** 00328 * Return a normalized version of the current WValue without modifying it. 00329 * \return Normalized version of the current WValue object. 00330 */ 00331 WValue normalized() const 00332 { 00333 WValue result = *this; 00334 result.normalize(); 00335 return result; 00336 } 00337 00338 /** 00339 * Returns the mean value of all values stored in this WValue. 00340 * \return Mean of the WValues components. 00341 */ 00342 T mean() const 00343 { 00344 WAssert( !m_components.empty(), "WValue has no entries." ); 00345 T sum = 0; 00346 for( typename std::vector< T >::const_iterator it = m_components.begin(); it != m_components.end(); it++ ) 00347 { 00348 sum += ( *it ); 00349 } 00350 return ( sum / static_cast< T >( m_components.size() ) ); 00351 } 00352 00353 /** 00354 * Returns the median of all values stored in this WValue. 00355 * \return Median of the WValues components. 00356 */ 00357 T median() const 00358 { 00359 WAssert( !m_components.empty(), "WValue has no entries. " ); 00360 std::vector< T > components( m_components ); 00361 std::sort( components.begin(), components.end() ); 00362 return components[ components.size() / 2 ]; 00363 } 00364 00365 /** 00366 * Changes the number of scalars held by this WValue. 00367 * \param size The number of scalars stored in the WValue. 00368 */ 00369 void resize( size_t size ) 00370 { 00371 m_components.resize( size ); 00372 } 00373 00374 protected: 00375 private: 00376 /** 00377 * This function is used by the constructors that have the different Eigen::MatrixX types as parameter. 00378 * \tparam EigenDataType The data type which is used by the Eigen::VectorX. 00379 * \param newValues The source Eigen::VectorX. 00380 */ 00381 template< typename EigenDataType > 00382 void copyFromEigenVector( const Eigen::Matrix< EigenDataType, Eigen::Dynamic, 1 >& newValues ) 00383 { 00384 for( std::size_t i = 0; i < m_components.size(); ++i ) 00385 { 00386 m_components[ i ] = static_cast< T >( newValues( i ) ); 00387 } 00388 } 00389 00390 /** 00391 * The components the value is composed of. This contains the actual data 00392 */ 00393 std::vector< T > m_components; 00394 }; 00395 00396 /** 00397 * Multiplies a WValue with a scalar 00398 * \param lhs left hand side of product 00399 * \param rhs right hand side of product 00400 * \return product of WValue with scalar 00401 */ 00402 template< typename T > inline const WValue< T > operator*( const WValue< T >& lhs, double rhs ) 00403 { 00404 WValue< T > result( lhs ); 00405 result *= rhs; 00406 return result; 00407 } 00408 00409 /** 00410 * This functions only exists to make scalar multiplication commutative 00411 * \param lhs left hand side of product 00412 * \param rhs right hand side of product 00413 * \return product of WValue with scalar 00414 */ 00415 template< typename T > inline const WValue< T > operator*( double lhs, const WValue< T >& rhs ) 00416 { 00417 WValue< T > result( rhs ); 00418 result *= lhs; 00419 return result; 00420 } 00421 00422 /** 00423 * Divides a WValue by a scalar 00424 * \param lhs left hand side of division 00425 * \param rhs right hand side of division 00426 * \return Quotien of WValue with scalar 00427 */ 00428 template< typename T > inline const WValue< T > operator/( const WValue< T >& lhs, double rhs ) 00429 { 00430 WValue< T > result( lhs ); 00431 result /= rhs; 00432 return result; 00433 } 00434 00435 /** 00436 * Writes a meaningful representation of that object to the given stream. 00437 * 00438 * \param os The operator will write to this stream. 00439 * \param rhs This will be written to the stream. 00440 * 00441 * \return the output stream 00442 */ 00443 template< typename U > inline std::ostream& operator<<( std::ostream& os, const WValue< U > &rhs ) 00444 { 00445 return string_utils::operator<<( os, rhs.m_components ); 00446 } 00447 00448 /** 00449 * Write an input stream into a WValue. 00450 * 00451 * \param in the input stream 00452 * \param rhs the value to where to write the stream 00453 * 00454 * \return the input stream 00455 */ 00456 template< typename U > inline std::istream& operator>>( std::istream& in, WValue< U >& rhs ) 00457 { 00458 return string_utils::operator>>( in, rhs.m_components ); 00459 } 00460 00461 #endif // WVALUE_H