OpenWalnut  1.4.0
WMatrixSym_test.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2013 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WMATRIXSYM_TEST_H
26 #define WMATRIXSYM_TEST_H
27 
28 #include <sstream>
29 #include <string>
30 #include <vector>
31 
32 #include <cxxtest/TestSuite.h>
33 #include <cxxtest/ValueTraits.h>
34 
35 #include "../../exceptions/WOutOfBounds.h"
36 #include "../../test/WTraitsBase.h"
37 #include "../WMatrixSym.h"
38 
39 #ifdef CXXTEST_RUNNING
40 namespace CxxTest
41 {
42 CXXTEST_TEMPLATE_INSTANTIATION
43 /**
44  * Enables better UnitTest OutPut if something fails with WFibers, so you see
45  * immedeatly what is failing.
46  */
47 class ValueTraits< WMatrixSym< double > > : public WTraitsBase
48 {
49 public:
50  /**
51  * Constructor for class allowing usable output of WMatrix in tests
52  *
53  * \param m the WMatrix to print
54  */
55  explicit ValueTraits( const WMatrixSym< double > &m )
56  {
57  std::stringstream tmp;
58  tmp.precision( 5 );
59  for( size_t row = 0; row < m.size(); row++ )
60  {
61  for( size_t col = row + 1; col < m.size(); col++ )
62  {
63  tmp << m( row, col ) << " ";
64  }
65  }
66  m_s = tmp.str();
67  }
68 };
69 }
70 #endif // CXXTEST_RUNNING
71 
72 /**
73  * Unit test this LookUp table class. All test performed on matrices with double as element type.
74  */
75 class WMatrixSymTest : public CxxTest::TestSuite
76 {
77 public:
78  /**
79  * Only the Elements of the upper/lower sym. Matrix should be stored.
80  */
82  {
83  WMatrixSymDBL t( 3 );
84  TS_ASSERT_EQUALS( t.m_data.size(), 3 );
85  }
86 
87  /**
88  * Access to elements on main diagonal is forbidden. Then other acess
89  * should be symmetric.
90  */
91  void testAccessOn3x3Matrix( void )
92  {
93  WMatrixSymDBL t( 3 );
94  double mydata[] = { 1.6, 0.2, 7.7 }; // NOLINT
95  std::vector< double > data( mydata, mydata + sizeof( mydata ) / sizeof( double ) );
96  t.setData( data );
97  TS_ASSERT_EQUALS( t( 1, 2 ), 7.7 );
98  TS_ASSERT_EQUALS( t( 2, 1 ), 7.7 );
99  }
100 
101  /**
102  * If new elements are set via the setData() method then it has to be
103  * checked if the dimension is valid for the number of elements which
104  * are given.
105  */
107  {
108  WMatrixSymDBL t( 4 );
109  double mydata[] = { 1.6, 0.2, 7.7 }; // NOLINT
110  std::vector< double > data( mydata, mydata + sizeof( mydata ) / sizeof( double ) );
111  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
112  }
113 
114  /**
115  * Accessing diagonal elements is forbidden and an exception should be thrown
116  */
118  {
119  WMatrixSymDBL t( 4 );
120  TS_ASSERT_THROWS_EQUALS( t( 0, 0 ), WOutOfBounds &e, std::string( e.what() ),
121  "Invalid Element Access ( 0, 0 ). No diagonal elements or indices bigger than 4 are allowed." );
122  }
123 
124  /**
125  * Renders the matrix to a string, where each row is in a separate line.
126  */
127  void testToString( void )
128  {
129  WMatrixSymDBL t( 3 );
130  double mydata[] = { 1.6, 0.2, 1/3.0 }; // NOLINT
131  std::vector< double > data( mydata, mydata + sizeof( mydata ) / sizeof( double ) );
132  t.setData( data );
133  std::string expected = "0.000000000 1.600000000 0.200000000\n1.600000000 0.000000000 0.333333333\n0.200000000 0.333333333 0.000000000";
134  TS_ASSERT_EQUALS( expected, t.toString() );
135  }
136 
137  /**
138  * There should be an output operator for symmetric matrices.
139  */
140  void testOutputStream( void )
141  {
142  WMatrixSymDBL t( 3 );
143  double mydata[] = { 1.6, 0.2, 1/3.0 }; // NOLINT
144  std::vector< double > data( mydata, mydata + sizeof( mydata ) / sizeof( double ) );
145  t.setData( data );
146  std::string expected = "0.00 1.60 0.20\n1.60 0.00 0.33\n0.20 0.33 0.00";
147  std::stringstream ss;
148  ss << std::setprecision( 2 ) << std::fixed;
149  ss << t;
150  TS_ASSERT_EQUALS( expected, ss.str() );
151  }
152 
153  /**
154  * There should be an input operator for symmetric matrices, reading data into a given matrix.
155  */
156  void testInputStream( void )
157  {
158  WMatrixSymDBL expected( 3 );
159  double mydata[] = { 1.6, 0.2, 0.3 }; // NOLINT
160  std::vector< double > data( mydata, mydata + sizeof( mydata ) / sizeof( double ) );
161  expected.setData( data );
162  std::stringstream ss( "0.0 1.6 0.2\n1.6 0.0 0.3\n0.2 0.3 0.0" );
163  WMatrixSymDBL actual( 3 );
164  ss >> actual;
165  TS_ASSERT_EQUALS( expected, actual );
166  }
167 };
168 
169 #endif // WMATRIXSYM_TEST_H