1 //
2 // special.hpp
3 //
4 // LGPL Version 2.1 HEADER START
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 //
9 // License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 //
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // Lesser General Public License for more details.
16 //
17 // You should have received a copy of the GNU Lesser General Public
18 // License along with this library; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20 // MA 02110-1301 USA
21 //
22 // LGPL Version 2.1 HEADER END
23 //
24
25 //
26 // Copyright (c) 2020, Regents of the University of Minnesota.
27 // All rights reserved.
28 //
29 // Contributors:
30 // Yaser Afshar
31 //
32
33 #ifndef SPECIAL_HPP
34 #define SPECIAL_HPP
35
36 #include <cmath>
37 #include <type_traits>
38
39 /*!
40 * \file special.hpp
41 *
42 * \brief This file contains special helper functions and a Pi constant
43 *
44 * The special helper functions and a constant are:
45 * \c MY_PI Pi constant
46 * \c Square x**2, use instead of std::pow(x, 2.0)
47 * \c Cube x**3, use instead of std::pow(x, 3.0)
48 * \c PowInt optimized version of std::pow(x, n) with n being integer
49 * \c IsOne return true if the input is (close to) one within a tolerance
50 * \c IsNotOne return true if the input is not (close to) one within a tolerance
51 * \c IsZero return true if the input is (close to) zero within a tolerance
52 * \c IsNotZero return true if the input is not (close to) zero within a
53 * tolerance
54 * \c FloatDivZero returns zero if the denominator (d) is zero in f/d
55 */
56
57 namespace special {
58 static constexpr double MY_PI = 3.14159265358979323846;
59
60 template <typename DataType>
61 static inline constexpr
62 typename std::enable_if<std::is_floating_point<DataType>::value,
63 DataType>::type
Square(DataType const & x)64 Square(DataType const &x) {
65 return x * x;
66 }
67
68 template <typename DataType>
69 static inline constexpr
70 typename std::enable_if<std::is_floating_point<DataType>::value,
71 DataType>::type
Cube(DataType const & x)72 Cube(DataType const &x) {
73 return x * x * x;
74 }
75
76 template <typename DataType>
77 static inline typename std::enable_if<std::is_floating_point<DataType>::value,
78 DataType>::type
PowInt(DataType const & x,int const n)79 PowInt(DataType const &x, int const n) {
80 if (x == 0.0) {
81 return 0.0;
82 }
83 int nn = (n > 0) ? n : -n;
84 DataType ww = x;
85 DataType yy;
86 for (yy = 1.0; nn != 0; nn >>= 1, ww *= ww) {
87 if (nn & 1) {
88 yy *= ww;
89 }
90 }
91 return (n > 0) ? yy : 1.0 / yy;
92 }
93
94 template <typename DataType>
95 static inline constexpr
96 typename std::enable_if<std::is_floating_point<DataType>::value, bool>::type
IsOne(DataType const f,double const tol=1e-20)97 IsOne(DataType const f, double const tol = 1e-20) {
98 return std::abs(f - 1.0) < tol;
99 }
100
101 template <typename DataType>
102 static inline constexpr
103 typename std::enable_if<std::is_floating_point<DataType>::value, bool>::type
IsNotOne(DataType const f,double const tol=1e-20)104 IsNotOne(DataType const f, double const tol = 1e-20) {
105 return std::abs(f - 1.0) >= tol;
106 }
107
108 template <typename DataType>
109 static inline constexpr
110 typename std::enable_if<std::is_floating_point<DataType>::value, bool>::type
IsZero(DataType const f,double const tol=1e-20)111 IsZero(DataType const f, double const tol = 1e-20) {
112 return std::abs(f) < tol;
113 }
114
115 template <typename DataType>
116 static inline constexpr
117 typename std::enable_if<std::is_floating_point<DataType>::value, bool>::type
IsNotZero(DataType const f,double const tol=1e-20)118 IsNotZero(DataType const f, double const tol = 1e-20) {
119 return std::abs(f) >= tol;
120 }
121
122 template <typename DataType>
123 static inline constexpr
124 typename std::enable_if<std::is_floating_point<DataType>::value,
125 DataType>::type
FloatDivZero(DataType const f,DataType const d)126 FloatDivZero(DataType const f, DataType const d) {
127 return IsZero<DataType>(d) ? 0.0 : f / d;
128 }
129 } // namespace special
130
131 #endif // SPECIAL_HPP