source: trunk/test/matrix_test.cc @ 1607

Last change on this file since 1607 was 1598, checked in by Peter, 13 years ago

Fixed some issues related to empty (zero sized) Matrix.

  • Matrix(size_t, size_t) now accepts 0 as argument
  • Matrix(const& Matrix) now works when passed Matrix is empty
  • assignment now works when rhs is empty

related to ticket:343

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.8 KB
Line 
1// $Id: matrix_test.cc 1598 2008-10-24 21:12:37Z peter $
2
3/*
4  Copyright (C) 2005 Jari Häkkinen, Peter Johansson
5  Copyright (C) 2006 Jari Häkkinen, Peter Johansson, Markus Ringnér
6  Copyright (C) 2007, 2008 Jari Häkkinen, Peter Johansson
7
8  This file is part of the yat library, http://dev.thep.lu.se/yat
9
10  The yat library is free software; you can redistribute it and/or
11  modify it under the terms of the GNU General Public License as
12  published by the Free Software Foundation; either version 3 of the
13  License, or (at your option) any later version.
14
15  The yat library 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 GNU
18  General Public License for more details.
19
20  You should have received a copy of the GNU General Public License
21  along with yat. If not, see <http://www.gnu.org/licenses/>.
22*/
23
24#include "Suite.h"
25
26#include "yat/utility/Matrix.h"
27
28#include <cstdio>
29#include <fstream>
30#include <iostream>
31
32class matrixwrapper
33{
34public:
35  matrixwrapper(size_t i,size_t j,double value=7)
36    : m_(i,j,value) {}
37
38  inline theplu::yat::utility::VectorView
39  row(const size_t& i) { return m_.row_view(i); }
40
41  inline const theplu::yat::utility::Matrix& matrix(void) const { return m_; }
42
43private:
44  theplu::yat::utility::Matrix m_;
45};
46
47
48int main(int argc, char* argv[])
49{
50  using namespace theplu::yat;
51  test::Suite suite(argc, argv);
52
53  suite.err() << "Testing matrix class" << std::endl;
54  utility::Matrix unit3x3(3,3);
55  for (size_t i=0; i<unit3x3.rows(); ++i)
56    unit3x3(i,i)=1;
57
58  suite.add(suite.test_stream(unit3x3));
59
60  suite.err() << "\tcopy constructor and operator!=" << std::endl;
61  utility::Matrix m(3,3,9);
62  utility::Matrix m2(m);
63  if (m2!=m)
64    suite.add(false);
65
66  suite.err() << "\toutput operator and istream constructor" << std::endl;
67  // Checking that the matrix output operator writes a file that the
68  // input operator can read.
69  std::ofstream my_out("/tmp/yat_test_matrix.txt");
70  my_out << m2;
71  my_out.close();
72  std::ifstream is("/tmp/yat_test_matrix.txt");
73  utility::Matrix m3(is);
74  is.close();
75  if (m3!=m2)
76    suite.add(false);
77  std::remove("/tmp/yat_test_matrix.txt");
78
79  suite.err() << "\toperator*=(double)" << std::endl;
80  utility::Matrix m4(3,3,1);
81  m4 *= 9;
82  if (m4!=m) {
83    suite.add(false);
84    suite.err() << "error operator*=(double)" << std::endl;
85  }
86
87  is.open(test::filename("data/knni_matrix.data").c_str());
88  // The stream input is a proper matrix file, with some stray empty
89  // lines and other whitespaces. The file is not expected to break
90  // things.
91  utility::Matrix m5(is);
92  is.close();
93  double m5_sum=0;
94  for (size_t i=0; i<m5.rows(); ++i)
95    for (size_t j=0; j<m5.columns(); ++j)
96      m5_sum+=m5(i,j);
97
98  // checking that copy constructor creates an independent object when
99  // a non-view matrix is copied
100  {
101    suite.err() << "\tcopy constructor" << std::endl;
102    utility::Matrix m2(m5);
103    suite.add(m2.rows()==m5.rows());
104    suite.add(m2.columns()==m5.columns());
105    suite.add(m2==m5);
106    suite.add(&m2 != &m5);
107  }
108
109  suite.err() << "\tsub-(row)vector" << std::endl;
110  // Checking that the row view works, i.e. mutation to the view are
111  // reflected in the viewed object.
112  double m5_sum2=0;
113  for (size_t i=0; i<m5.rows(); ++i)
114    for (size_t j=0; j<m5.columns(); ++j)
115      m5_sum2+=m5(i,j);
116  utility::VectorView v5subrow(m5,3);
117  double v5subrow_sum=0;
118  for (size_t i=0; i<v5subrow.size(); ++i) {
119    v5subrow_sum+=v5subrow(i);
120    v5subrow(i)=0;
121  }
122  double m5_sum3=0;
123  for (size_t i=0; i<m5.rows(); ++i)
124    for (size_t j=0; j<m5.columns(); ++j)
125      m5_sum3+=m5(i,j);
126  if (m5_sum3-m5_sum2+v5subrow_sum>1e-13) {
127    suite.add(false);
128    suite.err() << "error sub-vector test 1" << std::endl;
129  }
130
131  suite.err() << "\tsub-(column)vector" << std::endl;
132  // Checking that the column view works, i.e. mutation to the view
133  // are reflected in the viewed object.
134  m5_sum3=0;
135  for (size_t i=0; i<m5.rows(); ++i)
136    for (size_t j=0; j<m5.columns(); ++j)
137      m5_sum3+=m5(i,j);
138  utility::VectorView v5subcolumn = m5.column_view(0);
139  double v5subcolumn_sum=0;
140  for (size_t i=0; i<v5subcolumn.size(); ++i) {
141    v5subcolumn_sum+=v5subcolumn(i);
142    v5subcolumn(i)=1;
143  }
144  double m5_sum4=0;
145  for (size_t i=0; i<m5.rows(); ++i)
146    for (size_t j=0; j<m5.columns(); ++j)
147      m5_sum4+=m5(i,j);
148  if (m5_sum4-m5_sum3-v5subcolumn.size()+v5subcolumn_sum>1e-13) {
149    suite.add(false);
150    suite.err() << "error sub-vector test 2" << std::endl;
151  }
152
153  // Checking that the column view above mutates the values in the row
154  // view.
155  double v5subrow_sum2=0;
156  for (size_t i=0; i<v5subrow.size(); ++i)
157    v5subrow_sum2+=v5subrow(i);
158  if (v5subrow_sum2-v5subcolumn(3)>1e-13) {
159    suite.add(false);
160    suite.err() << "error sub-vector test 3" << std::endl;
161  }
162
163  suite.err() << "\tsub-vector and vector copying" << std::endl;
164  // Checking that a view is not inherited through the copy
165  // contructor.
166  utility::Vector v6(v5subrow);
167  v6.all(2);
168  double v5subrow_sum3=0;
169  for (size_t i=0; i<v5subrow.size(); ++i)
170    v5subrow_sum3+=v5subrow(i);
171  if (v5subrow_sum3-v5subrow_sum2>1e-13) {
172    suite.add(false);
173    suite.err() << "error sub-vector test 4" << std::endl;
174  }
175  // Checking that values in a vector is copied into a viewed matrix.
176  v5subrow = v6;
177  double m5_sum5=0;
178  for (size_t i=0; i<m5.rows(); ++i)
179    for (size_t j=0; j<m5.columns(); ++j)
180      m5_sum5+=m5(i,j);
181  if (m5_sum5-m5_sum4-v5subrow.size()*2+v5subrow_sum3>1e-13) {
182    suite.add(false);
183    suite.err() << "error sub-vector test 5" << std::endl;
184  }
185
186  // Checking that the memberfunction matrixwrapper::row() returns a
187  // view
188  suite.err() << "\tthat class member returns a view" << std::endl;
189  matrixwrapper mw(5,2);
190  utility::VectorView mwrow=mw.row(2);
191  if (mwrow.gsl_vector_p()->data != &(mw.matrix()(2,0))) {
192    suite.add(false);
193    suite.err() << "error sub-vector test 7" << std::endl;
194  }
195
196  suite.err() << "\tmatrix::nan()" << std::endl;
197  is.open(test::filename("data/sorlie_centroid_data.txt").c_str());
198  utility::Matrix* m_nan = new utility::Matrix(is,'\t');
199  utility::Matrix m_weight;
200  utility::nan(*m_nan,m_weight);
201  is.close();
202  if (m_weight(0,0)!=1){
203    suite.err() << "error in matrix::nan(): element(0,0) is " << m_weight(0,0)
204           << " expected 1." << std::endl;
205    suite.add(false);
206  }
207  if (m_weight(3,2)!=0){
208    suite.err() << "error in matrix::nan(): element(3,2) is " << m_weight(3,2)
209           << " expected 0." << std::endl;
210    suite.add(false);
211  }
212  delete m_nan;
213
214  suite.err() << "\toperator*=(matrix&)" << std::endl;
215  utility::Matrix m6(unit3x3);
216  m6 *= m;
217  if (m6!=m) {
218    suite.add(false);
219    suite.err() << "error operator*=(matrix) 1" << std::endl;
220  }
221  m6 *= unit3x3;
222  if (m6!=m) {
223    suite.add(false);
224    suite.err() << "error operator*=(matrix) 2" << std::endl;
225  }
226  m6*= utility::Matrix(3,4,1.0);
227  m6*= utility::Matrix(4,3,1.0);
228  m6*= utility::Matrix(3,5,2.0);
229  m6*= utility::Matrix(5,5,2.0);
230  m6*= utility::Matrix(5,3,2.0);
231  m6*= unit3x3;
232
233  utility::Matrix m7(0,0);
234  m7.resize(1,1);
235  m7 = utility::Matrix(0,0);
236  m7.resize(0,0);
237  m7 = utility::Matrix(0,0);
238
239  suite.return_value();
240}
Note: See TracBrowser for help on using the repository browser.