Commit 321ba8fa authored by Mathias Goldau's avatar Mathias Goldau
Browse files

[ADD] Stream operators (input, output) for WMatrixSym and Style and Doc corrections

parent 7648a428
......@@ -27,7 +27,9 @@
#include <algorithm>
#include <cassert>
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>
#include "../exceptions/WOutOfBounds.h"
......@@ -71,6 +73,17 @@ public:
* \return reference to the (i,j) element of the table
*/
T& operator()( size_t i, size_t j ) throw( WOutOfBounds );
/**
* Const version of the element access.
*
* \warning Acessing elements of the main diagonal is forbidden!
*
* \param i The i'th row
* \param j The j'th column
*
* \return Const reference to the (i,j) element of the table
*/
const T& operator()( size_t i, size_t j ) const throw( WOutOfBounds );
/**
......@@ -165,35 +178,113 @@ 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 )
std::stringstream ss;
ss << std::setprecision( 9 ) << std::fixed;
ss << *this;
return ss.str();
}
/**
* Compares two matrix elementwise. First tested their size, if equal elementwisely further tests.
*
* \tparam T Element type
* \param lhs Left symmetric matrix operand
* \param rhs Right symmetric matrix operand
*
* \return True if and only if all elements are equal.
*/
template< typename T >
inline bool operator==( WMatrixSymImpl< T > const& lhs, WMatrixSymImpl< T > const& rhs )
{
std::vector< T > l = lhs.getData();
std::vector< T > r = rhs.getData();
return l == r;
}
/**
* Output operator for symmetric Matrix producing full square matrix. Each row in separate line.
*
* \tparam T Element type
* \param os Output stream
* \param m Matrix to put to output stream
*
* \return Output stream
*/
template< typename T >
inline std::ostream& operator<<( std::ostream& os, const WMatrixSymImpl< T >& m )
{
size_t n = m.size();
for( size_t i = 0; i < n; ++i )
{
for( size_t j = 0; j < m_n; ++j )
for( size_t j = 0; j < n; ++j )
{
if( i != j )
{
ss << this->operator()(i,j);
os << m( i, j );
}
else
{
ss << "0.0";
os << 0.0;
}
if( ( j + 1 ) < m_n )
if( ( j + 1 ) < n )
{
ss << " ";
os << " ";
}
}
if( ( i + 1 ) < m_n )
if( ( i + 1 ) < n )
{
ss << std::endl;
os << std::endl;
}
}
return os;
}
/**
* Read elemnts of full square matrix into symmetric matrix. Only elements of the upper triangle matrix will be used.
* First all elements separated by white space are read and then dimension check is performed, to ensure all
* elements fit into sym Matrix then.
*
* \throw WOutOfBounds exception if element number missmatch occours.
*
* \tparam T Element type
* \param is Input Stream
* \param m Sym. Matrix to populate
*
* \return Input Stream
*/
template< typename T >
inline std::istream& operator>>( std::istream& is, WMatrixSymImpl< T >& m )
{
std::vector< T > elements;
T elm;
while( is >> elm )
{
elements.push_back( elm );
}
if( m.size() * m.size() != elements.size() )
{
std::stringstream ss;
ss << "Error: Input stream has: " << elements.size() << " elements, while matrix given to accommodate expected: ";
ss << m.size() * m.size() << " elements.";
throw WOutOfBounds( ss.str() );
}
typename std::vector< T >::const_iterator it = elements.begin();
for( size_t i = 0; i < m.size(); ++i )
{
for( size_t j = 0; j < m.size(); ++j )
{
if( j > i )
{
m( i, j ) = *it;
}
++it;
}
}
return ss.str();
return is;
}
template< typename T >
......
......@@ -25,14 +25,50 @@
#ifndef WMATRIXSYM_TEST_H
#define WMATRIXSYM_TEST_H
#include <sstream>
#include <string>
#include <vector>
#include <cxxtest/TestSuite.h>
#include <cxxtest/ValueTraits.h>
#include "../../exceptions/WOutOfBounds.h"
#include "../../test/WTraitsBase.h"
#include "../WMatrixSym.h"
#ifdef CXXTEST_RUNNING
namespace CxxTest
{
CXXTEST_TEMPLATE_INSTANTIATION
/**
* Enables better UnitTest OutPut if something fails with WFibers, so you see
* immedeatly what is failing.
*/
class ValueTraits< WMatrixSymImpl< double > > : public WTraitsBase
{
public:
/**
* Constructor for class allowing usable output of WMatrix in tests
*
* \param m the WMatrix to print
*/
explicit ValueTraits( const WMatrixSymImpl< double > &m )
{
std::stringstream tmp;
tmp.precision( 5 );
for( size_t row = 0; row < m.size(); row++ )
{
for( size_t col = row + 1; col < m.size(); col++ )
{
tmp << m( row, col ) << " ";
}
}
m_s = tmp.str();
}
};
}
#endif // CXXTEST_RUNNING
/**
* Unit test this LookUp table class. All test performed on matrices with double as element type.
*/
......@@ -85,15 +121,49 @@ public:
"Invalid Element Access ( 0, 0 ). No diagonal elements or indices bigger than 4 are allowed." );
}
/**
* Renders the matrix to a string, where each row is in a separate line.
*/
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";
std::string expected = "0.000000000 1.600000000 0.200000000\n1.600000000 0.000000000 0.333333333\n0.200000000 0.333333333 0.000000000";
TS_ASSERT_EQUALS( expected, t.toString() );
}
/**
* There should be an output operator for symmetric matrices.
*/
void testOutputStream( 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.00 1.60 0.20\n1.60 0.00 0.33\n0.20 0.33 0.00";
std::stringstream ss;
ss << std::setprecision( 2 ) << std::fixed;
ss << t;
TS_ASSERT_EQUALS( expected, ss.str() );
}
/**
* There should be an input operator for symmetric matrices, reading data into a given matrix.
*/
void testInputStream( void )
{
WMatrixSymDBL expected( 3 );
double mydata[] = { 1.6, 0.2, 0.3 }; // NOLINT
std::vector< double > data( mydata, mydata + sizeof( mydata ) / sizeof( double ) );
expected.setData( data );
std::stringstream ss( "0.0 1.6 0.2\n1.6 0.0 0.3\n0.2 0.3 0.0" );
WMatrixSymDBL actual( 3 );
ss >> actual;
TS_ASSERT_EQUALS( expected, actual );
}
};
#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