OpenWalnut  1.2.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
WMatrixSym.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 WMATRIXSYM_H
26 #define WMATRIXSYM_H
27 
28 #include <algorithm>
29 #include <cassert>
30 #include <vector>
31 
32 #include "../exceptions/WOutOfBounds.h"
33 
34 /**
35  * Symmetric square matrix, storing only the elements of the triangular matrix without the main
36  * diagonal. So in case of a NxN matrix there are only (N^2-N)/2 elements stored.
37  *
38  * \note There exists also a WWriter and WReader for storing/reading the matrix in VTK file format.
39  */
40 template< typename T >
42 {
43 friend class WMatrixSymTest;
44 public:
45  /**
46  * Type of stored elements.
47  */
48  typedef T value_type;
49 
50  /**
51  * Generates new symmetric matrix.
52  *
53  * \param n number of rows and cols
54  */
55  explicit WMatrixSymImpl( size_t n );
56 
57  /**
58  * Default constructor leaving all empty.
59  */
61 
62  /**
63  * Element acces operator as if the elements where stored as a normal matrix.
64  *
65  * \warning Acessing elements of the main diagonal is forbidden!
66  *
67  * \param i The i'th row
68  * \param j The j'th column
69  *
70  * \return reference to the (i,j) element of the table
71  */
72  T& operator()( size_t i, size_t j ) throw( WOutOfBounds );
73 
74  /**
75  * Returns the number of elements stored in this matrix.
76  * \return the number of elements stored in this matrix.
77  */
78  size_t numElements() const;
79 
80  /**
81  * Returns the number of rows and cols of the matrix.
82  * \return The number of rows and cols of the matrix.
83  */
84  size_t size() const;
85 
86  /**
87  * Returns the elements stored inside of this container.
88  *
89  * \return Read-only reference to the elements stored inside this container.
90  */
91  const std::vector< T >& getData() const;
92 
93  /**
94  * Resets the internal data to the given vector of elements.
95  *
96  * \param data new data in row major arrangement
97  */
98  void setData( const std::vector< T > &data ) throw( WOutOfBounds );
99 
100 private:
101  /**
102  * Internal data structure to store the elements. The order is row major.
103  */
104  std::vector< T > m_data;
105 
106  /**
107  * Number of rows and cols.
108  */
109  size_t m_n;
110 };
111 
112 template< typename T >
114  : m_data( ( n * ( n - 1 ) ) / 2, 0.0 ),
115  m_n( n )
116 {
117 }
118 
119 template< typename T >
121  : m_n( 0 )
122 {
123 }
124 
125 template< typename T >
126 inline T& WMatrixSymImpl< T >::operator()( size_t i, size_t j ) throw( WOutOfBounds )
127 {
128  if( i == j || i >= m_n || j >= m_n )
129  {
130  std::stringstream ss;
131  ss << "Invalid Element Access ( " << i << ", " << j << " ). No diagonal elements or indices bigger than " << m_n << " are allowed.";
132  throw WOutOfBounds( ss.str() );
133  }
134  if( i > j )
135  {
136  std::swap( i, j );
137  }
138  return m_data[( i * m_n + j - ( i + 1 ) * ( i + 2 ) / 2 )];
139 }
140 
141 template< typename T >
142 inline size_t WMatrixSymImpl< T >::numElements() const
143 {
144  return m_data.size();
145 }
146 
147 template< typename T >
148 inline size_t WMatrixSymImpl< T >::size() const
149 {
150  return m_n;
151 }
152 
153 template< typename T >
154 inline const typename std::vector< T >& WMatrixSymImpl< T >::getData() const
155 {
156  return m_data;
157 }
158 
159 template< typename T >
160 inline void WMatrixSymImpl< T >::setData( const std::vector< T > &data ) throw( WOutOfBounds )
161 {
162  if( m_n * ( m_n - 1 ) / 2 != data.size() )
163  {
164  std::stringstream ss;
165  ss << "Data vector length: " << data.size() << " doesn't fit to number of rows and cols: " << m_n;
166  throw WOutOfBounds( ss.str() );
167  }
168  m_data = std::vector< T >( data ); // copy content
169 }
170 
173 
174 #endif // WMATRIXSYM_H