OpenWalnut  1.5.0dev
WValue.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 WVALUE_H
26 #define WVALUE_H
27 
28 #include <algorithm>
29 #include <cmath>
30 #include <vector>
31 
32 #include <Eigen/Core>
33 
34 #include "../WAssert.h"
35 #include "../WStringUtils.h"
36 
37 /**
38  * Base class for all higher level values like tensors, vectors, matrices and so on.
39  */
40 template< typename T > class WValue
41 {
42 template< typename S > friend class WValue; //!< All WValues are friends of each other.
43 
44 // We exclude this from doxygen since they are documented already as functions and I don't want to duplicate that documentation
45 // \cond Suppress_Doxygen
46 template< typename U > friend std::ostream& operator<<( std::ostream& os, const WValue< U > &rhs );
47 template< typename U > friend std::istream& operator>>( std::istream& in, WValue< U >& rhs );
48 // \endcond
49 public:
50  /**
51  * Create a WValue with the given number of components.
52  * The components will be set to zero if T is a type representing numbers.
53  * \param nbComponents Number of elements the WValue consists of.
54  */
55  explicit WValue( size_t nbComponents )
56  : m_components( nbComponents )
57  {
58  }
59 
60  /**
61  * Create a WValue as copy of the one given as parameter.
62  * \param newValue The WValue to be copied.
63  */
64  WValue( const WValue& newValue )
65  : m_components( newValue.m_components )
66  {
67  }
68 
69  /**
70  * Create a WValue as copy of the one given as parameter but with another template type.
71  * \param newValue The WValue to be copied.
72  */
73  template< typename S > explicit WValue( const WValue< S >& newValue )
74  {
75  m_components.resize( newValue.m_components.size() );
76  for( size_t i = 0; i < m_components.size(); ++i )
77  {
78  m_components[i] = newValue.m_components[i];
79  }
80  }
81 
82  /**
83  * Create a WValue from the given Eigen::VectorXd.
84  * \param newValues The Eigen::VectorXd with the values.
85  */
86  explicit WValue( const Eigen::VectorXd& newValues )
87  : m_components( static_cast< std::size_t >( newValues.size() ) )
88  {
89  copyFromEigenVector( newValues );
90  }
91 
92  /**
93  * Create a WValue from the given Eigen::VectorXf.
94  * \param newValues The Eigen::VectorXf with the values.
95  */
96  explicit WValue( const Eigen::VectorXf& newValues )
97  : m_components( static_cast< std::size_t >( newValues.size() ) )
98  {
99  copyFromEigenVector( newValues );
100  }
101 
102  /**
103  * Create a WValue from the given Eigen::VectorXi.
104  * \param newValues The Eigen::VectorXi with the values.
105  */
106  explicit WValue( const Eigen::VectorXi& newValues )
107  : m_components( static_cast< std::size_t >( newValues.size() ) )
108  {
109  copyFromEigenVector( newValues );
110  }
111 
112  /**
113  * Get number of components the value consists of.
114  * \return The number of components the value consists of.
115  */
116  size_t size() const
117  {
118  return m_components.size();
119  }
120 
121  /**
122  * Returns a reference to the i-th component in order
123  * to provide access to the component.
124  * \param i element id
125  * \return A reference to the desired component.
126  */
127  T& operator[]( size_t i )
128  {
129  WAssert( i < m_components.size(), "Index out of bounds." );
130  return m_components[i];
131  }
132 
133  /**
134  * Returns a CONST reference to the i-th component in order
135  * to provide read-only access to the component.
136  * \param i element id
137  * \return A CONST reference to the desired component
138  */
139  const T& operator[]( size_t i ) const
140  {
141  WAssert( i < m_components.size(), "Index out of bounds." );
142  return m_components[i];
143  }
144 
145  /**
146  * Compares two WValues and returns true if they contain the same data.
147  * \param rhs The right hand side of the comparison
148  * \return The answer to whether both WValues contain the same data.
149  */
150  bool operator==( const WValue& rhs ) const
151  {
152  return ( m_components == rhs.m_components );
153  }
154 
155  /**
156  * Compares two WValues and returns true if they contain the different data.
157  * \param rhs The right hand side of the comparison
158  * \return The answer to whether both WValues do NOT contain the same data.
159  */
160  bool operator!=( const WValue& rhs ) const
161  {
162  return ( m_components != rhs.m_components );
163  }
164 
165  /**
166  * Assigns the contents of its argument to the contents of this WValue.
167  * \param rhs The right hand side of the assignment
168  * \return A reference to the left hand side of the assignment (i.e. the current object).
169  */
170  WValue& operator=( const WValue& rhs )
171  {
173  return *this;
174  }
175 
176  /**
177  * Adds a the argument component-wise to the components of this WValue
178  * \param rhs The right hand side of the assignment
179  * \return A reference to the left hand side of the assignment (i.e. the current object).
180  */
181  WValue& operator+=( const WValue& rhs )
182  {
183  WAssert( m_components.size() == rhs.m_components.size(), "Incompatible sizes of lhs and rhs of operator." );
184  for( unsigned int i = 0; i < m_components.size(); ++i )
185  m_components[i] += rhs.m_components[i];
186  return *this;
187  }
188 
189  /**
190  * Subtracts the argument component-wise from the components of this WValue
191  * \param rhs The right hand side of the assignment
192  * \return A reference to the left hand side of the assignment (i.e. the current object).
193  */
194  WValue& operator-=( const WValue& rhs )
195  {
196  WAssert( m_components.size() == rhs.m_components.size(), "Incompatible sizes of lhs and rhs of operator." );
197  for( unsigned int i = 0; i < m_components.size(); ++i )
198  m_components[i] -= rhs.m_components[i];
199  return *this;
200  }
201 
202  /**
203  * Scales each component of this WValue with the given scalar argument
204  * \param rhs The right hand side of the assignment
205  * \return A reference to the left hand side of the assignment (i.e. the (scaled) current object).
206  */
207  WValue& operator*=( double rhs )
208  {
209  for( unsigned int i = 0; i < m_components.size(); ++i )
210  m_components[i] *= rhs;
211  return *this;
212  }
213 
214  /**
215  * Scales each component of this WValue with the corresponding
216  * component of the given argument WValue
217  * \param rhs The right hand side of the assignment
218  * \return A reference to the left hand side of the assignment (i.e. the current (scaled) object).
219  */
220  WValue& operator*=( const WValue& rhs )
221  {
222  WAssert( m_components.size() == rhs.m_components.size(), "Incompatible sizes of lhs and rhs of operator." );
223  for( unsigned int i = 0; i < m_components.size(); ++i )
224  m_components[i] *= rhs.m_components[i];
225  return *this;
226  }
227 
228  /**
229  * Scales each component of this WValue with the given scalar argument
230  * \param rhs The right hand side of the assignment
231  * \return A reference to the left hand side of the assignment (i.e. the current (scaled) object).
232  */
233  WValue& operator/=( const double rhs )
234  {
235  for( unsigned int i = 0; i < m_components.size(); ++i )
236  m_components[i] /= rhs;
237  return *this;
238  }
239 
240 
241  /**
242  * Component-wise addition.
243  * \param summand2 The right hand side of the summation
244  * \result The sum of the WValues.
245  */
246  const WValue operator+( const WValue& summand2 ) const
247  {
248  WAssert( m_components.size() == summand2.m_components.size(), "Incompatible sizes of summands." );
249  WValue result( *this );
250  result += summand2;
251  return result;
252  }
253 
254  /**
255  * Component-wise subtraction.
256  * \param subtrahend The right hand side of the subtraction
257  * \result The difference of the WValues.
258  */
259  const WValue operator-( const WValue& subtrahend ) const
260  {
261  WAssert( m_components.size() == subtrahend.m_components.size(), "Incompatible sizes of subtrahend and minuend." );
262  WValue result( *this );
263  result -= subtrahend;
264  return result;
265  }
266 
267  /**
268  * Component-wise multiplication.
269  * \param factor2 The right hand side of the product
270  * \return The vector of the product of the components.
271  */
272  const WValue operator*( const WValue& factor2 ) const
273  {
274  WAssert( m_components.size() == factor2.m_components.size(), "Incompatible sizes of factors." );
275  WValue result( *this );
276  result *= factor2;
277  return result;
278  }
279 
280  /**
281  * Square root of sum of squares of elements.
282  * This function returns double instead of T
283  * because norm includes a square root and thus
284  * its computation automatically results in a
285  * floating point number.
286  * \return Double-precision norm of the WValue.
287  */
288  double norm() const
289  {
290  return sqrt( this->normSquare() );
291  }
292 
293  /**
294  * Sum of squares of elements.
295  * This function returns double instead of T
296  * because normSquare includes many squares and thus
297  * might return large values that might not fit into
298  * T's range of values. Double prevents an overflow.
299  * Additionally this is consistent with norm().
300  * \return Double-precision squared norm of the WValue.
301  */
302  double normSquare() const
303  {
304  double normSquare = 0.0;
305 
306  for( unsigned int i = 0; i < m_components.size(); ++i )
307  {
309  }
310 
311  return normSquare;
312  }
313 
314  /**
315  * Make the norm of this WValue be 1 by dividing by WValue::norm()
316  */
317  void normalize()
318  {
319  double currentNorm = norm();
320  for( unsigned int i = 0; i < m_components.size(); ++i )
321  {
322  WAssert( currentNorm > 0.0, "Norm is non-positive!" );
323  m_components[i] /= currentNorm;
324  }
325  }
326 
327  /**
328  * Return a normalized version of the current WValue without modifying it.
329  * \return Normalized version of the current WValue object.
330  */
332  {
333  WValue result = *this;
334  result.normalize();
335  return result;
336  }
337 
338  /**
339  * Returns the mean value of all values stored in this WValue.
340  * \return Mean of the WValues components.
341  */
342  T mean() const
343  {
344  WAssert( !m_components.empty(), "WValue has no entries." );
345  T sum = 0;
346  for( typename std::vector< T >::const_iterator it = m_components.begin(); it != m_components.end(); it++ )
347  {
348  sum += ( *it );
349  }
350  return ( sum / static_cast< T >( m_components.size() ) );
351  }
352 
353  /**
354  * Returns the median of all values stored in this WValue.
355  * \return Median of the WValues components.
356  */
357  T median() const
358  {
359  WAssert( !m_components.empty(), "WValue has no entries. " );
360  std::vector< T > components( m_components );
361  std::sort( components.begin(), components.end() );
362  return components[ components.size() / 2 ];
363  }
364 
365  /**
366  * Changes the number of scalars held by this WValue.
367  * \param size The number of scalars stored in the WValue.
368  */
369  void resize( size_t size )
370  {
371  m_components.resize( size );
372  }
373 
374 protected:
375 private:
376  /**
377  * This function is used by the constructors that have the different Eigen::MatrixX types as parameter.
378  * \tparam EigenDataType The data type which is used by the Eigen::VectorX.
379  * \param newValues The source Eigen::VectorX.
380  */
381  template< typename EigenDataType >
382  void copyFromEigenVector( const Eigen::Matrix< EigenDataType, Eigen::Dynamic, 1 >& newValues )
383  {
384  for( std::size_t i = 0; i < m_components.size(); ++i )
385  {
386  m_components[ i ] = static_cast< T >( newValues( i ) );
387  }
388  }
389 
390  /**
391  * The components the value is composed of. This contains the actual data
392  */
393  std::vector< T > m_components;
394 };
395 
396 /**
397  * Multiplies a WValue with a scalar
398  * \param lhs left hand side of product
399  * \param rhs right hand side of product
400  * \return product of WValue with scalar
401  */
402 template< typename T > inline const WValue< T > operator*( const WValue< T >& lhs, double rhs )
403 {
404  WValue< T > result( lhs );
405  result *= rhs;
406  return result;
407 }
408 
409 /**
410  * This functions only exists to make scalar multiplication commutative
411  * \param lhs left hand side of product
412  * \param rhs right hand side of product
413  * \return product of WValue with scalar
414  */
415 template< typename T > inline const WValue< T > operator*( double lhs, const WValue< T >& rhs )
416 {
417  WValue< T > result( rhs );
418  result *= lhs;
419  return result;
420 }
421 
422 /**
423  * Divides a WValue by a scalar
424  * \param lhs left hand side of division
425  * \param rhs right hand side of division
426  * \return Quotien of WValue with scalar
427  */
428 template< typename T > inline const WValue< T > operator/( const WValue< T >& lhs, double rhs )
429 {
430  WValue< T > result( lhs );
431  result /= rhs;
432  return result;
433 }
434 
435 /**
436  * Writes a meaningful representation of that object to the given stream.
437  *
438  * \param os The operator will write to this stream.
439  * \param rhs This will be written to the stream.
440  *
441  * \return the output stream
442  */
443 template< typename U > inline std::ostream& operator<<( std::ostream& os, const WValue< U > &rhs )
444 {
445  return string_utils::operator<<( os, rhs.m_components );
446 }
447 
448 /**
449  * Write an input stream into a WValue.
450  *
451  * \param in the input stream
452  * \param rhs the value to where to write the stream
453  *
454  * \return the input stream
455  */
456 template< typename U > inline std::istream& operator>>( std::istream& in, WValue< U >& rhs )
457 {
458  return string_utils::operator>>( in, rhs.m_components );
459 }
460 
461 #endif // WVALUE_H
Base class for all higher level values like tensors, vectors, matrices and so on.
Definition: WValue.h:41
WValue normalized() const
Return a normalized version of the current WValue without modifying it.
Definition: WValue.h:331
bool operator!=(const WValue &rhs) const
Compares two WValues and returns true if they contain the different data.
Definition: WValue.h:160
WValue & operator/=(const double rhs)
Scales each component of this WValue with the given scalar argument.
Definition: WValue.h:233
void resize(size_t size)
Changes the number of scalars held by this WValue.
Definition: WValue.h:369
WValue & operator*=(const WValue &rhs)
Scales each component of this WValue with the corresponding component of the given argument WValue.
Definition: WValue.h:220
WValue(const Eigen::VectorXf &newValues)
Create a WValue from the given Eigen::VectorXf.
Definition: WValue.h:96
WValue(const WValue &newValue)
Create a WValue as copy of the one given as parameter.
Definition: WValue.h:64
size_t size() const
Get number of components the value consists of.
Definition: WValue.h:116
const WValue operator-(const WValue &subtrahend) const
Component-wise subtraction.
Definition: WValue.h:259
WValue(const WValue< S > &newValue)
Create a WValue as copy of the one given as parameter but with another template type.
Definition: WValue.h:73
bool operator==(const WValue &rhs) const
Compares two WValues and returns true if they contain the same data.
Definition: WValue.h:150
const WValue operator+(const WValue &summand2) const
Component-wise addition.
Definition: WValue.h:246
WValue(const Eigen::VectorXd &newValues)
Create a WValue from the given Eigen::VectorXd.
Definition: WValue.h:86
WValue & operator+=(const WValue &rhs)
Adds a the argument component-wise to the components of this WValue.
Definition: WValue.h:181
WValue & operator-=(const WValue &rhs)
Subtracts the argument component-wise from the components of this WValue.
Definition: WValue.h:194
const WValue operator*(const WValue &factor2) const
Component-wise multiplication.
Definition: WValue.h:272
double norm() const
Square root of sum of squares of elements.
Definition: WValue.h:288
WValue & operator=(const WValue &rhs)
Assigns the contents of its argument to the contents of this WValue.
Definition: WValue.h:170
T median() const
Returns the median of all values stored in this WValue.
Definition: WValue.h:357
T mean() const
Returns the mean value of all values stored in this WValue.
Definition: WValue.h:342
void copyFromEigenVector(const Eigen::Matrix< EigenDataType, Eigen::Dynamic, 1 > &newValues)
This function is used by the constructors that have the different Eigen::MatrixX types as parameter.
Definition: WValue.h:382
std::vector< T > m_components
The components the value is composed of.
Definition: WValue.h:393
void normalize()
Make the norm of this WValue be 1 by dividing by WValue::norm()
Definition: WValue.h:317
WValue(const Eigen::VectorXi &newValues)
Create a WValue from the given Eigen::VectorXi.
Definition: WValue.h:106
WValue & operator*=(double rhs)
Scales each component of this WValue with the given scalar argument.
Definition: WValue.h:207
double normSquare() const
Sum of squares of elements.
Definition: WValue.h:302
T & operator[](size_t i)
Returns a reference to the i-th component in order to provide access to the component.
Definition: WValue.h:127
const T & operator[](size_t i) const
Returns a CONST reference to the i-th component in order to provide read-only access to the component...
Definition: WValue.h:139
WValue(size_t nbComponents)
Create a WValue with the given number of components.
Definition: WValue.h:55
std::ostream & operator<<(std::ostream &os, const std::vector< T > &v)
Writes every vector to an output stream such as cout, if its elements have an output operator defined...
Definition: WStringUtils.h:258
std::istream & operator>>(std::istream &in, std::vector< T > &v)
Write an input stream into the given vector.
Definition: WStringUtils.h:281