mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
merge
This commit is contained in:
@@ -95,7 +95,7 @@ template<typename MatrixType> void cholesky(const MatrixType& m)
|
||||
|
||||
{
|
||||
LLT<SquareMatrixType,Lower> chollo(symmLo);
|
||||
VERIFY_IS_APPROX(symm, chollo.matrixL().toDenseMatrix() * chollo.matrixL().adjoint().toDenseMatrix());
|
||||
VERIFY_IS_APPROX(symm, chollo.reconstructedMatrix());
|
||||
vecX = chollo.solve(vecB);
|
||||
VERIFY_IS_APPROX(symm * vecX, vecB);
|
||||
matX = chollo.solve(matB);
|
||||
@@ -103,7 +103,7 @@ template<typename MatrixType> void cholesky(const MatrixType& m)
|
||||
|
||||
// test the upper mode
|
||||
LLT<SquareMatrixType,Upper> cholup(symmUp);
|
||||
VERIFY_IS_APPROX(symm, cholup.matrixL().toDenseMatrix() * cholup.matrixL().adjoint().toDenseMatrix());
|
||||
VERIFY_IS_APPROX(symm, cholup.reconstructedMatrix());
|
||||
vecX = cholup.solve(vecB);
|
||||
VERIFY_IS_APPROX(symm * vecX, vecB);
|
||||
matX = cholup.solve(matB);
|
||||
@@ -119,8 +119,7 @@ template<typename MatrixType> void cholesky(const MatrixType& m)
|
||||
|
||||
{
|
||||
LDLT<SquareMatrixType> ldlt(symm);
|
||||
// TODO(keir): This doesn't make sense now that LDLT pivots.
|
||||
//VERIFY_IS_APPROX(symm, ldlt.matrixL() * ldlt.vectorD().asDiagonal() * ldlt.matrixL().adjoint());
|
||||
VERIFY_IS_APPROX(symm, ldlt.reconstructedMatrix());
|
||||
vecX = ldlt.solve(vecB);
|
||||
VERIFY_IS_APPROX(symm * vecX, vecB);
|
||||
matX = ldlt.solve(matB);
|
||||
|
||||
@@ -42,7 +42,7 @@ template<typename MatrixType> void inverse(const MatrixType& m)
|
||||
m2(rows, cols),
|
||||
mzero = MatrixType::Zero(rows, cols),
|
||||
identity = MatrixType::Identity(rows, rows);
|
||||
createRandomMatrixOfRank(rows,rows,rows,m1);
|
||||
createRandomPIMatrixOfRank(rows,rows,rows,m1);
|
||||
m2 = m1.inverse();
|
||||
VERIFY_IS_APPROX(m1, m2.inverse() );
|
||||
|
||||
|
||||
83
test/lu.cpp
83
test/lu.cpp
@@ -29,6 +29,7 @@ using namespace std;
|
||||
template<typename MatrixType> void lu_non_invertible()
|
||||
{
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename MatrixType::RealScalar RealScalar;
|
||||
/* this test covers the following files:
|
||||
LU.h
|
||||
*/
|
||||
@@ -51,11 +52,16 @@ template<typename MatrixType> void lu_non_invertible()
|
||||
cols2 = cols = MatrixType::ColsAtCompileTime;
|
||||
}
|
||||
|
||||
typedef typename ei_kernel_retval_base<FullPivLU<MatrixType> >::ReturnMatrixType KernelMatrixType;
|
||||
typedef typename ei_image_retval_base<FullPivLU<MatrixType> >::ReturnMatrixType ImageMatrixType;
|
||||
typedef Matrix<typename MatrixType::Scalar, Dynamic, Dynamic> DynamicMatrixType;
|
||||
typedef Matrix<typename MatrixType::Scalar, MatrixType::ColsAtCompileTime, MatrixType::ColsAtCompileTime>
|
||||
enum {
|
||||
RowsAtCompileTime = MatrixType::RowsAtCompileTime,
|
||||
ColsAtCompileTime = MatrixType::ColsAtCompileTime
|
||||
};
|
||||
typedef typename ei_kernel_retval_base<FullPivLU<MatrixType> >::ReturnType KernelMatrixType;
|
||||
typedef typename ei_image_retval_base<FullPivLU<MatrixType> >::ReturnType ImageMatrixType;
|
||||
typedef Matrix<typename MatrixType::Scalar, ColsAtCompileTime, ColsAtCompileTime>
|
||||
CMatrixType;
|
||||
typedef Matrix<typename MatrixType::Scalar, RowsAtCompileTime, RowsAtCompileTime>
|
||||
RMatrixType;
|
||||
|
||||
int rank = ei_random<int>(1, std::min(rows, cols)-1);
|
||||
|
||||
@@ -64,26 +70,28 @@ template<typename MatrixType> void lu_non_invertible()
|
||||
|
||||
MatrixType m1(rows, cols), m3(rows, cols2);
|
||||
CMatrixType m2(cols, cols2);
|
||||
createRandomMatrixOfRank(rank, rows, cols, m1);
|
||||
createRandomPIMatrixOfRank(rank, rows, cols, m1);
|
||||
|
||||
FullPivLU<MatrixType> lu(m1);
|
||||
// FIXME need better way to construct trapezoid matrices. extend triangularView to support rectangular.
|
||||
DynamicMatrixType u(rows,cols);
|
||||
for(int i = 0; i < rows; i++)
|
||||
for(int j = 0; j < cols; j++)
|
||||
u(i,j) = i>j ? Scalar(0) : lu.matrixLU()(i,j);
|
||||
DynamicMatrixType l(rows,rows);
|
||||
for(int i = 0; i < rows; i++)
|
||||
for(int j = 0; j < rows; j++)
|
||||
l(i,j) = (i<j || j>=cols) ? Scalar(0)
|
||||
: i==j ? Scalar(1)
|
||||
: lu.matrixLU()(i,j);
|
||||
FullPivLU<MatrixType> lu;
|
||||
|
||||
// The special value 0.01 below works well in tests. Keep in mind that we're only computing the rank
|
||||
// of singular values are either 0 or 1.
|
||||
// So it's not clear at all that the epsilon should play any role there.
|
||||
lu.setThreshold(RealScalar(0.01));
|
||||
lu.compute(m1);
|
||||
|
||||
MatrixType u(rows,cols);
|
||||
u = lu.matrixLU().template triangularView<Upper>();
|
||||
RMatrixType l = RMatrixType::Identity(rows,rows);
|
||||
l.block(0,0,rows,std::min(rows,cols)).template triangularView<StrictlyLower>()
|
||||
= lu.matrixLU().block(0,0,rows,std::min(rows,cols));
|
||||
|
||||
VERIFY_IS_APPROX(lu.permutationP() * m1 * lu.permutationQ(), l*u);
|
||||
|
||||
KernelMatrixType m1kernel = lu.kernel();
|
||||
ImageMatrixType m1image = lu.image(m1);
|
||||
|
||||
VERIFY_IS_APPROX(m1, lu.reconstructedMatrix());
|
||||
VERIFY(rank == lu.rank());
|
||||
VERIFY(cols - lu.rank() == lu.dimensionOfKernel());
|
||||
VERIFY(!lu.isInjective());
|
||||
@@ -91,9 +99,8 @@ template<typename MatrixType> void lu_non_invertible()
|
||||
VERIFY(!lu.isSurjective());
|
||||
VERIFY((m1 * m1kernel).isMuchSmallerThan(m1));
|
||||
VERIFY(m1image.fullPivLu().rank() == rank);
|
||||
DynamicMatrixType sidebyside(m1.rows(), m1.cols() + m1image.cols());
|
||||
sidebyside << m1, m1image;
|
||||
VERIFY(sidebyside.fullPivLu().rank() == rank);
|
||||
VERIFY_IS_APPROX(m1 * m1.adjoint() * m1image, m1image);
|
||||
|
||||
m2 = CMatrixType::Random(cols,cols2);
|
||||
m3 = m1*m2;
|
||||
m2 = CMatrixType::Random(cols,cols2);
|
||||
@@ -107,20 +114,19 @@ template<typename MatrixType> void lu_invertible()
|
||||
/* this test covers the following files:
|
||||
LU.h
|
||||
*/
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
|
||||
int size = ei_random<int>(1,200);
|
||||
|
||||
MatrixType m1(size, size), m2(size, size), m3(size, size);
|
||||
m1 = MatrixType::Random(size,size);
|
||||
FullPivLU<MatrixType> lu;
|
||||
lu.setThreshold(0.01);
|
||||
do {
|
||||
m1 = MatrixType::Random(size,size);
|
||||
lu.compute(m1);
|
||||
} while(!lu.isInvertible());
|
||||
|
||||
if (ei_is_same_type<RealScalar,float>::ret)
|
||||
{
|
||||
// let's build a matrix more stable to inverse
|
||||
MatrixType a = MatrixType::Random(size,size*2);
|
||||
m1 += a * a.adjoint();
|
||||
}
|
||||
|
||||
FullPivLU<MatrixType> lu(m1);
|
||||
VERIFY_IS_APPROX(m1, lu.reconstructedMatrix());
|
||||
VERIFY(0 == lu.dimensionOfKernel());
|
||||
VERIFY(lu.kernel().cols() == 1); // the kernel() should consist of a single (zero) column vector
|
||||
VERIFY(size == lu.rank());
|
||||
@@ -134,6 +140,23 @@ template<typename MatrixType> void lu_invertible()
|
||||
VERIFY_IS_APPROX(m2, lu.inverse()*m3);
|
||||
}
|
||||
|
||||
template<typename MatrixType> void lu_partial_piv()
|
||||
{
|
||||
/* this test covers the following files:
|
||||
PartialPivLU.h
|
||||
*/
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
|
||||
int rows = ei_random<int>(1,4);
|
||||
int cols = rows;
|
||||
|
||||
MatrixType m1(cols, rows);
|
||||
m1.setRandom();
|
||||
PartialPivLU<MatrixType> plu(m1);
|
||||
|
||||
VERIFY_IS_APPROX(m1, plu.reconstructedMatrix());
|
||||
}
|
||||
|
||||
template<typename MatrixType> void lu_verify_assert()
|
||||
{
|
||||
MatrixType tmp;
|
||||
@@ -176,6 +199,7 @@ void test_lu()
|
||||
|
||||
CALL_SUBTEST_4( lu_non_invertible<MatrixXd>() );
|
||||
CALL_SUBTEST_4( lu_invertible<MatrixXd>() );
|
||||
CALL_SUBTEST_4( lu_partial_piv<MatrixXd>() );
|
||||
CALL_SUBTEST_4( lu_verify_assert<MatrixXd>() );
|
||||
|
||||
CALL_SUBTEST_5( lu_non_invertible<MatrixXcf>() );
|
||||
@@ -184,6 +208,7 @@ void test_lu()
|
||||
|
||||
CALL_SUBTEST_6( lu_non_invertible<MatrixXcd>() );
|
||||
CALL_SUBTEST_6( lu_invertible<MatrixXcd>() );
|
||||
CALL_SUBTEST_6( lu_partial_piv<MatrixXcd>() );
|
||||
CALL_SUBTEST_6( lu_verify_assert<MatrixXcd>() );
|
||||
|
||||
CALL_SUBTEST_7(( lu_non_invertible<Matrix<float,Dynamic,16> >() ));
|
||||
|
||||
12
test/main.h
12
test/main.h
@@ -148,7 +148,7 @@ namespace Eigen
|
||||
|
||||
#define EIGEN_INTERNAL_DEBUGGING
|
||||
#define EIGEN_NICE_RANDOM
|
||||
#include <Eigen/QR> // required for createRandomMatrixOfRank
|
||||
#include <Eigen/QR> // required for createRandomPIMatrixOfRank
|
||||
|
||||
|
||||
#define VERIFY(a) do { if (!(a)) { \
|
||||
@@ -342,8 +342,13 @@ inline bool test_isUnitary(const MatrixBase<Derived>& m)
|
||||
return m.isUnitary(test_precision<typename ei_traits<Derived>::Scalar>());
|
||||
}
|
||||
|
||||
/** Creates a random Partial Isometry matrix of given rank.
|
||||
*
|
||||
* A partial isometry is a matrix all of whose singular values are either 0 or 1.
|
||||
* This is very useful to test rank-revealing algorithms.
|
||||
*/
|
||||
template<typename MatrixType>
|
||||
void createRandomMatrixOfRank(int desired_rank, int rows, int cols, MatrixType& m)
|
||||
void createRandomPIMatrixOfRank(int desired_rank, int rows, int cols, MatrixType& m)
|
||||
{
|
||||
typedef typename ei_traits<MatrixType>::Scalar Scalar;
|
||||
enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };
|
||||
@@ -360,7 +365,8 @@ void createRandomMatrixOfRank(int desired_rank, int rows, int cols, MatrixType&
|
||||
|
||||
if(desired_rank == 1)
|
||||
{
|
||||
m = VectorType::Random(rows) * VectorType::Random(cols).transpose();
|
||||
// here we normalize the vectors to get a partial isometry
|
||||
m = VectorType::Random(rows).normalized() * VectorType::Random(cols).normalized().transpose();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ template<typename MatrixType> void permutationmatrices(const MatrixType& m)
|
||||
typedef Matrix<int, Rows, 1> LeftPermutationVectorType;
|
||||
typedef PermutationMatrix<Cols> RightPermutationType;
|
||||
typedef Matrix<int, Cols, 1> RightPermutationVectorType;
|
||||
|
||||
|
||||
int rows = m.rows();
|
||||
int cols = m.cols();
|
||||
|
||||
@@ -72,7 +72,7 @@ template<typename MatrixType> void permutationmatrices(const MatrixType& m)
|
||||
Matrix<Scalar,Cols,Cols> rm(rp);
|
||||
|
||||
VERIFY_IS_APPROX(m_permuted, lm*m_original*rm);
|
||||
|
||||
|
||||
VERIFY_IS_APPROX(lp.inverse()*m_permuted*rp.inverse(), m_original);
|
||||
VERIFY((lp*lp.inverse()).toDenseMatrix().isIdentity());
|
||||
|
||||
@@ -86,6 +86,23 @@ template<typename MatrixType> void permutationmatrices(const MatrixType& m)
|
||||
identityp.setIdentity(rows);
|
||||
VERIFY_IS_APPROX(m_original, identityp*m_original);
|
||||
|
||||
// check inplace permutations
|
||||
m_permuted = m_original;
|
||||
m_permuted = lp.inverse() * m_permuted;
|
||||
VERIFY_IS_APPROX(m_permuted, lp.inverse()*m_original);
|
||||
|
||||
m_permuted = m_original;
|
||||
m_permuted = m_permuted * rp.inverse();
|
||||
VERIFY_IS_APPROX(m_permuted, m_original*rp.inverse());
|
||||
|
||||
m_permuted = m_original;
|
||||
m_permuted = lp * m_permuted;
|
||||
VERIFY_IS_APPROX(m_permuted, lp*m_original);
|
||||
|
||||
m_permuted = m_original;
|
||||
m_permuted = m_permuted * rp;
|
||||
VERIFY_IS_APPROX(m_permuted, m_original*rp);
|
||||
|
||||
if(rows>1 && cols>1)
|
||||
{
|
||||
lp2 = lp;
|
||||
@@ -114,7 +131,7 @@ void test_permutationmatrices()
|
||||
CALL_SUBTEST_2( permutationmatrices(Matrix3f()) );
|
||||
CALL_SUBTEST_3( permutationmatrices(Matrix<double,3,3,RowMajor>()) );
|
||||
CALL_SUBTEST_4( permutationmatrices(Matrix4d()) );
|
||||
CALL_SUBTEST_5( permutationmatrices(Matrix<double,4,6>()) );
|
||||
CALL_SUBTEST_5( permutationmatrices(Matrix<double,40,60>()) );
|
||||
CALL_SUBTEST_6( permutationmatrices(Matrix<double,Dynamic,Dynamic,RowMajor>(20, 30)) );
|
||||
CALL_SUBTEST_7( permutationmatrices(MatrixXcf(15, 10)) );
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ template<typename MatrixType> void qr()
|
||||
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> MatrixQType;
|
||||
typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType;
|
||||
MatrixType m1;
|
||||
createRandomMatrixOfRank(rank,rows,cols,m1);
|
||||
createRandomPIMatrixOfRank(rank,rows,cols,m1);
|
||||
ColPivHouseholderQR<MatrixType> qr(m1);
|
||||
VERIFY_IS_APPROX(rank, qr.rank());
|
||||
VERIFY(cols - qr.rank() == qr.dimensionOfKernel());
|
||||
@@ -64,7 +64,7 @@ template<typename MatrixType, int Cols2> void qr_fixedsize()
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
int rank = ei_random<int>(1, std::min(int(Rows), int(Cols))-1);
|
||||
Matrix<Scalar,Rows,Cols> m1;
|
||||
createRandomMatrixOfRank(rank,Rows,Cols,m1);
|
||||
createRandomPIMatrixOfRank(rank,Rows,Cols,m1);
|
||||
ColPivHouseholderQR<Matrix<Scalar,Rows,Cols> > qr(m1);
|
||||
VERIFY_IS_APPROX(rank, qr.rank());
|
||||
VERIFY(Cols - qr.rank() == qr.dimensionOfKernel());
|
||||
|
||||
@@ -35,7 +35,7 @@ template<typename MatrixType> void qr()
|
||||
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> MatrixQType;
|
||||
typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType;
|
||||
MatrixType m1;
|
||||
createRandomMatrixOfRank(rank,rows,cols,m1);
|
||||
createRandomPIMatrixOfRank(rank,rows,cols,m1);
|
||||
FullPivHouseholderQR<MatrixType> qr(m1);
|
||||
VERIFY_IS_APPROX(rank, qr.rank());
|
||||
VERIFY(cols - qr.rank() == qr.dimensionOfKernel());
|
||||
|
||||
@@ -147,6 +147,9 @@ endif(NOT EIGEN_NO_UPDATE)
|
||||
|
||||
# which ctest command to use for running the dashboard
|
||||
SET (CTEST_COMMAND "${EIGEN_CMAKE_DIR}ctest -D ${EIGEN_MODE}")
|
||||
if($ENV{EIGEN_CTEST_ARGS})
|
||||
SET (CTEST_COMMAND "${CTEST_COMMAND} $ENV{EIGEN_CTEST_ARGS}")
|
||||
endif($ENV{EIGEN_CTEST_ARGS})
|
||||
# what cmake command to use for configuring this dashboard
|
||||
SET (CTEST_CMAKE_COMMAND "${EIGEN_CMAKE_DIR}cmake -DEIGEN_LEAVE_TEST_IN_ALL_TARGET=ON")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user