aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/stable_norm.cpp
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2014-09-02 14:49:23 +0200
committerGravatar Gael Guennebaud <g.gael@free.fr>2014-09-02 14:49:23 +0200
commit18fbe7e7d4cdb737ef5775bbb32fe62b6f8ef70e (patch)
tree102f60e51633c94db94af71a2c734f06880c8f76 /test/stable_norm.cpp
parent3eb5253ca1352391f4ea31c4a2dd06c34c4a33e7 (diff)
Fix stableNorm() with respect to NaN and inf, and add respective unit tests. blueNorm() and hypotNorm() are broken wrt to NaN/inf
Diffstat (limited to 'test/stable_norm.cpp')
-rw-r--r--test/stable_norm.cpp69
1 files changed, 68 insertions, 1 deletions
diff --git a/test/stable_norm.cpp b/test/stable_norm.cpp
index 549f91fbf..88cab7aa3 100644
--- a/test/stable_norm.cpp
+++ b/test/stable_norm.cpp
@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
+// Copyright (C) 2009-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
@@ -14,6 +14,21 @@ template<typename T> bool isNotNaN(const T& x)
return x==x;
}
+template<typename T> bool isNaN(const T& x)
+{
+ return x!=x;
+}
+
+template<typename T> bool isInf(const T& x)
+{
+ return x > NumTraits<T>::highest();
+}
+
+template<typename T> bool isMinusInf(const T& x)
+{
+ return x < NumTraits<T>::lowest();
+}
+
// workaround aggressive optimization in ICC
template<typename T> EIGEN_DONT_INLINE T sub(T a, T b) { return a - b; }
@@ -106,6 +121,58 @@ template<typename MatrixType> void stable_norm(const MatrixType& m)
VERIFY_IS_APPROX(vrand.rowwise().stableNorm(), vrand.rowwise().norm());
VERIFY_IS_APPROX(vrand.rowwise().blueNorm(), vrand.rowwise().norm());
VERIFY_IS_APPROX(vrand.rowwise().hypotNorm(), vrand.rowwise().norm());
+
+ // test NaN, +inf, -inf
+ MatrixType v;
+ Index i = internal::random<Index>(0,rows-1);
+ Index j = internal::random<Index>(0,cols-1);
+
+ // NaN
+ {
+ v = vrand;
+ v(i,j) = RealScalar(0)/RealScalar(0);
+ VERIFY(!isFinite(v.squaredNorm())); VERIFY(isNaN(v.squaredNorm()));
+ VERIFY(!isFinite(v.norm())); VERIFY(isNaN(v.norm()));
+ VERIFY(!isFinite(v.stableNorm())); VERIFY(isNaN(v.stableNorm()));
+ VERIFY(!isFinite(v.blueNorm())); VERIFY(isNaN(v.blueNorm()));
+// VERIFY(!isFinite(v.hypotNorm())); //VERIFY(isNaN(v.hypotNorm()));
+ }
+
+ // +inf
+ {
+ v = vrand;
+ v(i,j) = RealScalar(1)/RealScalar(0);
+ VERIFY(!isFinite(v.squaredNorm())); VERIFY(isInf(v.squaredNorm()));
+ VERIFY(!isFinite(v.norm())); VERIFY(isInf(v.norm()));
+ VERIFY(!isFinite(v.stableNorm())); VERIFY(isInf(v.stableNorm()));
+// VERIFY(!isFinite(v.blueNorm())); //VERIFY(isInf(v.blueNorm()));
+// VERIFY(!isFinite(v.hypotNorm())); //VERIFY(isInf(v.hypotNorm()));
+ }
+
+ // -inf
+ {
+ v = vrand;
+ v(i,j) = RealScalar(-1)/RealScalar(0);
+ VERIFY(!isFinite(v.squaredNorm())); VERIFY(isInf(v.squaredNorm()));
+ VERIFY(!isFinite(v.norm())); VERIFY(isInf(v.norm()));
+ VERIFY(!isFinite(v.stableNorm())); VERIFY(isInf(v.stableNorm()));
+// VERIFY(!isFinite(v.blueNorm())); VERIFY(isInf(v.blueNorm()));
+// VERIFY(!isFinite(v.hypotNorm())); VERIFY(isInf(v.hypotNorm()));
+ }
+
+ // mix
+ {
+ Index i2 = internal::random<Index>(0,rows-1);
+ Index j2 = internal::random<Index>(0,cols-1);
+ v = vrand;
+ v(i,j) = RealScalar(-1)/RealScalar(0);
+ v(i2,j2) = RealScalar(0)/RealScalar(0);
+ VERIFY(!isFinite(v.squaredNorm())); VERIFY(isNaN(v.squaredNorm()));
+ VERIFY(!isFinite(v.norm())); VERIFY(isNaN(v.norm()));
+ VERIFY(!isFinite(v.stableNorm())); VERIFY(isNaN(v.stableNorm()));
+// VERIFY(!isFinite(v.blueNorm())); //VERIFY(isNaN(v.blueNorm()));
+// VERIFY(!isFinite(v.hypotNorm())); VERIFY(isNaN(v.hypotNorm()));
+ }
}
void test_stable_norm()