aboutsummaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2009-09-17 23:21:48 +0200
committerGravatar Gael Guennebaud <g.gael@free.fr>2009-09-17 23:21:48 +0200
commitf2737148b0988856de5f97c0738fa6473b707b8a (patch)
tree84f572ad4448e650014fd004dbf1a7adb689100a /test
parent9395326e4491b52d8fe0e6431e8843c9629acc79 (diff)
parent760636a237d875aa6f0e108e432fd98974ab25ea (diff)
merge
Diffstat (limited to 'test')
-rw-r--r--test/CMakeLists.txt2
-rw-r--r--test/adjoint.cpp9
-rw-r--r--test/cholesky.cpp18
-rw-r--r--test/conservative_resize.cpp4
-rw-r--r--test/geo_orthomethods.cpp6
-rw-r--r--test/geo_transformations.cpp4
-rw-r--r--test/householder.cpp9
-rw-r--r--test/jacobisvd.cpp8
-rw-r--r--test/main.h5
-rw-r--r--test/mixingtypes.cpp10
-rw-r--r--test/product_extra.cpp15
-rw-r--r--test/qr.cpp2
-rw-r--r--test/qr_colpivoting.cpp12
-rw-r--r--test/qr_fullpivoting.cpp8
-rw-r--r--test/redux.cpp2
-rw-r--r--test/stable_norm.cpp79
-rw-r--r--test/visitor.cpp131
17 files changed, 273 insertions, 51 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 03fbd48fc..f3c15612f 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -94,6 +94,7 @@ ei_add_test(basicstuff)
ei_add_test(linearstructure)
ei_add_test(cwiseop)
ei_add_test(redux)
+ei_add_test(visitor)
ei_add_test(product_small)
ei_add_test(product_large ${EI_OFLAG})
ei_add_test(product_extra ${EI_OFLAG})
@@ -115,6 +116,7 @@ ei_add_test(product_trmv ${EI_OFLAG})
ei_add_test(product_trmm ${EI_OFLAG})
ei_add_test(product_trsm ${EI_OFLAG})
ei_add_test(product_notemporary ${EI_OFLAG})
+ei_add_test(stable_norm)
ei_add_test(bandmatrix)
ei_add_test(cholesky " " "${GSL_LIBRARIES}")
ei_add_test(lu ${EI_OFLAG})
diff --git a/test/adjoint.cpp b/test/adjoint.cpp
index 964658c65..bebf47ac3 100644
--- a/test/adjoint.cpp
+++ b/test/adjoint.cpp
@@ -72,13 +72,6 @@ template<typename MatrixType> void adjoint(const MatrixType& m)
if(NumTraits<Scalar>::HasFloatingPoint)
VERIFY_IS_APPROX(v1.squaredNorm(), v1.norm() * v1.norm());
VERIFY_IS_MUCH_SMALLER_THAN(ei_abs(vzero.dot(v1)), static_cast<RealScalar>(1));
- if(NumTraits<Scalar>::HasFloatingPoint)
- {
- VERIFY_IS_MUCH_SMALLER_THAN(vzero.norm(), static_cast<RealScalar>(1));
- VERIFY_IS_APPROX(v1.norm(), v1.stableNorm());
- VERIFY_IS_APPROX(v1.blueNorm(), v1.stableNorm());
- VERIFY_IS_APPROX(v1.hypotNorm(), v1.stableNorm());
- }
// check compatibility of dot and adjoint
VERIFY(ei_isApprox(v1.dot(square * v2), (square.adjoint() * v1).dot(v2), largerEps));
@@ -124,7 +117,7 @@ void test_adjoint()
}
// test a large matrix only once
CALL_SUBTEST( adjoint(Matrix<float, 100, 100>()) );
-
+
{
MatrixXcf a(10,10), b(10,10);
VERIFY_RAISES_ASSERT(a = a.transpose());
diff --git a/test/cholesky.cpp b/test/cholesky.cpp
index df937fd0f..526a9f9d0 100644
--- a/test/cholesky.cpp
+++ b/test/cholesky.cpp
@@ -82,7 +82,7 @@ template<typename MatrixType> void cholesky(const MatrixType& m)
// // test gsl itself !
// VERIFY_IS_APPROX(vecB, _vecB);
// VERIFY_IS_APPROX(vecX, _vecX);
-//
+//
// Gsl::free(gMatA);
// Gsl::free(gSymm);
// Gsl::free(gVecB);
@@ -149,16 +149,16 @@ void test_cholesky()
{
for(int i = 0; i < g_repeat; i++) {
CALL_SUBTEST( cholesky(Matrix<double,1,1>()) );
-// CALL_SUBTEST( cholesky(MatrixXd(1,1)) );
-// CALL_SUBTEST( cholesky(Matrix2d()) );
-// CALL_SUBTEST( cholesky(Matrix3f()) );
-// CALL_SUBTEST( cholesky(Matrix4d()) );
+ CALL_SUBTEST( cholesky(MatrixXd(1,1)) );
+ CALL_SUBTEST( cholesky(Matrix2d()) );
+ CALL_SUBTEST( cholesky(Matrix3f()) );
+ CALL_SUBTEST( cholesky(Matrix4d()) );
CALL_SUBTEST( cholesky(MatrixXd(200,200)) );
CALL_SUBTEST( cholesky(MatrixXcd(100,100)) );
}
-// CALL_SUBTEST( cholesky_verify_assert<Matrix3f>() );
-// CALL_SUBTEST( cholesky_verify_assert<Matrix3d>() );
-// CALL_SUBTEST( cholesky_verify_assert<MatrixXf>() );
-// CALL_SUBTEST( cholesky_verify_assert<MatrixXd>() );
+ CALL_SUBTEST( cholesky_verify_assert<Matrix3f>() );
+ CALL_SUBTEST( cholesky_verify_assert<Matrix3d>() );
+ CALL_SUBTEST( cholesky_verify_assert<MatrixXf>() );
+ CALL_SUBTEST( cholesky_verify_assert<MatrixXd>() );
}
diff --git a/test/conservative_resize.cpp b/test/conservative_resize.cpp
index f0d025283..b92dd5449 100644
--- a/test/conservative_resize.cpp
+++ b/test/conservative_resize.cpp
@@ -65,7 +65,7 @@ void run_matrix_tests()
const int rows = ei_random<int>(50,75);
const int cols = ei_random<int>(50,75);
m = n = MatrixType::Random(50,50);
- m.conservativeResize(rows,cols,true);
+ m.conservativeResizeLike(MatrixType::Zero(rows,cols));
VERIFY_IS_APPROX(m.block(0,0,n.rows(),n.cols()), n);
VERIFY( rows<=50 || m.block(50,0,rows-50,cols).sum() == Scalar(0) );
VERIFY( cols<=50 || m.block(0,50,rows,cols-50).sum() == Scalar(0) );
@@ -102,7 +102,7 @@ void run_vector_tests()
{
const int size = ei_random<int>(50,100);
m = n = MatrixType::Random(50);
- m.conservativeResize(size,true);
+ m.conservativeResizeLike(MatrixType::Zero(size));
VERIFY_IS_APPROX(m.segment(0,50), n);
VERIFY( size<=50 || m.segment(50,size-50).sum() == Scalar(0) );
}
diff --git a/test/geo_orthomethods.cpp b/test/geo_orthomethods.cpp
index 5e1d5bdb4..540a63b82 100644
--- a/test/geo_orthomethods.cpp
+++ b/test/geo_orthomethods.cpp
@@ -86,10 +86,10 @@ template<typename Scalar, int Size> void orthomethods(int size=Size)
VERIFY_IS_MUCH_SMALLER_THAN(v0.unitOrthogonal().dot(v0), Scalar(1));
VERIFY_IS_APPROX(v0.unitOrthogonal().norm(), RealScalar(1));
- if (size>3)
+ if (size>=3)
{
- v0.template start<3>().setZero();
- v0.end(size-3).setRandom();
+ v0.template start<2>().setZero();
+ v0.end(size-2).setRandom();
VERIFY_IS_MUCH_SMALLER_THAN(v0.unitOrthogonal().dot(v0), Scalar(1));
VERIFY_IS_APPROX(v0.unitOrthogonal().norm(), RealScalar(1));
diff --git a/test/geo_transformations.cpp b/test/geo_transformations.cpp
index 914dbaf74..2b05f2457 100644
--- a/test/geo_transformations.cpp
+++ b/test/geo_transformations.cpp
@@ -296,10 +296,10 @@ template<typename Scalar, int Mode> void transformations(void)
t0.setIdentity();
t0.translate(v0);
t0.linear().setRandom();
- VERIFY_IS_APPROX(t0.inverse(Affine), t0.matrix().inverse());
+ VERIFY_IS_APPROX(t0.inverse(Affine).matrix(), t0.matrix().inverse());
t0.setIdentity();
t0.translate(v0).rotate(q1);
- VERIFY_IS_APPROX(t0.inverse(Isometry), t0.matrix().inverse());
+ VERIFY_IS_APPROX(t0.inverse(Isometry).matrix(), t0.matrix().inverse());
}
// test extract rotation and aligned scaling
diff --git a/test/householder.cpp b/test/householder.cpp
index 7d300899f..b27279479 100644
--- a/test/householder.cpp
+++ b/test/householder.cpp
@@ -43,7 +43,7 @@ template<typename MatrixType> void householder(const MatrixType& m)
Matrix<Scalar, EIGEN_ENUM_MAX(MatrixType::RowsAtCompileTime,MatrixType::ColsAtCompileTime), 1> _tmp(std::max(rows,cols));
Scalar* tmp = &_tmp.coeffRef(0,0);
-
+
Scalar beta;
RealScalar alpha;
EssentialVectorType essential;
@@ -58,7 +58,7 @@ template<typename MatrixType> void householder(const MatrixType& m)
v2 = v1;
v1.applyHouseholderOnTheLeft(essential,beta,tmp);
VERIFY_IS_APPROX(v1.norm(), v2.norm());
-
+
MatrixType m1(rows, cols),
m2(rows, cols);
@@ -72,7 +72,7 @@ template<typename MatrixType> void householder(const MatrixType& m)
VERIFY_IS_MUCH_SMALLER_THAN(m1.block(1,0,rows-1,cols).norm(), m1.norm());
VERIFY_IS_MUCH_SMALLER_THAN(ei_imag(m1(0,0)), ei_real(m1(0,0)));
VERIFY_IS_APPROX(ei_real(m1(0,0)), alpha);
-
+
v1 = VectorType::Random(rows);
if(even) v1.end(rows-1).setZero();
SquareMatrixType m3(rows,rows), m4(rows,rows);
@@ -84,6 +84,9 @@ template<typename MatrixType> void householder(const MatrixType& m)
VERIFY_IS_MUCH_SMALLER_THAN(m3.block(0,1,rows,rows-1).norm(), m3.norm());
VERIFY_IS_MUCH_SMALLER_THAN(ei_imag(m3(0,0)), ei_real(m3(0,0)));
VERIFY_IS_APPROX(ei_real(m3(0,0)), alpha);
+
+ // test householder sequence
+ // TODO test HouseholderSequence
}
void test_householder()
diff --git a/test/jacobisvd.cpp b/test/jacobisvd.cpp
index 5940b8497..2e3f089a0 100644
--- a/test/jacobisvd.cpp
+++ b/test/jacobisvd.cpp
@@ -36,14 +36,14 @@ template<typename MatrixType, unsigned int Options> void svd(const MatrixType& m
RowsAtCompileTime = MatrixType::RowsAtCompileTime,
ColsAtCompileTime = MatrixType::ColsAtCompileTime
};
-
+
typedef typename MatrixType::Scalar Scalar;
typedef typename NumTraits<Scalar>::Real RealScalar;
typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime> MatrixUType;
typedef Matrix<Scalar, ColsAtCompileTime, ColsAtCompileTime> MatrixVType;
typedef Matrix<Scalar, RowsAtCompileTime, 1> ColVectorType;
typedef Matrix<Scalar, ColsAtCompileTime, 1> InputVectorType;
-
+
MatrixType a;
if(pickrandom) a = MatrixType::Random(rows,cols);
else a = m;
@@ -53,7 +53,7 @@ template<typename MatrixType, unsigned int Options> void svd(const MatrixType& m
sigma.diagonal() = svd.singularValues().template cast<Scalar>();
MatrixUType u = svd.matrixU();
MatrixVType v = svd.matrixV();
-
+
VERIFY_IS_APPROX(a, u * sigma * v.adjoint());
VERIFY_IS_UNITARY(u);
VERIFY_IS_UNITARY(v);
@@ -98,7 +98,7 @@ void test_jacobisvd()
}
CALL_SUBTEST(( svd<MatrixXf,0>(MatrixXf(300,200)) ));
CALL_SUBTEST(( svd<MatrixXcd,AtLeastAsManyColsAsRows>(MatrixXcd(100,150)) ));
-
+
CALL_SUBTEST(( svd_verify_assert<Matrix3f>() ));
CALL_SUBTEST(( svd_verify_assert<Matrix3d>() ));
CALL_SUBTEST(( svd_verify_assert<MatrixXf>() ));
diff --git a/test/main.h b/test/main.h
index 619fc9e06..8c93e856c 100644
--- a/test/main.h
+++ b/test/main.h
@@ -40,6 +40,11 @@
#define DEFAULT_REPEAT 10
+#ifdef __ICC
+// disable warning #279: controlling expression is constant
+#pragma warning disable 279
+#endif
+
namespace Eigen
{
static std::vector<std::string> g_test_stack;
diff --git a/test/mixingtypes.cpp b/test/mixingtypes.cpp
index 7dc57e6f7..3e322c7fe 100644
--- a/test/mixingtypes.cpp
+++ b/test/mixingtypes.cpp
@@ -175,9 +175,9 @@ void test_mixingtypes()
{
// check that our operator new is indeed called:
CALL_SUBTEST(mixingtypes<3>());
-// CALL_SUBTEST(mixingtypes<4>());
-// CALL_SUBTEST(mixingtypes<Dynamic>(20));
-//
-// CALL_SUBTEST(mixingtypes_small<4>());
-// CALL_SUBTEST(mixingtypes_large(20));
+ CALL_SUBTEST(mixingtypes<4>());
+ CALL_SUBTEST(mixingtypes<Dynamic>(20));
+
+ CALL_SUBTEST(mixingtypes_small<4>());
+ CALL_SUBTEST(mixingtypes_large(20));
}
diff --git a/test/product_extra.cpp b/test/product_extra.cpp
index fcec362a5..3ad99fc7a 100644
--- a/test/product_extra.cpp
+++ b/test/product_extra.cpp
@@ -104,13 +104,24 @@ template<typename MatrixType> void product_extra(const MatrixType& m)
VERIFY_IS_APPROX((-m1.adjoint() * s2) * (s1 * v1.adjoint()),
(-m1.adjoint()*s2).eval() * (s1 * v1.adjoint()).eval());
+ // test the vector-matrix product with non aligned starts
+ int i = ei_random<int>(0,m1.rows()-2);
+ int j = ei_random<int>(0,m1.cols()-2);
+ int r = ei_random<int>(1,m1.rows()-i);
+ int c = ei_random<int>(1,m1.cols()-j);
+ int i2 = ei_random<int>(0,m1.rows()-1);
+ int j2 = ei_random<int>(0,m1.cols()-1);
+
+ VERIFY_IS_APPROX(m1.col(j2).adjoint() * m1.block(0,j,m1.rows(),c), m1.col(j2).adjoint().eval() * m1.block(0,j,m1.rows(),c).eval());
+ VERIFY_IS_APPROX(m1.block(i,0,r,m1.cols()) * m1.row(i2).adjoint(), m1.block(i,0,r,m1.cols()).eval() * m1.row(i2).adjoint().eval());
+
}
void test_product_extra()
{
for(int i = 0; i < g_repeat; i++) {
- CALL_SUBTEST( product_extra(MatrixXf(ei_random<int>(1,320), ei_random<int>(1,320))) );
+ CALL_SUBTEST( product_extra(MatrixXf(ei_random<int>(2,320), ei_random<int>(2,320))) );
CALL_SUBTEST( product_extra(MatrixXcf(ei_random<int>(50,50), ei_random<int>(50,50))) );
- CALL_SUBTEST( product_extra(Matrix<std::complex<double>,Dynamic,Dynamic,RowMajor>(ei_random<int>(1,50), ei_random<int>(1,50))) );
+ CALL_SUBTEST( product_extra(Matrix<std::complex<double>,Dynamic,Dynamic,RowMajor>(ei_random<int>(2,50), ei_random<int>(2,50))) );
}
}
diff --git a/test/qr.cpp b/test/qr.cpp
index f2e2eda61..f185ac86e 100644
--- a/test/qr.cpp
+++ b/test/qr.cpp
@@ -78,7 +78,7 @@ template<typename MatrixType> void qr_invertible()
m3 = MatrixType::Random(size,size);
qr.solve(m3, &m2);
VERIFY_IS_APPROX(m3, m1*m2);
-
+
// now construct a matrix with prescribed determinant
m1.setZero();
for(int i = 0; i < size; i++) m1(i,i) = ei_random<Scalar>();
diff --git a/test/qr_colpivoting.cpp b/test/qr_colpivoting.cpp
index 283855451..588a41e56 100644
--- a/test/qr_colpivoting.cpp
+++ b/test/qr_colpivoting.cpp
@@ -42,18 +42,18 @@ template<typename MatrixType> void qr()
VERIFY(!qr.isInjective());
VERIFY(!qr.isInvertible());
VERIFY(!qr.isSurjective());
-
+
MatrixType r = qr.matrixQR();
// FIXME need better way to construct trapezoid
for(int i = 0; i < rows; i++) for(int j = 0; j < cols; j++) if(i>j) r(i,j) = Scalar(0);
-
+
MatrixType b = qr.matrixQ() * r;
MatrixType c = MatrixType::Zero(rows,cols);
-
+
for(int i = 0; i < cols; ++i) c.col(qr.colsPermutation().coeff(i)) = b.col(i);
VERIFY_IS_APPROX(m1, c);
-
+
MatrixType m2 = MatrixType::Random(cols,cols2);
MatrixType m3 = m1*m2;
m2 = MatrixType::Random(cols,cols2);
@@ -116,9 +116,7 @@ template<typename MatrixType> void qr_verify_assert()
void test_qr_colpivoting()
{
- for(int i = 0; i < 1; i++) {
- // FIXME : very weird bug here
-// CALL_SUBTEST( qr(Matrix2f()) );
+ for(int i = 0; i < 1; i++) {
CALL_SUBTEST( qr<MatrixXf>() );
CALL_SUBTEST( qr<MatrixXd>() );
CALL_SUBTEST( qr<MatrixXcd>() );
diff --git a/test/qr_fullpivoting.cpp b/test/qr_fullpivoting.cpp
index 525c669a5..3a37bcb46 100644
--- a/test/qr_fullpivoting.cpp
+++ b/test/qr_fullpivoting.cpp
@@ -46,14 +46,14 @@ template<typename MatrixType> void qr()
MatrixType r = qr.matrixQR();
// FIXME need better way to construct trapezoid
for(int i = 0; i < rows; i++) for(int j = 0; j < cols; j++) if(i>j) r(i,j) = Scalar(0);
-
+
MatrixType b = qr.matrixQ() * r;
MatrixType c = MatrixType::Zero(rows,cols);
-
+
for(int i = 0; i < cols; ++i) c.col(qr.colsPermutation().coeff(i)) = b.col(i);
VERIFY_IS_APPROX(m1, c);
-
+
MatrixType m2 = MatrixType::Random(cols,cols2);
MatrixType m3 = m1*m2;
m2 = MatrixType::Random(cols,cols2);
@@ -88,7 +88,7 @@ template<typename MatrixType> void qr_invertible()
m3 = MatrixType::Random(size,size);
VERIFY(qr.solve(m3, &m2));
VERIFY_IS_APPROX(m3, m1*m2);
-
+
// now construct a matrix with prescribed determinant
m1.setZero();
for(int i = 0; i < size; i++) m1(i,i) = ei_random<Scalar>();
diff --git a/test/redux.cpp b/test/redux.cpp
index 2a0dc97f1..951b34bca 100644
--- a/test/redux.cpp
+++ b/test/redux.cpp
@@ -120,7 +120,7 @@ void test_redux()
CALL_SUBTEST( matrixRedux(MatrixXi(8, 12)) );
}
for(int i = 0; i < g_repeat; i++) {
- CALL_SUBTEST( vectorRedux(VectorXf(5)) );
+ CALL_SUBTEST( vectorRedux(Vector4f()) );
CALL_SUBTEST( vectorRedux(VectorXd(10)) );
CALL_SUBTEST( vectorRedux(VectorXf(33)) );
}
diff --git a/test/stable_norm.cpp b/test/stable_norm.cpp
new file mode 100644
index 000000000..b8fbf5271
--- /dev/null
+++ b/test/stable_norm.cpp
@@ -0,0 +1,79 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2009 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 3 of the License, or (at your option) any later version.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#include "main.h"
+
+template<typename MatrixType> void stable_norm(const MatrixType& m)
+{
+ /* this test covers the following files:
+ StableNorm.h
+ */
+
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename NumTraits<Scalar>::Real RealScalar;
+
+ int rows = m.rows();
+ int cols = m.cols();
+
+ Scalar big = ei_random<Scalar>() * std::numeric_limits<RealScalar>::max() * RealScalar(1e-4);
+ Scalar small = static_cast<RealScalar>(1)/big;
+
+ MatrixType vzero = MatrixType::Zero(rows, cols),
+ vrand = MatrixType::Random(rows, cols),
+ vbig(rows, cols),
+ vsmall(rows,cols);
+
+ vbig.fill(big);
+ vsmall.fill(small);
+
+ VERIFY_IS_MUCH_SMALLER_THAN(vzero.norm(), static_cast<RealScalar>(1));
+ VERIFY_IS_APPROX(vrand.stableNorm(), vrand.norm());
+ VERIFY_IS_APPROX(vrand.blueNorm(), vrand.norm());
+ VERIFY_IS_APPROX(vrand.hypotNorm(), vrand.norm());
+
+ RealScalar size = static_cast<RealScalar>(m.size());
+
+ // test overflow
+ VERIFY_IS_NOT_APPROX(static_cast<Scalar>(vbig.norm()), ei_sqrt(size)*big); // here the default norm must fail
+ VERIFY_IS_APPROX(static_cast<Scalar>(vbig.stableNorm()), ei_sqrt(size)*big);
+ VERIFY_IS_APPROX(static_cast<Scalar>(vbig.blueNorm()), ei_sqrt(size)*big);
+ VERIFY_IS_APPROX(static_cast<Scalar>(vbig.hypotNorm()), ei_sqrt(size)*big);
+
+ // test underflow
+ VERIFY_IS_NOT_APPROX(static_cast<Scalar>(vsmall.norm()), ei_sqrt(size)*small); // here the default norm must fail
+ VERIFY_IS_APPROX(static_cast<Scalar>(vsmall.stableNorm()), ei_sqrt(size)*small);
+ VERIFY_IS_APPROX(static_cast<Scalar>(vsmall.blueNorm()), ei_sqrt(size)*small);
+ VERIFY_IS_APPROX(static_cast<Scalar>(vsmall.hypotNorm()), ei_sqrt(size)*small);
+}
+
+void test_stable_norm()
+{
+ for(int i = 0; i < g_repeat; i++) {
+ CALL_SUBTEST( stable_norm(Matrix<float, 1, 1>()) );
+ CALL_SUBTEST( stable_norm(Vector4d()) );
+ CALL_SUBTEST( stable_norm(VectorXd(ei_random<int>(10,2000))) );
+ CALL_SUBTEST( stable_norm(VectorXf(ei_random<int>(10,2000))) );
+ CALL_SUBTEST( stable_norm(VectorXcd(ei_random<int>(10,2000))) );
+ }
+}
diff --git a/test/visitor.cpp b/test/visitor.cpp
new file mode 100644
index 000000000..b78782b78
--- /dev/null
+++ b/test/visitor.cpp
@@ -0,0 +1,131 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 3 of the License, or (at your option) any later version.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#include "main.h"
+
+template<typename MatrixType> void matrixVisitor(const MatrixType& p)
+{
+ typedef typename MatrixType::Scalar Scalar;
+
+ int rows = p.rows();
+ int cols = p.cols();
+
+ // construct a random matrix where all coefficients are different
+ MatrixType m;
+ m = MatrixType::Random(rows, cols);
+ for(int i = 0; i < m.size(); i++)
+ for(int i2 = 0; i2 < i; i2++)
+ while(m(i) == m(i2)) // yes, ==
+ m(i) = ei_random<Scalar>();
+
+ Scalar minc = Scalar(1000), maxc = Scalar(-1000);
+ int minrow,mincol,maxrow,maxcol;
+ for(int j = 0; j < cols; j++)
+ for(int i = 0; i < rows; i++)
+ {
+ if(m(i,j) < minc)
+ {
+ minc = m(i,j);
+ minrow = i;
+ mincol = j;
+ }
+ if(m(i,j) > maxc)
+ {
+ maxc = m(i,j);
+ maxrow = i;
+ maxcol = j;
+ }
+ }
+ int eigen_minrow, eigen_mincol, eigen_maxrow, eigen_maxcol;
+ Scalar eigen_minc, eigen_maxc;
+ eigen_minc = m.minCoeff(&eigen_minrow,&eigen_mincol);
+ eigen_maxc = m.maxCoeff(&eigen_maxrow,&eigen_maxcol);
+ VERIFY(minrow == eigen_minrow);
+ VERIFY(maxrow == eigen_maxrow);
+ VERIFY(mincol == eigen_mincol);
+ VERIFY(maxcol == eigen_maxcol);
+ VERIFY_IS_APPROX(minc, eigen_minc);
+ VERIFY_IS_APPROX(maxc, eigen_maxc);
+ VERIFY_IS_APPROX(minc, m.minCoeff());
+ VERIFY_IS_APPROX(maxc, m.maxCoeff());
+}
+
+template<typename VectorType> void vectorVisitor(const VectorType& w)
+{
+ typedef typename VectorType::Scalar Scalar;
+
+ int size = w.size();
+
+ // construct a random vector where all coefficients are different
+ VectorType v;
+ v = VectorType::Random(size);
+ for(int i = 0; i < size; i++)
+ for(int i2 = 0; i2 < i; i2++)
+ while(v(i) == v(i2)) // yes, ==
+ v(i) = ei_random<Scalar>();
+
+ Scalar minc = Scalar(1000), maxc = Scalar(-1000);
+ int minidx,maxidx;
+ for(int i = 0; i < size; i++)
+ {
+ if(v(i) < minc)
+ {
+ minc = v(i);
+ minidx = i;
+ }
+ if(v(i) > maxc)
+ {
+ maxc = v(i);
+ maxidx = i;
+ }
+ }
+ int eigen_minidx, eigen_maxidx;
+ Scalar eigen_minc, eigen_maxc;
+ eigen_minc = v.minCoeff(&eigen_minidx);
+ eigen_maxc = v.maxCoeff(&eigen_maxidx);
+ VERIFY(minidx == eigen_minidx);
+ VERIFY(maxidx == eigen_maxidx);
+ VERIFY_IS_APPROX(minc, eigen_minc);
+ VERIFY_IS_APPROX(maxc, eigen_maxc);
+ VERIFY_IS_APPROX(minc, v.minCoeff());
+ VERIFY_IS_APPROX(maxc, v.maxCoeff());
+}
+
+void test_visitor()
+{
+ for(int i = 0; i < g_repeat; i++) {
+ CALL_SUBTEST( matrixVisitor(Matrix<float, 1, 1>()) );
+ CALL_SUBTEST( matrixVisitor(Matrix2f()) );
+ CALL_SUBTEST( matrixVisitor(Matrix4d()) );
+ CALL_SUBTEST( matrixVisitor(MatrixXd(8, 12)) );
+ CALL_SUBTEST( matrixVisitor(Matrix<double,Dynamic,Dynamic,RowMajor>(20, 20)) );
+ CALL_SUBTEST( matrixVisitor(MatrixXi(8, 12)) );
+ }
+ for(int i = 0; i < g_repeat; i++) {
+ CALL_SUBTEST( vectorVisitor(Vector4f()) );
+ CALL_SUBTEST( vectorVisitor(VectorXd(10)) );
+ CALL_SUBTEST( vectorVisitor(RowVectorXd(10)) );
+ CALL_SUBTEST( vectorVisitor(VectorXf(33)) );
+ }
+}