5 #ifndef BPP_NUMERIC_MATRIX_MATRIXTOOLS_H 6 #define BPP_NUMERIC_MATRIX_MATRIXTOOLS_H 11 #include "../../Io/OutputStream.h" 12 #include "../VectorTools.h" 35 template<
class MatrixA,
class MatrixO>
36 static void copy(
const MatrixA& A, MatrixO& O)
38 O.resize(A.getNumberOfRows(), A.getNumberOfColumns());
39 for (
size_t i = 0; i < A.getNumberOfRows(); i++)
41 for (
size_t j = 0; j < A.getNumberOfColumns(); j++)
54 template<
class MatrixA,
class MatrixO>
55 static void copyUp(
const MatrixA& A, MatrixO& O)
57 size_t nr(A.getNumberOfRows()), nc(A.getNumberOfColumns());
59 for (
size_t i = 0; i < nr - 1; i++)
61 for (
size_t j = 0; j < nc; j++)
63 O(i, j) = A(i + 1, j);
66 for (
size_t j = 0; j < nc; j++)
78 template<
class MatrixA,
class MatrixO>
79 static void copyDown(
const MatrixA& A, MatrixO& O)
81 size_t nr(A.getNumberOfRows()), nc(A.getNumberOfColumns());
83 for (
size_t i = 1; i < nr; i++)
85 for (
size_t j = 0; j < nc; j++)
87 O(i, j) = A(i - 1, j);
90 for (
size_t j = 0; j < nc; j++)
102 template<
class Matrix>
106 for (
size_t i = 0; i < n; i++)
108 for (
size_t j = 0; j < n; j++)
110 O(i, j) = (i == j) ? 1 : 0;
119 template<
class Scalar>
124 for (
size_t i = 0; i < n; i++)
126 for (
size_t j = 0; j < n; j++) { O(i, j) = (i == j) ? D[i] : 0;}
135 template<
class Scalar>
139 for (
size_t i = 0; i < n; i++)
141 for (
size_t j = 0; j < n; j++) { O(i, j) = (i == j) ? x : 0;}
150 template<
class Scalar>
155 if (nc != nr)
throw DimensionException(
"MatrixTools::diag(). M must be a square matrix.", nr, nc);
157 for (
size_t i = 0; i < nc; i++) { O[i] = M(i, i);}
165 template<
class Matrix,
class Scalar>
182 template<
class Matrix,
class Scalar>
200 template<
class Matrix,
class Scalar>
203 if ((a == 1) && (b == 0))
210 A(i, j) = a * A(i, j) + b;
220 template<
class Scalar>
227 if (ncA != nrB)
throw DimensionException(
"MatrixTools::mult(). nrows B != ncols A.", nrB, ncA);
229 for (
size_t i = 0; i < nrA; i++)
231 for (
size_t j = 0; j < ncB; j++)
234 for (
size_t k = 0; k < ncA; k++)
236 O(i, j) += A(i, k) * B(k, j);
252 template<
class Scalar>
259 if (ncA != nrB)
throw DimensionException(
"MatrixTools::mult(). nrows B != ncols A.", nrB, ncA);
262 for (
size_t i = 0; i < nrA; i++)
264 for (
size_t j = 0; j < ncB; j++)
268 for (
size_t k = 0; k < ncA; k++)
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);
289 template<
class Scalar>
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);
299 for (
size_t i = 0; i < nrA; i++)
301 for (
size_t j = 0; j < ncB; j++)
304 for (
size_t k = 0; k < ncA; k++)
306 O(i, j) += A(i, k) * B(k, j) * D[k];
330 template<
class Scalar>
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);
340 Scalar ab, iaib, iab, aib;
342 for (
size_t i = 0; i < nrA; i++)
344 for (
size_t j = 0; j < ncB; j++)
348 for (
size_t k = 0; k < ncA; k++)
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);
353 O(i, j) += ab * D[k] - aib * iD[k];
354 iO(i, j) += ab * iD[k] + aib * D[k];
376 template<
class Scalar>
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);
388 for (
size_t i = 0; i < nrA; i++)
390 for (
size_t j = 0; j < ncB; j++)
392 O(i, j) = A(i, 0) * D[0] * B(0, j);
394 O(i, j) += A(i, 0) * U[0] * B(1, j);
395 for (
size_t k = 1; k < ncA - 1; k++)
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));
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);
413 template<
class MatrixA,
class MatrixB>
414 static void add(MatrixA& A,
const MatrixB& B)
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);
424 for (
size_t i = 0; i < nrA; i++)
426 for (
size_t j = 0; j < ncA; j++)
441 template<
class MatrixA,
class MatrixB,
class Scalar>
442 static void add(MatrixA& A, Scalar& x,
const MatrixB& B)
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);
451 for (
size_t i = 0; i < nrA; i++)
453 for (
size_t j = 0; j < ncA; j++)
455 A(i, j) += x * B(i, j);
471 template<
class Matrix>
496 pow(A, (p - 1) / 2, tmp);
513 template<
class Scalar>
520 rightEV = eigen.
getV();
521 inv(rightEV, leftEV);
535 template<
class Scalar>
542 rightEV = eigen.
getV();
543 inv(rightEV, leftEV);
556 template<
class Matrix,
class Scalar>
563 getId<Matrix>(n, vO[0]);
566 for (
size_t i = 1; i < p; i++)
568 mult(vO[i], A, vO[i + 1]);
576 template<
class Matrix>
581 std::vector<size_t> pos(2);
584 double currentMax = std::log(0.);
585 for (
size_t i = 0; i < nrows; i++)
587 for (
size_t j = 0; j < ncols; j++)
589 double currentValue = m(i, j);
591 if (currentValue > currentMax)
595 currentMax = currentValue;
608 template<
class Matrix>
613 std::vector<size_t> pos(2);
616 double currentMin = -std::log(0.);
617 for (
size_t i = 0; i < nrows; i++)
619 for (
size_t j = 0; j < ncols; j++)
621 double currentValue = m(i, j);
622 if (currentValue < currentMin)
626 currentMin = currentValue;
644 Real currentMax = std::log(0.);
645 for (
size_t i = 0; i < nrows; i++)
647 for (
size_t j = 0; j < ncols; j++)
649 Real currentValue = m(i, j);
651 if (currentValue > currentMax)
653 currentMax = currentValue;
670 Real currentMin = -std::log(0.);
671 for (
size_t i = 0; i < nrows; i++)
673 for (
size_t j = 0; j < ncols; j++)
675 Real currentValue = m(i, j);
676 if (currentValue < currentMin)
678 currentMin = currentValue;
691 template<
class Matrix>
695 out <<
"[" << std::endl;
701 out << m(i, j) <<
", ";
705 out <<
"]" << std::endl;
716 template<
class Matrix>
729 out << m(i, j) <<
", ";
743 template<
class Matrix>
744 static void printForR(
const Matrix& m,
const std::string& variableName =
"x", std::ostream& out = std::cout)
747 out << variableName <<
"<-matrix(c(";
760 out <<
"), nrow=" << m.
getNumberOfRows() <<
", byrow=TRUE)" << std::endl;
771 static void print(
const std::vector<Real>& v, std::ostream& out = std::cout)
773 out << v.size() << std::endl;
775 for (
size_t i = 0; i < v.size() - 1; i++)
779 if (v.size() > 0) out << v[v.size() - 1];
780 out <<
"]" << std::endl;
787 template<
class Matrix>
796 template<
class Scalar>
803 return lu.solve(I, O);
815 template<
class Scalar>
827 template<
class MatrixA,
class MatrixO>
830 O.resize(A.getNumberOfColumns(), A.getNumberOfRows());
831 for (
size_t i = 0; i < A.getNumberOfColumns(); i++)
833 for (
size_t j = 0; j < A.getNumberOfRows(); j++)
844 template<
class MatrixA>
847 if (A.getNumberOfColumns() != A.getNumberOfRows())
850 for (
size_t i = 0; i < A.getNumberOfColumns(); i++)
852 for (
size_t j = i + 1; j < A.getNumberOfRows(); j++)
854 if (A(i, j) != A(j, i))
873 template<
class Scalar>
882 scale(O, 1. / static_cast<double>(n));
884 for (
size_t i = 0; i < r; i++)
886 for (
size_t j = 0; j < n; j++)
888 mean(i, 0) += A(i, j);
890 mean(i, 0) /=
static_cast<double>(n);
895 mult(mean, tMean, meanMat);
908 template<
class Scalar>
917 O.
resize(nrA * nrB, ncA * ncB);
919 for (
size_t ia = 0; ia < nrA; ia++)
921 for (
size_t ja = 0; ja < ncA; ja++)
923 Scalar aij = A(ia, ja);
924 for (
size_t ib = 0; ib < nrB; ib++)
926 for (
size_t jb = 0; jb < ncB; jb++)
928 O(ia * nrB + ib, ja * ncB + jb) = aij * B(ib, jb);
945 template<
class Scalar>
952 O.
resize(nrA * dim, ncA * dim);
954 for (
size_t ia = 0; ia < nrA; ia++)
956 for (
size_t ja = 0; ja < ncA; ja++)
958 Scalar aij = A(ia, ja);
959 for (
size_t ib = 0; ib < dim; ib++)
961 for (
size_t jb = 0; jb < dim; jb++)
963 O(ia * dim + ib, ja * dim + jb) = aij * ((ib == jb) ? v : 0);
981 template<
class Scalar>
990 O.
resize(nrA * nrB, ncA * ncB);
992 for (
size_t ia = 0; ia < nrA; ia++)
994 for (
size_t ja = 0; ja < ncA; ja++)
996 const Scalar& aij = (ia == ja) ? dA : A(ia, ja);
998 for (
size_t ib = 0; ib < nrB; ib++)
1000 for (
size_t jb = 0; jb < ncB; jb++)
1002 O(ia * nrB + ib, ja * ncB + jb) = aij * ((ib == jb) ? dB : B(ib, jb));
1016 template<
class Scalar>
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);
1026 for (
size_t i = 0; i < nrA; i++)
1028 for (
size_t j = 0; j < ncA; j++)
1030 O(i, j) = A(i, j) * B(i, j);
1045 template<
class Scalar>
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);
1056 for (
size_t i = 0; i < nrA; i++)
1058 for (
size_t j = 0; j < ncA; j++)
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);
1074 template<
class Scalar>
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);
1085 for (
size_t i = 0; i < nrA; i++)
1087 for (
size_t j = 0; j < ncA; j++)
1089 O(i, j) = A(i, j) * B[i];
1095 for (
size_t i = 0; i < nrA; i++)
1097 for (
size_t j = 0; j < ncA; j++)
1099 O(i, j) = A(i, j) * B[j];
1112 template<
class Scalar>
1119 O.
resize(nrA + nrB, ncA + ncB);
1121 for (
size_t ia = 0; ia < nrA; ia++)
1123 for (
size_t ja = 0; ja < ncA; ja++)
1125 O(ia, ja) = A(ia, ja);
1129 for (
size_t ia = 0; ia < nrA; ia++)
1131 for (
size_t jb = 0; jb < ncB; jb++)
1133 O(ia, ncA + jb) = 0;
1137 for (
size_t ib = 0; ib < nrB; ib++)
1139 for (
size_t ja = 0; ja < ncA; ja++)
1141 O(nrA + ib, ja) = 0;
1145 for (
size_t ib = 0; ib < nrB; ib++)
1147 for (
size_t jb = 0; jb < nrB; jb++)
1149 O(nrA + ib, ncA + jb) = B(ib, jb);
1160 template<
class Scalar>
1165 for (
size_t k = 0; k < vA.size(); k++)
1167 nr += vA[k]->getNumberOfRows();
1168 nc += vA[k]->getNumberOfColumns();
1171 for (
size_t k = 0; k < nr; k++)
1173 for (
size_t k2 = 0; k2 < nc; k2++)
1181 for (
size_t k = 0; k < vA.size(); k++)
1188 O(rk + i, ck + j) = (*Ak)(i, j);
1202 template<
class Scalar>
1208 for (
size_t i = 0; i < n; i++)
1211 for (
size_t j = 0; j < m; j++)
1223 template<
class Scalar>
1252 template<
class Scalar>
1254 std::vector<int>& rowSol,
1255 std::vector<int>& colSol,
1256 std::vector<Scalar>& u,
1257 std::vector<Scalar>& v)
1261 throw Exception(
"MatrixTools::lap. Cost matrix should be scare.");
1263 bool unassignedFound;
1265 size_t numFree = 0, previousNumFree, f, k, freeRow;
1267 std::vector<size_t> free(dim);
1268 std::vector<size_t> pred(dim);
1269 size_t j, j1, j2, endOfPath, last, low, up;
1270 std::vector<size_t> colList(dim);
1271 std::vector<short int> matches(dim, 0);
1274 size_t uMin, uSubMin;
1276 std::vector<Scalar> d(dim);
1279 for (j = dim; j > 0; j--)
1282 min = assignCost(0, j - 1);
1284 for (i = 1; i < dim; ++i)
1286 if (assignCost(i, j - 1) < min)
1288 min = assignCost(i, j - 1);
1294 if (++matches[iMin] == 1)
1297 rowSol[iMin] =
static_cast<int>(j - 1);
1298 colSol[j - 1] =
static_cast<int>(iMin);
1305 for (i = 0; i < dim; i++)
1307 if (matches[i] == 0)
1308 free[numFree++] = i;
1311 if (matches[i] == 1)
1313 j1 =
static_cast<size_t>(rowSol[i]);
1315 for (j = 0; j < dim; j++)
1318 if (assignCost(i, j - 1) - v[j] < min)
1319 min = assignCost(i, j - 1) - v[j - 1];
1321 v[j1] = v[j1] -
min;
1335 previousNumFree = numFree;
1337 while (k < previousNumFree)
1343 uMin = assignCost(i, 0) - v[0];
1345 uSubMin =
static_cast<size_t>(-std::log(0));
1346 for (j = 1; j < dim; j++)
1348 h = assignCost(i, j) - v[j];
1371 v[j1] = v[j1] - (uSubMin - uMin);
1384 rowSol[i] =
static_cast<int>(j1);
1385 colSol[j1] =
static_cast<int>(i);
1393 free[--k] =
static_cast<size_t>(i0);
1399 free[numFree++] =
static_cast<size_t>(i0);
1404 while (loopcnt < 2);
1407 for (f = 0; f < numFree; f++)
1413 for (j = 0; j < dim; j++)
1415 d[j] = assignCost(freeRow, j) - v[j];
1424 unassignedFound =
false;
1433 min = d[colList[up++]];
1434 for (k = up; k < dim; k++)
1446 colList[k] = colList[up];
1453 for (k = low; k < up; k++)
1455 if (colSol[colList[k]] < 0)
1457 endOfPath = colList[k];
1458 unassignedFound =
true;
1464 if (!unassignedFound)
1469 i =
static_cast<size_t>(colSol[j1]);
1470 h = assignCost(i, j1) - v[j1] -
min;
1472 for (k = up; k < dim; k++)
1475 v2 = assignCost(i, j) - v[j] - h;
1485 unassignedFound =
true;
1491 colList[k] = colList[up];
1500 while (!unassignedFound);
1503 for (k = 0; k <= last; k++)
1506 v[j1] = v[j1] + d[j1] -
min;
1512 i = pred[endOfPath];
1513 colSol[endOfPath] =
static_cast<int>(i);
1515 endOfPath =
static_cast<size_t>(rowSol[i]);
1516 rowSol[i] =
static_cast<int>(j1);
1518 while (i != freeRow);
1523 for (i = 0; i < dim; i++)
1525 j =
static_cast<size_t>(rowSol[i]);
1526 u[i] = assignCost(i, j) - v[j];
1527 lapCost = lapCost + assignCost(i, j);
1534 #endif // BPP_NUMERIC_MATRIX_MATRIXTOOLS_H The matrix template interface.
virtual void resize(size_t nRows, size_t nCols)=0
Resize the matrix.
virtual size_t getNumberOfColumns() const =0
const RowMatrix< Real > & getV() const
Return the eigenvector matrix.
Computes eigenvalues and eigenvectors of a real (non-complex) matrix.
Exception base class. Overload exception constructor (to control the exceptions mechanism). Destructor is already virtual (from std::exception)
const std::vector< Real > & getRealEigenValues() const
Return the real parts of the eigenvalues.
virtual size_t getNumberOfRows() const =0
Exception thrown when a dimension problem occured.