bpp-core3  3.0.0
MatrixTools.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_MATRIXTOOLS_H
6 #define BPP_NUMERIC_MATRIX_MATRIXTOOLS_H
7 
8 #include <cstdio>
9 #include <iostream>
10 
11 #include "../../Io/OutputStream.h"
12 #include "../VectorTools.h"
13 #include "EigenValue.h"
14 #include "LUDecomposition.h"
15 #include "Matrix.h"
16 
17 namespace bpp
18 {
23 {
24 public:
27 
28 public:
35  template<class MatrixA, class MatrixO>
36  static void copy(const MatrixA& A, MatrixO& O)
37  {
38  O.resize(A.getNumberOfRows(), A.getNumberOfColumns());
39  for (size_t i = 0; i < A.getNumberOfRows(); i++)
40  {
41  for (size_t j = 0; j < A.getNumberOfColumns(); j++)
42  {
43  O(i, j) = A(i, j);
44  }
45  }
46  }
47 
54  template<class MatrixA, class MatrixO>
55  static void copyUp(const MatrixA& A, MatrixO& O)
56  {
57  size_t nr(A.getNumberOfRows()), nc(A.getNumberOfColumns());
58  O.resize(nr, nc);
59  for (size_t i = 0; i < nr - 1; i++)
60  {
61  for (size_t j = 0; j < nc; j++)
62  {
63  O(i, j) = A(i + 1, j);
64  }
65  }
66  for (size_t j = 0; j < nc; j++)
67  {
68  O(nr - 1, j) = 0;
69  }
70  }
71 
78  template<class MatrixA, class MatrixO>
79  static void copyDown(const MatrixA& A, MatrixO& O)
80  {
81  size_t nr(A.getNumberOfRows()), nc(A.getNumberOfColumns());
82  O.resize(nr, nc);
83  for (size_t i = 1; i < nr; i++)
84  {
85  for (size_t j = 0; j < nc; j++)
86  {
87  O(i, j) = A(i - 1, j);
88  }
89  }
90  for (size_t j = 0; j < nc; j++)
91  {
92  O(0, j) = 0;
93  }
94  }
95 
102  template<class Matrix>
103  static void getId(size_t n, Matrix& O)
104  {
105  O.resize(n, n);
106  for (size_t i = 0; i < n; i++)
107  {
108  for (size_t j = 0; j < n; j++)
109  {
110  O(i, j) = (i == j) ? 1 : 0;
111  }
112  }
113  }
114 
119  template<class Scalar>
120  static void diag(const std::vector<Scalar>& D, Matrix<Scalar>& O)
121  {
122  size_t n = D.size();
123  O.resize(n, n);
124  for (size_t i = 0; i < n; i++)
125  {
126  for (size_t j = 0; j < n; j++) { O(i, j) = (i == j) ? D[i] : 0;}
127  }
128  }
129 
135  template<class Scalar>
136  static void diag(const Scalar x, size_t n, Matrix<Scalar>& O)
137  {
138  O.resize(n, n);
139  for (size_t i = 0; i < n; i++)
140  {
141  for (size_t j = 0; j < n; j++) { O(i, j) = (i == j) ? x : 0;}
142  }
143  }
144 
150  template<class Scalar>
151  static void diag(const Matrix<Scalar>& M, std::vector<Scalar>& O)
152  {
153  size_t nc = M.getNumberOfColumns();
154  size_t nr = M.getNumberOfRows();
155  if (nc != nr) throw DimensionException("MatrixTools::diag(). M must be a square matrix.", nr, nc);
156  O.resize(nc);
157  for (size_t i = 0; i < nc; i++) { O[i] = M(i, i);}
158  }
159 
165  template<class Matrix, class Scalar>
166  static void fill(Matrix& M, Scalar x)
167  {
168  for (size_t i = 0; i < M.getNumberOfRows(); i++)
169  {
170  for (size_t j = 0; j < M.getNumberOfColumns(); j++)
171  {
172  M(i, j) = x;
173  }
174  }
175  }
176 
182  template<class Matrix, class Scalar>
183  static void fillDiag(Matrix& M, Scalar x)
184  {
185  for (size_t i = 0; i < M.getNumberOfRows(); i++)
186  {
187  M(i, i) = x;
188  }
189  }
190 
200  template<class Matrix, class Scalar>
201  static void scale(Matrix& A, Scalar a, Scalar b = 0)
202  {
203  if ((a == 1) && (b == 0))
204  return;
205 
206  for (size_t i = 0; i < A.getNumberOfRows(); i++)
207  {
208  for (size_t j = 0; j < A.getNumberOfColumns(); j++)
209  {
210  A(i, j) = a * A(i, j) + b;
211  }
212  }
213  }
214 
220  template<class Scalar>
221  static void mult(const Matrix<Scalar>& A, const Matrix<Scalar>& B, Matrix<Scalar>& O)
222  {
223  size_t ncA = A.getNumberOfColumns();
224  size_t nrA = A.getNumberOfRows();
225  size_t nrB = B.getNumberOfRows();
226  size_t ncB = B.getNumberOfColumns();
227  if (ncA != nrB) throw DimensionException("MatrixTools::mult(). nrows B != ncols A.", nrB, ncA);
228  O.resize(nrA, ncB);
229  for (size_t i = 0; i < nrA; i++)
230  {
231  for (size_t j = 0; j < ncB; j++)
232  {
233  O(i, j) = 0;
234  for (size_t k = 0; k < ncA; k++)
235  {
236  O(i, j) += A(i, k) * B(k, j);
237  }
238  }
239  }
240  }
241 
252  template<class Scalar>
253  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)
254  {
255  size_t ncA = A.getNumberOfColumns();
256  size_t nrA = A.getNumberOfRows();
257  size_t nrB = B.getNumberOfRows();
258  size_t ncB = B.getNumberOfColumns();
259  if (ncA != nrB) throw DimensionException("MatrixTools::mult(). nrows B != ncols A.", nrB, ncA);
260  O.resize(nrA, ncB);
261  iO.resize(nrA, ncB);
262  for (size_t i = 0; i < nrA; i++)
263  {
264  for (size_t j = 0; j < ncB; j++)
265  {
266  O(i, j) = 0;
267  iO(i, j) = 0;
268  for (size_t k = 0; k < ncA; k++)
269  {
270  O(i, j) += A(i, k) * B(k, j) - iA(i, k) * iB(k, j);
271  iO(i, j) += A(i, k) * iB(k, j) + iA(i, k) * B(k, j);
272  }
273  }
274  }
275  }
276 
289  template<class Scalar>
290  static void mult(const Matrix<Scalar>& A, const std::vector<Scalar>& D, const Matrix<Scalar>& B, Matrix<Scalar>& O)
291  {
292  size_t ncA = A.getNumberOfColumns();
293  size_t nrA = A.getNumberOfRows();
294  size_t nrB = B.getNumberOfRows();
295  size_t ncB = B.getNumberOfColumns();
296  if (ncA != nrB) throw DimensionException("MatrixTools::mult(). nrows B != ncols A.", nrB, ncA);
297  if (ncA != D.size()) throw DimensionException("MatrixTools::mult(). Vector size is not equal to matrix size.", D.size(), ncA);
298  O.resize(nrA, ncB);
299  for (size_t i = 0; i < nrA; i++)
300  {
301  for (size_t j = 0; j < ncB; j++)
302  {
303  O(i, j) = 0;
304  for (size_t k = 0; k < ncA; k++)
305  {
306  O(i, j) += A(i, k) * B(k, j) * D[k];
307  }
308  }
309  }
310  }
311 
330  template<class Scalar>
331  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)
332  {
333  size_t ncA = A.getNumberOfColumns();
334  size_t nrA = A.getNumberOfRows();
335  size_t nrB = B.getNumberOfRows();
336  size_t ncB = B.getNumberOfColumns();
337  if (ncA != nrB) throw DimensionException("MatrixTools::mult(). nrows B != ncols A.", nrB, ncA);
338  if (ncA != D.size()) throw DimensionException("MatrixTools::mult(). Vector size is not equal to matrix size.", D.size(), ncA);
339  O.resize(nrA, ncB);
340  Scalar ab, iaib, iab, aib;
341 
342  for (size_t i = 0; i < nrA; i++)
343  {
344  for (size_t j = 0; j < ncB; j++)
345  {
346  O(i, j) = 0;
347  iO(i, j) = 0;
348  for (size_t k = 0; k < ncA; k++)
349  {
350  ab = A(i, k) * B(k, j) - iA(i, k) * iB(k, j);
351  aib = A(i, k) * iB(k, j) + iA(i, k) * B(k, j);
352 
353  O(i, j) += ab * D[k] - aib * iD[k];
354  iO(i, j) += ab * iD[k] + aib * D[k];
355  }
356  }
357  }
358  }
359 
376  template<class Scalar>
377  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)
378  {
379  size_t ncA = A.getNumberOfColumns();
380  size_t nrA = A.getNumberOfRows();
381  size_t nrB = B.getNumberOfRows();
382  size_t ncB = B.getNumberOfColumns();
383  if (ncA != nrB) throw DimensionException("MatrixTools::mult(). nrows B != ncols A.", nrB, ncA);
384  if (ncA != D.size()) throw DimensionException("MatrixTools::mult(). Vector size is not equal to matrix size.", D.size(), ncA);
385  if (ncA != U.size() + 1) throw DimensionException("MatrixTools::mult(). Vector size is not equal to matrix size-1.", U.size(), ncA);
386  if (ncA != L.size() + 1) throw DimensionException("MatrixTools::mult(). Vector size is not equal to matrix size-1.", L.size(), ncA);
387  O.resize(nrA, ncB);
388  for (size_t i = 0; i < nrA; i++)
389  {
390  for (size_t j = 0; j < ncB; j++)
391  {
392  O(i, j) = A(i, 0) * D[0] * B(0, j);
393  if (nrB > 1)
394  O(i, j) += A(i, 0) * U[0] * B(1, j);
395  for (size_t k = 1; k < ncA - 1; k++)
396  {
397  O(i, j) += A(i, k) * (L[k - 1] * B(k - 1, j) + D[k] * B(k, j) + U[k] * B(k + 1, j));
398  }
399  if (ncA >= 2)
400  O(i, j) += A(i, ncA - 1) * L[ncA - 2] * B(ncA - 2, j);
401  O(i, j) += A(i, ncA - 1) * D[ncA - 1] * B(ncA - 1, j);
402  }
403  }
404  }
405 
413  template<class MatrixA, class MatrixB>
414  static void add(MatrixA& A, const MatrixB& B)
415  {
416  size_t ncA = A.getNumberOfColumns();
417  size_t nrA = A.getNumberOfRows();
418  size_t nrB = B.getNumberOfRows();
419  size_t ncB = B.getNumberOfColumns();
420  if (ncA > ncB) throw DimensionException("MatrixTools::operator+=(). A and B must have the same number of columns.", ncB, ncA);
421  if (nrA > nrB) throw DimensionException("MatrixTools::operator+=(). A and B must have the same number of rows.", nrB, nrA);
422 
423 
424  for (size_t i = 0; i < nrA; i++)
425  {
426  for (size_t j = 0; j < ncA; j++)
427  {
428  A(i, j) += B(i, j);
429  }
430  }
431  }
432 
441  template<class MatrixA, class MatrixB, class Scalar>
442  static void add(MatrixA& A, Scalar& x, const MatrixB& B)
443  {
444  size_t ncA = A.getNumberOfColumns();
445  size_t nrA = A.getNumberOfRows();
446  size_t nrB = B.getNumberOfRows();
447  size_t ncB = B.getNumberOfColumns();
448  if (ncA != ncB) throw DimensionException("MatrixTools::operator+(). A and B must have the same number of columns.", ncB, ncA);
449  if (nrA != nrB) throw DimensionException("MatrixTools::operator+(). A and B must have the same number of rows.", nrB, nrA);
450 
451  for (size_t i = 0; i < nrA; i++)
452  {
453  for (size_t j = 0; j < ncA; j++)
454  {
455  A(i, j) += x * B(i, j);
456  }
457  }
458  }
459 
471  template<class Matrix>
472  static void pow(const Matrix& A, size_t p, Matrix& O)
473  {
474  size_t n = A.getNumberOfRows();
475  if (n != A.getNumberOfColumns()) throw DimensionException("MatrixTools::pow(). nrows != ncols.", A.getNumberOfColumns(), A.getNumberOfRows());
476  switch (p)
477  {
478  case 0:
479  getId<Matrix>(n, O);
480  break;
481  case 1:
482  copy(A, O);
483  break;
484  case 2:
485  mult(A, A, O);
486  break;
487  default:
488  Matrix tmp;
489  if (!(p % 2))
490  {
491  pow(A, p / 2, tmp);
492  pow(tmp, 2, O);
493  }
494  else
495  {
496  pow(A, (p - 1) / 2, tmp);
497  mult(tmp, tmp, O);
498  mult(A, O, tmp);
499  copy(tmp, O);
500  }
501  }
502  }
503 
513  template<class Scalar>
514  static void pow(const Matrix<Scalar>& A, double p, Matrix<Scalar>& O)
515  {
516  size_t n = A.getNumberOfRows();
517  if (n != A.getNumberOfColumns()) throw DimensionException("MatrixTools::pow(). nrows != ncols.", A.getNumberOfColumns(), A.getNumberOfRows());
518  EigenValue<Scalar> eigen(A);
519  RowMatrix<Scalar> rightEV, leftEV;
520  rightEV = eigen.getV();
521  inv(rightEV, leftEV);
522  mult(rightEV, VectorTools::pow(eigen.getRealEigenValues(), p), leftEV, O);
523  }
524 
535  template<class Scalar>
536  static void exp(const Matrix<Scalar>& A, Matrix<Scalar>& O)
537  {
538  size_t n = A.getNumberOfRows();
539  if (n != A.getNumberOfColumns()) throw DimensionException("MatrixTools::exp(). nrows != ncols.", A.getNumberOfColumns(), A.getNumberOfRows());
540  EigenValue<Scalar> eigen(A);
541  RowMatrix<Scalar> rightEV, leftEV;
542  rightEV = eigen.getV();
543  inv(rightEV, leftEV);
544  mult(rightEV, VectorTools::exp(eigen.getRealEigenValues()), leftEV, O);
545  }
546 
556  template<class Matrix, class Scalar>
557  static void Taylor(const Matrix& A, size_t p, std::vector< RowMatrix<Scalar>>& vO)
558  {
559  size_t n = A.getNumberOfRows();
560  if (n != A.getNumberOfColumns())
561  throw DimensionException("MatrixTools::pow(). nrows != ncols.", A.getNumberOfColumns(), A.getNumberOfRows());
562  vO.resize(p + 1);
563  getId<Matrix>(n, vO[0]);
564  copy(A, vO[1]);
565 
566  for (size_t i = 1; i < p; i++)
567  {
568  mult(vO[i], A, vO[i + 1]);
569  }
570  }
571 
576  template<class Matrix>
577  static std::vector<size_t> whichMax(const Matrix& m)
578  {
579  size_t nrows = m.getNumberOfRows();
580  size_t ncols = m.getNumberOfColumns();
581  std::vector<size_t> pos(2);
582  size_t imax = 0;
583  size_t jmax = 0;
584  double currentMax = std::log(0.);
585  for (size_t i = 0; i < nrows; i++)
586  {
587  for (size_t j = 0; j < ncols; j++)
588  {
589  double currentValue = m(i, j);
590  // cout << currentValue << "\t" << (currentValue > currentMax) << endl;
591  if (currentValue > currentMax)
592  {
593  imax = i;
594  jmax = j;
595  currentMax = currentValue;
596  }
597  }
598  }
599  pos[0] = imax;
600  pos[1] = jmax;
601  return pos;
602  }
603 
608  template<class Matrix>
609  static std::vector<size_t> whichMin(const Matrix& m)
610  {
611  size_t nrows = m.getNumberOfRows();
612  size_t ncols = m.getNumberOfColumns();
613  std::vector<size_t> pos(2);
614  size_t imin = 0;
615  size_t jmin = 0;
616  double currentMin = -std::log(0.);
617  for (size_t i = 0; i < nrows; i++)
618  {
619  for (size_t j = 0; j < ncols; j++)
620  {
621  double currentValue = m(i, j);
622  if (currentValue < currentMin)
623  {
624  imin = i;
625  jmin = j;
626  currentMin = currentValue;
627  }
628  }
629  }
630  pos[0] = imin;
631  pos[1] = jmin;
632  return pos;
633  }
634 
639  template<class Real>
640  static Real max(const Matrix<Real>& m)
641  {
642  size_t nrows = m.getNumberOfRows();
643  size_t ncols = m.getNumberOfColumns();
644  Real currentMax = std::log(0.);
645  for (size_t i = 0; i < nrows; i++)
646  {
647  for (size_t j = 0; j < ncols; j++)
648  {
649  Real currentValue = m(i, j);
650  // cout << currentValue << "\t" << (currentValue > currentMax) << endl;
651  if (currentValue > currentMax)
652  {
653  currentMax = currentValue;
654  }
655  }
656  }
657  return currentMax;
658  }
659 
660 
665  template<class Real>
666  static Real min(const Matrix<Real>& m)
667  {
668  size_t nrows = m.getNumberOfRows();
669  size_t ncols = m.getNumberOfColumns();
670  Real currentMin = -std::log(0.);
671  for (size_t i = 0; i < nrows; i++)
672  {
673  for (size_t j = 0; j < ncols; j++)
674  {
675  Real currentValue = m(i, j);
676  if (currentValue < currentMin)
677  {
678  currentMin = currentValue;
679  }
680  }
681  }
682  return currentMin;
683  }
684 
691  template<class Matrix>
692  static void print(const Matrix& m, std::ostream& out = std::cout)
693  {
694  out << m.getNumberOfRows() << "x" << m.getNumberOfColumns() << std::endl;
695  out << "[" << std::endl;
696  for (size_t i = 0; i < m.getNumberOfRows(); i++)
697  {
698  out << "[";
699  for (size_t j = 0; j < m.getNumberOfColumns() - 1; j++)
700  {
701  out << m(i, j) << ", ";
702  }
703  if (m.getNumberOfColumns() > 0) out << m(i, m.getNumberOfColumns() - 1) << "]" << std::endl;
704  }
705  out << "]" << std::endl;
706  }
707 
716  template<class Matrix>
717  static void print(const Matrix& m, bpp::OutputStream& out, char pIn = '(', char pOut = ')')
718  {
719  out << pIn;
720 
721  for (size_t i = 0; i < m.getNumberOfRows(); i++)
722  {
723  if (i != 0)
724  out << ",";
725 
726  out << pIn;
727  for (size_t j = 0; j < m.getNumberOfColumns() - 1; j++)
728  {
729  out << m(i, j) << ", ";
730  }
731  if (m.getNumberOfColumns() > 0) out << m(i, m.getNumberOfColumns() - 1) << pOut;
732  }
733  out << pOut;
734  }
735 
743  template<class Matrix>
744  static void printForR(const Matrix& m, const std::string& variableName = "x", std::ostream& out = std::cout)
745  {
746  out.precision(12);
747  out << variableName << "<-matrix(c(";
748  for (size_t i = 0; i < m.getNumberOfRows(); i++)
749  {
750  if (i > 0)
751  out << std::endl;
752 
753  for (size_t j = 0; j < m.getNumberOfColumns(); j++)
754  {
755  if (i > 0 || j > 0)
756  out << ", ";
757  out << m(i, j);
758  }
759  }
760  out << "), nrow=" << m.getNumberOfRows() << ", byrow=TRUE)" << std::endl;
761  }
762 
763 
770  template<class Real>
771  static void print(const std::vector<Real>& v, std::ostream& out = std::cout)
772  {
773  out << v.size() << std::endl;
774  out << "[";
775  for (size_t i = 0; i < v.size() - 1; i++)
776  {
777  out << v[i] << ", ";
778  }
779  if (v.size() > 0) out << v[v.size() - 1];
780  out << "]" << std::endl;
781  }
782 
787  template<class Matrix>
788  static bool isSquare(const Matrix& A) { return A.getNumberOfRows() == A.getNumberOfColumns(); }
789 
796  template<class Scalar>
797  static Scalar inv(const Matrix<Scalar>& A, Matrix<Scalar>& O)
798  {
799  if (!isSquare(A)) throw DimensionException("MatrixTools::inv(). Matrix A is not a square matrix.", A.getNumberOfRows(), A.getNumberOfColumns());
802  getId(A.getNumberOfRows(), I);
803  return lu.solve(I, O);
804  }
805 
815  template<class Scalar>
816  static double det(const Matrix<Scalar>& A)
817  {
818  if (!isSquare(A)) throw DimensionException("MatrixTools::det(). Matrix A is not a square matrix.", A.getNumberOfRows(), A.getNumberOfColumns());
820  return lu.det();
821  }
822 
827  template<class MatrixA, class MatrixO>
828  static void transpose(const MatrixA& A, MatrixO& O)
829  {
830  O.resize(A.getNumberOfColumns(), A.getNumberOfRows());
831  for (size_t i = 0; i < A.getNumberOfColumns(); i++)
832  {
833  for (size_t j = 0; j < A.getNumberOfRows(); j++)
834  {
835  O(i, j) = A(j, i);
836  }
837  }
838  }
839 
844  template<class MatrixA>
845  static bool isSymmetric(const MatrixA& A)
846  {
847  if (A.getNumberOfColumns() != A.getNumberOfRows())
848  return false;
849 
850  for (size_t i = 0; i < A.getNumberOfColumns(); i++)
851  {
852  for (size_t j = i + 1; j < A.getNumberOfRows(); j++)
853  {
854  if (A(i, j) != A(j, i))
855  return false;
856  }
857  }
858  return true;
859  }
860 
873  template<class Scalar>
874  static void covar(const Matrix<Scalar>& A, Matrix<Scalar>& O)
875  {
876  size_t r = A.getNumberOfRows();
877  size_t n = A.getNumberOfColumns();
878  O.resize(r, r);
880  transpose(A, tA);
881  mult(A, tA, O);
882  scale(O, 1. / static_cast<double>(n));
883  RowMatrix<Scalar> mean(r, 1);
884  for (size_t i = 0; i < r; i++)
885  {
886  for (size_t j = 0; j < n; j++)
887  {
888  mean(i, 0) += A(i, j);
889  }
890  mean(i, 0) /= static_cast<double>(n);
891  }
892  RowMatrix<Scalar> tMean;
893  transpose(mean, tMean);
894  RowMatrix<Scalar> meanMat;
895  mult(mean, tMean, meanMat);
896  scale(meanMat, -1.);
897  add(O, meanMat);
898  }
899 
908  template<class Scalar>
909  static void kroneckerMult(const Matrix<Scalar>& A, const Matrix<Scalar>& B, Matrix<Scalar>& O, bool check = true)
910  {
911  size_t ncA = A.getNumberOfColumns();
912  size_t nrA = A.getNumberOfRows();
913  size_t nrB = B.getNumberOfRows();
914  size_t ncB = B.getNumberOfColumns();
915 
916  if (check)
917  O.resize(nrA * nrB, ncA * ncB);
918 
919  for (size_t ia = 0; ia < nrA; ia++)
920  {
921  for (size_t ja = 0; ja < ncA; ja++)
922  {
923  Scalar aij = A(ia, ja);
924  for (size_t ib = 0; ib < nrB; ib++)
925  {
926  for (size_t jb = 0; jb < ncB; jb++)
927  {
928  O(ia * nrB + ib, ja * ncB + jb) = aij * B(ib, jb);
929  }
930  }
931  }
932  }
933  }
934 
945  template<class Scalar>
946  static void kroneckerMult(const Matrix<Scalar>& A, size_t dim, const Scalar& v, Matrix<Scalar>& O, bool check = true)
947  {
948  size_t ncA = A.getNumberOfColumns();
949  size_t nrA = A.getNumberOfRows();
950 
951  if (check)
952  O.resize(nrA * dim, ncA * dim);
953 
954  for (size_t ia = 0; ia < nrA; ia++)
955  {
956  for (size_t ja = 0; ja < ncA; ja++)
957  {
958  Scalar aij = A(ia, ja);
959  for (size_t ib = 0; ib < dim; ib++)
960  {
961  for (size_t jb = 0; jb < dim; jb++)
962  {
963  O(ia * dim + ib, ja * dim + jb) = aij * ((ib == jb) ? v : 0);
964  }
965  }
966  }
967  }
968  }
969 
981  template<class Scalar>
982  static void kroneckerMult(const Matrix<Scalar>& A, const Matrix<Scalar>& B, const Scalar& dA, const Scalar& dB, Matrix<Scalar>& O, bool check = true)
983  {
984  size_t ncA = A.getNumberOfColumns();
985  size_t nrA = A.getNumberOfRows();
986  size_t nrB = B.getNumberOfRows();
987  size_t ncB = B.getNumberOfColumns();
988 
989  if (check)
990  O.resize(nrA * nrB, ncA * ncB);
991 
992  for (size_t ia = 0; ia < nrA; ia++)
993  {
994  for (size_t ja = 0; ja < ncA; ja++)
995  {
996  const Scalar& aij = (ia == ja) ? dA : A(ia, ja);
997 
998  for (size_t ib = 0; ib < nrB; ib++)
999  {
1000  for (size_t jb = 0; jb < ncB; jb++)
1001  {
1002  O(ia * nrB + ib, ja * ncB + jb) = aij * ((ib == jb) ? dB : B(ib, jb));
1003  }
1004  }
1005  }
1006  }
1007  }
1008 
1016  template<class Scalar>
1017  static void hadamardMult(const Matrix<Scalar>& A, const Matrix<Scalar>& B, Matrix<Scalar>& O)
1018  {
1019  size_t ncA = A.getNumberOfColumns();
1020  size_t nrA = A.getNumberOfRows();
1021  size_t nrB = B.getNumberOfRows();
1022  size_t ncB = B.getNumberOfColumns();
1023  if (nrA != nrB) throw DimensionException("MatrixTools::hadamardMult(). nrows A != nrows B.", nrA, nrB);
1024  if (ncA != ncB) throw DimensionException("MatrixTools::hadamardMult(). ncols A != ncols B.", ncA, ncB);
1025  O.resize(nrA, ncA);
1026  for (size_t i = 0; i < nrA; i++)
1027  {
1028  for (size_t j = 0; j < ncA; j++)
1029  {
1030  O(i, j) = A(i, j) * B(i, j);
1031  }
1032  }
1033  }
1034 
1045  template<class Scalar>
1046  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)
1047  {
1048  size_t ncA = A.getNumberOfColumns();
1049  size_t nrA = A.getNumberOfRows();
1050  size_t nrB = B.getNumberOfRows();
1051  size_t ncB = B.getNumberOfColumns();
1052  if (nrA != nrB) throw DimensionException("MatrixTools::hadamardMult(). nrows A != nrows B.", nrA, nrB);
1053  if (ncA != ncB) throw DimensionException("MatrixTools::hadamardMult(). ncols A != ncols B.", ncA, ncB);
1054  O.resize(nrA, ncA);
1055  iO.resize(nrA, ncA);
1056  for (size_t i = 0; i < nrA; i++)
1057  {
1058  for (size_t j = 0; j < ncA; j++)
1059  {
1060  O(i, j) = A(i, j) * B(i, j) - iA(i, j) * iB(i, j);
1061  iO(i, j) = iA(i, j) * B(i, j) + A(i, j) * iB(i, j);
1062  }
1063  }
1064  }
1065 
1074  template<class Scalar>
1075  static void hadamardMult(const Matrix<Scalar>& A, const std::vector<Scalar>& B, Matrix<Scalar>& O, bool row = true)
1076  {
1077  size_t ncA = A.getNumberOfColumns();
1078  size_t nrA = A.getNumberOfRows();
1079  size_t sB = B.size();
1080  if (row == true && nrA != sB) throw DimensionException("MatrixTools::hadamardMult(). nrows A != size of B.", nrA, sB);
1081  if (row == false && ncA != sB) throw DimensionException("MatrixTools::hadamardMult(). ncols A != size of B.", ncA, sB);
1082  O.resize(nrA, ncA);
1083  if (row)
1084  {
1085  for (size_t i = 0; i < nrA; i++)
1086  {
1087  for (size_t j = 0; j < ncA; j++)
1088  {
1089  O(i, j) = A(i, j) * B[i];
1090  }
1091  }
1092  }
1093  else
1094  {
1095  for (size_t i = 0; i < nrA; i++)
1096  {
1097  for (size_t j = 0; j < ncA; j++)
1098  {
1099  O(i, j) = A(i, j) * B[j];
1100  }
1101  }
1102  }
1103  }
1104 
1112  template<class Scalar>
1113  static void directSum(const Matrix<Scalar>& A, const Matrix<Scalar>& B, Matrix<Scalar>& O)
1114  {
1115  size_t ncA = A.getNumberOfColumns();
1116  size_t nrA = A.getNumberOfRows();
1117  size_t nrB = B.getNumberOfRows();
1118  size_t ncB = B.getNumberOfColumns();
1119  O.resize(nrA + nrB, ncA + ncB);
1120 
1121  for (size_t ia = 0; ia < nrA; ia++)
1122  {
1123  for (size_t ja = 0; ja < ncA; ja++)
1124  {
1125  O(ia, ja) = A(ia, ja);
1126  }
1127  }
1128 
1129  for (size_t ia = 0; ia < nrA; ia++)
1130  {
1131  for (size_t jb = 0; jb < ncB; jb++)
1132  {
1133  O(ia, ncA + jb) = 0;
1134  }
1135  }
1136 
1137  for (size_t ib = 0; ib < nrB; ib++)
1138  {
1139  for (size_t ja = 0; ja < ncA; ja++)
1140  {
1141  O(nrA + ib, ja) = 0;
1142  }
1143  }
1144 
1145  for (size_t ib = 0; ib < nrB; ib++)
1146  {
1147  for (size_t jb = 0; jb < nrB; jb++)
1148  {
1149  O(nrA + ib, ncA + jb) = B(ib, jb);
1150  }
1151  }
1152  }
1153 
1160  template<class Scalar>
1161  static void directSum(const std::vector< Matrix<Scalar>*>& vA, Matrix<Scalar>& O)
1162  {
1163  size_t nr = 0;
1164  size_t nc = 0;
1165  for (size_t k = 0; k < vA.size(); k++)
1166  {
1167  nr += vA[k]->getNumberOfRows();
1168  nc += vA[k]->getNumberOfColumns();
1169  }
1170  O.resize(nr, nc);
1171  for (size_t k = 0; k < nr; k++)
1172  {
1173  for (size_t k2 = 0; k2 < nc; k2++)
1174  {
1175  O(k, k2) = 0;
1176  }
1177  }
1178 
1179  size_t rk = 0; // Row counter
1180  size_t ck = 0; // Col counter
1181  for (size_t k = 0; k < vA.size(); k++)
1182  {
1183  const Matrix<Scalar>* Ak = vA[k];
1184  for (size_t i = 0; i < Ak->getNumberOfRows(); i++)
1185  {
1186  for (size_t j = 0; j < Ak->getNumberOfColumns(); j++)
1187  {
1188  O(rk + i, ck + j) = (*Ak)(i, j);
1189  }
1190  }
1191  rk += Ak->getNumberOfRows();
1192  ck += Ak->getNumberOfColumns();
1193  }
1194  }
1195 
1202  template<class Scalar>
1203  static void toVVdouble(const Matrix<Scalar>& M, std::vector< std::vector<Scalar>>& vO)
1204  {
1205  size_t n = M.getNumberOfRows();
1206  size_t m = M.getNumberOfColumns();
1207  vO.resize(n);
1208  for (size_t i = 0; i < n; i++)
1209  {
1210  vO[i].resize(m);
1211  for (size_t j = 0; j < m; j++)
1212  {
1213  vO[i][j] = M(i, j);
1214  }
1215  }
1216  }
1217 
1223  template<class Scalar>
1224  static Scalar sumElements(const Matrix<Scalar>& M)
1225  {
1226  Scalar sum = 0;
1227  for (size_t i = 0; i < M.getNumberOfRows(); i++)
1228  {
1229  for (size_t j = 0; j < M.getNumberOfColumns(); j++)
1230  {
1231  sum += M(i, j);
1232  }
1233  }
1234  return sum;
1235  }
1236 
1237 
1252  template<class Scalar>
1253  static Scalar lap(Matrix<Scalar>& assignCost,
1254  std::vector<int>& rowSol,
1255  std::vector<int>& colSol,
1256  std::vector<Scalar>& u,
1257  std::vector<Scalar>& v)
1258  {
1259  size_t dim = assignCost.getNumberOfRows();
1260  if (assignCost.getNumberOfColumns() != dim)
1261  throw Exception("MatrixTools::lap. Cost matrix should be scare.");
1262 
1263  bool unassignedFound;
1264  size_t i, iMin;
1265  size_t numFree = 0, previousNumFree, f, k, freeRow;
1266  int i0;
1267  std::vector<size_t> free(dim); // list of unassigned rows.
1268  std::vector<size_t> pred(dim); // row-predecessor of column in augmenting/alternating path.
1269  size_t j, j1, j2, endOfPath, last, low, up;
1270  std::vector<size_t> colList(dim); // list of columns to be scanned in various ways.
1271  std::vector<short int> matches(dim, 0); // counts how many times a row could be assigned.
1272  Scalar min;
1273  Scalar h;
1274  size_t uMin, uSubMin;
1275  Scalar v2;
1276  std::vector<Scalar> d(dim); // 'cost-distance' in augmenting path calculation.
1277 
1278  // Column reduction
1279  for (j = dim; j > 0; j--) // reverse order gives better results.
1280  {
1281  // find minimum cost over rows.
1282  min = assignCost(0, j - 1);
1283  iMin = 0;
1284  for (i = 1; i < dim; ++i)
1285  {
1286  if (assignCost(i, j - 1) < min)
1287  {
1288  min = assignCost(i, j - 1);
1289  iMin = i;
1290  }
1291  }
1292  v[j - 1] = min;
1293 
1294  if (++matches[iMin] == 1)
1295  {
1296  // init assignment if minimum row assigned for first time.
1297  rowSol[iMin] = static_cast<int>(j - 1);
1298  colSol[j - 1] = static_cast<int>(iMin);
1299  }
1300  else
1301  colSol[j - 1] = -1; // row already assigned, column not assigned.
1302  }
1303 
1304  // Reduction tranfer
1305  for (i = 0; i < dim; i++)
1306  {
1307  if (matches[i] == 0) // fill list of unassigned 'free' rows.
1308  free[numFree++] = i;
1309  else
1310  {
1311  if (matches[i] == 1) // transfer reduction from rows that are assigned once.
1312  {
1313  j1 = static_cast<size_t>(rowSol[i]); // rowSol[i] is >= 0 here
1314  min = -std::log(0);
1315  for (j = 0; j < dim; j++)
1316  {
1317  if (j != j1)
1318  if (assignCost(i, j - 1) - v[j] < min)
1319  min = assignCost(i, j - 1) - v[j - 1];
1320  }
1321  v[j1] = v[j1] - min;
1322  }
1323  }
1324  }
1325 
1326  // Augmenting row reduction
1327  short loopcnt = 0; // do-loop to be done twice.
1328  do
1329  {
1330  loopcnt++;
1331 
1332  // scan all free rows.
1333  // in some cases, a free row may be replaced with another one to be scanned next.
1334  k = 0;
1335  previousNumFree = numFree;
1336  numFree = 0; // start list of rows still free after augmenting row reduction.
1337  while (k < previousNumFree)
1338  {
1339  i = free[k];
1340  k++;
1341 
1342  // find minimum and second minimum reduced cost over columns.
1343  uMin = assignCost(i, 0) - v[0];
1344  j1 = 0;
1345  uSubMin = static_cast<size_t>(-std::log(0));
1346  for (j = 1; j < dim; j++)
1347  {
1348  h = assignCost(i, j) - v[j];
1349  if (h < uSubMin)
1350  {
1351  if (h >= uMin)
1352  {
1353  uSubMin = h;
1354  j2 = j;
1355  }
1356  else
1357  {
1358  uSubMin = uMin;
1359  uMin = h;
1360  j2 = j1;
1361  j1 = j;
1362  }
1363  }
1364  }
1365 
1366  i0 = colSol[j1];
1367  if (uMin < uSubMin)
1368  {
1369  // change the reduction of the minimum column to increase the minimum
1370  // reduced cost in the row to the subminimum.
1371  v[j1] = v[j1] - (uSubMin - uMin);
1372  }
1373  else // minimum and subminimum equal.
1374  {
1375  if (i0 >= 0) // minimum column j1 is assigned.
1376  {
1377  // swap columns j1 and j2, as j2 may be unassigned.
1378  j1 = j2;
1379  i0 = colSol[j2];
1380  }
1381  }
1382 
1383  // (re-)assign i to j1, possibly de-assigning an i0.
1384  rowSol[i] = static_cast<int>(j1);
1385  colSol[j1] = static_cast<int>(i);
1386 
1387  if (i0 >= 0) // minimum column j1 assigned earlier.
1388  {
1389  if (uMin < uSubMin)
1390  {
1391  // put in current k, and go back to that k.
1392  // continue augmenting path i - j1 with i0.
1393  free[--k] = static_cast<size_t>(i0);
1394  }
1395  else
1396  {
1397  // no further augmenting reduction possible.
1398  // store i0 in list of free rows for next phase.
1399  free[numFree++] = static_cast<size_t>(i0);
1400  }
1401  }
1402  }
1403  }
1404  while (loopcnt < 2); // repeat once.
1405 
1406  // Augment solution for each free row.
1407  for (f = 0; f < numFree; f++)
1408  {
1409  freeRow = free[f]; // start row of augmenting path.
1410 
1411  // Dijkstra shortest path algorithm.
1412  // runs until unassigned column added to shortest path tree.
1413  for (j = 0; j < dim; j++)
1414  {
1415  d[j] = assignCost(freeRow, j) - v[j];
1416  pred[j] = freeRow;
1417  colList[j] = j; // init column list.
1418  }
1419 
1420  low = 0; // columns in 0..low-1 are ready, now none.
1421  up = 0; // columns in low..up-1 are to be scanned for current minimum, now none.
1422  // columns in up..dim-1 are to be considered later to find new minimum,
1423  // at this stage the list simply contains all columns
1424  unassignedFound = false;
1425  do
1426  {
1427  if (up == low) // no more columns to be scanned for current minimum.
1428  {
1429  last = low - 1;
1430 
1431  // scan columns for up..dim-1 to find all indices for which new minimum occurs.
1432  // store these indices between low..up-1 (increasing up).
1433  min = d[colList[up++]];
1434  for (k = up; k < dim; k++)
1435  {
1436  j = colList[k];
1437  h = d[j];
1438  if (h <= min)
1439  {
1440  if (h < min) // new minimum.
1441  {
1442  up = low; // restart list at index low.
1443  min = h;
1444  }
1445  // new index with same minimum, put on undex up, and extend list.
1446  colList[k] = colList[up];
1447  colList[up++] = j;
1448  }
1449  }
1450 
1451  // check if any of the minimum columns happens to be unassigned.
1452  // if so, we have an augmenting path right away.
1453  for (k = low; k < up; k++)
1454  {
1455  if (colSol[colList[k]] < 0)
1456  {
1457  endOfPath = colList[k];
1458  unassignedFound = true;
1459  break;
1460  }
1461  }
1462  }
1463 
1464  if (!unassignedFound)
1465  {
1466  // update 'distances' between freerow and all unscanned columns, via next scanned column.
1467  j1 = colList[low];
1468  low++;
1469  i = static_cast<size_t>(colSol[j1]);
1470  h = assignCost(i, j1) - v[j1] - min;
1471 
1472  for (k = up; k < dim; k++)
1473  {
1474  j = colList[k];
1475  v2 = assignCost(i, j) - v[j] - h;
1476  if (v2 < d[j])
1477  {
1478  pred[j] = i;
1479  if (v2 == min) // new column found at same minimum value
1480  {
1481  if (colSol[j] < 0)
1482  {
1483  // if unassigned, shortest augmenting path is complete.
1484  endOfPath = j;
1485  unassignedFound = true;
1486  break;
1487  }
1488  // else add to list to be scanned right away.
1489  else
1490  {
1491  colList[k] = colList[up];
1492  colList[up++] = j;
1493  }
1494  }
1495  d[j] = v2;
1496  }
1497  }
1498  }
1499  }
1500  while (!unassignedFound);
1501 
1502  // update column prices.
1503  for (k = 0; k <= last; k++)
1504  {
1505  j1 = colList[k];
1506  v[j1] = v[j1] + d[j1] - min;
1507  }
1508 
1509  // reset row and column assignments along the alternating path.
1510  do
1511  {
1512  i = pred[endOfPath];
1513  colSol[endOfPath] = static_cast<int>(i);
1514  j1 = endOfPath;
1515  endOfPath = static_cast<size_t>(rowSol[i]);
1516  rowSol[i] = static_cast<int>(j1);
1517  }
1518  while (i != freeRow);
1519  }
1520 
1521  // calculate optimal cost.
1522  Scalar lapCost = 0;
1523  for (i = 0; i < dim; i++)
1524  {
1525  j = static_cast<size_t>(rowSol[i]);
1526  u[i] = assignCost(i, j) - v[j];
1527  lapCost = lapCost + assignCost(i, j);
1528  }
1529 
1530  return lapCost;
1531  }
1532 };
1533 } // end of namespace bpp.
1534 #endif // BPP_NUMERIC_MATRIX_MATRIXTOOLS_H
The matrix template interface.
Definition: Matrix.h:22
static void add(MatrixA &A, const MatrixB &B)
Add matrix B to matrix A.
Definition: MatrixTools.h:414
static void copyUp(const MatrixA &A, MatrixO &O)
O(i,j)=A(i+1,j) and O(nbRow,j)=0.
Definition: MatrixTools.h:55
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:744
static std::vector< T > pow(const std::vector< T > &v1, T &b)
Definition: VectorTools.h:841
static bool isSquare(const Matrix &A)
Definition: MatrixTools.h:788
static void copyDown(const MatrixA &A, MatrixO &O)
O(i,j)=A(i-1,j) and O(0,j)=0.
Definition: MatrixTools.h:79
static void diag(const std::vector< Scalar > &D, Matrix< Scalar > &O)
Definition: MatrixTools.h:120
static void toVVdouble(const Matrix< Scalar > &M, std::vector< std::vector< Scalar >> &vO)
Convert to a vector of vector.
Definition: MatrixTools.h:1203
virtual void resize(size_t nRows, size_t nCols)=0
Resize the matrix.
static Real min(const Matrix< Real > &m)
Definition: MatrixTools.h:666
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:557
static void print(const Matrix &m, std::ostream &out=std::cout)
Print a matrix to a stream.
Definition: MatrixTools.h:692
static std::vector< size_t > whichMin(const Matrix &m)
Definition: MatrixTools.h:609
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:1075
static bool isSymmetric(const MatrixA &A)
Definition: MatrixTools.h:845
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:36
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:377
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:1046
static void exp(const Matrix< Scalar > &A, Matrix< Scalar > &O)
Perform matrix exponentiation using diagonalization.
Definition: MatrixTools.h:536
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:331
Matrix storage by row.
Definition: Matrix.h:92
static void fillDiag(Matrix &M, Scalar x)
Set all diagonal elements in M to value x.
Definition: MatrixTools.h:183
static double exp(const T &x)
Definition: VectorTools.h:787
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:1113
static void print(const Matrix &m, bpp::OutputStream &out, char pIn='(', char pOut=')')
Print a matrix to a stream.
Definition: MatrixTools.h:717
static void diag(const Matrix< Scalar > &M, std::vector< Scalar > &O)
Definition: MatrixTools.h:151
virtual size_t getNumberOfColumns() const =0
const RowMatrix< Real > & getV() const
Return the eigenvector matrix.
Definition: EigenValue.h:1131
static Scalar inv(const Matrix< Scalar > &A, Matrix< Scalar > &O)
Definition: MatrixTools.h:797
static void getId(size_t n, Matrix &O)
Get a identity matrix of a given size.
Definition: MatrixTools.h:103
static Scalar sumElements(const Matrix< Scalar > &M)
Sum all elements in M.
Definition: MatrixTools.h:1224
static Real max(const Matrix< Real > &m)
Definition: MatrixTools.h:640
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:253
static std::vector< size_t > whichMax(const Matrix &m)
Definition: MatrixTools.h:577
static void mult(const Matrix< Scalar > &A, const Matrix< Scalar > &B, Matrix< Scalar > &O)
Definition: MatrixTools.h:221
static void pow(const Matrix &A, size_t p, Matrix &O)
Compute the power of a given matrix.
Definition: MatrixTools.h:472
Computes eigenvalues and eigenvectors of a real (non-complex) matrix.
Definition: EigenValue.h:69
OutputStream interface.
Definition: OutputStream.h:29
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:909
LU Decomposition.
static void directSum(const std::vector< Matrix< Scalar > *> &vA, Matrix< Scalar > &O)
Compute the direct sum of n row matrices.
Definition: MatrixTools.h:1161
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:514
static void transpose(const MatrixA &A, MatrixO &O)
Definition: MatrixTools.h:828
Exception base class. Overload exception constructor (to control the exceptions mechanism). Destructor is already virtual (from std::exception)
Definition: Exceptions.h:20
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:201
static void diag(const Scalar x, size_t n, Matrix< Scalar > &O)
Definition: MatrixTools.h:136
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:1017
const std::vector< Real > & getRealEigenValues() const
Return the real parts of the eigenvalues.
Definition: EigenValue.h:1138
static void print(const std::vector< Real > &v, std::ostream &out=std::cout)
Print a vector to a stream.
Definition: MatrixTools.h:771
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:290
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:946
virtual size_t getNumberOfRows() const =0
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:982
Exception thrown when a dimension problem occured.
static void fill(Matrix &M, Scalar x)
Set all elements in M to value x.
Definition: MatrixTools.h:166
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:1253
static void add(MatrixA &A, Scalar &x, const MatrixB &B)
Add matrix x.B to matrix A.
Definition: MatrixTools.h:442
static void covar(const Matrix< Scalar > &A, Matrix< Scalar > &O)
Compute the variance-covariance matrix of an input matrix.
Definition: MatrixTools.h:874
Functions dealing with matrices.
Definition: MatrixTools.h:22
static double det(const Matrix< Scalar > &A)
Get determinant of a square matrix.
Definition: MatrixTools.h:816