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