bpp-core3  3.0.0
MatrixTools.h
Go to the documentation of this file.
1 //
2 // File: MatrixTools.h
3 // Authors:
4 // Julien Dutheil
5 // Created: 2004-01-19 16:42:25
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. This file is part of the Bio++ project.
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 #ifndef BPP_NUMERIC_MATRIX_MATRIXTOOLS_H
42 #define BPP_NUMERIC_MATRIX_MATRIXTOOLS_H
43 
44 #include <cstdio>
45 #include <iostream>
46 
47 #include "../../Io/OutputStream.h"
48 #include "../VectorTools.h"
49 #include "EigenValue.h"
50 #include "LUDecomposition.h"
51 #include "Matrix.h"
52 
53 namespace bpp
54 {
59 {
60 public:
63 
64 public:
71  template<class MatrixA, class MatrixO>
72  static void copy(const MatrixA& A, MatrixO& O)
73  {
74  O.resize(A.getNumberOfRows(), A.getNumberOfColumns());
75  for (size_t i = 0; i < A.getNumberOfRows(); i++)
76  {
77  for (size_t j = 0; j < A.getNumberOfColumns(); j++)
78  {
79  O(i, j) = A(i, j);
80  }
81  }
82  }
83 
91  template<class MatrixA, class MatrixO>
92  static void copyUp(const MatrixA& A, MatrixO& O)
93  {
94  size_t nr(A.getNumberOfRows()), nc(A.getNumberOfColumns());
95  O.resize(nr, nc);
96  for (size_t i = 0; i < nr - 1; i++)
97  {
98  for (size_t j = 0; j < nc; j++)
99  {
100  O(i, j) = A(i + 1, j);
101  }
102  }
103  for (size_t j = 0; j < nc; j++)
104  {
105  O(nr - 1, j) = 0;
106  }
107  }
108 
116  template<class MatrixA, class MatrixO>
117  static void copyDown(const MatrixA& A, MatrixO& O)
118  {
119  size_t nr(A.getNumberOfRows()), nc(A.getNumberOfColumns());
120  O.resize(nr, nc);
121  for (size_t i = 1; i < nr; i++)
122  {
123  for (size_t j = 0; j < nc; j++)
124  {
125  O(i, j) = A(i - 1, j);
126  }
127  }
128  for (size_t j = 0; j < nc; j++)
129  {
130  O(0, j) = 0;
131  }
132  }
133 
140  template<class Matrix>
141  static void getId(size_t n, Matrix& O)
142  {
143  O.resize(n, n);
144  for (size_t i = 0; i < n; i++)
145  {
146  for (size_t j = 0; j < n; j++)
147  {
148  O(i, j) = (i == j) ? 1 : 0;
149  }
150  }
151  }
152 
157  template<class Scalar>
158  static void diag(const std::vector<Scalar>& D, Matrix<Scalar>& O)
159  {
160  size_t n = D.size();
161  O.resize(n, n);
162  for (size_t i = 0; i < n; i++)
163  {
164  for (size_t j = 0; j < n; j++) { O(i, j) = (i == j) ? D[i] : 0;}
165  }
166  }
167 
173  template<class Scalar>
174  static void diag(const Scalar x, size_t n, Matrix<Scalar>& O)
175  {
176  O.resize(n, n);
177  for (size_t i = 0; i < n; i++)
178  {
179  for (size_t j = 0; j < n; j++) { O(i, j) = (i == j) ? x : 0;}
180  }
181  }
182 
188  template<class Scalar>
189  static void diag(const Matrix<Scalar>& M, std::vector<Scalar>& O)
190  {
191  size_t nc = M.getNumberOfColumns();
192  size_t nr = M.getNumberOfRows();
193  if (nc != nr) throw DimensionException("MatrixTools::diag(). M must be a square matrix.", nr, nc);
194  O.resize(nc);
195  for (size_t i = 0; i < nc; i++) { O[i] = M(i, i);}
196  }
197 
203  template<class Matrix, class Scalar>
204  static void fill(Matrix& M, Scalar x)
205  {
206  for (size_t i = 0; i < M.getNumberOfRows(); i++)
207  {
208  for (size_t j = 0; j < M.getNumberOfColumns(); j++)
209  {
210  M(i, j) = x;
211  }
212  }
213  }
214 
220  template<class Matrix, class Scalar>
221  static void fillDiag(Matrix& M, Scalar x)
222  {
223  for (size_t i = 0; i < M.getNumberOfRows(); i++)
224  {
225  M(i, i) = x;
226  }
227  }
228 
238  template<class Matrix, class Scalar>
239  static void scale(Matrix& A, Scalar a, Scalar b = 0)
240  {
241  for (size_t i = 0; i < A.getNumberOfRows(); i++)
242  {
243  for (size_t j = 0; j < A.getNumberOfColumns(); j++)
244  {
245  A(i, j) = a * A(i, j) + b;
246  }
247  }
248  }
249 
255  template<class Scalar>
256  static void mult(const Matrix<Scalar>& A, const Matrix<Scalar>& B, Matrix<Scalar>& O)
257  {
258  size_t ncA = A.getNumberOfColumns();
259  size_t nrA = A.getNumberOfRows();
260  size_t nrB = B.getNumberOfRows();
261  size_t ncB = B.getNumberOfColumns();
262  if (ncA != nrB) throw DimensionException("MatrixTools::mult(). nrows B != ncols A.", nrB, ncA);
263  O.resize(nrA, ncB);
264  for (size_t i = 0; i < nrA; i++)
265  {
266  for (size_t j = 0; j < ncB; j++)
267  {
268  O(i, j) = 0;
269  for (size_t k = 0; k < ncA; k++)
270  {
271  O(i, j) += A(i, k) * B(k, j);
272  }
273  }
274  }
275  }
276 
288  template<class Scalar>
289  static void mult(const Matrix<Scalar>& A, const Matrix<Scalar>& iA, const Matrix<Scalar>& B, const Matrix<Scalar>& iB, Matrix<Scalar>& O, Matrix<Scalar>& iO)
290  {
291  size_t ncA = A.getNumberOfColumns();
292  size_t nrA = A.getNumberOfRows();
293  size_t nrB = B.getNumberOfRows();
294  size_t ncB = B.getNumberOfColumns();
295  if (ncA != nrB) throw DimensionException("MatrixTools::mult(). nrows B != ncols A.", nrB, ncA);
296  O.resize(nrA, ncB);
297  iO.resize(nrA, ncB);
298  for (size_t i = 0; i < nrA; i++)
299  {
300  for (size_t j = 0; j < ncB; j++)
301  {
302  O(i, j) = 0;
303  iO(i, j) = 0;
304  for (size_t k = 0; k < ncA; k++)
305  {
306  O(i, j) += A(i, k) * B(k, j) - iA(i, k) * iB(k, j);
307  iO(i, j) += A(i, k) * iB(k, j) + iA(i, k) * B(k, j);
308  }
309  }
310  }
311  }
312 
325  template<class Scalar>
326  static void mult(const Matrix<Scalar>& A, const std::vector<Scalar>& D, const Matrix<Scalar>& B, Matrix<Scalar>& O)
327  {
328  size_t ncA = A.getNumberOfColumns();
329  size_t nrA = A.getNumberOfRows();
330  size_t nrB = B.getNumberOfRows();
331  size_t ncB = B.getNumberOfColumns();
332  if (ncA != nrB) throw DimensionException("MatrixTools::mult(). nrows B != ncols A.", nrB, ncA);
333  if (ncA != D.size()) throw DimensionException("MatrixTools::mult(). Vector size is not equal to matrix size.", D.size(), ncA);
334  O.resize(nrA, ncB);
335  for (size_t i = 0; i < nrA; i++)
336  {
337  for (size_t j = 0; j < ncB; j++)
338  {
339  O(i, j) = 0;
340  for (size_t k = 0; k < ncA; k++)
341  {
342  O(i, j) += A(i, k) * B(k, j) * D[k];
343  }
344  }
345  }
346  }
347 
366  template<class Scalar>
367  static void mult(const Matrix<Scalar>& A, const Matrix<Scalar>& iA, const std::vector<Scalar>& D, const std::vector<Scalar>& iD, const Matrix<Scalar>& B, const Matrix<Scalar>& iB, Matrix<Scalar>& O, Matrix<Scalar>& iO)
368  {
369  size_t ncA = A.getNumberOfColumns();
370  size_t nrA = A.getNumberOfRows();
371  size_t nrB = B.getNumberOfRows();
372  size_t ncB = B.getNumberOfColumns();
373  if (ncA != nrB) throw DimensionException("MatrixTools::mult(). nrows B != ncols A.", nrB, ncA);
374  if (ncA != D.size()) throw DimensionException("MatrixTools::mult(). Vector size is not equal to matrix size.", D.size(), ncA);
375  O.resize(nrA, ncB);
376  Scalar ab, iaib, iab, aib;
377 
378  for (size_t i = 0; i < nrA; i++)
379  {
380  for (size_t j = 0; j < ncB; j++)
381  {
382  O(i, j) = 0;
383  iO(i, j) = 0;
384  for (size_t k = 0; k < ncA; k++)
385  {
386  ab = A(i, k) * B(k, j) - iA(i, k) * iB(k, j);
387  aib = A(i, k) * iB(k, j) + iA(i, k) * B(k, j);
388 
389  O(i, j) += ab * D[k] - aib * iD[k];
390  iO(i, j) += ab * iD[k] + aib * D[k];
391  }
392  }
393  }
394  }
395 
412  template<class Scalar>
413  static void mult(const Matrix<Scalar>& A, const std::vector<Scalar>& D, const std::vector<Scalar>& U, const std::vector<Scalar>& L, const Matrix<Scalar>& B, Matrix<Scalar>& O)
414  {
415  size_t ncA = A.getNumberOfColumns();
416  size_t nrA = A.getNumberOfRows();
417  size_t nrB = B.getNumberOfRows();
418  size_t ncB = B.getNumberOfColumns();
419  if (ncA != nrB) throw DimensionException("MatrixTools::mult(). nrows B != ncols A.", nrB, ncA);
420  if (ncA != D.size()) throw DimensionException("MatrixTools::mult(). Vector size is not equal to matrix size.", D.size(), ncA);
421  if (ncA != U.size() + 1) throw DimensionException("MatrixTools::mult(). Vector size is not equal to matrix size-1.", U.size(), ncA);
422  if (ncA != L.size() + 1) throw DimensionException("MatrixTools::mult(). Vector size is not equal to matrix size-1.", L.size(), ncA);
423  O.resize(nrA, ncB);
424  for (size_t i = 0; i < nrA; i++)
425  {
426  for (size_t j = 0; j < ncB; j++)
427  {
428  O(i, j) = A(i, 0) * D[0] * B(0, j);
429  if (nrB > 1)
430  O(i, j) += A(i, 0) * U[0] * B(1, j);
431  for (size_t k = 1; k < ncA - 1; k++)
432  {
433  O(i, j) += A(i, k) * (L[k - 1] * B(k - 1, j) + D[k] * B(k, j) + U[k] * B(k + 1, j));
434  }
435  if (ncA >= 2)
436  O(i, j) += A(i, ncA - 1) * L[ncA - 2] * B(ncA - 2, j);
437  O(i, j) += A(i, ncA - 1) * D[ncA - 1] * B(ncA - 1, j);
438  }
439  }
440  }
441 
450  template<class MatrixA, class MatrixB>
451  static void add(MatrixA& A, const MatrixB& B)
452  {
453  size_t ncA = A.getNumberOfColumns();
454  size_t nrA = A.getNumberOfRows();
455  size_t nrB = B.getNumberOfRows();
456  size_t ncB = B.getNumberOfColumns();
457  if (ncA > ncB) throw DimensionException("MatrixTools::operator+=(). A and B must have the same number of columns.", ncB, ncA);
458  if (nrA > nrB) throw DimensionException("MatrixTools::operator+=(). A and B must have the same number of rows.", nrB, nrA);
459 
460 
461  for (size_t i = 0; i < nrA; i++)
462  {
463  for (size_t j = 0; j < ncA; j++)
464  {
465  A(i, j) += B(i, j);
466  }
467  }
468  }
469 
478  template<class MatrixA, class MatrixB, class Scalar>
479  static void add(MatrixA& A, Scalar& x, const MatrixB& B)
480  {
481  size_t ncA = A.getNumberOfColumns();
482  size_t nrA = A.getNumberOfRows();
483  size_t nrB = B.getNumberOfRows();
484  size_t ncB = B.getNumberOfColumns();
485  if (ncA != ncB) throw DimensionException("MatrixTools::operator+(). A and B must have the same number of columns.", ncB, ncA);
486  if (nrA != nrB) throw DimensionException("MatrixTools::operator+(). A and B must have the same number of rows.", nrB, nrA);
487 
488  for (size_t i = 0; i < nrA; i++)
489  {
490  for (size_t j = 0; j < ncA; j++)
491  {
492  A(i, j) += x * B(i, j);
493  }
494  }
495  }
496 
508  template<class Matrix>
509  static void pow(const Matrix& A, size_t p, Matrix& O)
510  {
511  size_t n = A.getNumberOfRows();
512  if (n != A.getNumberOfColumns()) throw DimensionException("MatrixTools::pow(). nrows != ncols.", A.getNumberOfColumns(), A.getNumberOfRows());
513  switch (p)
514  {
515  case 0:
516  getId<Matrix>(n, O);
517  break;
518  case 1:
519  copy(A, O);
520  break;
521  case 2:
522  mult(A, A, O);
523  break;
524  default:
525  Matrix tmp;
526  if (p % 2)
527  {
528  pow(A, p / 2, tmp);
529  pow(tmp, 2, O);
530  }
531  else
532  {
533  pow(A, (p - 1) / 2, tmp);
534  pow(tmp, 2, O);
535  mult(A, O, tmp);
536  copy(tmp, O);
537  }
538  }
539  }
540 
550  template<class Scalar>
551  static void pow(const Matrix<Scalar>& A, double p, Matrix<Scalar>& O)
552  {
553  size_t n = A.getNumberOfRows();
554  if (n != A.getNumberOfColumns()) throw DimensionException("MatrixTools::pow(). nrows != ncols.", A.getNumberOfColumns(), A.getNumberOfRows());
555  EigenValue<Scalar> eigen(A);
556  RowMatrix<Scalar> rightEV, leftEV;
557  rightEV = eigen.getV();
558  inv(rightEV, leftEV);
559  mult(rightEV, VectorTools::pow(eigen.getRealEigenValues(), p), leftEV, O);
560  }
561 
572  template<class Scalar>
573  static void exp(const Matrix<Scalar>& A, Matrix<Scalar>& O)
574  {
575  size_t n = A.getNumberOfRows();
576  if (n != A.getNumberOfColumns()) throw DimensionException("MatrixTools::exp(). nrows != ncols.", A.getNumberOfColumns(), A.getNumberOfRows());
577  EigenValue<Scalar> eigen(A);
578  RowMatrix<Scalar> rightEV, leftEV;
579  rightEV = eigen.getV();
580  inv(rightEV, leftEV);
581  mult(rightEV, VectorTools::exp(eigen.getRealEigenValues()), leftEV, O);
582  }
583 
594  template<class Matrix, class Scalar>
595  static void Taylor(const Matrix& A, size_t p, std::vector< RowMatrix<Scalar> >& vO)
596  {
597  size_t n = A.getNumberOfRows();
598  if (n != A.getNumberOfColumns())
599  throw DimensionException("MatrixTools::pow(). nrows != ncols.", A.getNumberOfColumns(), A.getNumberOfRows());
600  vO.resize(p + 1);
601  getId<Matrix>(n, vO[0]);
602  copy(A, vO[1]);
603 
604  for (size_t i = 1; i < p; i++)
605  {
606  mult(vO[i], A, vO[i + 1]);
607  }
608  }
609 
614  template<class Matrix>
615  static std::vector<size_t> whichMax(const Matrix& m)
616  {
617  size_t nrows = m.getNumberOfRows();
618  size_t ncols = m.getNumberOfColumns();
619  std::vector<size_t> pos(2);
620  size_t imax = 0;
621  size_t jmax = 0;
622  double currentMax = std::log(0.);
623  for (size_t i = 0; i < nrows; i++)
624  {
625  for (size_t j = 0; j < ncols; j++)
626  {
627  double currentValue = m(i, j);
628  // cout << currentValue << "\t" << (currentValue > currentMax) << endl;
629  if (currentValue > currentMax)
630  {
631  imax = i;
632  jmax = j;
633  currentMax = currentValue;
634  }
635  }
636  }
637  pos[0] = imax;
638  pos[1] = jmax;
639  return pos;
640  }
641 
646  template<class Matrix>
647  static std::vector<size_t> whichMin(const Matrix& m)
648  {
649  size_t nrows = m.getNumberOfRows();
650  size_t ncols = m.getNumberOfColumns();
651  std::vector<size_t> pos(2);
652  size_t imin = 0;
653  size_t jmin = 0;
654  double currentMin = -std::log(0.);
655  for (size_t i = 0; i < nrows; i++)
656  {
657  for (size_t j = 0; j < ncols; j++)
658  {
659  double currentValue = m(i, j);
660  if (currentValue < currentMin)
661  {
662  imin = i;
663  jmin = j;
664  currentMin = currentValue;
665  }
666  }
667  }
668  pos[0] = imin;
669  pos[1] = jmin;
670  return pos;
671  }
672 
677  template<class Real>
678  static Real max(const Matrix<Real>& m)
679  {
680  size_t nrows = m.getNumberOfRows();
681  size_t ncols = m.getNumberOfColumns();
682  Real currentMax = std::log(0.);
683  for (size_t i = 0; i < nrows; i++)
684  {
685  for (size_t j = 0; j < ncols; j++)
686  {
687  Real currentValue = m(i, j);
688  // cout << currentValue << "\t" << (currentValue > currentMax) << endl;
689  if (currentValue > currentMax)
690  {
691  currentMax = currentValue;
692  }
693  }
694  }
695  return currentMax;
696  }
697 
698 
703  template<class Real>
704  static Real min(const Matrix<Real>& m)
705  {
706  size_t nrows = m.getNumberOfRows();
707  size_t ncols = m.getNumberOfColumns();
708  Real currentMin = -std::log(0.);
709  for (size_t i = 0; i < nrows; i++)
710  {
711  for (size_t j = 0; j < ncols; j++)
712  {
713  Real currentValue = m(i, j);
714  if (currentValue < currentMin)
715  {
716  currentMin = currentValue;
717  }
718  }
719  }
720  return currentMin;
721  }
722 
729  template<class Matrix>
730  static void print(const Matrix& m, std::ostream& out = std::cout)
731  {
732  out << m.getNumberOfRows() << "x" << m.getNumberOfColumns() << std::endl;
733  out << "[" << std::endl;
734  for (size_t i = 0; i < m.getNumberOfRows(); i++)
735  {
736  out << "[";
737  for (size_t j = 0; j < m.getNumberOfColumns() - 1; j++)
738  {
739  out << m(i, j) << ", ";
740  }
741  if (m.getNumberOfColumns() > 0) out << m(i, m.getNumberOfColumns() - 1) << "]" << std::endl;
742  }
743  out << "]" << std::endl;
744  }
745 
754  template<class Matrix>
755  static void print(const Matrix& m, bpp::OutputStream& out, char pIn = '(', char pOut = ')')
756  {
757  out << pIn;
758 
759  for (size_t i = 0; i < m.getNumberOfRows(); i++)
760  {
761  if (i != 0)
762  out << ",";
763 
764  out << pIn;
765  for (size_t j = 0; j < m.getNumberOfColumns() - 1; j++)
766  {
767  out << m(i, j) << ", ";
768  }
769  if (m.getNumberOfColumns() > 0) out << m(i, m.getNumberOfColumns() - 1) << pOut;
770  }
771  out << pOut;
772  }
773 
781  template<class Matrix>
782  static void printForR(const Matrix& m, const std::string& variableName = "x", std::ostream& out = std::cout)
783  {
784  out.precision(12);
785  out << variableName << "<-matrix(c(";
786  for (size_t i = 0; i < m.getNumberOfRows(); i++)
787  {
788  if (i > 0)
789  out << std::endl;
790 
791  for (size_t j = 0; j < m.getNumberOfColumns(); j++)
792  {
793  if (i > 0 || j > 0)
794  out << ", ";
795  out << m(i, j);
796  }
797  }
798  out << "), nrow=" << m.getNumberOfRows() << ", byrow=TRUE)" << std::endl;
799  }
800 
801 
808  template<class Real>
809  static void print(const std::vector<Real>& v, std::ostream& out = std::cout)
810  {
811  out << v.size() << std::endl;
812  out << "[";
813  for (size_t i = 0; i < v.size() - 1; i++)
814  {
815  out << v[i] << ", ";
816  }
817  if (v.size() > 0) out << v[v.size() - 1];
818  out << "]" << std::endl;
819  }
820 
825  template<class Matrix>
826  static bool isSquare(const Matrix& A) { return A.getNumberOfRows() == A.getNumberOfColumns(); }
827 
834  template<class Scalar>
835  static Scalar inv(const Matrix<Scalar>& A, Matrix<Scalar>& O)
836  {
837  if (!isSquare(A)) throw DimensionException("MatrixTools::inv(). Matrix A is not a square matrix.", A.getNumberOfRows(), A.getNumberOfColumns());
840  getId(A.getNumberOfRows(), I);
841  return lu.solve(I, O);
842  }
843 
853  template<class Scalar>
854  static double det(const Matrix<Scalar>& A)
855  {
856  if (!isSquare(A)) throw DimensionException("MatrixTools::det(). Matrix A is not a square matrix.", A.getNumberOfRows(), A.getNumberOfColumns());
858  return lu.det();
859  }
860 
865  template<class MatrixA, class MatrixO>
866  static void transpose(const MatrixA& A, MatrixO& O)
867  {
868  O.resize(A.getNumberOfColumns(), A.getNumberOfRows());
869  for (size_t i = 0; i < A.getNumberOfColumns(); i++)
870  {
871  for (size_t j = 0; j < A.getNumberOfRows(); j++)
872  {
873  O(i, j) = A(j, i);
874  }
875  }
876  }
877 
882  template<class MatrixA>
883  static bool isSymmetric(const MatrixA& A)
884  {
885  if (A.getNumberOfColumns() != A.getNumberOfRows())
886  return false;
887 
888  for (size_t i = 0; i < A.getNumberOfColumns(); i++)
889  {
890  for (size_t j = i + 1; j < A.getNumberOfRows(); j++)
891  {
892  if (A(i, j) != A(j, i))
893  return false;
894  }
895  }
896  return true;
897  }
898 
911  template<class Scalar>
912  static void covar(const Matrix<Scalar>& A, Matrix<Scalar>& O)
913  {
914  size_t r = A.getNumberOfRows();
915  size_t n = A.getNumberOfColumns();
916  O.resize(r, r);
918  transpose(A, tA);
919  mult(A, tA, O);
920  scale(O, 1. / static_cast<double>(n));
921  RowMatrix<Scalar> mean(r, 1);
922  for (size_t i = 0; i < r; i++)
923  {
924  for (size_t j = 0; j < n; j++)
925  {
926  mean(i, 0) += A(i, j);
927  }
928  mean(i, 0) /= static_cast<double>(n);
929  }
930  RowMatrix<Scalar> tMean;
931  transpose(mean, tMean);
932  RowMatrix<Scalar> meanMat;
933  mult(mean, tMean, meanMat);
934  scale(meanMat, -1.);
935  add(O, meanMat);
936  }
937 
946  template<class Scalar>
947  static void kroneckerMult(const Matrix<Scalar>& A, const Matrix<Scalar>& B, Matrix<Scalar>& O, bool check = true)
948  {
949  size_t ncA = A.getNumberOfColumns();
950  size_t nrA = A.getNumberOfRows();
951  size_t nrB = B.getNumberOfRows();
952  size_t ncB = B.getNumberOfColumns();
953 
954  if (check)
955  O.resize(nrA * nrB, ncA * ncB);
956 
957  for (size_t ia = 0; ia < nrA; ia++)
958  {
959  for (size_t ja = 0; ja < ncA; ja++)
960  {
961  Scalar aij = A(ia, ja);
962  for (size_t ib = 0; ib < nrB; ib++)
963  {
964  for (size_t jb = 0; jb < ncB; jb++)
965  {
966  O(ia * nrB + ib, ja * ncB + jb) = aij * B(ib, jb);
967  }
968  }
969  }
970  }
971  }
972 
983  template<class Scalar>
984  static void kroneckerMult(const Matrix<Scalar>& A, size_t dim, const Scalar& v, Matrix<Scalar>& O, bool check = true)
985  {
986  size_t ncA = A.getNumberOfColumns();
987  size_t nrA = A.getNumberOfRows();
988 
989  if (check)
990  O.resize(nrA * dim, ncA * dim);
991 
992  for (size_t ia = 0; ia < nrA; ia++)
993  {
994  for (size_t ja = 0; ja < ncA; ja++)
995  {
996  Scalar aij = A(ia, ja);
997  for (size_t ib = 0; ib < dim; ib++)
998  {
999  for (size_t jb = 0; jb < dim; jb++)
1000  {
1001  O(ia * dim + ib, ja * dim + jb) = aij * ((ib == jb) ? v : 0);
1002  }
1003  }
1004  }
1005  }
1006  }
1007 
1019  template<class Scalar>
1020  static void kroneckerMult(const Matrix<Scalar>& A, const Matrix<Scalar>& B, const Scalar& dA, const Scalar& dB, Matrix<Scalar>& O, bool check = true)
1021  {
1022  size_t ncA = A.getNumberOfColumns();
1023  size_t nrA = A.getNumberOfRows();
1024  size_t nrB = B.getNumberOfRows();
1025  size_t ncB = B.getNumberOfColumns();
1026 
1027  if (check)
1028  O.resize(nrA * nrB, ncA * ncB);
1029 
1030  for (size_t ia = 0; ia < nrA; ia++)
1031  {
1032  for (size_t ja = 0; ja < ncA; ja++)
1033  {
1034  const Scalar& aij = (ia == ja) ? dA : A(ia, ja);
1035 
1036  for (size_t ib = 0; ib < nrB; ib++)
1037  {
1038  for (size_t jb = 0; jb < ncB; jb++)
1039  {
1040  O(ia * nrB + ib, ja * ncB + jb) = aij * ((ib == jb) ? dB : B(ib, jb));
1041  }
1042  }
1043  }
1044  }
1045  }
1046 
1054  template<class Scalar>
1055  static void hadamardMult(const Matrix<Scalar>& A, const Matrix<Scalar>& B, Matrix<Scalar>& O)
1056  {
1057  size_t ncA = A.getNumberOfColumns();
1058  size_t nrA = A.getNumberOfRows();
1059  size_t nrB = B.getNumberOfRows();
1060  size_t ncB = B.getNumberOfColumns();
1061  if (nrA != nrB) throw DimensionException("MatrixTools::hadamardMult(). nrows A != nrows B.", nrA, nrB);
1062  if (ncA != ncB) throw DimensionException("MatrixTools::hadamardMult(). ncols A != ncols B.", ncA, ncB);
1063  O.resize(nrA, ncA);
1064  for (size_t i = 0; i < nrA; i++)
1065  {
1066  for (size_t j = 0; j < ncA; j++)
1067  {
1068  O(i, j) = A(i, j) * B(i, j);
1069  }
1070  }
1071  }
1072 
1083  template<class Scalar>
1084  static void hadamardMult(const Matrix<Scalar>& A, const Matrix<Scalar>& iA, const Matrix<Scalar>& B, const Matrix<Scalar>& iB, Matrix<Scalar>& O, Matrix<Scalar>& iO)
1085  {
1086  size_t ncA = A.getNumberOfColumns();
1087  size_t nrA = A.getNumberOfRows();
1088  size_t nrB = B.getNumberOfRows();
1089  size_t ncB = B.getNumberOfColumns();
1090  if (nrA != nrB) throw DimensionException("MatrixTools::hadamardMult(). nrows A != nrows B.", nrA, nrB);
1091  if (ncA != ncB) throw DimensionException("MatrixTools::hadamardMult(). ncols A != ncols B.", ncA, ncB);
1092  O.resize(nrA, ncA);
1093  iO.resize(nrA, ncA);
1094  for (size_t i = 0; i < nrA; i++)
1095  {
1096  for (size_t j = 0; j < ncA; j++)
1097  {
1098  O(i, j) = A(i, j) * B(i, j) - iA(i, j) * iB(i, j);
1099  iO(i, j) = iA(i, j) * B(i, j) + A(i, j) * iB(i, j);
1100  }
1101  }
1102  }
1103 
1112  template<class Scalar>
1113  static void hadamardMult(const Matrix<Scalar>& A, const std::vector<Scalar>& B, Matrix<Scalar>& O, bool row = true)
1114  {
1115  size_t ncA = A.getNumberOfColumns();
1116  size_t nrA = A.getNumberOfRows();
1117  size_t sB = B.size();
1118  if (row == true && nrA != sB) throw DimensionException("MatrixTools::hadamardMult(). nrows A != size of B.", nrA, sB);
1119  if (row == false && ncA != sB) throw DimensionException("MatrixTools::hadamardMult(). ncols A != size of B.", ncA, sB);
1120  O.resize(nrA, ncA);
1121  if (row)
1122  {
1123  for (size_t i = 0; i < nrA; i++)
1124  {
1125  for (size_t j = 0; j < ncA; j++)
1126  {
1127  O(i, j) = A(i, j) * B[i];
1128  }
1129  }
1130  }
1131  else
1132  {
1133  for (size_t i = 0; i < nrA; i++)
1134  {
1135  for (size_t j = 0; j < ncA; j++)
1136  {
1137  O(i, j) = A(i, j) * B[j];
1138  }
1139  }
1140  }
1141  }
1142 
1150  template<class Scalar>
1151  static void directSum(const Matrix<Scalar>& A, const Matrix<Scalar>& B, Matrix<Scalar>& O)
1152  {
1153  size_t ncA = A.getNumberOfColumns();
1154  size_t nrA = A.getNumberOfRows();
1155  size_t nrB = B.getNumberOfRows();
1156  size_t ncB = B.getNumberOfColumns();
1157  O.resize(nrA + nrB, ncA + ncB);
1158 
1159  for (size_t ia = 0; ia < nrA; ia++)
1160  {
1161  for (size_t ja = 0; ja < ncA; ja++)
1162  {
1163  O(ia, ja) = A(ia, ja);
1164  }
1165  }
1166 
1167  for (size_t ia = 0; ia < nrA; ia++)
1168  {
1169  for (size_t jb = 0; jb < ncB; jb++)
1170  {
1171  O(ia, ncA + jb) = 0;
1172  }
1173  }
1174 
1175  for (size_t ib = 0; ib < nrB; ib++)
1176  {
1177  for (size_t ja = 0; ja < ncA; ja++)
1178  {
1179  O(nrA + ib, ja) = 0;
1180  }
1181  }
1182 
1183  for (size_t ib = 0; ib < nrB; ib++)
1184  {
1185  for (size_t jb = 0; jb < nrB; jb++)
1186  {
1187  O(nrA + ib, ncA + jb) = B(ib, jb);
1188  }
1189  }
1190  }
1191 
1198  template<class Scalar>
1199  static void directSum(const std::vector< Matrix<Scalar>*>& vA, Matrix<Scalar>& O)
1200  {
1201  size_t nr = 0;
1202  size_t nc = 0;
1203  for (size_t k = 0; k < vA.size(); k++)
1204  {
1205  nr += vA[k]->getNumberOfRows();
1206  nc += vA[k]->getNumberOfColumns();
1207  }
1208  O.resize(nr, nc);
1209  for (size_t k = 0; k < nr; k++)
1210  {
1211  for (size_t k2 = 0; k2 < nc; k2++)
1212  {
1213  O(k, k2) = 0;
1214  }
1215  }
1216 
1217  size_t rk = 0; // Row counter
1218  size_t ck = 0; // Col counter
1219  for (size_t k = 0; k < vA.size(); k++)
1220  {
1221  const Matrix<Scalar>* Ak = vA[k];
1222  for (size_t i = 0; i < Ak->getNumberOfRows(); i++)
1223  {
1224  for (size_t j = 0; j < Ak->getNumberOfColumns(); j++)
1225  {
1226  O(rk + i, ck + j) = (*Ak)(i, j);
1227  }
1228  }
1229  rk += Ak->getNumberOfRows();
1230  ck += Ak->getNumberOfColumns();
1231  }
1232  }
1233 
1240  template<class Scalar>
1241  static void toVVdouble(const Matrix<Scalar>& M, std::vector< std::vector<Scalar> >& vO)
1242  {
1243  size_t n = M.getNumberOfRows();
1244  size_t m = M.getNumberOfColumns();
1245  vO.resize(n);
1246  for (size_t i = 0; i < n; i++)
1247  {
1248  vO[i].resize(m);
1249  for (size_t j = 0; j < m; j++)
1250  {
1251  vO[i][j] = M(i, j);
1252  }
1253  }
1254  }
1255 
1261  template<class Scalar>
1262  static Scalar sumElements(const Matrix<Scalar>& M)
1263  {
1264  Scalar sum = 0;
1265  for (size_t i = 0; i < M.getNumberOfRows(); i++)
1266  {
1267  for (size_t j = 0; j < M.getNumberOfColumns(); j++)
1268  {
1269  sum += M(i, j);
1270  }
1271  }
1272  return sum;
1273  }
1274 
1275 
1290  template<class Scalar>
1291  static Scalar lap(Matrix<Scalar>& assignCost,
1292  std::vector<int>& rowSol,
1293  std::vector<int>& colSol,
1294  std::vector<Scalar>& u,
1295  std::vector<Scalar>& v)
1296  {
1297  size_t dim = assignCost.getNumberOfRows();
1298  if (assignCost.getNumberOfColumns() != dim)
1299  throw Exception("MatrixTools::lap. Cost matrix should be scare.");
1300 
1301  bool unassignedFound;
1302  size_t i, iMin;
1303  size_t numFree = 0, previousNumFree, f, k, freeRow;
1304  int i0;
1305  std::vector<size_t> free(dim); // list of unassigned rows.
1306  std::vector<size_t> pred(dim); // row-predecessor of column in augmenting/alternating path.
1307  size_t j, j1, j2, endOfPath, last, low, up;
1308  std::vector<size_t> colList(dim); // list of columns to be scanned in various ways.
1309  std::vector<short int> matches(dim, 0); // counts how many times a row could be assigned.
1310  Scalar min;
1311  Scalar h;
1312  size_t uMin, uSubMin;
1313  Scalar v2;
1314  std::vector<Scalar> d(dim); // 'cost-distance' in augmenting path calculation.
1315 
1316  // Column reduction
1317  for (j = dim; j > 0; j--) // reverse order gives better results.
1318  {
1319  // find minimum cost over rows.
1320  min = assignCost(0, j - 1);
1321  iMin = 0;
1322  for (i = 1; i < dim; ++i)
1323  {
1324  if (assignCost(i, j - 1) < min)
1325  {
1326  min = assignCost(i, j - 1);
1327  iMin = i;
1328  }
1329  }
1330  v[j - 1] = min;
1331 
1332  if (++matches[iMin] == 1)
1333  {
1334  // init assignment if minimum row assigned for first time.
1335  rowSol[iMin] = static_cast<int>(j - 1);
1336  colSol[j - 1] = static_cast<int>(iMin);
1337  }
1338  else
1339  colSol[j - 1] = -1; // row already assigned, column not assigned.
1340  }
1341 
1342  // Reduction tranfer
1343  for (i = 0; i < dim; i++)
1344  {
1345  if (matches[i] == 0) // fill list of unassigned 'free' rows.
1346  free[numFree++] = i;
1347  else
1348  {
1349  if (matches[i] == 1) // transfer reduction from rows that are assigned once.
1350  {
1351  j1 = static_cast<size_t>(rowSol[i]); // rowSol[i] is >= 0 here
1352  min = -std::log(0);
1353  for (j = 0; j < dim; j++)
1354  {
1355  if (j != j1)
1356  if (assignCost(i, j - 1) - v[j] < min)
1357  min = assignCost(i, j - 1) - v[j - 1];
1358  }
1359  v[j1] = v[j1] - min;
1360  }
1361  }
1362  }
1363 
1364  // Augmenting row reduction
1365  short loopcnt = 0; // do-loop to be done twice.
1366  do
1367  {
1368  loopcnt++;
1369 
1370  // scan all free rows.
1371  // in some cases, a free row may be replaced with another one to be scanned next.
1372  k = 0;
1373  previousNumFree = numFree;
1374  numFree = 0; // start list of rows still free after augmenting row reduction.
1375  while (k < previousNumFree)
1376  {
1377  i = free[k];
1378  k++;
1379 
1380  // find minimum and second minimum reduced cost over columns.
1381  uMin = assignCost(i, 0) - v[0];
1382  j1 = 0;
1383  uSubMin = static_cast<size_t>(-std::log(0));
1384  for (j = 1; j < dim; j++)
1385  {
1386  h = assignCost(i, j) - v[j];
1387  if (h < uSubMin)
1388  {
1389  if (h >= uMin)
1390  {
1391  uSubMin = h;
1392  j2 = j;
1393  }
1394  else
1395  {
1396  uSubMin = uMin;
1397  uMin = h;
1398  j2 = j1;
1399  j1 = j;
1400  }
1401  }
1402  }
1403 
1404  i0 = colSol[j1];
1405  if (uMin < uSubMin)
1406  {
1407  // change the reduction of the minimum column to increase the minimum
1408  // reduced cost in the row to the subminimum.
1409  v[j1] = v[j1] - (uSubMin - uMin);
1410  }
1411  else // minimum and subminimum equal.
1412  {
1413  if (i0 >= 0) // minimum column j1 is assigned.
1414  {
1415  // swap columns j1 and j2, as j2 may be unassigned.
1416  j1 = j2;
1417  i0 = colSol[j2];
1418  }
1419  }
1420 
1421  // (re-)assign i to j1, possibly de-assigning an i0.
1422  rowSol[i] = static_cast<int>(j1);
1423  colSol[j1] = static_cast<int>(i);
1424 
1425  if (i0 >= 0) // minimum column j1 assigned earlier.
1426  {
1427  if (uMin < uSubMin)
1428  {
1429  // put in current k, and go back to that k.
1430  // continue augmenting path i - j1 with i0.
1431  free[--k] = static_cast<size_t>(i0);
1432  }
1433  else
1434  {
1435  // no further augmenting reduction possible.
1436  // store i0 in list of free rows for next phase.
1437  free[numFree++] = static_cast<size_t>(i0);
1438  }
1439  }
1440  }
1441  }
1442  while (loopcnt < 2); // repeat once.
1443 
1444  // Augment solution for each free row.
1445  for (f = 0; f < numFree; f++)
1446  {
1447  freeRow = free[f]; // start row of augmenting path.
1448 
1449  // Dijkstra shortest path algorithm.
1450  // runs until unassigned column added to shortest path tree.
1451  for (j = 0; j < dim; j++)
1452  {
1453  d[j] = assignCost(freeRow, j) - v[j];
1454  pred[j] = freeRow;
1455  colList[j] = j; // init column list.
1456  }
1457 
1458  low = 0; // columns in 0..low-1 are ready, now none.
1459  up = 0; // columns in low..up-1 are to be scanned for current minimum, now none.
1460  // columns in up..dim-1 are to be considered later to find new minimum,
1461  // at this stage the list simply contains all columns
1462  unassignedFound = false;
1463  do
1464  {
1465  if (up == low) // no more columns to be scanned for current minimum.
1466  {
1467  last = low - 1;
1468 
1469  // scan columns for up..dim-1 to find all indices for which new minimum occurs.
1470  // store these indices between low..up-1 (increasing up).
1471  min = d[colList[up++]];
1472  for (k = up; k < dim; k++)
1473  {
1474  j = colList[k];
1475  h = d[j];
1476  if (h <= min)
1477  {
1478  if (h < min) // new minimum.
1479  {
1480  up = low; // restart list at index low.
1481  min = h;
1482  }
1483  // new index with same minimum, put on undex up, and extend list.
1484  colList[k] = colList[up];
1485  colList[up++] = j;
1486  }
1487  }
1488 
1489  // check if any of the minimum columns happens to be unassigned.
1490  // if so, we have an augmenting path right away.
1491  for (k = low; k < up; k++)
1492  {
1493  if (colSol[colList[k]] < 0)
1494  {
1495  endOfPath = colList[k];
1496  unassignedFound = true;
1497  break;
1498  }
1499  }
1500  }
1501 
1502  if (!unassignedFound)
1503  {
1504  // update 'distances' between freerow and all unscanned columns, via next scanned column.
1505  j1 = colList[low];
1506  low++;
1507  i = static_cast<size_t>(colSol[j1]);
1508  h = assignCost(i, j1) - v[j1] - min;
1509 
1510  for (k = up; k < dim; k++)
1511  {
1512  j = colList[k];
1513  v2 = assignCost(i, j) - v[j] - h;
1514  if (v2 < d[j])
1515  {
1516  pred[j] = i;
1517  if (v2 == min) // new column found at same minimum value
1518  {
1519  if (colSol[j] < 0)
1520  {
1521  // if unassigned, shortest augmenting path is complete.
1522  endOfPath = j;
1523  unassignedFound = true;
1524  break;
1525  }
1526  // else add to list to be scanned right away.
1527  else
1528  {
1529  colList[k] = colList[up];
1530  colList[up++] = j;
1531  }
1532  }
1533  d[j] = v2;
1534  }
1535  }
1536  }
1537  }
1538  while (!unassignedFound);
1539 
1540  // update column prices.
1541  for (k = 0; k <= last; k++)
1542  {
1543  j1 = colList[k];
1544  v[j1] = v[j1] + d[j1] - min;
1545  }
1546 
1547  // reset row and column assignments along the alternating path.
1548  do
1549  {
1550  i = pred[endOfPath];
1551  colSol[endOfPath] = static_cast<int>(i);
1552  j1 = endOfPath;
1553  endOfPath = static_cast<size_t>(rowSol[i]);
1554  rowSol[i] = static_cast<int>(j1);
1555  }
1556  while (i != freeRow);
1557  }
1558 
1559  // calculate optimal cost.
1560  Scalar lapCost = 0;
1561  for (i = 0; i < dim; i++)
1562  {
1563  j = static_cast<size_t>(rowSol[i]);
1564  u[i] = assignCost(i, j) - v[j];
1565  lapCost = lapCost + assignCost(i, j);
1566  }
1567 
1568  return lapCost;
1569  }
1570 };
1571 } // end of namespace bpp.
1572 #endif // BPP_NUMERIC_MATRIX_MATRIXTOOLS_H
Exception thrown when a dimension problem occured.
Computes eigenvalues and eigenvectors of a real (non-complex) matrix.
Definition: EigenValue.h:107
const RowMatrix< Real > & getV() const
Return the eigenvector matrix.
Definition: EigenValue.h:1168
const std::vector< Real > & getRealEigenValues() const
Return the real parts of the eigenvalues.
Definition: EigenValue.h:1175
Exception base class. Overload exception constructor (to control the exceptions mechanism)....
Definition: Exceptions.h:59
LU Decomposition.
Real det() const
Compute determinant using LU factors.
Real solve(const Matrix< Real > &B, Matrix< Real > &X) const
Solve A*X = B.
Functions dealing with matrices.
Definition: MatrixTools.h:59
static Scalar inv(const Matrix< Scalar > &A, Matrix< Scalar > &O)
Definition: MatrixTools.h:835
static void print(const std::vector< Real > &v, std::ostream &out=std::cout)
Print a vector to a stream.
Definition: MatrixTools.h:809
static void directSum(const std::vector< Matrix< Scalar > * > &vA, Matrix< Scalar > &O)
Compute the direct sum of n row matrices.
Definition: MatrixTools.h:1199
static void mult(const Matrix< Scalar > &A, const Matrix< Scalar > &iA, const Matrix< Scalar > &B, const Matrix< Scalar > &iB, Matrix< Scalar > &O, Matrix< Scalar > &iO)
Product of complex matrices as couples of matrices.
Definition: MatrixTools.h:289
static void pow(const Matrix &A, size_t p, Matrix &O)
Compute the power of a given matrix.
Definition: MatrixTools.h:509
static bool isSquare(const Matrix &A)
Definition: MatrixTools.h:826
static void copy(const MatrixA &A, MatrixO &O)
Copy operation. This function supplies the lack of inheritence of the assigment operator :D .
Definition: MatrixTools.h:72
static void diag(const Matrix< Scalar > &M, std::vector< Scalar > &O)
Definition: MatrixTools.h:189
static void printForR(const Matrix &m, const std::string &variableName="x", std::ostream &out=std::cout)
Print a matrix to a stream, so that it is read by R.
Definition: MatrixTools.h:782
static void add(MatrixA &A, const MatrixB &B)
Add matrix B to matrix A.
Definition: MatrixTools.h:451
static void mult(const Matrix< Scalar > &A, const Matrix< Scalar > &B, Matrix< Scalar > &O)
Definition: MatrixTools.h:256
static void diag(const Scalar x, size_t n, Matrix< Scalar > &O)
Definition: MatrixTools.h:174
static void Taylor(const Matrix &A, size_t p, std::vector< RowMatrix< Scalar > > &vO)
Compute a vector of the first powers of a given matrix.
Definition: MatrixTools.h:595
static void kroneckerMult(const Matrix< Scalar > &A, size_t dim, const Scalar &v, Matrix< Scalar > &O, bool check=true)
Compute the Kronecker product of one Matrice with a diagonal matrix, which main term and dimension ar...
Definition: MatrixTools.h:984
static void kroneckerMult(const Matrix< Scalar > &A, const Matrix< Scalar > &B, Matrix< Scalar > &O, bool check=true)
Compute the Kronecker product of two row matrices.
Definition: MatrixTools.h:947
static void mult(const Matrix< Scalar > &A, const std::vector< Scalar > &D, const std::vector< Scalar > &U, const std::vector< Scalar > &L, const Matrix< Scalar > &B, Matrix< Scalar > &O)
Compute A . (U+D+L) . B where D is a diagonal matrix, U (resp. L) is a matrix in which the only non-z...
Definition: MatrixTools.h:413
static void add(MatrixA &A, Scalar &x, const MatrixB &B)
Add matrix x.B to matrix A.
Definition: MatrixTools.h:479
static void hadamardMult(const Matrix< Scalar > &A, const Matrix< Scalar > &iA, const Matrix< Scalar > &B, const Matrix< Scalar > &iB, Matrix< Scalar > &O, Matrix< Scalar > &iO)
Compute the Hadamard product of two row matrices with same dimensions.
Definition: MatrixTools.h:1084
static void getId(size_t n, Matrix &O)
Get a identity matrix of a given size.
Definition: MatrixTools.h:141
static void copyUp(const MatrixA &A, MatrixO &O)
O(i,j)=A(i+1,j) and O(nbRow,j)=0.
Definition: MatrixTools.h:92
static void directSum(const Matrix< Scalar > &A, const Matrix< Scalar > &B, Matrix< Scalar > &O)
Compute the direct sum of two row matrices.
Definition: MatrixTools.h:1151
static void copyDown(const MatrixA &A, MatrixO &O)
O(i,j)=A(i-1,j) and O(0,j)=0.
Definition: MatrixTools.h:117
static Real max(const Matrix< Real > &m)
Definition: MatrixTools.h:678
static void covar(const Matrix< Scalar > &A, Matrix< Scalar > &O)
Compute the variance-covariance matrix of an input matrix.
Definition: MatrixTools.h:912
static std::vector< size_t > whichMax(const Matrix &m)
Definition: MatrixTools.h:615
static void pow(const Matrix< Scalar > &A, double p, Matrix< Scalar > &O)
Compute the power of a given matrix, using eigen value decomposition.
Definition: MatrixTools.h:551
static void diag(const std::vector< Scalar > &D, Matrix< Scalar > &O)
Definition: MatrixTools.h:158
static Scalar sumElements(const Matrix< Scalar > &M)
Sum all elements in M.
Definition: MatrixTools.h:1262
static void exp(const Matrix< Scalar > &A, Matrix< Scalar > &O)
Perform matrix exponentiation using diagonalization.
Definition: MatrixTools.h:573
static void print(const Matrix &m, bpp::OutputStream &out, char pIn='(', char pOut=')')
Print a matrix to a stream.
Definition: MatrixTools.h:755
static void transpose(const MatrixA &A, MatrixO &O)
Definition: MatrixTools.h:866
static Real min(const Matrix< Real > &m)
Definition: MatrixTools.h:704
static void hadamardMult(const Matrix< Scalar > &A, const std::vector< Scalar > &B, Matrix< Scalar > &O, bool row=true)
Compute the "Hadamard" product of a row matrix and a vector containing weights, according to rows or ...
Definition: MatrixTools.h:1113
static void hadamardMult(const Matrix< Scalar > &A, const Matrix< Scalar > &B, Matrix< Scalar > &O)
Compute the Hadamard product of two row matrices with same dimensions.
Definition: MatrixTools.h:1055
static void scale(Matrix &A, Scalar a, Scalar b=0)
Multiply all elements of a matrix by a given value, and add a constant.
Definition: MatrixTools.h:239
static void fill(Matrix &M, Scalar x)
Set all elements in M to value x.
Definition: MatrixTools.h:204
static bool isSymmetric(const MatrixA &A)
Definition: MatrixTools.h:883
static void print(const Matrix &m, std::ostream &out=std::cout)
Print a matrix to a stream.
Definition: MatrixTools.h:730
static std::vector< size_t > whichMin(const Matrix &m)
Definition: MatrixTools.h:647
static void mult(const Matrix< Scalar > &A, const std::vector< Scalar > &D, const Matrix< Scalar > &B, Matrix< Scalar > &O)
Compute A . D . B where D is a diagonal matrix in O(n^3).
Definition: MatrixTools.h:326
static Scalar lap(Matrix< Scalar > &assignCost, std::vector< int > &rowSol, std::vector< int > &colSol, std::vector< Scalar > &u, std::vector< Scalar > &v)
Linear Assignment Problem.
Definition: MatrixTools.h:1291
static void toVVdouble(const Matrix< Scalar > &M, std::vector< std::vector< Scalar > > &vO)
Convert to a vector of vector.
Definition: MatrixTools.h:1241
static void fillDiag(Matrix &M, Scalar x)
Set all diagonal elements in M to value x.
Definition: MatrixTools.h:221
static void kroneckerMult(const Matrix< Scalar > &A, const Matrix< Scalar > &B, const Scalar &dA, const Scalar &dB, Matrix< Scalar > &O, bool check=true)
Compute the Kronecker product of two row matrices in which the diagonal element is changed.
Definition: MatrixTools.h:1020
static double det(const Matrix< Scalar > &A)
Get determinant of a square matrix.
Definition: MatrixTools.h:854
static void mult(const Matrix< Scalar > &A, const Matrix< Scalar > &iA, const std::vector< Scalar > &D, const std::vector< Scalar > &iD, const Matrix< Scalar > &B, const Matrix< Scalar > &iB, Matrix< Scalar > &O, Matrix< Scalar > &iO)
Compute A . D . B where D is a diagonal matrix in O(n^3).
Definition: MatrixTools.h:367
The matrix template interface.
Definition: Matrix.h:61
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
OutputStream interface.
Definition: OutputStream.h:67
Matrix storage by row.
Definition: Matrix.h:131
static double exp(const T &x)
Definition: VectorTools.h:826
static std::vector< T > pow(const std::vector< T > &v1, T &b)
Definition: VectorTools.h:880