OpenWalnut  1.4.0
WMatrixSym_test.h
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2013 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_TEST_H
00026 #define WMATRIXSYM_TEST_H
00027 
00028 #include <sstream>
00029 #include <string>
00030 #include <vector>
00031 
00032 #include <cxxtest/TestSuite.h>
00033 #include <cxxtest/ValueTraits.h>
00034 
00035 #include "../../exceptions/WOutOfBounds.h"
00036 #include "../../test/WTraitsBase.h"
00037 #include "../WMatrixSym.h"
00038 
00039 #ifdef CXXTEST_RUNNING
00040 namespace CxxTest
00041 {
00042 CXXTEST_TEMPLATE_INSTANTIATION
00043 /**
00044  * Enables better UnitTest OutPut if something fails with WFibers, so you see
00045  * immedeatly what is failing.
00046  */
00047 class ValueTraits< WMatrixSym< double > > : public WTraitsBase
00048 {
00049 public:
00050     /**
00051      * Constructor for class allowing usable output of WMatrix in tests
00052      *
00053      * \param m the WMatrix to print
00054      */
00055     explicit ValueTraits( const WMatrixSym< double > &m )
00056     {
00057         std::stringstream tmp;
00058         tmp.precision( 5 );
00059         for( size_t row = 0; row < m.size(); row++ )
00060         {
00061           for( size_t col = row + 1; col < m.size(); col++ )
00062           {
00063               tmp << m( row, col ) << " ";
00064           }
00065         }
00066         m_s = tmp.str();
00067     }
00068 };
00069 }
00070 #endif // CXXTEST_RUNNING
00071 
00072 /**
00073  * Unit test this LookUp table class. All test performed on matrices with double as element type.
00074  */
00075 class WMatrixSymTest : public CxxTest::TestSuite
00076 {
00077 public:
00078     /**
00079      * Only the Elements of the upper/lower sym. Matrix should be stored.
00080      */
00081     void testOperatorOn3x3Matrix( void )
00082     {
00083         WMatrixSymDBL t( 3 );
00084         TS_ASSERT_EQUALS( t.m_data.size(), 3 );
00085     }
00086 
00087     /**
00088      * Access to elements on main diagonal is forbidden. Then other acess
00089      * should be symmetric.
00090      */
00091     void testAccessOn3x3Matrix( void )
00092     {
00093         WMatrixSymDBL t( 3 );
00094         double mydata[] = { 1.6, 0.2, 7.7 }; // NOLINT
00095         std::vector< double > data( mydata, mydata + sizeof( mydata ) / sizeof( double ) );
00096         t.setData( data );
00097         TS_ASSERT_EQUALS( t( 1, 2 ), 7.7 );
00098         TS_ASSERT_EQUALS( t( 2, 1 ), 7.7 );
00099     }
00100 
00101     /**
00102      * If new elements are set via the setData() method then it has to be
00103      * checked if the dimension is valid for the number of elements which
00104      * are given.
00105      */
00106     void testSetDataWithInvalidLengthForDimension( void )
00107     {
00108         WMatrixSymDBL t( 4 );
00109         double mydata[] = { 1.6, 0.2, 7.7 }; // NOLINT
00110         std::vector< double > data( mydata, mydata + sizeof( mydata ) / sizeof( double ) );
00111         TS_ASSERT_THROWS_EQUALS( t.setData( data ), WOutOfBounds &e, std::string( e.what() ), "Data vector length: 3 doesn't fit to number of rows and cols: 4" ); // NOLINT line length
00112     }
00113 
00114     /**
00115      * Accessing diagonal elements is forbidden and an exception should be thrown
00116      */
00117     void testInvalidAccessOnMainDiagonal( void )
00118     {
00119         WMatrixSymDBL t( 4 );
00120         TS_ASSERT_THROWS_EQUALS( t( 0, 0 ), WOutOfBounds &e, std::string( e.what() ),
00121                 "Invalid Element Access ( 0, 0 ). No diagonal elements or indices bigger than 4 are allowed." );
00122     }
00123 
00124     /**
00125      * Renders the matrix to a string, where each row is in a separate line.
00126      */
00127     void testToString( void )
00128     {
00129         WMatrixSymDBL t( 3 );
00130         double mydata[] = { 1.6, 0.2, 1/3.0 }; // NOLINT
00131         std::vector< double > data( mydata, mydata + sizeof( mydata ) / sizeof( double ) );
00132         t.setData( data );
00133         std::string expected = "0.000000000 1.600000000 0.200000000\n1.600000000 0.000000000 0.333333333\n0.200000000 0.333333333 0.000000000";
00134         TS_ASSERT_EQUALS( expected, t.toString() );
00135     }
00136 
00137     /**
00138      * There should be an output operator for symmetric matrices.
00139      */
00140     void testOutputStream( void )
00141     {
00142         WMatrixSymDBL t( 3 );
00143         double mydata[] = { 1.6, 0.2, 1/3.0 }; // NOLINT
00144         std::vector< double > data( mydata, mydata + sizeof( mydata ) / sizeof( double ) );
00145         t.setData( data );
00146         std::string expected = "0.00 1.60 0.20\n1.60 0.00 0.33\n0.20 0.33 0.00";
00147         std::stringstream ss;
00148         ss << std::setprecision( 2 ) << std::fixed;
00149         ss << t;
00150         TS_ASSERT_EQUALS( expected, ss.str() );
00151     }
00152 
00153     /**
00154      * There should be an input operator for symmetric matrices, reading data into a given matrix.
00155      */
00156     void testInputStream( void )
00157     {
00158         WMatrixSymDBL expected( 3 );
00159         double mydata[] = { 1.6, 0.2, 0.3 }; // NOLINT
00160         std::vector< double > data( mydata, mydata + sizeof( mydata ) / sizeof( double ) );
00161         expected.setData( data );
00162         std::stringstream ss( "0.0 1.6 0.2\n1.6 0.0 0.3\n0.2 0.3 0.0" );
00163         WMatrixSymDBL actual( 3 );
00164         ss >> actual;
00165         TS_ASSERT_EQUALS( expected, actual );
00166     }
00167 };
00168 
00169 #endif  // WMATRIXSYM_TEST_H