aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2013-04-16 15:10:40 +0200
committerGravatar Gael Guennebaud <g.gael@free.fr>2013-04-16 15:10:40 +0200
commit94e20f485c44731230095dbf8a7344fc6ea4b431 (patch)
treef8b97bbe8f36cfcce76108ca5d9648844fb1bec1
parentd4b0c19a463692e3ef4fb9c70ad1419d097a1dcf (diff)
Big 564: add hasNaN and isFinite members
-rw-r--r--Eigen/src/Core/BooleanRedux.h20
-rw-r--r--Eigen/src/Core/DenseBase.h5
-rw-r--r--test/CMakeLists.txt1
-rw-r--r--test/special_numbers.cpp59
4 files changed, 83 insertions, 2 deletions
diff --git a/Eigen/src/Core/BooleanRedux.h b/Eigen/src/Core/BooleanRedux.h
index a235a14e6..f6afeb034 100644
--- a/Eigen/src/Core/BooleanRedux.h
+++ b/Eigen/src/Core/BooleanRedux.h
@@ -129,6 +129,26 @@ inline typename DenseBase<Derived>::Index DenseBase<Derived>::count() const
return derived().template cast<bool>().template cast<Index>().sum();
}
+/** \returns true is \c *this contains at least one Not A Number (NaN).
+ *
+ * \sa isFinite()
+ */
+template<typename Derived>
+inline bool DenseBase<Derived>::hasNaN() const
+{
+ return !((derived().array()==derived().array()).all());
+}
+
+/** \returns true if \c *this contains only finite numbers, i.e., no NaN and no +/-INF values.
+ *
+ * \sa hasNaN()
+ */
+template<typename Derived>
+inline bool DenseBase<Derived>::isFinite() const
+{
+ return !((derived()-derived()).hasNaN());
+}
+
} // end namespace Eigen
#endif // EIGEN_ALLANDANY_H
diff --git a/Eigen/src/Core/DenseBase.h b/Eigen/src/Core/DenseBase.h
index c17364f30..dfdf6c4a8 100644
--- a/Eigen/src/Core/DenseBase.h
+++ b/Eigen/src/Core/DenseBase.h
@@ -336,6 +336,9 @@ template<typename Derived> class DenseBase
bool isConstant(const Scalar& value, const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
bool isZero(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
bool isOnes(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
+
+ inline bool hasNaN() const;
+ inline bool isFinite() const;
inline Derived& operator*=(const Scalar& other);
inline Derived& operator/=(const Scalar& other);
@@ -415,8 +418,6 @@ template<typename Derived> class DenseBase
return derived().coeff(0,0);
}
-/////////// Array module ///////////
-
bool all(void) const;
bool any(void) const;
Index count() const;
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 45eb96ab3..be9617d85 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -222,6 +222,7 @@ ei_add_test(evaluators)
ei_add_test(sizeoverflow)
ei_add_test(prec_inverse_4x4)
ei_add_test(vectorwiseop)
+ei_add_test(special_numbers)
ei_add_test(simplicial_cholesky)
ei_add_test(conjugate_gradient)
diff --git a/test/special_numbers.cpp b/test/special_numbers.cpp
new file mode 100644
index 000000000..a5936184e
--- /dev/null
+++ b/test/special_numbers.cpp
@@ -0,0 +1,59 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2013 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
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include "main.h"
+
+template<typename Scalar> void special_numbers()
+{
+ typedef typename NumTraits<Scalar>::Real RealScalar;
+ typedef Matrix<Scalar, Dynamic,Dynamic> MatType;
+ int rows = internal::random<int>(1,300);
+ int cols = internal::random<int>(1,300);
+
+ Scalar nan = Scalar(0)/Scalar(0);
+ Scalar inf = Scalar(1)/Scalar(0);
+ Scalar s1 = internal::random<Scalar>();
+
+ MatType m1 = MatType::Random(rows,cols),
+ mnan = MatType::Random(rows,cols),
+ minf = MatType::Random(rows,cols),
+ mboth = MatType::Random(rows,cols);
+
+ int n = internal::random<int>(1,10);
+ for(int k=0; k<n; ++k)
+ {
+ mnan(internal::random<int>(0,rows-1), internal::random<int>(0,cols-1)) = nan;
+ minf(internal::random<int>(0,rows-1), internal::random<int>(0,cols-1)) = inf;
+ }
+ mboth = mnan + minf;
+
+ VERIFY(!m1.hasNaN());
+ VERIFY(m1.isFinite());
+
+ VERIFY(mnan.hasNaN());
+ VERIFY((s1*mnan).hasNaN());
+ VERIFY(!minf.hasNaN());
+ VERIFY(!(2*minf).hasNaN());
+ VERIFY(mboth.hasNaN());
+ VERIFY(mboth.array().hasNaN());
+
+ VERIFY(!mnan.isFinite());
+ VERIFY(!minf.isFinite());
+ VERIFY(!(minf-mboth).isFinite());
+ VERIFY(!mboth.isFinite());
+ VERIFY(!mboth.array().isFinite());
+}
+
+void test_special_numbers()
+{
+ for(int i = 0; i < 10*g_repeat; i++) {
+ CALL_SUBTEST_1( special_numbers<float>() );
+ CALL_SUBTEST_1( special_numbers<double>() );
+ }
+}