source: trunk/test/matrix_test.cc @ 1598

Last change on this file since 1598 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
RevLine 
[271]1// $Id: matrix_test.cc 1598 2008-10-24 21:12:37Z peter $
2
[675]3/*
[831]4  Copyright (C) 2005 Jari Häkkinen, Peter Johansson
[1275]5  Copyright (C) 2006 Jari Häkkinen, Peter Johansson, Markus Ringnér
6  Copyright (C) 2007, 2008 Jari Häkkinen, Peter Johansson
[271]7
[1437]8  This file is part of the yat library, http://dev.thep.lu.se/yat
[675]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
[1486]12  published by the Free Software Foundation; either version 3 of the
[675]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
[1487]21  along with yat. If not, see <http://www.gnu.org/licenses/>.
[675]22*/
23
[1240]24#include "Suite.h"
25
[1121]26#include "yat/utility/Matrix.h"
[675]27
[679]28#include <cstdio>
[271]29#include <fstream>
30#include <iostream>
31
[420]32class matrixwrapper
33{
34public:
35  matrixwrapper(size_t i,size_t j,double value=7)
36    : m_(i,j,value) {}
37
[1015]38  inline theplu::yat::utility::VectorView
[1028]39  row(const size_t& i) { return m_.row_view(i); }
[420]40
[1121]41  inline const theplu::yat::utility::Matrix& matrix(void) const { return m_; }
[420]42
43private:
[1121]44  theplu::yat::utility::Matrix m_;
[420]45};
46
47
[1240]48int main(int argc, char* argv[])
[420]49{
[680]50  using namespace theplu::yat;
[1240]51  test::Suite suite(argc, argv);
[420]52
[1240]53  suite.err() << "Testing matrix class" << std::endl;
[1121]54  utility::Matrix unit3x3(3,3);
[762]55  for (size_t i=0; i<unit3x3.rows(); ++i)
56    unit3x3(i,i)=1;
[271]57
[1360]58  suite.add(suite.test_stream(unit3x3));
59
[1240]60  suite.err() << "\tcopy constructor and operator!=" << std::endl;
[1121]61  utility::Matrix m(3,3,9);
62  utility::Matrix m2(m);
[271]63  if (m2!=m)
[1240]64    suite.add(false);
[420]65
[1240]66  suite.err() << "\toutput operator and istream constructor" << std::endl;
[420]67  // Checking that the matrix output operator writes a file that the
68  // input operator can read.
[1251]69  std::ofstream my_out("/tmp/yat_test_matrix.txt");
[271]70  my_out << m2;
71  my_out.close();
[1251]72  std::ifstream is("/tmp/yat_test_matrix.txt");
[1121]73  utility::Matrix m3(is);
[271]74  is.close();
75  if (m3!=m2)
[1240]76    suite.add(false);
[1251]77  std::remove("/tmp/yat_test_matrix.txt");
[271]78
[1240]79  suite.err() << "\toperator*=(double)" << std::endl;
[1121]80  utility::Matrix m4(3,3,1);
[393]81  m4 *= 9;
[420]82  if (m4!=m) {
[1240]83    suite.add(false);
84    suite.err() << "error operator*=(double)" << std::endl;
[271]85  }
86
[1251]87  is.open(test::filename("data/knni_matrix.data").c_str());
[420]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.
[1121]91  utility::Matrix m5(is);
[420]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);
[393]97
[793]98  // checking that copy constructor creates an independent object when
99  // a non-view matrix is copied
100  {
[1240]101    suite.err() << "\tcopy constructor" << std::endl;
[1121]102    utility::Matrix m2(m5);
[1240]103    suite.add(m2.rows()==m5.rows());
104    suite.add(m2.columns()==m5.columns());
105    suite.add(m2==m5);
106    suite.add(&m2 != &m5);
[793]107  }
108
[1240]109  suite.err() << "\tsub-(row)vector" << std::endl;
[420]110  // Checking that the row view works, i.e. mutation to the view are
111  // reflected in the viewed object.
[1098]112  double m5_sum2=0;
[793]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);
[1015]116  utility::VectorView v5subrow(m5,3);
[420]117  double v5subrow_sum=0;
118  for (size_t i=0; i<v5subrow.size(); ++i) {
119    v5subrow_sum+=v5subrow(i);
[1151]120    v5subrow(i)=0;
[420]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) {
[1240]127    suite.add(false);
128    suite.err() << "error sub-vector test 1" << std::endl;
[420]129  }
130
[1240]131  suite.err() << "\tsub-(column)vector" << std::endl;
[420]132  // Checking that the column view works, i.e. mutation to the view
133  // are reflected in the viewed object.
[793]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);
[1028]138  utility::VectorView v5subcolumn = m5.column_view(0);
[420]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) {
[1240]149    suite.add(false);
150    suite.err() << "error sub-vector test 2" << std::endl;
[420]151  }
[793]152
[420]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) {
[1240]159    suite.add(false);
160    suite.err() << "error sub-vector test 3" << std::endl;
[420]161  }
162
[1240]163  suite.err() << "\tsub-vector and vector copying" << std::endl;
[420]164  // Checking that a view is not inherited through the copy
165  // contructor.
[1120]166  utility::Vector v6(v5subrow);
[830]167  v6.all(2);
[420]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) {
[1240]172    suite.add(false);
173    suite.err() << "error sub-vector test 4" << std::endl;
[420]174  }
175  // Checking that values in a vector is copied into a viewed matrix.
[830]176  v5subrow = v6;
[420]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) {
[1240]182    suite.add(false);
183    suite.err() << "error sub-vector test 5" << std::endl;
[420]184  }
185
186  // Checking that the memberfunction matrixwrapper::row() returns a
187  // view
[1240]188  suite.err() << "\tthat class member returns a view" << std::endl;
[420]189  matrixwrapper mw(5,2);
[1015]190  utility::VectorView mwrow=mw.row(2);
[420]191  if (mwrow.gsl_vector_p()->data != &(mw.matrix()(2,0))) {
[1240]192    suite.add(false);
193    suite.err() << "error sub-vector test 7" << std::endl;
[420]194  }
195
[1240]196  suite.err() << "\tmatrix::nan()" << std::endl;
[1251]197  is.open(test::filename("data/sorlie_centroid_data.txt").c_str());
[1121]198  utility::Matrix* m_nan = new utility::Matrix(is,'\t');
199  utility::Matrix m_weight;
[774]200  utility::nan(*m_nan,m_weight);
[516]201  is.close();
202  if (m_weight(0,0)!=1){
[1240]203    suite.err() << "error in matrix::nan(): element(0,0) is " << m_weight(0,0)
[516]204           << " expected 1." << std::endl;
[1240]205    suite.add(false);
[516]206  }
207  if (m_weight(3,2)!=0){
[1240]208    suite.err() << "error in matrix::nan(): element(3,2) is " << m_weight(3,2)
[516]209           << " expected 0." << std::endl;
[1240]210    suite.add(false);
[516]211  }
212  delete m_nan;
213
[1240]214  suite.err() << "\toperator*=(matrix&)" << std::endl;
[1121]215  utility::Matrix m6(unit3x3);
[762]216  m6 *= m;
217  if (m6!=m) {
[1240]218    suite.add(false);
219    suite.err() << "error operator*=(matrix) 1" << std::endl;
[762]220  }
221  m6 *= unit3x3;
222  if (m6!=m) {
[1240]223    suite.add(false);
224    suite.err() << "error operator*=(matrix) 2" << std::endl;
[762]225  }
[1121]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);
[796]231  m6*= unit3x3;
[762]232
[1598]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
[1240]239  suite.return_value();
[271]240}
Note: See TracBrowser for help on using the repository browser.