diff --git a/Eigen/Core b/Eigen/Core index db2fde30d..0cb89bb60 100644 --- a/Eigen/Core +++ b/Eigen/Core @@ -44,7 +44,7 @@ namespace Eigen { #include "src/Core/Dot.h" #include "src/Core/Product.h" #include "src/Core/DiagonalProduct.h" -#include "src/Core/InverseProduct.h" +#include "src/Core/SolveTriangular.h" #include "src/Core/MapBase.h" #include "src/Core/Map.h" #include "src/Core/Block.h" diff --git a/Eigen/src/Cholesky/Cholesky.h b/Eigen/src/Cholesky/Cholesky.h index 48145fa46..af5dfb430 100644 --- a/Eigen/src/Cholesky/Cholesky.h +++ b/Eigen/src/Cholesky/Cholesky.h @@ -141,7 +141,7 @@ typename Derived::Eval Cholesky::solve(const MatrixBase &b) const int size = m_matrix.rows(); ei_assert(size==b.rows()); - return m_matrix.adjoint().template part().inverseProduct(matrixL().inverseProduct(b)); + return m_matrix.adjoint().template part().solveTriangular(matrixL().solveTriangular(b)); } /** \cholesky_module diff --git a/Eigen/src/Cholesky/CholeskyWithoutSquareRoot.h b/Eigen/src/Cholesky/CholeskyWithoutSquareRoot.h index 1eb9904fc..69dcdb8a2 100644 --- a/Eigen/src/Cholesky/CholeskyWithoutSquareRoot.h +++ b/Eigen/src/Cholesky/CholeskyWithoutSquareRoot.h @@ -148,9 +148,9 @@ typename Derived::Eval CholeskyWithoutSquareRoot::solve(const Matrix ei_assert(size==b.rows()); return m_matrix.adjoint().template part() - .inverseProduct( + .solveTriangular( (matrixL() - .inverseProduct(b)) + .solveTriangular(b)) .cwise()/m_matrix.diagonal() ); } diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index 25a4c8b08..8ad54e62a 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -320,10 +320,10 @@ template class MatrixBase Derived& operator*=(const MatrixBase& other); template - typename OtherDerived::Eval inverseProduct(const MatrixBase& other) const; + typename OtherDerived::Eval solveTriangular(const MatrixBase& other) const; template - void inverseProductInPlace(MatrixBase& other) const; + void solveTriangularInPlace(MatrixBase& other) const; template diff --git a/Eigen/src/Core/InverseProduct.h b/Eigen/src/Core/SolveTriangular.h similarity index 96% rename from Eigen/src/Core/InverseProduct.h rename to Eigen/src/Core/SolveTriangular.h index cd27c4ddf..a9867e63c 100755 --- a/Eigen/src/Core/InverseProduct.h +++ b/Eigen/src/Core/SolveTriangular.h @@ -212,13 +212,13 @@ struct ei_trisolve_selector } }; -/** "in-place" version of MatrixBase::inverseProduct() where the result is written in \a other +/** "in-place" version of MatrixBase::solveTriangular() where the result is written in \a other * - * \sa inverseProduct() + * \sa solveTriangular() */ template template -void MatrixBase::inverseProductInPlace(MatrixBase& other) const +void MatrixBase::solveTriangularInPlace(MatrixBase& other) const { ei_assert(derived().cols() == derived().rows()); ei_assert(derived().cols() == other.rows()); @@ -244,10 +244,10 @@ void MatrixBase::inverseProductInPlace(MatrixBase& other) */ template template -typename OtherDerived::Eval MatrixBase::inverseProduct(const MatrixBase& other) const +typename OtherDerived::Eval MatrixBase::solveTriangular(const MatrixBase& other) const { typename OtherDerived::Eval res(other); - inverseProductInPlace(res); + solveTriangularInPlace(res); return res; } diff --git a/Eigen/src/LU/LU.h b/Eigen/src/LU/LU.h index a7d5cd2e8..59f1051be 100644 --- a/Eigen/src/LU/LU.h +++ b/Eigen/src/LU/LU.h @@ -257,7 +257,7 @@ void LU::computeKernel(Matrix() - .inverseProductInPlace(y); + .solveTriangularInPlace(y); for(int i = 0; i < m_rank; i++) result->row(m_q.coeff(i)) = y.row(i); @@ -309,7 +309,7 @@ bool LU::solve( l.setZero(); l.corner(Eigen::TopLeft,rows,smalldim) = m_lu.corner(Eigen::TopLeft,rows,smalldim); - l.template marked().inverseProductInPlace(c); + l.template marked().solveTriangularInPlace(c); // Step 3 if(!isSurjective()) @@ -326,7 +326,7 @@ bool LU::solve( d(c.corner(TopLeft, m_rank, c.cols())); m_lu.corner(TopLeft, m_rank, m_rank) .template marked() - .inverseProductInPlace(d); + .solveTriangularInPlace(d); // Step 4 result->resize(m_lu.cols(), b.cols()); diff --git a/Eigen/src/QR/SelfAdjointEigenSolver.h b/Eigen/src/QR/SelfAdjointEigenSolver.h index 2d833bf13..d366bafc7 100644 --- a/Eigen/src/QR/SelfAdjointEigenSolver.h +++ b/Eigen/src/QR/SelfAdjointEigenSolver.h @@ -230,17 +230,17 @@ compute(const MatrixType& matA, const MatrixType& matB, bool computeEigenvectors Cholesky cholB(matB); // compute C = inv(U') A inv(U) - MatrixType matC = cholB.matrixL().inverseProduct(matA); + MatrixType matC = cholB.matrixL().solveTriangular(matA); // FIXME since we currently do not support A * inv(U), // let's do (inv(U') A')' : - matC = (cholB.matrixL().inverseProduct(matC.adjoint())).adjoint(); + matC = (cholB.matrixL().solveTriangular(matC.adjoint())).adjoint(); compute(matC, computeEigenvectors); if (computeEigenvectors) { // transform back the eigen vectors: evecs = inv(U) * evecs - m_eivec = cholB.matrixL().adjoint().template marked().inverseProduct(m_eivec); + m_eivec = cholB.matrixL().adjoint().template marked().solveTriangular(m_eivec); } } diff --git a/Eigen/src/Sparse/SparseMatrixBase.h b/Eigen/src/Sparse/SparseMatrixBase.h index cc43e7e07..e36e7e760 100644 --- a/Eigen/src/Sparse/SparseMatrixBase.h +++ b/Eigen/src/Sparse/SparseMatrixBase.h @@ -142,7 +142,7 @@ class SparseMatrixBase : public MatrixBase } template - OtherDerived inverseProduct(const MatrixBase& other) const; + OtherDerived solveTriangular(const MatrixBase& other) const; protected: diff --git a/Eigen/src/Sparse/TriangularSolver.h b/Eigen/src/Sparse/TriangularSolver.h index 41361a471..45679fe86 100644 --- a/Eigen/src/Sparse/TriangularSolver.h +++ b/Eigen/src/Sparse/TriangularSolver.h @@ -155,7 +155,7 @@ struct ei_sparse_trisolve_selector template template -OtherDerived SparseMatrixBase::inverseProduct(const MatrixBase& other) const +OtherDerived SparseMatrixBase::solveTriangular(const MatrixBase& other) const { ei_assert(derived().cols() == other.rows()); ei_assert(!(Flags & ZeroDiagBit)); diff --git a/bench/benchCholesky.cpp b/bench/benchCholesky.cpp index dd0c7f83b..f64b61b71 100644 --- a/bench/benchCholesky.cpp +++ b/bench/benchCholesky.cpp @@ -18,7 +18,7 @@ using namespace Eigen; #endif #ifndef TRIES -#define TRIES 4 +#define TRIES 10 #endif typedef float Scalar; @@ -29,6 +29,13 @@ __attribute__ ((noinline)) void benchCholesky(const MatrixType& m) int rows = m.rows(); int cols = m.cols(); + int cost = 0; + for (int j=0; j(size2); - Scalar* b = ei_aligned_malloc(size2); + Scalar* b = ei_aligned_malloc(size2+4)+1; Scalar* c = ei_aligned_malloc(size2); for (int i=0; i2 ; --innersize) { if (size2%innersize==0) { int outersize = size2/innersize; - MatrixXf ma = MatrixXf::map(a, innersize, outersize ); - MatrixXf mb = MatrixXf::map(b, innersize, outersize ); - MatrixXf mc = MatrixXf::map(c, innersize, outersize ); + MatrixXf ma = Map(a, innersize, outersize ); + MatrixXf mb = Map(b, innersize, outersize ); + MatrixXf mc = Map(c, innersize, outersize ); timer.reset(); for (int k=0; k<3; ++k) { @@ -60,9 +60,9 @@ int main(int argc, char* argv[]) } } - VectorXf va = VectorXf::map(a, size2); - VectorXf vb = VectorXf::map(b, size2); - VectorXf vc = VectorXf::map(c, size2); + VectorXf va = Map(a, size2); + VectorXf vb = Map(b, size2); + VectorXf vc = Map(c, size2); timer.reset(); for (int k=0; k<3; ++k) { @@ -95,40 +95,40 @@ void benchVec(Scalar* a, Scalar* b, Scalar* c, int size) for (int k=0; k().inverseProduct(B); + X = L.template marked().solveTriangular(B); } static inline void cholesky(const gene_matrix & X, gene_matrix & C, int N){ @@ -146,6 +146,7 @@ public : static inline void lu_decomp(const gene_matrix & X, gene_matrix & C, int N){ C = X.lu().matrixLU(); +// C = X.inverse(); } static inline void tridiagonalization(const gene_matrix & X, gene_matrix & C, int N){ diff --git a/doc/snippets/MatrixBase_marked.cpp b/doc/snippets/MatrixBase_marked.cpp index f367def43..d4c11c6fc 100644 --- a/doc/snippets/MatrixBase_marked.cpp +++ b/doc/snippets/MatrixBase_marked.cpp @@ -6,4 +6,4 @@ n.part() *= 2; cout << "Here is the matrix n:" << endl << n << endl; cout << "And now here is m.inverse()*n, taking advantage of the fact that" " m is upper-triangular:" << endl - << m.marked().inverseProduct(n); + << m.marked().solveTriangular(n); diff --git a/test/submatrices.cpp b/test/submatrices.cpp index f0475f99f..cc00ae810 100644 --- a/test/submatrices.cpp +++ b/test/submatrices.cpp @@ -66,6 +66,7 @@ template void submatrices(const MatrixType& m) m2 = MatrixType::Random(rows, cols), m3(rows, cols), mzero = MatrixType::Zero(rows, cols), + ones = MatrixType::Ones(rows, cols), identity = Matrix ::Identity(rows, rows), square = Matrix @@ -121,6 +122,14 @@ template void submatrices(const MatrixType& m) Matrix b = m1.template block(3,3); VERIFY_IS_APPROX(b, m1.block(3,3,BlockRows,BlockCols)); } + + // stress some basic stuffs with block matrices + VERIFY(ones.col(c1).sum() == Scalar(rows)); + VERIFY(ones.row(r1).sum() == Scalar(cols)); + + VERIFY(ones.col(c1).dot(ones.col(c2)) == Scalar(rows)); + std::cerr << ones.row(r1).dot(ones.row(r2)) << " == " << cols << "\n"; + VERIFY(ones.row(r1).dot(ones.row(r2)) == Scalar(cols)); } void test_submatrices() @@ -131,5 +140,6 @@ void test_submatrices() CALL_SUBTEST( submatrices(MatrixXcf(3, 3)) ); CALL_SUBTEST( submatrices(MatrixXi(8, 12)) ); CALL_SUBTEST( submatrices(MatrixXcd(20, 20)) ); + CALL_SUBTEST( submatrices(MatrixXf(20, 20)) ); } } diff --git a/test/triangular.cpp b/test/triangular.cpp index a1e5383bc..de3b85537 100644 --- a/test/triangular.cpp +++ b/test/triangular.cpp @@ -80,15 +80,15 @@ template void triangular(const MatrixType& m) // test back and forward subsitution m3 = m1.template part(); - VERIFY(m3.template marked().inverseProduct(m3).cwise().abs().isIdentity(test_precision())); + VERIFY(m3.template marked().solveTriangular(m3).cwise().abs().isIdentity(test_precision())); m3 = m1.template part(); - VERIFY(m3.template marked().inverseProduct(m3).cwise().abs().isIdentity(test_precision())); + VERIFY(m3.template marked().solveTriangular(m3).cwise().abs().isIdentity(test_precision())); // FIXME these tests failed due to numerical issues // m1 = MatrixType::Random(rows, cols); - // VERIFY_IS_APPROX(m1.template part().eval() * (m1.template part().inverseProduct(m2)), m2); - // VERIFY_IS_APPROX(m1.template part().eval() * (m1.template part().inverseProduct(m2)), m2); + // VERIFY_IS_APPROX(m1.template part().eval() * (m1.template part().solveTriangular(m2)), m2); + // VERIFY_IS_APPROX(m1.template part().eval() * (m1.template part().solveTriangular(m2)), m2); VERIFY((m1.template part() * m2.template part()).isUpper());