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 WMATRIXSYM_H 00026 #define WMATRIXSYM_H 00027 00028 #include <algorithm> 00029 #include <cassert> 00030 #include <vector> 00031 00032 #include "../exceptions/WOutOfBounds.h" 00033 00034 /** 00035 * Symmetric square matrix, storing only the elements of the triangular matrix without the main 00036 * diagonal. So in case of a NxN matrix there are only (N^2-N)/2 elements stored. 00037 * 00038 * \note There exists also a WWriter and WReader for storing/reading the matrix in VTK file format. 00039 */ 00040 template< typename T > 00041 class WMatrixSymImpl 00042 { 00043 friend class WMatrixSymTest; 00044 public: 00045 /** 00046 * Type of stored elements. 00047 */ 00048 typedef T value_type; 00049 00050 /** 00051 * Generates new symmetric matrix. 00052 * 00053 * \param n number of rows and cols 00054 */ 00055 explicit WMatrixSymImpl( size_t n ); 00056 00057 /** 00058 * Default constructor leaving all empty. 00059 */ 00060 WMatrixSymImpl(); 00061 00062 /** 00063 * Element acces operator as if the elements where stored as a normal matrix. 00064 * 00065 * \warning Acessing elements of the main diagonal is forbidden! 00066 * 00067 * \param i The i'th row 00068 * \param j The j'th column 00069 * 00070 * \return reference to the (i,j) element of the table 00071 */ 00072 T& operator()( size_t i, size_t j ) throw( WOutOfBounds ); 00073 00074 /** 00075 * Returns the number of elements stored in this matrix. 00076 * \return the number of elements stored in this matrix. 00077 */ 00078 size_t numElements() const; 00079 00080 /** 00081 * Returns the number of rows and cols of the matrix. 00082 * \return The number of rows and cols of the matrix. 00083 */ 00084 size_t size() const; 00085 00086 /** 00087 * Returns the elements stored inside of this container. 00088 * 00089 * \return Read-only reference to the elements stored inside this container. 00090 */ 00091 const std::vector< T >& getData() const; 00092 00093 /** 00094 * Resets the internal data to the given vector of elements. 00095 * 00096 * \param data new data in row major arrangement 00097 */ 00098 void setData( const std::vector< T > &data ) throw( WOutOfBounds ); 00099 00100 private: 00101 /** 00102 * Internal data structure to store the elements. The order is row major. 00103 */ 00104 std::vector< T > m_data; 00105 00106 /** 00107 * Number of rows and cols. 00108 */ 00109 size_t m_n; 00110 }; 00111 00112 template< typename T > 00113 inline WMatrixSymImpl< T >::WMatrixSymImpl( size_t n ) 00114 : m_data( ( n * ( n - 1 ) ) / 2, 0.0 ), 00115 m_n( n ) 00116 { 00117 } 00118 00119 template< typename T > 00120 inline WMatrixSymImpl< T >::WMatrixSymImpl() 00121 : m_n( 0 ) 00122 { 00123 } 00124 00125 template< typename T > 00126 inline T& WMatrixSymImpl< T >::operator()( size_t i, size_t j ) throw( WOutOfBounds ) 00127 { 00128 if( i == j || i >= m_n || j >= m_n ) 00129 { 00130 std::stringstream ss; 00131 ss << "Invalid Element Access ( " << i << ", " << j << " ). No diagonal elements or indices bigger than " << m_n << " are allowed."; 00132 throw WOutOfBounds( ss.str() ); 00133 } 00134 if( i > j ) 00135 { 00136 std::swap( i, j ); 00137 } 00138 return m_data[( i * m_n + j - ( i + 1 ) * ( i + 2 ) / 2 )]; 00139 } 00140 00141 template< typename T > 00142 inline size_t WMatrixSymImpl< T >::numElements() const 00143 { 00144 return m_data.size(); 00145 } 00146 00147 template< typename T > 00148 inline size_t WMatrixSymImpl< T >::size() const 00149 { 00150 return m_n; 00151 } 00152 00153 template< typename T > 00154 inline const typename std::vector< T >& WMatrixSymImpl< T >::getData() const 00155 { 00156 return m_data; 00157 } 00158 00159 template< typename T > 00160 inline void WMatrixSymImpl< T >::setData( const std::vector< T > &data ) throw( WOutOfBounds ) 00161 { 00162 if( m_n * ( m_n - 1 ) / 2 != data.size() ) 00163 { 00164 std::stringstream ss; 00165 ss << "Data vector length: " << data.size() << " doesn't fit to number of rows and cols: " << m_n; 00166 throw WOutOfBounds( ss.str() ); 00167 } 00168 m_data = std::vector< T >( data ); // copy content 00169 } 00170 00171 typedef WMatrixSymImpl< double > WMatrixSymDBL; 00172 typedef WMatrixSymImpl< float > WMatrixSymFLT; 00173 00174 #endif // WMATRIXSYM_H