source: trunk/test/matrix_test.cc @ 789

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

Addresses #193. vector now works as outlined here. Added some
functionality. Added a clone function that facilitates resizing of
vectors. clone is needed since assignement operator functionality is
changed.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.9 KB
Line 
1// $Id: matrix_test.cc 789 2007-03-10 20:07:13Z 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
189  // Checking that the memberfunction matrixwrapper::row() returns a
190  // view
191  *error << "\tthat class member returns a view" << std::endl;
192  matrixwrapper mw(5,2);
193  utility::vector mwrow=mw.row(2);
194  if (mwrow.gsl_vector_p()->data != &(mw.matrix()(2,0))) {
195    ok=false;
196    *error << "error sub-vector test 7" << std::endl;
197  }
198
199  *error << "\tsub-matrix of a sub-matrix" << std::endl;
200  // Checking that a sub-matrix of a sub-matrix can be created.
201  utility::matrix sub(m5,3,3,3,3);
202  utility::matrix subsub(sub,2,1,1,2);
203  subsub(0,0)=23221121;
204  if (&sub(2,1)!=&subsub(0,0) || subsub(0,0)!=m5(5,4) || &subsub(0,0)!=&m5(5,4)){
205    ok=false;
206    *error << "error sub-matrix test 1" << std::endl;
207  }
208
209  *error << "\tmatrix::nan()" << std::endl;
210  is.open("data/sorlie_centroid_data.txt");
211  utility::matrix* m_nan = new utility::matrix(is,'\t');
212  utility::matrix m_weight;
213  utility::nan(*m_nan,m_weight);
214  is.close();
215  if (m_weight(0,0)!=1){
216    *error << "error in matrix::nan(): element(0,0) is " << m_weight(0,0)
217           << " expected 1." << std::endl;
218    ok=false;
219  }
220  if (m_weight(3,2)!=0){
221    *error << "error in matrix::nan(): element(3,2) is " << m_weight(3,2)
222           << " expected 0." << std::endl;
223    ok=false;
224  }
225  delete m_nan;
226
227  *error << "\toperator*=(matrix&)" << std::endl;
228  utility::matrix m6(unit3x3);
229  m6 *= m;
230  if (m6!=m) {
231    ok=false;
232    *error << "error operator*=(matrix) 1" << std::endl;
233  }
234  m6 *= unit3x3;
235  if (m6!=m) {
236    ok=false;
237    *error << "error operator*=(matrix) 2" << std::endl;
238  }
239
240  if (error!=&std::cerr)
241    delete error;
242
243  return (ok ? 0 : -1);
244}
Note: See TracBrowser for help on using the repository browser.