bpp-core  2.2.0
Matrix.h
Go to the documentation of this file.
1 //
2 // File: Matrix.h
3 // Authors: Julien Dutheil
4 // Sylvain Gaillard
5 // Created on: Tue Apr 07 11:58 2004
6 //
7 
8 /*
9  Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
10 
11  This software is a computer program whose purpose is to provide classes
12  for numerical calculus.
13 
14  This software is governed by the CeCILL license under French law and
15  abiding by the rules of distribution of free software. You can use,
16  modify and/ or redistribute the software under the terms of the CeCILL
17  license as circulated by CEA, CNRS and INRIA at the following URL
18  "http://www.cecill.info".
19 
20  As a counterpart to the access to the source code and rights to copy,
21  modify and redistribute granted by the license, users are provided only
22  with a limited warranty and the software's author, the holder of the
23  economic rights, and the successive licensors have only limited
24  liability.
25 
26  In this respect, the user's attention is drawn to the risks associated
27  with loading, using, modifying and/or developing or reproducing the
28  software by the user in light of its specific status of free software,
29  that may mean that it is complicated to manipulate, and that also
30  therefore means that it is reserved for developers and experienced
31  professionals having in-depth computer knowledge. Users are therefore
32  encouraged to load and test the software's suitability as regards their
33  requirements in conditions enabling the security of their systems and/or
34  data to be ensured and, more generally, to use and operate it in the
35  same conditions as regards security.
36 
37  The fact that you are presently reading this means that you have had
38  knowledge of the CeCILL license and that you accept its terms.
39  */
40 
41 
42 #ifndef _MATRIX_H_
43 #define _MATRIX_H_
44 
45 #include <vector>
46 #include "../../Clonable.h"
47 #include "../NumConstants.h"
48 #include "../NumTools.h"
49 #include "../VectorExceptions.h"
50 #include <iostream>
51 
52 namespace bpp
53 {
57 template<class Scalar>
58 class Matrix :
59  public Clonable
60 {
61 public:
62  Matrix() {}
63  virtual ~Matrix() {}
64 
65 public:
66 
72  virtual const Scalar& operator()(size_t i, size_t j) const = 0;
73 
79  virtual Scalar& operator()(size_t i, size_t j) = 0;
80 
81  virtual bool equals(const Matrix& m, double threshold = NumConstants::TINY())
82  {
84  return false;
85  for (size_t i = 0; i < getNumberOfRows(); i++)
86  {
87  for (size_t j = 0; j < getNumberOfColumns(); j++)
88  {
89  if (NumTools::abs<double>(static_cast<double>(operator()(i, j)) - static_cast<double>(m(i, j))) > threshold) return false;
90  }
91  }
92  return true;
93  }
97  virtual size_t getNumberOfRows() const = 0;
101  virtual size_t getNumberOfColumns() const = 0;
106  virtual std::vector<Scalar> row(size_t i) const = 0;
111  virtual std::vector<Scalar> col(size_t j) const = 0;
118  virtual void resize(size_t nRows, size_t nCols) = 0;
119 };
120 
121 
128 template<class Scalar>
129 class RowMatrix :
130  public Matrix<Scalar>
131 {
132 private:
133  std::vector< std::vector<Scalar> > m_;
134 
135 public:
136  RowMatrix() : m_() {}
137 
138  RowMatrix(size_t nRow, size_t nCol) : m_(nRow)
139  {
140  for (size_t i = 0; i < nRow; i++)
141  {
142  m_[i].resize(nCol);
143  }
144  }
145 
147  {
148  size_t nr = m.getNumberOfRows();
149  size_t nc = m.getNumberOfColumns();
150  for (size_t i = 0; i < nr; i++)
151  {
152  m_[i].resize(nc);
153  for (size_t j = 0; j < nc; j++)
154  {
155  m_[i][j] = m(i, j);
156  }
157  }
158  }
159 
161  {
162  size_t nr = m.getNumberOfRows();
163  m_.resize(nr);
164  size_t nc = m.getNumberOfColumns();
165  for (size_t i = 0; i < nr; i++)
166  {
167  m_[i].resize(nc);
168  for (size_t j = 0; j < nc; j++)
169  {
170  m_[i][j] = m(i, j);
171  }
172  }
173  return *this;
174  }
175 
176  virtual ~RowMatrix() {}
177 
178 public:
179  RowMatrix* clone() const { return new RowMatrix(*this); }
180 
181  const Scalar& operator()(size_t i, size_t j) const { return m_[i][j]; }
182 
183  Scalar& operator()(size_t i, size_t j) { return m_[i][j]; }
184 
185  size_t getNumberOfRows() const { return m_.size(); }
186 
187  size_t getNumberOfColumns() const { return m_.size() == 0 ? 0 : m_[0].size(); }
188 
189  std::vector<Scalar> row(size_t i) const
190  {
191  std::vector<Scalar> r(getNumberOfColumns());
192  for (size_t j = 0; j < getNumberOfColumns(); j++) { r[j] = operator()(i, j); }
193  return r;
194  }
195 
196  const std::vector<Scalar>& getRow(size_t i) const
197  {
198  return m_[i];
199  }
200 
201  std::vector<Scalar> col(size_t j) const
202  {
203  std::vector<Scalar> c(getNumberOfRows());
204  for (size_t i = 0; i < getNumberOfRows(); i++) { c[i] = operator()(i, j); }
205  return c;
206  }
207 
208  void resize(size_t nRows, size_t nCols)
209  {
210  m_.resize(nRows);
211  for (size_t i = 0; i < nRows; i++)
212  {
213  m_[i].resize(nCols);
214  }
215  }
216 
217  void addRow(const std::vector<Scalar>& newRow) throw (DimensionException)
218  {
219  if (getNumberOfColumns()!=0 && newRow.size() != getNumberOfColumns())
220  throw DimensionException("RowMatrix::addRow: invalid row dimension", newRow.size(), getNumberOfColumns());
221  m_.push_back(newRow);
222  }
223 };
224 
231  template<class Scalar>
232  class ColMatrix :
233  public Matrix<Scalar>
234  {
235  private:
236  std::vector< std::vector<Scalar> > m_;
237 
238  public:
239  ColMatrix() : m_() {}
240 
241  ColMatrix(size_t nRow, size_t nCol) : m_(nCol)
242  {
243  for (size_t i = 0; i < nCol; i++)
244  {
245  m_[i].resize(nRow);
246  }
247  }
248 
250  {
251  size_t nr = m.getNumberOfRows();
252  size_t nc = m.getNumberOfColumns();
253  for (size_t i = 0; i < nc; i++)
254  {
255  m_[i].resize(nr);
256  for (size_t j = 0; j < nr; j++)
257  {
258  m_[i][j] = m(j, i);
259  }
260  }
261  }
262 
264  {
265  size_t nc = m.getNumberOfColumns();
266  m_.resize(nc);
267  size_t nr = m.getNumberOfRows();
268  for (size_t i = 0; i < nc; i++)
269  {
270  m_[i].resize(nr);
271  for (size_t j = 0; j < nr; j++)
272  {
273  m_[i][j] = m(j, i);
274  }
275  }
276  return *this;
277  }
278 
279  virtual ~ColMatrix() {}
280 
281  public:
282  ColMatrix* clone() const { return new ColMatrix(*this); }
283 
284  const Scalar& operator()(size_t i, size_t j) const { return m_[j][i]; }
285 
286  Scalar& operator()(size_t i, size_t j) { return m_[j][i]; }
287 
288  size_t getNumberOfColumns() const { return m_.size(); }
289 
290  size_t getNumberOfRows() const { return m_.size() == 0 ? 0 : m_[0].size(); }
291 
292  std::vector<Scalar> row(size_t i) const
293  {
294  std::vector<Scalar> r(getNumberOfColumns());
295  for (size_t j = 0; j < getNumberOfColumns(); j++) { r[j] = operator()(i, j); }
296  return r;
297  }
298 
299  const std::vector<Scalar>& getCol(size_t i) const
300  {
301  return m_[i];
302  }
303 
304  std::vector<Scalar> col(size_t j) const
305  {
306  std::vector<Scalar> c(getNumberOfRows());
307  for (size_t i = 0; i < getNumberOfRows(); i++) { c[i] = operator()(i, j); }
308  return c;
309  }
310 
311  void resize(size_t nRows, size_t nCols)
312  {
313  m_.resize(nCols);
314  for (size_t i = 0; i < nCols; i++)
315  {
316  m_[i].resize(nRows);
317  }
318  }
319 
320  void addCol(const std::vector<Scalar>& newCol) throw (DimensionException)
321  {
322  if (getNumberOfRows()!=0 && newCol.size() != getNumberOfRows())
323  throw DimensionException("ColMatrix::addCol: invalid column dimension", newCol.size(), getNumberOfRows());
324  m_.push_back(newCol);
325  }
326  };
327 
344 template<class Scalar>
346  public Matrix<Scalar>
347 {
348 private:
349  std::vector<Scalar> m_;
350  size_t rows_;
351  size_t cols_;
352 
353 public:
358  rows_(0),
359  cols_(0) { resize_(0, 0); }
360 
364  LinearMatrix(size_t nRow, size_t nCol) : m_(),
365  rows_(nRow),
366  cols_(nCol) { resize_(nRow, nCol); }
367 
369  {
370  size_t nr = m.getNumberOfRows();
371  size_t nc = m.getNumberOfColumns();
372  for (size_t i = 0; i < nr; i++)
373  {
374  for (size_t j = 0; j < nc; j++)
375  {
376  m_[i * cols_ + j] = m(i, j);
377  }
378  }
379  }
380 
382  {
383  size_t nr = m.getNumberOfRows();
384  size_t nc = m.getNumberOfColumns();
385  m_.resize(nr * nc);
386  for (size_t i = 0; i < nr; i++)
387  {
388  m_[i].resize(nc);
389  for (size_t j = 0; j < nc; j++)
390  {
391  m_[i * cols_ + j] = m(i, j);
392  }
393  }
394  return *this;
395  }
396 
400  virtual ~LinearMatrix() {}
401 
402 public:
403  LinearMatrix* clone() const { return new LinearMatrix(*this); }
404 
405  const Scalar& operator()(size_t i, size_t j) const { return m_[i * cols_ + j]; }
406 
407  Scalar& operator()(size_t i, size_t j) { return m_[i * cols_ + j]; }
408 
409  size_t getNumberOfRows() const { return rows_; }
410 
411  size_t getNumberOfColumns() const { return cols_; }
412 
413  std::vector<Scalar> row(size_t i) const
414  {
415  std::vector<Scalar> r(getNumberOfColumns());
416  for (size_t j = 0; j < getNumberOfColumns(); j++)
417  {
418  r[j] = operator()(i, j);
419  }
420  return r;
421  }
422 
423  std::vector<Scalar> col(size_t j) const
424  {
425  std::vector<Scalar> c(getNumberOfRows());
426  for (size_t i = 0; i < getNumberOfRows(); i++)
427  {
428  c[i] = operator()(i, j);
429  }
430  return c;
431  }
432 
439  void resize(size_t nRows, size_t nCols)
440  {
441  resize(nRows, nCols, true);
442  }
443 
487  void resize(size_t nRows, size_t nCols, bool keepValues)
488  {
490  if (keepValues)
491  tmpM = *this;
492  resize_(nRows, nCols);
493  if (keepValues)
494  {
495  for (size_t i = 0; i < nRows; i++)
496  {
497  for (size_t j = 0; j < nCols; j++)
498  {
499  if (i < tmpM.getNumberOfRows() && j < tmpM.getNumberOfColumns())
500  {
501  operator()(i, j) = tmpM(i, j);
502  }
503  else
504  {
505  operator()(i, j) = 0;
506  }
507  }
508  }
509  }
510  }
511 
512 private:
516  void resize_(size_t nRows, size_t nCols)
517  {
518  m_.resize(nRows * nCols);
519  rows_ = nRows;
520  cols_ = nCols;
521  }
522 };
523 
524 template<class Scalar>
525 bool operator==(const Matrix<Scalar>& m1, const Matrix<Scalar>& m2)
526 {
527  if (m1.getNumberOfRows() != m2.getNumberOfRows() || m1.getNumberOfColumns() != m2.getNumberOfColumns())
528  return false;
529  for (size_t i = 0; i < m1.getNumberOfRows(); i++)
530  {
531  for (size_t j = 0; j < m1.getNumberOfColumns(); j++)
532  {
533  if (m1(i, j) != m2(i, j))
534  return false;
535  }
536  }
537  return true;
538 }
539 } // end of namespace bpp.
540 
541 #endif // _MATRIX_H_
542 
void resize(size_t nRows, size_t nCols)
Resize the matrix.
Definition: Matrix.h:311
The matrix template interface.
Definition: Matrix.h:58
size_t getNumberOfRows() const
Definition: Matrix.h:409
size_t cols_
Definition: Matrix.h:351
Scalar & operator()(size_t i, size_t j)
Definition: Matrix.h:286
RowMatrix & operator=(const Matrix< Scalar > &m)
Definition: Matrix.h:160
void resize(size_t nRows, size_t nCols, bool keepValues)
Resize the matrix.
Definition: Matrix.h:487
LinearMatrix & operator=(const Matrix< Scalar > &m)
Definition: Matrix.h:381
This class allows to perform a correspondence analysis.
virtual void resize(size_t nRows, size_t nCols)=0
Resize the matrix.
const Scalar & operator()(size_t i, size_t j) const
Definition: Matrix.h:284
size_t getNumberOfRows() const
Definition: Matrix.h:290
ColMatrix * clone() const
Create a copy of this object and send a pointer to it.
Definition: Matrix.h:282
Scalar & operator()(size_t i, size_t j)
Definition: Matrix.h:183
void resize_(size_t nRows, size_t nCols)
Internal basic resize fonctionnalities.
Definition: Matrix.h:516
LinearMatrix(size_t nRow, size_t nCol)
build a nRow x nCol matrix.
Definition: Matrix.h:364
const Scalar & operator()(size_t i, size_t j) const
Definition: Matrix.h:405
std::vector< Scalar > col(size_t j) const
Definition: Matrix.h:423
size_t getNumberOfColumns() const
Definition: Matrix.h:288
Matrix()
Definition: Matrix.h:62
Matrix storage in one vector.
Definition: Matrix.h:345
std::vector< std::vector< Scalar > > m_
Definition: Matrix.h:236
RowMatrix(const Matrix< Scalar > &m)
Definition: Matrix.h:146
std::vector< Scalar > col(size_t j) const
Definition: Matrix.h:304
Matrix storage by row.
Definition: Matrix.h:129
void resize(size_t nRows, size_t nCols)
Resize the matrix.
Definition: Matrix.h:439
virtual const Scalar & operator()(size_t i, size_t j) const =0
ColMatrix & operator=(const Matrix< Scalar > &m)
Definition: Matrix.h:263
Matrix storage by column.
Definition: Matrix.h:232
RowMatrix * clone() const
Create a copy of this object and send a pointer to it.
Definition: Matrix.h:179
ColMatrix(size_t nRow, size_t nCol)
Definition: Matrix.h:241
size_t getNumberOfColumns() const
Definition: Matrix.h:411
static double TINY()
Definition: NumConstants.h:81
virtual size_t getNumberOfColumns() const =0
virtual std::vector< Scalar > col(size_t j) const =0
void addCol(const std::vector< Scalar > &newCol)
Definition: Matrix.h:320
virtual ~ColMatrix()
Definition: Matrix.h:279
void resize(size_t nRows, size_t nCols)
Resize the matrix.
Definition: Matrix.h:208
bool operator==(const Matrix< Scalar > &m1, const Matrix< Scalar > &m2)
Definition: Matrix.h:525
LinearMatrix()
Build a 0 x 0 matrix.
Definition: Matrix.h:357
virtual ~RowMatrix()
Definition: Matrix.h:176
const std::vector< Scalar > & getCol(size_t i) const
Definition: Matrix.h:299
The Clonable interface (allow an object to be cloned).
Definition: Clonable.h:99
size_t getNumberOfRows() const
Definition: Matrix.h:185
LinearMatrix * clone() const
Create a copy of this object and send a pointer to it.
Definition: Matrix.h:403
std::vector< Scalar > row(size_t i) const
Definition: Matrix.h:413
virtual std::vector< Scalar > row(size_t i) const =0
std::vector< Scalar > col(size_t j) const
Definition: Matrix.h:201
const std::vector< Scalar > & getRow(size_t i) const
Definition: Matrix.h:196
void addRow(const std::vector< Scalar > &newRow)
Definition: Matrix.h:217
std::vector< Scalar > row(size_t i) const
Definition: Matrix.h:189
virtual ~Matrix()
Definition: Matrix.h:63
ColMatrix(const Matrix< Scalar > &m)
Definition: Matrix.h:249
RowMatrix(size_t nRow, size_t nCol)
Definition: Matrix.h:138
virtual size_t getNumberOfRows() const =0
Scalar & operator()(size_t i, size_t j)
Definition: Matrix.h:407
std::vector< std::vector< Scalar > > m_
Definition: Matrix.h:133
virtual bool equals(const Matrix &m, double threshold=NumConstants::TINY())
Definition: Matrix.h:81
const Scalar & operator()(size_t i, size_t j) const
Definition: Matrix.h:181
LinearMatrix(const Matrix< Scalar > &m)
Definition: Matrix.h:368
virtual ~LinearMatrix()
Destructor.
Definition: Matrix.h:400
size_t getNumberOfColumns() const
Definition: Matrix.h:187
std::vector< Scalar > row(size_t i) const
Definition: Matrix.h:292
Exception thrown when a dimension problem occured.
size_t rows_
Definition: Matrix.h:350
std::vector< Scalar > m_
Definition: Matrix.h:349