Skip to content

Commit dfdfa75

Browse files
author
Thomas Grützmacher
committed
Fixed isfinite implementation and added test
Both the implementation and the documentation of the self-written `isfinite` was wrong and is now fixed. Also added a test to check the implementation of `isfinite`.
1 parent 1b9b919 commit dfdfa75

File tree

3 files changed

+106
-6
lines changed

3 files changed

+106
-6
lines changed

core/test/base/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ ginkgo_create_test(extended_float)
99
ginkgo_create_test(executor)
1010
ginkgo_create_test(iterator_factory)
1111
ginkgo_create_test(lin_op)
12+
ginkgo_create_test(math)
1213
ginkgo_create_test(matrix_data)
1314
ginkgo_create_test(mtx_io)
1415
ginkgo_create_test(perturbation)

core/test/base/math.cpp

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*******************************<GINKGO LICENSE>******************************
2+
Copyright (c) 2017-2019, the Ginkgo authors
3+
All rights reserved.
4+
5+
Redistribution and use in source and binary forms, with or without
6+
modification, are permitted provided that the following conditions
7+
are met:
8+
9+
1. Redistributions of source code must retain the above copyright
10+
notice, this list of conditions and the following disclaimer.
11+
12+
2. Redistributions in binary form must reproduce the above copyright
13+
notice, this list of conditions and the following disclaimer in the
14+
documentation and/or other materials provided with the distribution.
15+
16+
3. Neither the name of the copyright holder nor the names of its
17+
contributors may be used to endorse or promote products derived from
18+
this software without specific prior written permission.
19+
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21+
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22+
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23+
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24+
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+
******************************<GINKGO LICENSE>*******************************/
32+
33+
#include <ginkgo/core/base/math.hpp>
34+
35+
36+
#include <cmath>
37+
#include <complex>
38+
#include <limits>
39+
40+
41+
#include <gtest/gtest.h>
42+
43+
44+
namespace {
45+
46+
47+
template <typename T>
48+
void test_real_isfinite()
49+
{
50+
using limits = std::numeric_limits<T>;
51+
constexpr auto inf{limits::infinity()};
52+
53+
ASSERT_TRUE(gko::isfinite(T{0}));
54+
ASSERT_TRUE(gko::isfinite(-T{0}));
55+
ASSERT_TRUE(gko::isfinite(T{1}));
56+
ASSERT_FALSE(gko::isfinite(inf));
57+
ASSERT_FALSE(gko::isfinite(-inf));
58+
ASSERT_FALSE(gko::isfinite(limits::quiet_NaN()));
59+
ASSERT_FALSE(gko::isfinite(limits::signaling_NaN()));
60+
}
61+
62+
63+
template <typename T>
64+
void test_complex_isfinite()
65+
{
66+
using limits = std::numeric_limits<T>;
67+
using c_type = std::complex<T>;
68+
constexpr auto inf{limits::infinity()};
69+
constexpr auto quiet_nan{limits::quiet_NaN()};
70+
constexpr auto signaling_nan{limits::signaling_NaN()};
71+
72+
ASSERT_TRUE(gko::isfinite(c_type{T{0}, T{0}}));
73+
ASSERT_TRUE(gko::isfinite(c_type{-T{0}, -T{0}}));
74+
ASSERT_TRUE(gko::isfinite(c_type{T{1}, T{0}}));
75+
ASSERT_TRUE(gko::isfinite(c_type{T{0}, T{1}}));
76+
ASSERT_FALSE(gko::isfinite(c_type{inf, T{0}}));
77+
ASSERT_FALSE(gko::isfinite(c_type{-inf, T{0}}));
78+
ASSERT_FALSE(gko::isfinite(c_type{quiet_nan, T{0}}));
79+
ASSERT_FALSE(gko::isfinite(c_type{signaling_nan, T{0}}));
80+
ASSERT_FALSE(gko::isfinite(c_type{T{0}, inf}));
81+
ASSERT_FALSE(gko::isfinite(c_type{T{0}, -inf}));
82+
ASSERT_FALSE(gko::isfinite(c_type{T{0}, quiet_nan}));
83+
ASSERT_FALSE(gko::isfinite(c_type{T{0}, signaling_nan}));
84+
}
85+
86+
87+
TEST(IsFinite, Float) { test_real_isfinite<float>(); }
88+
89+
90+
TEST(IsFinite, Double) { test_real_isfinite<float>(); }
91+
92+
93+
TEST(IsFinite, FloatComplex) { test_complex_isfinite<float>(); }
94+
95+
96+
TEST(IsFinite, DoubleComplex) { test_complex_isfinite<double>(); }
97+
98+
99+
} // namespace

include/ginkgo/core/base/math.hpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -563,13 +563,13 @@ using std::isfinite;
563563
*
564564
* @param value complex value to check
565565
*
566-
* returns `true` if a component of the complex value is either positive or
567-
* negative infinity or NaN. Otherwise `false`
566+
* returns `false` if a component of the complex value is either positive or
567+
* negative infinity or NaN. Otherwise `true`
568568
*/
569569
#define GKO_DEFINE_ISFINITE_FOR_COMPLEX_TYPE(_type) \
570570
GKO_INLINE GKO_ATTRIBUTES bool isfinite(const _type &value) \
571571
{ \
572-
return isfinite(value.real()) || isfinite(value.imag()); \
572+
return isfinite(value.real()) && isfinite(value.imag()); \
573573
} \
574574
static_assert(true, \
575575
"This assert is used to counter the false positive extra " \
@@ -593,14 +593,14 @@ using std::isfinite; // use the optimized function for all supported types
593593
*
594594
* @param value complex value to check
595595
*
596-
* returns `true` if a component of value is either positive or negative
597-
* infinity or NaN. Otherwise `false`
596+
* returns `false` if a component of value is either positive or negative
597+
* infinity or NaN. Otherwise `true`
598598
*/
599599
template <typename T>
600600
GKO_INLINE GKO_ATTRIBUTES xstd::enable_if_t<is_complex_s<T>::value, bool>
601601
isfinite(const T &value)
602602
{
603-
return isfinite(value.real()) || isfinite(value.imag());
603+
return isfinite(value.real()) && isfinite(value.imag());
604604
}
605605

606606
#endif // defined(__CUDACC_VER_MAJOR__) && defined(__CUDACC_VER_MINOR__) &&

0 commit comments

Comments
 (0)