From 46fe7a3d9ec14ea56a879c48ba7f15e78342c8cb Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Mon, 1 Sep 2008 17:31:21 +0000 Subject: [PATCH] if EIGEN_NICE_RANDOM is defined, the random functions will return numbers with few bits left of the comma and for floating-point types will never return zero. This replaces the custom functions in test/main.h, so one does not anymore need to think about that when writing tests. --- Eigen/src/Core/MathFunctions.h | 14 ++++++++++++++ test/adjoint.cpp | 16 ++++++++-------- test/array.cpp | 8 ++++---- test/basicstuff.cpp | 12 ++++++------ test/cholesky.cpp | 8 ++++---- test/cwiseop.cpp | 10 +++++----- test/eigensolver.cpp | 8 ++++---- test/geometry.cpp | 14 +++++++------- test/inverse.cpp | 4 ++-- test/linearstructure.cpp | 8 ++++---- test/lu.cpp | 16 ++++++++-------- test/main.h | 21 +-------------------- test/sum.cpp | 4 ++-- test/svd.cpp | 6 +++--- test/triangular.cpp | 12 ++++++------ 15 files changed, 78 insertions(+), 83 deletions(-) diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h index 8aa36bd1d..a523db4c3 100644 --- a/Eigen/src/Core/MathFunctions.h +++ b/Eigen/src/Core/MathFunctions.h @@ -89,7 +89,14 @@ inline float ei_pow(float x, float y) { return std::pow(x, y); } template<> inline float ei_random(float a, float b) { +#ifdef EIGEN_NICE_RANDOM + int i; + do { i = ei_random(256*int(a),256*int(b)); + } while(i==0); + return i/256.f; +#else return a + (b-a) * std::rand() / RAND_MAX; +#endif } template<> inline float ei_random() { @@ -123,7 +130,14 @@ inline double ei_pow(double x, double y) { return std::pow(x, y); } template<> inline double ei_random(double a, double b) { +#ifdef EIGEN_NICE_RANDOM + int i; + do { i= ei_random(256*int(a),256*int(b)); + } while(i==0); + return i/256.; +#else return a + (b-a) * std::rand() / RAND_MAX; +#endif } template<> inline double ei_random() { diff --git a/test/adjoint.cpp b/test/adjoint.cpp index 982584eea..9a50e076e 100644 --- a/test/adjoint.cpp +++ b/test/adjoint.cpp @@ -41,19 +41,19 @@ template void adjoint(const MatrixType& m) if (ei_is_same_type::ret) largerEps = 1e-3f; - MatrixType m1 = test_random_matrix(rows, cols), - m2 = test_random_matrix(rows, cols), + MatrixType m1 = MatrixType::Random(rows, cols), + m2 = MatrixType::Random(rows, cols), m3(rows, cols), mzero = MatrixType::Zero(rows, cols), identity = SquareMatrixType::Identity(rows, rows), - square = test_random_matrix(rows, rows); - VectorType v1 = test_random_matrix(rows), - v2 = test_random_matrix(rows), - v3 = test_random_matrix(rows), + square = SquareMatrixType::Random(rows, rows); + VectorType v1 = VectorType::Random(rows), + v2 = VectorType::Random(rows), + v3 = VectorType::Random(rows), vzero = VectorType::Zero(rows); - Scalar s1 = test_random(), - s2 = test_random(); + Scalar s1 = ei_random(), + s2 = ei_random(); // check basic compatibility of adjoint, transpose, conjugate VERIFY_IS_APPROX(m1.transpose().conjugate().adjoint(), m1); diff --git a/test/array.cpp b/test/array.cpp index 25387d0cd..f0b09051f 100644 --- a/test/array.cpp +++ b/test/array.cpp @@ -38,12 +38,12 @@ template void scalarAdd(const MatrixType& m) int rows = m.rows(); int cols = m.cols(); - MatrixType m1 = test_random_matrix(rows, cols), - m2 = test_random_matrix(rows, cols), + MatrixType m1 = MatrixType::Random(rows, cols), + m2 = MatrixType::Random(rows, cols), m3(rows, cols); - Scalar s1 = test_random(), - s2 = test_random(); + Scalar s1 = ei_random(), + s2 = ei_random(); VERIFY_IS_APPROX(m1.cwise() + s1, s1 + m1.cwise()); VERIFY_IS_APPROX(m1.cwise() + s1, MatrixType::Constant(rows,cols,s1) + m1); diff --git a/test/basicstuff.cpp b/test/basicstuff.cpp index 8b322deda..769e021af 100644 --- a/test/basicstuff.cpp +++ b/test/basicstuff.cpp @@ -34,18 +34,18 @@ template void basicStuff(const MatrixType& m) // this test relies a lot on Random.h, and there's not much more that we can do // to test it, hence I consider that we will have tested Random.h - MatrixType m1 = test_random_matrix(rows, cols), - m2 = test_random_matrix(rows, cols), + MatrixType m1 = MatrixType::Random(rows, cols), + m2 = MatrixType::Random(rows, cols), m3(rows, cols), mzero = MatrixType::Zero(rows, cols), identity = Matrix ::Identity(rows, rows), - square = test_random_matrix >(rows, rows); - VectorType v1 = test_random_matrix(rows), - v2 = test_random_matrix(rows), + square = Matrix::Random(rows, rows); + VectorType v1 = VectorType::Random(rows), + v2 = VectorType::Random(rows), vzero = VectorType::Zero(rows); - Scalar x = test_random(); + Scalar x = ei_random(); int r = ei_random(0, rows-1), c = ei_random(0, cols-1); diff --git a/test/cholesky.cpp b/test/cholesky.cpp index ca57f7644..36a11c723 100644 --- a/test/cholesky.cpp +++ b/test/cholesky.cpp @@ -43,12 +43,12 @@ template void cholesky(const MatrixType& m) typedef Matrix SquareMatrixType; typedef Matrix VectorType; - MatrixType a0 = test_random_matrix(rows,cols); - VectorType vecB = test_random_matrix(rows); - MatrixType matB = test_random_matrix(rows,cols); + MatrixType a0 = MatrixType::Random(rows,cols); + VectorType vecB = VectorType::Random(rows); + MatrixType matB = MatrixType::Random(rows,cols); SquareMatrixType symm = a0 * a0.adjoint(); // let's make sure the matrix is not singular or near singular - MatrixType a1 = test_random_matrix(rows,cols); + MatrixType a1 = MatrixType::Random(rows,cols); symm += a1 * a1.adjoint(); #ifdef HAS_GSL diff --git a/test/cwiseop.cpp b/test/cwiseop.cpp index 14a5dfda9..53830106b 100644 --- a/test/cwiseop.cpp +++ b/test/cwiseop.cpp @@ -43,16 +43,16 @@ template void cwiseops(const MatrixType& m) int rows = m.rows(); int cols = m.cols(); - MatrixType m1 = test_random_matrix(rows, cols), - m2 = test_random_matrix(rows, cols), + MatrixType m1 = MatrixType::Random(rows, cols), + m2 = MatrixType::Random(rows, cols), m3(rows, cols), mzero = MatrixType::Zero(rows, cols), mones = MatrixType::Ones(rows, cols), identity = Matrix ::Identity(rows, rows), - square = test_random_matrix >(rows, rows); - VectorType v1 = test_random_matrix(rows), - v2 = test_random_matrix(rows), + square = Matrix::Random(rows, rows); + VectorType v1 = VectorType::Random(rows), + v2 = VectorType::Random(rows), vzero = VectorType::Zero(rows); int r = ei_random(0, rows-1), diff --git a/test/eigensolver.cpp b/test/eigensolver.cpp index 48ae50587..beccdc321 100644 --- a/test/eigensolver.cpp +++ b/test/eigensolver.cpp @@ -45,12 +45,12 @@ template void eigensolver(const MatrixType& m) RealScalar largerEps = 10*test_precision(); - MatrixType a = test_random_matrix(rows,cols); - MatrixType a1 = test_random_matrix(rows,cols); + MatrixType a = MatrixType::Random(rows,cols); + MatrixType a1 = MatrixType::Random(rows,cols); MatrixType symmA = a.adjoint() * a + a1.adjoint() * a1; - MatrixType b = test_random_matrix(rows,cols); - MatrixType b1 = test_random_matrix(rows,cols); + MatrixType b = MatrixType::Random(rows,cols); + MatrixType b1 = MatrixType::Random(rows,cols); MatrixType symmB = b.adjoint() * b + b1.adjoint() * b1; SelfAdjointEigenSolver eiSymm(symmA); diff --git a/test/geometry.cpp b/test/geometry.cpp index 3561359fe..10e6bbe92 100644 --- a/test/geometry.cpp +++ b/test/geometry.cpp @@ -49,10 +49,10 @@ template void geometry(void) typedef Translation Translation3; Quaternion q1, q2; - Vector3 v0 = test_random_matrix(), - v1 = test_random_matrix(), - v2 = test_random_matrix(); - Vector2 u0 = test_random_matrix(); + Vector3 v0 = Vector3::Random(), + v1 = Vector3::Random(), + v2 = Vector3::Random(); + Vector2 u0 = Vector2::Random(); Matrix3 matrot1; Scalar a = ei_random(-M_PI, M_PI); @@ -134,7 +134,7 @@ template void geometry(void) t1.setIdentity(); t1.linear() = q1.toRotationMatrix(); - v0 << 50, 2, 1;//= test_random_matrix().cwiseProduct(Vector3(10,2,0.5)); + v0 << 50, 2, 1;//= ei_random_matrix().cwiseProduct(Vector3(10,2,0.5)); t0.scale(v0); t1.prescale(v0); @@ -169,8 +169,8 @@ template void geometry(void) // 2D transformation Transform2 t20, t21; - Vector2 v20 = test_random_matrix(); - Vector2 v21 = test_random_matrix(); + Vector2 v20 = Vector2::Random(); + Vector2 v21 = Vector2::Random(); for (int k=0; k<2; ++k) if (ei_abs(v21[k])<1e-3) v21[k] = 1e-3; t21.setIdentity(); diff --git a/test/inverse.cpp b/test/inverse.cpp index eaa7bfd3f..42121072c 100644 --- a/test/inverse.cpp +++ b/test/inverse.cpp @@ -38,7 +38,7 @@ template void inverse(const MatrixType& m) typedef typename NumTraits::Real RealScalar; typedef Matrix VectorType; - MatrixType m1 = test_random_matrix(rows, cols), + MatrixType m1 = MatrixType::Random(rows, cols), m2(rows, cols), mzero = MatrixType::Zero(rows, cols), identity = MatrixType::Identity(rows, rows); @@ -46,7 +46,7 @@ template void inverse(const MatrixType& m) if (ei_is_same_type::ret) { // let's build a more stable to inverse matrix - MatrixType a = test_random_matrix(rows,cols); + MatrixType a = MatrixType::Random(rows,cols); m1 += m1 * m1.adjoint() + a * a.adjoint(); } diff --git a/test/linearstructure.cpp b/test/linearstructure.cpp index 5178839c9..39b4690a0 100644 --- a/test/linearstructure.cpp +++ b/test/linearstructure.cpp @@ -38,13 +38,13 @@ template void linearStructure(const MatrixType& m) // this test relies a lot on Random.h, and there's not much more that we can do // to test it, hence I consider that we will have tested Random.h - MatrixType m1 = test_random_matrix(rows, cols), - m2 = test_random_matrix(rows, cols), + MatrixType m1 = MatrixType::Random(rows, cols), + m2 = MatrixType::Random(rows, cols), m3(rows, cols), mzero = MatrixType::Zero(rows, cols); - Scalar s1 = test_random(); - while (ei_abs(s1)<1e-3) s1 = test_random(); + Scalar s1 = ei_random(); + while (ei_abs(s1)<1e-3) s1 = ei_random(); int r = ei_random(0, rows-1), c = ei_random(0, cols-1); diff --git a/test/lu.cpp b/test/lu.cpp index 0f4e0ab64..e34462c95 100644 --- a/test/lu.cpp +++ b/test/lu.cpp @@ -56,7 +56,7 @@ template void lu_non_invertible() int rank = ei_random(1, std::min(rows, cols)-1); MatrixType m1(rows, cols), m2(cols, cols2), m3(rows, cols2), k(1,1); - m1 = test_random_matrix(rows,cols); + m1 = MatrixType::Random(rows,cols); if(rows <= cols) for(int i = rank; i < rows; i++) m1.row(i).setZero(); else @@ -72,12 +72,12 @@ template void lu_non_invertible() VERIFY((m1 * lu.kernel()).isMuchSmallerThan(m1)); lu.computeKernel(&k); VERIFY((m1 * k).isMuchSmallerThan(m1)); - m2 = test_random_matrix(cols,cols2); + m2 = MatrixType::Random(cols,cols2); m3 = m1*m2; - m2 = test_random_matrix(cols,cols2); + m2 = MatrixType::Random(cols,cols2); lu.solve(m3, &m2); VERIFY_IS_APPROX(m3, m1*m2); - m3 = test_random_matrix(rows,cols2); + m3 = MatrixType::Random(rows,cols2); VERIFY(!lu.solve(m3, &m2)); } @@ -90,12 +90,12 @@ template void lu_invertible() int size = ei_random(10,200); MatrixType m1(size, size), m2(size, size), m3(size, size); - m1 = test_random_matrix(size,size); + m1 = MatrixType::Random(size,size); if (ei_is_same_type::ret) { // let's build a matrix more stable to inverse - MatrixType a = test_random_matrix(size,size*2); + MatrixType a = MatrixType::Random(size,size*2); m1 += a * a.adjoint(); } @@ -105,11 +105,11 @@ template void lu_invertible() VERIFY(lu.isInjective()); VERIFY(lu.isSurjective()); VERIFY(lu.isInvertible()); - m3 = test_random_matrix(size,size); + m3 = MatrixType::Random(size,size); lu.solve(m3, &m2); VERIFY_IS_APPROX(m3, m1*m2); VERIFY_IS_APPROX(m2, lu.inverse()*m3); - m3 = test_random_matrix(size,size); + m3 = MatrixType::Random(size,size); VERIFY(lu.solve(m3, &m2)); } diff --git a/test/main.h b/test/main.h index b1410386f..4e9621543 100644 --- a/test/main.h +++ b/test/main.h @@ -135,6 +135,7 @@ namespace Eigen #define EIGEN_INTERNAL_DEBUGGING +#define EIGEN_NICE_RANDOM #include namespace Eigen { @@ -221,26 +222,6 @@ inline bool test_ei_isMuchSmallerThan(const MatrixBase& m, return m.isMuchSmallerThan(s, test_precision::Scalar>()); } -template T test_random(); - -template<> int test_random() { return ei_random(-100,100); } -template<> float test_random() { return float(ei_random(-1000,1000)) / 256.f; } -template<> double test_random() { return double(ei_random(-1000,1000)) / 256.; } -template<> std::complex test_random() -{ return std::complex(test_random(),test_random()); } -template<> std::complex test_random() -{ return std::complex(test_random(),test_random()); } - -template -MatrixType test_random_matrix(int rows = MatrixType::RowsAtCompileTime, int cols = MatrixType::ColsAtCompileTime) -{ - MatrixType res(rows, cols); - for (int j=0; j(); - return res; -} - } // end namespace Eigen diff --git a/test/sum.cpp b/test/sum.cpp index d9add1979..58e5eb9d3 100644 --- a/test/sum.cpp +++ b/test/sum.cpp @@ -31,7 +31,7 @@ template void matrixSum(const MatrixType& m) int rows = m.rows(); int cols = m.cols(); - MatrixType m1 = test_random_matrix(rows, cols); + MatrixType m1 = MatrixType::Random(rows, cols); VERIFY_IS_MUCH_SMALLER_THAN(MatrixType::Zero(rows, cols).sum(), Scalar(1)); VERIFY_IS_APPROX(MatrixType::Ones(rows, cols).sum(), Scalar(rows*cols)); @@ -45,7 +45,7 @@ template void vectorSum(const VectorType& w) typedef typename VectorType::Scalar Scalar; int size = w.size(); - VectorType v = test_random_matrix(size); + VectorType v = VectorType::Random(size); for(int i = 1; i < size; i++) { Scalar s = Scalar(0); diff --git a/test/svd.cpp b/test/svd.cpp index 605c7f7aa..4776ef7e7 100644 --- a/test/svd.cpp +++ b/test/svd.cpp @@ -35,9 +35,9 @@ template void svd(const MatrixType& m) typedef typename MatrixType::Scalar Scalar; typedef typename NumTraits::Real RealScalar; - MatrixType a = test_random_matrix(rows,cols); + MatrixType a = MatrixType::Random(rows,cols); Matrix b = - test_random_matrix >(rows,1); + Matrix::Random(rows,1); Matrix x(cols,1), x2(cols,1); RealScalar largerEps = test_precision(); @@ -56,7 +56,7 @@ template void svd(const MatrixType& m) { if (ei_is_same_type::ret) { - MatrixType a1 = test_random_matrix(rows,cols); + MatrixType a1 = MatrixType::Random(rows,cols); a += a * a.adjoint() + a1 * a1.adjoint(); } SVD svd(a); diff --git a/test/triangular.cpp b/test/triangular.cpp index 388d78e1e..22a19f974 100644 --- a/test/triangular.cpp +++ b/test/triangular.cpp @@ -35,8 +35,8 @@ template void triangular(const MatrixType& m) int rows = m.rows(); int cols = m.cols(); - MatrixType m1 = test_random_matrix(rows, cols), - m2 = test_random_matrix(rows, cols), + MatrixType m1 = MatrixType::Random(rows, cols), + m2 = MatrixType::Random(rows, cols), m3(rows, cols), m4(rows, cols), r1(rows, cols), @@ -47,8 +47,8 @@ template void triangular(const MatrixType& m) ::Identity(rows, rows), square = Matrix ::Random(rows, rows); - VectorType v1 = test_random_matrix(rows), - v2 = test_random_matrix(rows), + VectorType v1 = VectorType::Random(rows), + v2 = VectorType::Random(rows), vzero = VectorType::Zero(rows); MatrixType m1up = m1.template part(); @@ -81,9 +81,9 @@ template void triangular(const MatrixType& m) m1.template part() = (m2.transpose() * m2).lazy(); VERIFY_IS_APPROX(m3.template part(), m1); - m1 = test_random_matrix(rows, cols); + m1 = MatrixType::Random(rows, cols); for (int i=0; i(); + while (ei_abs2(m1(i,i))<1e-3) m1(i,i) = ei_random(); Transpose trm4(m4); // test back and forward subsitution