bpp-core3  3.0.0
Matrix.h
Go to the documentation of this file.
1 //
2 // File: Matrix.h
3 // Authors:
4 // Julien Dutheil
5 // Sylvain Gaillard
6 // Created: 2004-04-07 11:58:00
7 //
8 
9 /*
10  Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
11 
12  This software is a computer program whose purpose is to provide classes
13  for numerical calculus.
14 
15  This software is governed by the CeCILL license under French law and
16  abiding by the rules of distribution of free software. You can use,
17  modify and/ or redistribute the software under the terms of the CeCILL
18  license as circulated by CEA, CNRS and INRIA at the following URL
19  "http://www.cecill.info".
20 
21  As a counterpart to the access to the source code and rights to copy,
22  modify and redistribute granted by the license, users are provided only
23  with a limited warranty and the software's author, the holder of the
24  economic rights, and the successive licensors have only limited
25  liability.
26 
27  In this respect, the user's attention is drawn to the risks associated
28  with loading, using, modifying and/or developing or reproducing the
29  software by the user in light of its specific status of free software,
30  that may mean that it is complicated to manipulate, and that also
31  therefore means that it is reserved for developers and experienced
32  professionals having in-depth computer knowledge. Users are therefore
33  encouraged to load and test the software's suitability as regards their
34  requirements in conditions enabling the security of their systems and/or
35  data to be ensured and, more generally, to use and operate it in the
36  same conditions as regards security.
37 
38  The fact that you are presently reading this means that you have had
39  knowledge of the CeCILL license and that you accept its terms.
40 */
41 
42 #ifndef BPP_NUMERIC_MATRIX_MATRIX_H
43 #define BPP_NUMERIC_MATRIX_MATRIX_H
44 
45 #include <iostream>
46 #include <vector>
47 
48 #include "../../Clonable.h"
49 #include "../NumConstants.h"
50 #include "../NumTools.h"
51 #include "../VectorExceptions.h"
52 
53 namespace bpp
54 {
58 template<class Scalar>
59 class Matrix :
60  public Clonable
61 {
62 public:
63  Matrix() {}
64  virtual ~Matrix() {}
65 
66 public:
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 protected:
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>& getRow(size_t i)
202  {
203  return m_[i];
204  }
205 
206  std::vector<Scalar> col(size_t j) const
207  {
208  std::vector<Scalar> c(getNumberOfRows());
209  for (size_t i = 0; i < getNumberOfRows(); i++) { c[i] = operator()(i, j); }
210  return c;
211  }
212 
213  void resize(size_t nRows, size_t nCols)
214  {
215  m_.resize(nRows);
216  for (size_t i = 0; i < nRows; i++)
217  {
218  m_[i].resize(nCols);
219  }
220  }
221 
222  void addRow(const std::vector<Scalar>& newRow)
223  {
224  if (getNumberOfColumns() != 0 && newRow.size() != getNumberOfColumns())
225  throw DimensionException("RowMatrix::addRow: invalid row dimension", newRow.size(), getNumberOfColumns());
226  m_.push_back(newRow);
227  }
228 };
229 
236 template<class Scalar>
237 class ColMatrix :
238  public Matrix<Scalar>
239 {
240 private:
241  std::vector< std::vector<Scalar> > m_;
242 
243 public:
244  ColMatrix() : m_() {}
245 
246  ColMatrix(size_t nRow, size_t nCol) : m_(nCol)
247  {
248  for (size_t i = 0; i < nCol; i++)
249  {
250  m_[i].resize(nRow);
251  }
252  }
253 
255  {
256  size_t nr = m.getNumberOfRows();
257  size_t nc = m.getNumberOfColumns();
258  for (size_t i = 0; i < nc; i++)
259  {
260  m_[i].resize(nr);
261  for (size_t j = 0; j < nr; j++)
262  {
263  m_[i][j] = m(j, i);
264  }
265  }
266  }
267 
269  {
270  size_t nc = m.getNumberOfColumns();
271  m_.resize(nc);
272  size_t nr = m.getNumberOfRows();
273  for (size_t i = 0; i < nc; i++)
274  {
275  m_[i].resize(nr);
276  for (size_t j = 0; j < nr; j++)
277  {
278  m_[i][j] = m(j, i);
279  }
280  }
281  return *this;
282  }
283 
284  virtual ~ColMatrix() {}
285 
286 public:
287  ColMatrix* clone() const { return new ColMatrix(*this); }
288 
289  const Scalar& operator()(size_t i, size_t j) const { return m_[j][i]; }
290 
291  Scalar& operator()(size_t i, size_t j) { return m_[j][i]; }
292 
293  size_t getNumberOfColumns() const { return m_.size(); }
294 
295  size_t getNumberOfRows() const { return m_.size() == 0 ? 0 : m_[0].size(); }
296 
297  std::vector<Scalar> row(size_t i) const
298  {
299  std::vector<Scalar> r(getNumberOfColumns());
300  for (size_t j = 0; j < getNumberOfColumns(); j++) { r[j] = operator()(i, j); }
301  return r;
302  }
303 
304  const std::vector<Scalar>& getCol(size_t i) const
305  {
306  return m_[i];
307  }
308 
309  std::vector<Scalar>& getCol(size_t i)
310  {
311  return m_[i];
312  }
313 
314  std::vector<Scalar> col(size_t j) const
315  {
316  std::vector<Scalar> c(getNumberOfRows());
317  for (size_t i = 0; i < getNumberOfRows(); i++) { c[i] = operator()(i, j); }
318  return c;
319  }
320 
321  void resize(size_t nRows, size_t nCols)
322  {
323  m_.resize(nCols);
324  for (size_t i = 0; i < nCols; i++)
325  {
326  m_[i].resize(nRows);
327  }
328  }
329 
330  void addCol(const std::vector<Scalar>& newCol)
331  {
332  if (getNumberOfRows() != 0 && newCol.size() != getNumberOfRows())
333  throw DimensionException("ColMatrix::addCol: invalid column dimension", newCol.size(), getNumberOfRows());
334  m_.push_back(newCol);
335  }
336 };
337 
354 template<class Scalar>
356  public Matrix<Scalar>
357 {
358 private:
359  std::vector<Scalar> m_;
360  size_t rows_;
361  size_t cols_;
362 
363 public:
368  rows_(0),
369  cols_(0) { resize_(0, 0); }
370 
374  LinearMatrix(size_t nRow, size_t nCol) : m_(),
375  rows_(nRow),
376  cols_(nCol) { resize_(nRow, nCol); }
377 
379  {
380  for (size_t i = 0; i < rows_; i++)
381  {
382  for (size_t j = 0; j < cols_; j++)
383  {
384  m_[i * cols_ + j] = m(i, j);
385  }
386  }
387  }
388 
390  {
391  rows_ = m.getNumberOfRows();
393  m_.resize(rows_ * cols_);
394  for (size_t i = 0; i < rows_; i++)
395  {
396  for (size_t j = 0; j < cols_; j++)
397  {
398  m_[i * cols_ + j] = m(i, j);
399  }
400  }
401 
402  return *this;
403  }
404 
408  virtual ~LinearMatrix() {}
409 
410 public:
411  LinearMatrix* clone() const { return new LinearMatrix(*this); }
412 
413  const Scalar& operator()(size_t i, size_t j) const { return m_[i * cols_ + j]; }
414 
415  Scalar& operator()(size_t i, size_t j) { return m_[i * cols_ + j]; }
416 
417  size_t getNumberOfRows() const { return rows_; }
418 
419  size_t getNumberOfColumns() const { return cols_; }
420 
421  std::vector<Scalar> row(size_t i) const
422  {
423  std::vector<Scalar> r(getNumberOfColumns());
424  for (size_t j = 0; j < getNumberOfColumns(); j++)
425  {
426  r[j] = operator()(i, j);
427  }
428  return r;
429  }
430 
431  std::vector<Scalar> col(size_t j) const
432  {
433  std::vector<Scalar> c(getNumberOfRows());
434  for (size_t i = 0; i < getNumberOfRows(); i++)
435  {
436  c[i] = operator()(i, j);
437  }
438  return c;
439  }
440 
447  void resize(size_t nRows, size_t nCols)
448  {
449  resize(nRows, nCols, true);
450  }
451 
495  void resize(size_t nRows, size_t nCols, bool keepValues)
496  {
498  if (keepValues)
499  tmpM = *this;
500  resize_(nRows, nCols);
501  if (keepValues)
502  {
503  for (size_t i = 0; i < nRows; i++)
504  {
505  for (size_t j = 0; j < nCols; j++)
506  {
507  if (i < tmpM.getNumberOfRows() && j < tmpM.getNumberOfColumns())
508  {
509  operator()(i, j) = tmpM(i, j);
510  }
511  else
512  {
513  operator()(i, j) = 0;
514  }
515  }
516  }
517  }
518  }
519 
520 private:
524  void resize_(size_t nRows, size_t nCols)
525  {
526  m_.resize(nRows * nCols);
527  rows_ = nRows;
528  cols_ = nCols;
529  }
530 };
531 
532 template<class Scalar>
533 bool operator==(const Matrix<Scalar>& m1, const Matrix<Scalar>& m2)
534 {
535  if (m1.getNumberOfRows() != m2.getNumberOfRows() || m1.getNumberOfColumns() != m2.getNumberOfColumns())
536  return false;
537  for (size_t i = 0; i < m1.getNumberOfRows(); i++)
538  {
539  for (size_t j = 0; j < m1.getNumberOfColumns(); j++)
540  {
541  if (m1(i, j) != m2(i, j))
542  return false;
543  }
544  }
545  return true;
546 }
547 } // end of namespace bpp.
548 #endif // BPP_NUMERIC_MATRIX_MATRIX_H
The Clonable interface (allow an object to be cloned).
Definition: Clonable.h:103
Matrix storage by column.
Definition: Matrix.h:239
std::vector< Scalar > col(size_t j) const
Definition: Matrix.h:314
const std::vector< Scalar > & getCol(size_t i) const
Definition: Matrix.h:304
virtual ~ColMatrix()
Definition: Matrix.h:284
std::vector< Scalar > & getCol(size_t i)
Definition: Matrix.h:309
std::vector< Scalar > row(size_t i) const
Definition: Matrix.h:297
size_t getNumberOfColumns() const
Definition: Matrix.h:293
Scalar & operator()(size_t i, size_t j)
Definition: Matrix.h:291
void resize(size_t nRows, size_t nCols)
Resize the matrix.
Definition: Matrix.h:321
const Scalar & operator()(size_t i, size_t j) const
Definition: Matrix.h:289
ColMatrix * clone() const
Create a copy of this object and send a pointer to it.
Definition: Matrix.h:287
ColMatrix(const Matrix< Scalar > &m)
Definition: Matrix.h:254
ColMatrix & operator=(const Matrix< Scalar > &m)
Definition: Matrix.h:268
void addCol(const std::vector< Scalar > &newCol)
Definition: Matrix.h:330
ColMatrix(size_t nRow, size_t nCol)
Definition: Matrix.h:246
std::vector< std::vector< Scalar > > m_
Definition: Matrix.h:241
size_t getNumberOfRows() const
Definition: Matrix.h:295
Exception thrown when a dimension problem occured.
Matrix storage in one vector.
Definition: Matrix.h:357
void resize(size_t nRows, size_t nCols)
Resize the matrix.
Definition: Matrix.h:447
const Scalar & operator()(size_t i, size_t j) const
Definition: Matrix.h:413
LinearMatrix & operator=(const Matrix< Scalar > &m)
Definition: Matrix.h:389
Scalar & operator()(size_t i, size_t j)
Definition: Matrix.h:415
size_t rows_
Definition: Matrix.h:360
std::vector< Scalar > m_
Definition: Matrix.h:359
LinearMatrix(size_t nRow, size_t nCol)
build a nRow x nCol matrix.
Definition: Matrix.h:374
void resize_(size_t nRows, size_t nCols)
Internal basic resize fonctionnalities.
Definition: Matrix.h:524
virtual ~LinearMatrix()
Destructor.
Definition: Matrix.h:408
size_t getNumberOfRows() const
Definition: Matrix.h:417
LinearMatrix()
Build a 0 x 0 matrix.
Definition: Matrix.h:367
std::vector< Scalar > col(size_t j) const
Definition: Matrix.h:431
LinearMatrix(const Matrix< Scalar > &m)
Definition: Matrix.h:378
size_t getNumberOfColumns() const
Definition: Matrix.h:419
std::vector< Scalar > row(size_t i) const
Definition: Matrix.h:421
size_t cols_
Definition: Matrix.h:361
LinearMatrix * clone() const
Create a copy of this object and send a pointer to it.
Definition: Matrix.h:411
void resize(size_t nRows, size_t nCols, bool keepValues)
Resize the matrix.
Definition: Matrix.h:495
The matrix template interface.
Definition: Matrix.h:61
virtual std::vector< Scalar > row(size_t i) const =0
virtual std::vector< Scalar > col(size_t j) const =0
Matrix()
Definition: Matrix.h:63
virtual bool equals(const Matrix &m, double threshold=NumConstants::TINY())
Definition: Matrix.h:81
virtual size_t getNumberOfColumns() const =0
virtual void resize(size_t nRows, size_t nCols)=0
Resize the matrix.
virtual size_t getNumberOfRows() const =0
virtual Scalar & operator()(size_t i, size_t j)=0
virtual const Scalar & operator()(size_t i, size_t j) const =0
virtual ~Matrix()
Definition: Matrix.h:64
static double TINY()
Definition: NumConstants.h:82
Matrix storage by row.
Definition: Matrix.h:131
const Scalar & operator()(size_t i, size_t j) const
Definition: Matrix.h:181
size_t getNumberOfRows() const
Definition: Matrix.h:185
std::vector< Scalar > col(size_t j) const
Definition: Matrix.h:206
void addRow(const std::vector< Scalar > &newRow)
Definition: Matrix.h:222
RowMatrix & operator=(const Matrix< Scalar > &m)
Definition: Matrix.h:160
RowMatrix * clone() const
Create a copy of this object and send a pointer to it.
Definition: Matrix.h:179
size_t getNumberOfColumns() const
Definition: Matrix.h:187
const std::vector< Scalar > & getRow(size_t i) const
Definition: Matrix.h:196
std::vector< Scalar > & getRow(size_t i)
Definition: Matrix.h:201
std::vector< Scalar > row(size_t i) const
Definition: Matrix.h:189
Scalar & operator()(size_t i, size_t j)
Definition: Matrix.h:183
RowMatrix(const Matrix< Scalar > &m)
Definition: Matrix.h:146
RowMatrix(size_t nRow, size_t nCol)
Definition: Matrix.h:138
void resize(size_t nRows, size_t nCols)
Resize the matrix.
Definition: Matrix.h:213
std::vector< std::vector< Scalar > > m_
Definition: Matrix.h:133
bool operator==(const Matrix< Scalar > &m1, const Matrix< Scalar > &m2)
Definition: Matrix.h:533