mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-04-20 08:39:37 +08:00
improve/fix stable_norm unit test
This commit is contained in:
parent
626afe8b62
commit
4b5d359c3a
@ -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>
|
||||||
|
@ -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());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user