improve/fix stable_norm unit test

This commit is contained in:
Gael Guennebaud 2010-06-08 13:29:27 +02:00
parent 626afe8b62
commit 4b5d359c3a
2 changed files with 36 additions and 17 deletions

View File

@ -51,8 +51,8 @@ void testVectorType(const VectorType& base)
{ {
typedef typename ei_traits<VectorType>::Scalar Scalar; typedef typename ei_traits<VectorType>::Scalar Scalar;
Scalar low = ei_random<Scalar>(-500,500); Scalar low = ei_random<Scalar>(-500,500);
Scalar high = ei_random<Scalar>(-500,500); Scalar high = ei_random<Scalar>(-500,500);
if (low>high) std::swap(low,high); if (low>high) std::swap(low,high);
const int size = base.size(); const int size = base.size();
const Scalar step = (high-low)/(size-1); const Scalar step = (high-low)/(size-1);
@ -91,7 +91,7 @@ void testVectorType(const VectorType& base)
Matrix<Scalar,Dynamic,1> size_changer(size+50); Matrix<Scalar,Dynamic,1> size_changer(size+50);
size_changer.setLinSpaced(low,high,size); size_changer.setLinSpaced(low,high,size);
VERIFY( size_changer.size() == size ); VERIFY( size_changer.size() == size );
} }
template<typename MatrixType> template<typename MatrixType>

View File

@ -24,6 +24,11 @@
#include "main.h" #include "main.h"
template<typename T> bool isFinite(const T& x)
{
return x==x && x>=NumTraits<T>::lowest() && x<=NumTraits<T>::highest();
}
template<typename MatrixType> void stable_norm(const MatrixType& m) template<typename MatrixType> void stable_norm(const MatrixType& m)
{ {
/* this test covers the following files: /* this test covers the following files:
@ -50,7 +55,7 @@ template<typename MatrixType> void stable_norm(const MatrixType& m)
int rows = m.rows(); int rows = m.rows();
int cols = m.cols(); int cols = m.cols();
Scalar big = ei_abs(ei_random<Scalar>()) * (std::numeric_limits<RealScalar>::max() * RealScalar(1e-4)); Scalar big = ei_random<Scalar>()) * (std::numeric_limits<RealScalar>::max() * RealScalar(1e-4);
Scalar small = static_cast<RealScalar>(1)/big; Scalar small = static_cast<RealScalar>(1)/big;
MatrixType vzero = MatrixType::Zero(rows, cols), MatrixType vzero = MatrixType::Zero(rows, cols),
@ -68,22 +73,36 @@ template<typename MatrixType> void stable_norm(const MatrixType& m)
RealScalar size = static_cast<RealScalar>(m.size()); RealScalar size = static_cast<RealScalar>(m.size());
// test overflow // test isFinite
/* VERIFY_IS_NOT_APPROX(static_cast<Scalar>(vbig.norm()), ei_sqrt(size)*big); // here the default norm must fail VERIFY(!isFinite( ei_abs(big)/RealScalar(0)));
Does not succeed on gcc (Ubuntu 4.4.1-4ubuntu9) 4.4.1, Intel Core 2 Duo T7300 with no SSE optimizations VERIFY(!isFinite(-ei_abs(big)/RealScalar(0)));
*/ VERIFY(!isFinite(ei_sqrt(-ei_abs(big))));
VERIFY_IS_APPROX(static_cast<Scalar>(vbig.stableNorm()), ei_sqrt(size)*big); // test overflow
VERIFY_IS_APPROX(static_cast<Scalar>(vbig.blueNorm()), ei_sqrt(size)*big); VERIFY(isFinite(ei_sqrt(size)*ei_abs(big)));
VERIFY_IS_APPROX(static_cast<Scalar>(vbig.hypotNorm()), ei_sqrt(size)*big); #ifdef EIGEN_VECTORIZE_SSE
// since x87 FPU uses 80bits of precision overflow is not detected
if(ei_packet_traits<Scalar>::size>1)
{
VERIFY_IS_NOT_APPROX(static_cast<Scalar>(vbig.norm()), ei_sqrt(size)*big); // here the default norm must fail
}
#endif
VERIFY_IS_APPROX(vbig.stableNorm(), ei_sqrt(size)*ei_abs(big));
VERIFY_IS_APPROX(vbig.blueNorm(), ei_sqrt(size)*ei_abs(big));
VERIFY_IS_APPROX(vbig.hypotNorm(), ei_sqrt(size)*ei_abs(big));
// test underflow // test underflow
/* VERIFY_IS_NOT_APPROX(static_cast<Scalar>(vsmall.norm()), ei_sqrt(size)*small); // here the default norm must fail VERIFY(isFinite(ei_sqrt(size)*ei_abs(small)));
Does not succeed on gcc (Ubuntu 4.4.1-4ubuntu9) 4.4.1, Intel Core 2 Duo T7300 with no SSE optimizations #ifdef EIGEN_VECTORIZE_SSE
*/ // since x87 FPU uses 80bits of precision underflow is not detected
VERIFY_IS_APPROX(static_cast<Scalar>(vsmall.stableNorm()), ei_sqrt(size)*small); if(ei_packet_traits<Scalar>::size>1)
VERIFY_IS_APPROX(static_cast<Scalar>(vsmall.blueNorm()), ei_sqrt(size)*small); {
VERIFY_IS_APPROX(static_cast<Scalar>(vsmall.hypotNorm()), ei_sqrt(size)*small); VERIFY_IS_NOT_APPROX(static_cast<Scalar>(vsmall.norm()), ei_sqrt(size)*small); // here the default norm must fail
}
#endif
VERIFY_IS_APPROX(vsmall.stableNorm(), ei_sqrt(size)*ei_abs(small));
VERIFY_IS_APPROX(vsmall.blueNorm(), ei_sqrt(size)*ei_abs(small));
VERIFY_IS_APPROX(vsmall.hypotNorm(), ei_sqrt(size)*ei_abs(small));
// Test compilation of cwise() version // Test compilation of cwise() version
VERIFY_IS_APPROX(vrand.colwise().stableNorm(), vrand.colwise().norm()); VERIFY_IS_APPROX(vrand.colwise().stableNorm(), vrand.colwise().norm());