bpp-core3  3.0.0
Matrix.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
5 #ifndef BPP_NUMERIC_MATRIX_MATRIX_H
6 #define BPP_NUMERIC_MATRIX_MATRIX_H
7 
8 #include <iostream>
9 #include <vector>
10 
11 #include "../../Clonable.h"
12 #include "../NumConstants.h"
13 #include "../NumTools.h"
14 #include "../VectorExceptions.h"
15 
16 namespace bpp
17 {
21 template<class Scalar>
22 class Matrix :
23  public Clonable
24 {
25 public:
26  Matrix() {}
27  virtual ~Matrix() {}
28 
29 public:
35  virtual const Scalar& operator()(size_t i, size_t j) const = 0;
36 
42  virtual Scalar& operator()(size_t i, size_t j) = 0;
43 
44  virtual bool equals(const Matrix& m, double threshold = NumConstants::TINY())
45  {
47  return false;
48  for (size_t i = 0; i < getNumberOfRows(); i++)
49  {
50  for (size_t j = 0; j < getNumberOfColumns(); j++)
51  {
52  if (NumTools::abs<double>(static_cast<double>(operator()(i, j)) - static_cast<double>(m(i, j))) > threshold) return false;
53  }
54  }
55  return true;
56  }
60  virtual size_t getNumberOfRows() const = 0;
64  virtual size_t getNumberOfColumns() const = 0;
69  virtual std::vector<Scalar> row(size_t i) const = 0;
74  virtual std::vector<Scalar> col(size_t j) const = 0;
81  virtual void resize(size_t nRows, size_t nCols) = 0;
82 };
83 
84 
91 template<class Scalar>
92 class RowMatrix :
93  public Matrix<Scalar>
94 {
95 protected:
96  std::vector< std::vector<Scalar>> m_;
97 
98 public:
99  RowMatrix() : m_() {}
100 
101  RowMatrix(size_t nRow, size_t nCol) : m_(nRow)
102  {
103  for (size_t i = 0; i < nRow; i++)
104  {
105  m_[i].resize(nCol);
106  }
107  }
108 
110  {
111  size_t nr = m.getNumberOfRows();
112  size_t nc = m.getNumberOfColumns();
113  for (size_t i = 0; i < nr; i++)
114  {
115  m_[i].resize(nc);
116  for (size_t j = 0; j < nc; j++)
117  {
118  m_[i][j] = m(i, j);
119  }
120  }
121  }
122 
124  {
125  size_t nr = m.getNumberOfRows();
126  m_.resize(nr);
127  size_t nc = m.getNumberOfColumns();
128  for (size_t i = 0; i < nr; i++)
129  {
130  m_[i].resize(nc);
131  for (size_t j = 0; j < nc; j++)
132  {
133  m_[i][j] = m(i, j);
134  }
135  }
136  return *this;
137  }
138 
139 // virtual ~RowMatrix() {}
140 
141 public:
142  RowMatrix* clone() const { return new RowMatrix(*this); }
143 
144  const Scalar& operator()(size_t i, size_t j) const { return m_[i][j]; }
145 
146  Scalar& operator()(size_t i, size_t j) { return m_[i][j]; }
147 
148  size_t getNumberOfRows() const { return m_.size(); }
149 
150  size_t getNumberOfColumns() const { return m_.size() == 0 ? 0 : m_[0].size(); }
151 
152  std::vector<Scalar> row(size_t i) const
153  {
154  std::vector<Scalar> r(getNumberOfColumns());
155  for (size_t j = 0; j < getNumberOfColumns(); j++) { r[j] = operator()(i, j); }
156  return r;
157  }
158 
159  const std::vector<Scalar>& getRow(size_t i) const
160  {
161  return m_[i];
162  }
163 
164  std::vector<Scalar>& getRow(size_t i)
165  {
166  return m_[i];
167  }
168 
169  std::vector<Scalar> col(size_t j) const
170  {
171  std::vector<Scalar> c(getNumberOfRows());
172  for (size_t i = 0; i < getNumberOfRows(); i++) { c[i] = operator()(i, j); }
173  return c;
174  }
175 
176  void resize(size_t nRows, size_t nCols)
177  {
178  m_.resize(nRows);
179  for (size_t i = 0; i < nRows; i++)
180  {
181  m_[i].resize(nCols);
182  }
183  }
184 
185  void addRow(const std::vector<Scalar>& newRow)
186  {
187  if (getNumberOfColumns() != 0 && newRow.size() != getNumberOfColumns())
188  throw DimensionException("RowMatrix::addRow: invalid row dimension", newRow.size(), getNumberOfColumns());
189  m_.push_back(newRow);
190  }
191 };
192 
199 template<class Scalar>
200 class ColMatrix :
201  public Matrix<Scalar>
202 {
203 private:
204  std::vector< std::vector<Scalar>> m_;
205 
206 public:
207  ColMatrix() : m_() {}
208 
209  ColMatrix(size_t nRow, size_t nCol) : m_(nCol)
210  {
211  for (size_t i = 0; i < nCol; i++)
212  {
213  m_[i].resize(nRow);
214  }
215  }
216 
218  {
219  size_t nr = m.getNumberOfRows();
220  size_t nc = m.getNumberOfColumns();
221  for (size_t i = 0; i < nc; i++)
222  {
223  m_[i].resize(nr);
224  for (size_t j = 0; j < nr; j++)
225  {
226  m_[i][j] = m(j, i);
227  }
228  }
229  }
230 
232  {
233  size_t nc = m.getNumberOfColumns();
234  m_.resize(nc);
235  size_t nr = m.getNumberOfRows();
236  for (size_t i = 0; i < nc; i++)
237  {
238  m_[i].resize(nr);
239  for (size_t j = 0; j < nr; j++)
240  {
241  m_[i][j] = m(j, i);
242  }
243  }
244  return *this;
245  }
246 
247  virtual ~ColMatrix() {}
248 
249 public:
250  ColMatrix* clone() const { return new ColMatrix(*this); }
251 
252  const Scalar& operator()(size_t i, size_t j) const { return m_[j][i]; }
253 
254  Scalar& operator()(size_t i, size_t j) { return m_[j][i]; }
255 
256  size_t getNumberOfColumns() const { return m_.size(); }
257 
258  size_t getNumberOfRows() const { return m_.size() == 0 ? 0 : m_[0].size(); }
259 
260  std::vector<Scalar> row(size_t i) const
261  {
262  std::vector<Scalar> r(getNumberOfColumns());
263  for (size_t j = 0; j < getNumberOfColumns(); j++) { r[j] = operator()(i, j); }
264  return r;
265  }
266 
267  const std::vector<Scalar>& getCol(size_t i) const
268  {
269  return m_[i];
270  }
271 
272  std::vector<Scalar>& getCol(size_t i)
273  {
274  return m_[i];
275  }
276 
277  std::vector<Scalar> col(size_t j) const
278  {
279  std::vector<Scalar> c(getNumberOfRows());
280  for (size_t i = 0; i < getNumberOfRows(); i++) { c[i] = operator()(i, j); }
281  return c;
282  }
283 
284  void resize(size_t nRows, size_t nCols)
285  {
286  m_.resize(nCols);
287  for (size_t i = 0; i < nCols; i++)
288  {
289  m_[i].resize(nRows);
290  }
291  }
292 
293  void addCol(const std::vector<Scalar>& newCol)
294  {
295  if (getNumberOfRows() != 0 && newCol.size() != getNumberOfRows())
296  throw DimensionException("ColMatrix::addCol: invalid column dimension", newCol.size(), getNumberOfRows());
297  m_.push_back(newCol);
298  }
299 };
300 
317 template<class Scalar>
319  public Matrix<Scalar>
320 {
321 private:
322  std::vector<Scalar> m_;
323  size_t rows_;
324  size_t cols_;
325 
326 public:
330  LinearMatrix() : m_(),
331  rows_(0),
332  cols_(0) { resize_(0, 0); }
333 
337  LinearMatrix(size_t nRow, size_t nCol) : m_(),
338  rows_(nRow),
339  cols_(nCol) { resize_(nRow, nCol); }
340 
342  {
343  for (size_t i = 0; i < rows_; i++)
344  {
345  for (size_t j = 0; j < cols_; j++)
346  {
347  m_[i * cols_ + j] = m(i, j);
348  }
349  }
350  }
351 
353  {
354  rows_ = m.getNumberOfRows();
355  cols_ = m.getNumberOfColumns();
356  m_.resize(rows_ * cols_);
357  for (size_t i = 0; i < rows_; i++)
358  {
359  for (size_t j = 0; j < cols_; j++)
360  {
361  m_[i * cols_ + j] = m(i, j);
362  }
363  }
364 
365  return *this;
366  }
367 
371  virtual ~LinearMatrix() {}
372 
373 public:
374  LinearMatrix* clone() const { return new LinearMatrix(*this); }
375 
376  const Scalar& operator()(size_t i, size_t j) const { return m_[i * cols_ + j]; }
377 
378  Scalar& operator()(size_t i, size_t j) { return m_[i * cols_ + j]; }
379 
380  size_t getNumberOfRows() const { return rows_; }
381 
382  size_t getNumberOfColumns() const { return cols_; }
383 
384  std::vector<Scalar> row(size_t i) const
385  {
386  std::vector<Scalar> r(getNumberOfColumns());
387  for (size_t j = 0; j < getNumberOfColumns(); j++)
388  {
389  r[j] = operator()(i, j);
390  }
391  return r;
392  }
393 
394  std::vector<Scalar> col(size_t j) const
395  {
396  std::vector<Scalar> c(getNumberOfRows());
397  for (size_t i = 0; i < getNumberOfRows(); i++)
398  {
399  c[i] = operator()(i, j);
400  }
401  return c;
402  }
403 
410  void resize(size_t nRows, size_t nCols)
411  {
412  resize(nRows, nCols, true);
413  }
414 
458  void resize(size_t nRows, size_t nCols, bool keepValues)
459  {
461  if (keepValues)
462  tmpM = *this;
463  resize_(nRows, nCols);
464  if (keepValues)
465  {
466  for (size_t i = 0; i < nRows; i++)
467  {
468  for (size_t j = 0; j < nCols; j++)
469  {
470  if (i < tmpM.getNumberOfRows() && j < tmpM.getNumberOfColumns())
471  {
472  operator()(i, j) = tmpM(i, j);
473  }
474  else
475  {
476  operator()(i, j) = 0;
477  }
478  }
479  }
480  }
481  }
482 
483 private:
487  void resize_(size_t nRows, size_t nCols)
488  {
489  m_.resize(nRows * nCols);
490  rows_ = nRows;
491  cols_ = nCols;
492  }
493 };
494 
495 template<class Scalar>
496 bool operator==(const Matrix<Scalar>& m1, const Matrix<Scalar>& m2)
497 {
498  if (m1.getNumberOfRows() != m2.getNumberOfRows() || m1.getNumberOfColumns() != m2.getNumberOfColumns())
499  return false;
500  for (size_t i = 0; i < m1.getNumberOfRows(); i++)
501  {
502  for (size_t j = 0; j < m1.getNumberOfColumns(); j++)
503  {
504  if (m1(i, j) != m2(i, j))
505  return false;
506  }
507  }
508  return true;
509 }
510 } // end of namespace bpp.
511 #endif // BPP_NUMERIC_MATRIX_MATRIX_H
void resize(size_t nRows, size_t nCols)
Resize the matrix.
Definition: Matrix.h:284
The matrix template interface.
Definition: Matrix.h:22
size_t getNumberOfRows() const
Definition: Matrix.h:380
size_t cols_
Definition: Matrix.h:324
Scalar & operator()(size_t i, size_t j)
Definition: Matrix.h:254
RowMatrix & operator=(const Matrix< Scalar > &m)
Definition: Matrix.h:123
void resize(size_t nRows, size_t nCols, bool keepValues)
Resize the matrix.
Definition: Matrix.h:458
LinearMatrix & operator=(const Matrix< Scalar > &m)
Definition: Matrix.h:352
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:252
size_t getNumberOfRows() const
Definition: Matrix.h:258
std::vector< Scalar > & getRow(size_t i)
Definition: Matrix.h:164
ColMatrix * clone() const
Create a copy of this object and send a pointer to it.
Definition: Matrix.h:250
Scalar & operator()(size_t i, size_t j)
Definition: Matrix.h:146
void resize_(size_t nRows, size_t nCols)
Internal basic resize fonctionnalities.
Definition: Matrix.h:487
LinearMatrix(size_t nRow, size_t nCol)
build a nRow x nCol matrix.
Definition: Matrix.h:337
const Scalar & operator()(size_t i, size_t j) const
Definition: Matrix.h:376
std::vector< Scalar > col(size_t j) const
Definition: Matrix.h:394
size_t getNumberOfColumns() const
Definition: Matrix.h:256
Matrix()
Definition: Matrix.h:26
Matrix storage in one vector.
Definition: Matrix.h:318
std::vector< std::vector< Scalar > > m_
Definition: Matrix.h:204
RowMatrix(const Matrix< Scalar > &m)
Definition: Matrix.h:109
std::vector< Scalar > col(size_t j) const
Definition: Matrix.h:277
Matrix storage by row.
Definition: Matrix.h:92
void resize(size_t nRows, size_t nCols)
Resize the matrix.
Definition: Matrix.h:410
virtual const Scalar & operator()(size_t i, size_t j) const =0
ColMatrix & operator=(const Matrix< Scalar > &m)
Definition: Matrix.h:231
Matrix storage by column.
Definition: Matrix.h:200
RowMatrix * clone() const
Create a copy of this object and send a pointer to it.
Definition: Matrix.h:142
ColMatrix(size_t nRow, size_t nCol)
Definition: Matrix.h:209
size_t getNumberOfColumns() const
Definition: Matrix.h:382
static double TINY()
Definition: NumConstants.h:46
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:293
virtual ~ColMatrix()
Definition: Matrix.h:247
void resize(size_t nRows, size_t nCols)
Resize the matrix.
Definition: Matrix.h:176
bool operator==(const Matrix< Scalar > &m1, const Matrix< Scalar > &m2)
Definition: Matrix.h:496
LinearMatrix()
Build a 0 x 0 matrix.
Definition: Matrix.h:330
const std::vector< Scalar > & getCol(size_t i) const
Definition: Matrix.h:267
The Clonable interface (allow an object to be cloned).
Definition: Clonable.h:63
size_t getNumberOfRows() const
Definition: Matrix.h:148
LinearMatrix * clone() const
Create a copy of this object and send a pointer to it.
Definition: Matrix.h:374
std::vector< Scalar > row(size_t i) const
Definition: Matrix.h:384
virtual std::vector< Scalar > row(size_t i) const =0
std::vector< Scalar > col(size_t j) const
Definition: Matrix.h:169
const std::vector< Scalar > & getRow(size_t i) const
Definition: Matrix.h:159
void addRow(const std::vector< Scalar > &newRow)
Definition: Matrix.h:185
std::vector< Scalar > row(size_t i) const
Definition: Matrix.h:152
virtual ~Matrix()
Definition: Matrix.h:27
ColMatrix(const Matrix< Scalar > &m)
Definition: Matrix.h:217
std::vector< Scalar > & getCol(size_t i)
Definition: Matrix.h:272
RowMatrix(size_t nRow, size_t nCol)
Definition: Matrix.h:101
virtual size_t getNumberOfRows() const =0
Scalar & operator()(size_t i, size_t j)
Definition: Matrix.h:378
std::vector< std::vector< Scalar > > m_
Definition: Matrix.h:96
virtual bool equals(const Matrix &m, double threshold=NumConstants::TINY())
Definition: Matrix.h:44
const Scalar & operator()(size_t i, size_t j) const
Definition: Matrix.h:144
LinearMatrix(const Matrix< Scalar > &m)
Definition: Matrix.h:341
virtual ~LinearMatrix()
Destructor.
Definition: Matrix.h:371
size_t getNumberOfColumns() const
Definition: Matrix.h:150
std::vector< Scalar > row(size_t i) const
Definition: Matrix.h:260
Exception thrown when a dimension problem occured.
size_t rows_
Definition: Matrix.h:323
std::vector< Scalar > m_
Definition: Matrix.h:322