aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/lu.cpp
diff options
context:
space:
mode:
authorGravatar Benoit Jacob <jacob.benoit.1@gmail.com>2010-02-23 15:40:24 -0500
committerGravatar Benoit Jacob <jacob.benoit.1@gmail.com>2010-02-23 15:40:24 -0500
commitd92df336ad21c7f8e0289f8ac3084b6313a17fe4 (patch)
tree32c090cb95df3120c87354ad16fc7a4330e88a29 /test/lu.cpp
parent7dc75380c101b9b4f3882f78fe6a5e9ae8963cac (diff)
Further LU test improvements. I'm not aware of any test failures anymore, not even with huge numbers of repetitions.
Finally the createRandomMatrixOfRank() function is renamed to createRandomPIMatrixOfRank, where PI stands for 'partial isometry', that is, a matrix whose singular values are 0 or 1.
Diffstat (limited to 'test/lu.cpp')
-rw-r--r--test/lu.cpp65
1 files changed, 24 insertions, 41 deletions
diff --git a/test/lu.cpp b/test/lu.cpp
index 02f6ec805..442202a33 100644
--- a/test/lu.cpp
+++ b/test/lu.cpp
@@ -28,9 +28,6 @@ using namespace std;
template<typename MatrixType> void lu_non_invertible()
{
- static int times_called = 0;
- times_called++;
-
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::RealScalar RealScalar;
/* this test covers the following files:
@@ -55,11 +52,16 @@ template<typename MatrixType> void lu_non_invertible()
cols2 = cols = 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, Dynamic, Dynamic> DynamicMatrixType;
- typedef Matrix<typename MatrixType::Scalar, MatrixType::ColsAtCompileTime, MatrixType::ColsAtCompileTime>
+ 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);
@@ -68,26 +70,21 @@ template<typename MatrixType> void lu_non_invertible()
MatrixType m1(rows, cols), m3(rows, cols2);
CMatrixType m2(cols, cols2);
- createRandomProjectionOfRank(rank, rows, cols, m1);
+ createRandomPIMatrixOfRank(rank, rows, cols, m1);
FullPivLU<MatrixType> lu;
- // The special value 0.01 below works well in tests. Keep in mind that we're only computing the rank of projections.
- // So it's not clear at all the epsilon should play any role there.
+ // 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);
- // 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);
+ 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);
@@ -101,20 +98,8 @@ template<typename MatrixType> void lu_non_invertible()
VERIFY(!lu.isSurjective());
VERIFY((m1 * m1kernel).isMuchSmallerThan(m1));
VERIFY(m1image.fullPivLu().rank() == rank);
+ VERIFY_IS_APPROX(m1 * m1.adjoint() * m1image, m1image);
- // The following test is damn hard to get to succeed over a large number of repetitions.
- // We're checking that the image is indeed the image, i.e. adding it as new columns doesn't increase the rank.
- // Since we've already tested rank() above, the point here is not to test rank(), it is to test image().
- // Since image() is implemented in a very simple way that doesn't leave much room for choice, the occasional
- // errors that we get here (one in 1e+4 repetitions roughly) are probably just a sign that it's a really
- // hard test, so we just limit how many times it's run.
- if(times_called < 100)
- {
- DynamicMatrixType sidebyside(m1.rows(), m1.cols() + m1image.cols());
- sidebyside << m1, m1image;
- VERIFY(sidebyside.fullPivLu().rank() == rank);
- }
-
m2 = CMatrixType::Random(cols,cols2);
m3 = m1*m2;
m2 = CMatrixType::Random(cols,cols2);
@@ -128,20 +113,18 @@ 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);
-
- 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;
+ lu.setThreshold(0.01);
+ do {
+ m1 = MatrixType::Random(size,size);
+ lu.compute(m1);
+ } while(!lu.isInvertible());
- FullPivLU<MatrixType> lu(m1);
VERIFY(0 == lu.dimensionOfKernel());
VERIFY(lu.kernel().cols() == 1); // the kernel() should consist of a single (zero) column vector
VERIFY(size == lu.rank());