Commit 01fb8387 authored by Mathias Goldau's avatar Mathias Goldau
Browse files

[ADD] A member function to render a symmetric Matrix to a string. This will be...

[ADD] A member function to render a symmetric Matrix to a string. This will be needed to save them to plain text files.
parent 5fac4797
......@@ -71,6 +71,7 @@ public:
* \return reference to the (i,j) element of the table
*/
T& operator()( size_t i, size_t j ) throw( WOutOfBounds );
const T& operator()( size_t i, size_t j ) const throw( WOutOfBounds );
/**
* Returns the number of elements stored in this matrix.
......@@ -98,6 +99,14 @@ public:
*/
void setData( const std::vector< T > &data ) throw( WOutOfBounds );
/**
* Renders the matrix to a full nxn matrix, where the main diagonal is set to 0.0 and the m(i,j) == m(j,i).
* Each column is separated by exactly one space and each row is separated by a newline.
*
* @return Multiline string containing the nxn symmetric matrix.
*/
std::string toString( void ) const;
private:
/**
* Internal data structure to store the elements. The order is row major.
......@@ -123,6 +132,23 @@ inline WMatrixSymImpl< T >::WMatrixSymImpl()
{
}
template< typename T >
inline const T& WMatrixSymImpl< T >::operator()( size_t i, size_t j ) const throw( WOutOfBounds )
{
if( i == j || i >= m_n || j >= m_n )
{
std::stringstream ss;
ss << "Invalid Element Access ( " << i << ", " << j << " ). No diagonal elements or indices bigger than " << m_n << " are allowed.";
throw WOutOfBounds( ss.str() );
}
if( i > j )
{
std::swap( i, j );
}
return m_data[( i * m_n + j - ( i + 1 ) * ( i + 2 ) / 2 )];
}
template< typename T >
inline T& WMatrixSymImpl< T >::operator()( size_t i, size_t j ) throw( WOutOfBounds )
{
......@@ -139,6 +165,37 @@ inline T& WMatrixSymImpl< T >::operator()( size_t i, size_t j ) throw( WOutOfBou
return m_data[( i * m_n + j - ( i + 1 ) * ( i + 2 ) / 2 )];
}
template< typename T >
inline std::string WMatrixSymImpl< T >::toString( void ) const
{
std::stringstream ss;
ss.precision( 3 );
ss << std::fixed;
for( size_t i = 0; i < m_n; ++i )
{
for( size_t j = 0; j < m_n; ++j )
{
if( i != j )
{
ss << this->operator()(i,j);
}
else
{
ss << "0.0";
}
if( ( j + 1 ) < m_n )
{
ss << " ";
}
}
if( ( i + 1 ) < m_n )
{
ss << std::endl;
}
}
return ss.str();
}
template< typename T >
inline size_t WMatrixSymImpl< T >::numElements() const
{
......
......@@ -81,11 +81,19 @@ public:
void testInvalidAccessOnMainDiagonal( void )
{
WMatrixSymDBL t( 4 );
double mydata[] = { 1.6, 0.2, 7.7 }; // NOLINT
std::vector< double > data( mydata, mydata + sizeof( mydata ) / sizeof( double ) );
TS_ASSERT_THROWS_EQUALS( t( 0, 0 ), WOutOfBounds &e, std::string( e.what() ),
"Invalid Element Access ( 0, 0 ). No diagonal elements or indices bigger than 4 are allowed." );
}
void testToString( void )
{
WMatrixSymDBL t( 3 );
double mydata[] = { 1.6, 0.2, 1/3.0 }; // NOLINT
std::vector< double > data( mydata, mydata + sizeof( mydata ) / sizeof( double ) );
t.setData( data );
std::string expected = "0.0 1.600 0.200\n1.600 0.0 0.333\n0.200 0.333 0.0";
TS_ASSERT_EQUALS( expected, t.toString() );
}
};
#endif // WMATRIXSYM_TEST_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment