OpenWalnut 1.2.5
WValue.h
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
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends