source: trunk/test/matrix_test.cc @ 774

Last change on this file since 774 was 774, checked in by Jari Häkkinen, 15 years ago

Fixes #194.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.2 KB
Line 
1// $Id: matrix_test.cc 774 2007-03-01 21:52:48Z jari $
2
3/*
4  Copyright (C) The authors contributing to this file.
5
6  This file is part of the yat library, http://lev.thep.lu.se/trac/yat
7
8  The yat library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2 of the
11  License, or (at your option) any later version.
12
13  The yat library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21  02111-1307, USA.
22*/
23
24#include "yat/utility/matrix.h"
25
26#include <cstdio>
27#include <fstream>
28#include <iostream>
29
30class matrixwrapper
31{
32public:
33  matrixwrapper(size_t i,size_t j,double value=7)
34    : m_(i,j,value) {}
35
36  inline theplu::yat::utility::vector
37  row(const size_t& i) { return theplu::yat::utility::vector(m_,i); }
38
39  inline const theplu::yat::utility::matrix& matrix(void) const { return m_; }
40
41private:
42  theplu::yat::utility::matrix m_;
43};
44
45
46int main(const int argc,const char* argv[])
47{
48  using namespace theplu::yat;
49  std::ostream* error;
50  if (argc>1 && argv[1]==std::string("-v"))
51    error = &std::cerr;
52  else {
53    error = new std::ofstream("/dev/null");
54    if (argc>1)
55      std::cout << "matrix_test -v : for printing extra information\n";
56  }
57
58  *error << "Testing matrix class" << std::endl;
59  bool ok = true;
60  utility::matrix unit3x3(3,3);
61  for (size_t i=0; i<unit3x3.rows(); ++i)
62    unit3x3(i,i)=1;
63
64  *error << "\tcopy constructor and operator!=" << std::endl;
65  utility::matrix m(3,3,9);
66  utility::matrix m2(m);
67  if (m2!=m)
68    ok=false;
69
70  *error << "\toutput operator and istream constructor" << std::endl;
71  // Checking that the matrix output operator writes a file that the
72  // input operator can read.
73  std::ofstream my_out("data/tmp_test_matrix.txt");
74  my_out << m2;
75  my_out.close();
76  std::ifstream is("data/tmp_test_matrix.txt");
77  utility::matrix m3(is);
78  is.close();
79  if (m3!=m2)
80    ok=false;
81  std::remove("data/tmp_test_matrix.txt");
82
83  *error << "\toperator*=(double)" << std::endl;
84  utility::matrix m4(3,3,1);
85  m4 *= 9;
86  if (m4!=m) {
87    ok=false;
88    *error << "error operator*=(double)" << std::endl;
89  }
90
91  *error << "\tsub-matrix" << std::endl;
92  // Checking that sub-matrices work, i.e. mutation to the view are
93  // reflected in the viewed object.
94  is.open("data/knni_matrix.data");
95  // The stream input is a proper matrix file, with some stray empty
96  // lines and other whitespaces. The file is not expected to break
97  // things.
98  utility::matrix m5(is);
99  is.close();
100  double m5_sum=0;
101  for (size_t i=0; i<m5.rows(); ++i)
102    for (size_t j=0; j<m5.columns(); ++j)
103      m5_sum+=m5(i,j);
104  utility::matrix* m5sub=new utility::matrix(m5,3,3,3,3);
105  double m5sub_sum=0;
106  for (size_t i=0; i<m5sub->rows(); ++i)
107    for (size_t j=0; j<m5sub->columns(); ++j) {
108      m5sub_sum+=(*m5sub)(i,j);
109      (*m5sub)(i,j)=1;
110    }
111  delete m5sub;
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  if (m5_sum2-m5_sum-9+m5sub_sum>1e-13) {
117    ok=false;
118    *error << "error sub-matrix test" << std::endl;
119  }
120
121  *error << "\tsub-(row)vector" << std::endl;
122  // Checking that the row view works, i.e. mutation to the view are
123  // reflected in the viewed object.
124  utility::vector v5subrow(m5,3);
125  double v5subrow_sum=0;
126  for (size_t i=0; i<v5subrow.size(); ++i) {
127    v5subrow_sum+=v5subrow(i);
128    v5subrow[i]=0;
129  }
130  double m5_sum3=0;
131  for (size_t i=0; i<m5.rows(); ++i)
132    for (size_t j=0; j<m5.columns(); ++j)
133      m5_sum3+=m5(i,j);
134  if (m5_sum3-m5_sum2+v5subrow_sum>1e-13) {
135    ok=false;
136    *error << "error sub-vector test 1" << std::endl;
137  }
138
139  *error << "\tsub-(column)vector" << std::endl;
140  // Checking that the column view works, i.e. mutation to the view
141  // are reflected in the viewed object.
142  utility::vector v5subcolumn(m5,0,false);
143  double v5subcolumn_sum=0;
144  for (size_t i=0; i<v5subcolumn.size(); ++i) {
145    v5subcolumn_sum+=v5subcolumn(i);
146    v5subcolumn(i)=1;
147  }
148  double m5_sum4=0;
149  for (size_t i=0; i<m5.rows(); ++i)
150    for (size_t j=0; j<m5.columns(); ++j)
151      m5_sum4+=m5(i,j);
152  if (m5_sum4-m5_sum3-v5subcolumn.size()+v5subcolumn_sum>1e-13) {
153    ok=false;
154    *error << "error sub-vector test 2" << std::endl;
155  }
156  // Checking that the column view above mutates the values in the row
157  // view.
158  double v5subrow_sum2=0;
159  for (size_t i=0; i<v5subrow.size(); ++i)
160    v5subrow_sum2+=v5subrow(i);
161  if (v5subrow_sum2-v5subcolumn(3)>1e-13) {
162    ok=false;
163    *error << "error sub-vector test 3" << std::endl;
164  }
165
166  *error << "\tsub-vector and vector copying" << std::endl;
167  // Checking that a view is not inherited through the copy
168  // contructor.
169  utility::vector v6(v5subrow);
170  v6.set_all(2);
171  double v5subrow_sum3=0;
172  for (size_t i=0; i<v5subrow.size(); ++i)
173    v5subrow_sum3+=v5subrow(i);
174  if (v5subrow_sum3-v5subrow_sum2>1e-13) {
175    ok=false;
176    *error << "error sub-vector test 4" << std::endl;
177  }
178  // Checking that values in a vector is copied into a viewed matrix.
179  v5subrow.set(v6);
180  double m5_sum5=0;
181  for (size_t i=0; i<m5.rows(); ++i)
182    for (size_t j=0; j<m5.columns(); ++j)
183      m5_sum5+=m5(i,j);
184  if (m5_sum5-m5_sum4-v5subrow.size()*2+v5subrow_sum3>1e-13) {
185    ok=false;
186    *error << "error sub-vector test 5" << std::endl;
187  }
188  // Checking that vector::operator= indeed makes a view to become a
189  // "normal" vector.
190  v5subrow=utility::vector(23,22);
191  double m5_sum6=0;
192  for (size_t i=0; i<m5.rows(); ++i)
193    for (size_t j=0; j<m5.columns(); ++j)
194      m5_sum6+=m5(i,j);
195  if (m5_sum6-m5_sum5>1e-13) {
196    ok=false;
197    *error << "error sub-vector test 6" << std::endl;
198  }
199
200  // Checking that the memberfunction matrixwrapper::row() returns a
201  // view
202  *error << "\tthat class member returns a view" << std::endl;
203  matrixwrapper mw(5,2);
204  utility::vector mwrow=mw.row(2);
205  if (mwrow.gsl_vector_p()->data != &(mw.matrix()(2,0))) {
206    ok=false;
207    *error << "error sub-vector test 7" << std::endl;
208  }
209
210  *error << "\tsub-matrix of a sub-matrix" << std::endl;
211  // Checking that a sub-matrix of a sub-matrix can be created.
212  utility::matrix sub(m5,3,3,3,3);
213  utility::matrix subsub(sub,2,1,1,2);
214  subsub(0,0)=23221121;
215  if (&sub(2,1)!=&subsub(0,0) || subsub(0,0)!=m5(5,4) || &subsub(0,0)!=&m5(5,4)){
216    ok=false;
217    *error << "error sub-matrix test 1" << std::endl;
218  }
219
220  *error << "\tmatrix::nan()" << std::endl;
221  is.open("data/sorlie_centroid_data.txt");
222  utility::matrix* m_nan = new utility::matrix(is,'\t');
223  utility::matrix m_weight;
224  utility::nan(*m_nan,m_weight);
225  is.close();
226  if (m_weight(0,0)!=1){
227    *error << "error in matrix::nan(): element(0,0) is " << m_weight(0,0)
228           << " expected 1." << std::endl;
229    ok=false;
230  }
231  if (m_weight(3,2)!=0){
232    *error << "error in matrix::nan(): element(3,2) is " << m_weight(3,2)
233           << " expected 0." << std::endl;
234    ok=false;
235  }
236  delete m_nan;
237
238  *error << "\toperator*=(matrix&)" << std::endl;
239  utility::matrix m6(unit3x3);
240  m6 *= m;
241  if (m6!=m) {
242    ok=false;
243    *error << "error operator*=(matrix) 1" << std::endl;
244  }
245  m6 *= unit3x3;
246  if (m6!=m) {
247    ok=false;
248    *error << "error operator*=(matrix) 2" << std::endl;
249  }
250
251  if (error!=&std::cerr)
252    delete error;
253
254  return (ok ? 0 : -1);
255}
Note: See TracBrowser for help on using the repository browser.