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