itom  4.1.0
numeric.h
1 /* ********************************************************************
2  itom software
3  URL: http://www.uni-stuttgart.de/ito
4  Copyright (C) 2020, Institut fuer Technische Optik (ITO),
5  Universitaet Stuttgart, Germany
6 
7  This file is part of itom and its software development toolkit (SDK).
8 
9  itom is free software; you can redistribute it and/or modify it
10  under the terms of the GNU Library General Public Licence as published by
11  the Free Software Foundation; either version 2 of the Licence, or (at
12  your option) any later version.
13 
14  In addition, as a special exception, the Institut fuer Technische
15  Optik (ITO) gives you certain additional rights.
16  These rights are described in the ITO LGPL Exception version 1.0,
17  which can be found in the file LGPL_EXCEPTION.txt in this package.
18 
19  itom is distributed in the hope that it will be useful, but
20  WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library
22  General Public Licence for more details.
23 
24  You should have received a copy of the GNU Library General Public License
25  along with itom. If not, see <http://www.gnu.org/licenses/>.
26 *********************************************************************** */
27 
28 #ifndef NUMERIC_H
29 #define NUMERIC_H
30 
31 #include "typeDefs.h"
32 #include "color.h"
33 #include <limits>
34 
35 namespace ito
36 {
38 
47  template<typename _Tp> inline bool isNotZero(_Tp value)
48  {
49  return !(value == 0);
50  }
51 
53  template<> inline bool isNotZero<float32>(float32 value)
54  {
55  if (fabs(value) < std::numeric_limits<float32>::epsilon())
56  return false;
57  else
58  return true;
59  }
60 
62  template<> inline bool isNotZero<float64>(float64 value)
63  {
64  if (fabs(value) < std::numeric_limits<float64>::epsilon())
65  return false;
66  else
67  return true;
68  }
69 
70 
72 
81  template<typename _Tp> inline bool isFinite(_Tp /*value*/)
82  {
83  return true;
84  }
85 
87  template<> inline bool isFinite<float32>(float32 value)
88  {
89  unsigned char *ch = (unsigned char *)&value;
90  return (ch[3] & 0x7f) != 0x7f || (ch[2] & 0x80) != 0x80;
91  }
92 
94  template<> inline bool isFinite<float64>(float64 value)
95  {
96  unsigned char *ch = (unsigned char *)&value;
97  return (ch[7] & 0x7f) != 0x7f || (ch[6] & 0xf0) != 0xf0;
98  }
99 
101  template<> inline bool isFinite<complex64>(complex64 value)
102  {
103  float32 realVal = value.real();
104  float32 imagVal = value.real();
105  unsigned char *chreal = (unsigned char *)&realVal;
106  unsigned char *chimag = (unsigned char *)&imagVal;
107  return ((chreal[3] & 0x7f) != 0x7f || (chreal[2] & 0x80) != 0x80) && ((chimag[3] & 0x7f) != 0x7f || (chimag[2] & 0x80) != 0x80);
108  }
109 
111  template<> inline bool isFinite<complex128>(complex128 value)
112  {
113  float64 realVal = value.real();
114  float64 imagVal = value.real();
115  unsigned char *chreal = (unsigned char *)&realVal;
116  unsigned char *chimag = (unsigned char *)&imagVal;
117  return ((chreal[7] & 0x7f) != 0x7f || (chreal[6] & 0xf0) != 0xf0) && ((chimag[7] & 0x7f) != 0x7f || (chimag[6] & 0xf0) != 0xf0);
118  }
119 
121 
130  template<typename _Tp> inline bool isNaN(_Tp value)
131  {
132  return false;
133  }
134 
136  template<> inline bool isNaN<float32>(float32 value)
137  {
138  unsigned char *ch = (unsigned char *)&value;
139  return (ch[3] & 0x7f) == 0x7f && ch[2] > 0x80;
140  }
142  template<> inline bool isNaN<float64>(float64 value)
143  {
144  unsigned char *ch = (unsigned char *)&value;
145  return (ch[7] & 0x7f) == 0x7f && ch[6] > 0xf0;
146  }
147 
149  template<> inline bool isNaN<complex64>(complex64 value)
150  {
151  float32 realVal = value.real();
152  float32 imagVal = value.real();
153  unsigned char *chreal = (unsigned char *)&realVal;
154  unsigned char *chimag = (unsigned char *)&imagVal;
155  return ((chreal[3] & 0x7f) == 0x7f && chreal[2] > 0x80) || ((chimag[3] & 0x7f) == 0x7f && chimag[2] > 0x80);
156  }
157 
159  template<> inline bool isNaN<complex128>(complex128 value)
160  {
161  float64 realVal = value.real();
162  float64 imagVal = value.real();
163  unsigned char *chreal = (unsigned char *)&realVal;
164  unsigned char *chimag = (unsigned char *)&imagVal;
165  return ((chreal[7] & 0x7f) == 0x7f && chreal[6] > 0xf0) || ((chimag[7] & 0x7f) == 0x7f && chimag[6] > 0xf0);
166  }
167 
169 
178  template<typename _Tp> inline bool isInf(_Tp /*value*/)
179  {
180  return false;
181  }
182 
184  template<> inline bool isInf<float32>(float32 value)
185  {
186  unsigned char *ch = (unsigned char *)&value;
187  return (ch[3] & 0x7f) == 0x7f && ch[2] == 0x80;
188  }
189 
191  template<> inline bool isInf<float64>(float64 value)
192  {
193  unsigned char *ch = (unsigned char *)&value;
194  return (ch[7] & 0x7f) == 0x7f && ch[6] == 0xf0;
195  }
196 
198  template<> inline bool isInf<complex64>(complex64 value)
199  {
200  float32 realVal = value.real();
201  float32 imagVal = value.real();
202  unsigned char *chreal = (unsigned char *)&realVal;
203  unsigned char *chimag = (unsigned char *)&imagVal;
204  return ((chreal[3] & 0x7f) == 0x7f && chreal[2] == 0x80) || ((chimag[3] & 0x7f) == 0x7f && chimag[2] == 0x80);
205  }
206 
208  template<> inline bool isInf<complex128>(complex128 value)
209  {
210  float64 realVal = value.real();
211  float64 imagVal = value.real();
212  unsigned char *chreal = (unsigned char *)&realVal;
213  unsigned char *chimag = (unsigned char *)&imagVal;
214  return ((chreal[7] & 0x7f) == 0x7f && chreal[6] == 0xf0) || ((chimag[7] & 0x7f) == 0x7f && chimag[6] == 0xf0);
215  }
216 
218 
228  template<typename _Tp> inline bool isZeroValue(_Tp v, _Tp /*epsilon*/)
229  {
230  return v == 0;
231  }
232 
233  template<> inline bool isZeroValue(Rgba32 v, Rgba32 /*epsilon*/)
234  {
235  return v == Rgba32::zeros();
236  }
237 
238  template<> inline bool isZeroValue(float32 v, float32 epsilon)
239  {
240  return v >= epsilon ? false : (v <= -epsilon ? false : true);
241  }
242 
243  template<> inline bool isZeroValue(float64 v, float64 epsilon)
244  {
245  return v >= epsilon ? false : (v <= -epsilon ? false : true);
246  }
247 
248  template<> inline bool isZeroValue(std::complex<ito::float32> v, std::complex<ito::float32> epsilon)
249  {
250  return isZeroValue<ito::float32>(v.real(), epsilon.real()) && isZeroValue<ito::float32>(v.imag(), epsilon.real());
251  }
252 
253  template<> inline bool isZeroValue(std::complex<ito::float64> v, std::complex<ito::float64> epsilon)
254  {
255  return isZeroValue<ito::float64>(v.real(), epsilon.real()) && isZeroValue<ito::float64>(v.imag(), epsilon.real());
256  }
257 
258 
260 
263  template<typename _Tp> inline bool areEqual(_Tp a, _Tp b)
264  {
265  //for fixed-point and Rgba32 data types
266  return a == b;
267  }
268 
269  template<> inline bool areEqual(float32 a, float32 b)
270  {
271  return fabs(a - b) < std::numeric_limits<float32>::epsilon();
272  }
273 
274  template<> inline bool areEqual(float64 a, float64 b)
275  {
276  return fabs(a - b) < std::numeric_limits<float64>::epsilon();
277  }
278 
279  template<> inline bool areEqual(complex64 a, complex64 b)
280  {
281  return areEqual<ito::float32>(a.real(), b.real()) && areEqual<ito::float32>(a.imag(), b.imag());
282  }
283 
284  template<> inline bool areEqual(complex128 a, complex128 b)
285  {
286  return areEqual<ito::float64>(a.real(), b.real()) && areEqual<ito::float64>(a.imag(), b.imag());
287  }
288 
289 
290 } // namespace ito
291 
292 #endif // NUMERIC_H
bool isNotZero(_Tp value)
method returns whether a given variable is not equal to zero.
Definition: numeric.h:47
bool isInf< complex64 >(complex64 value)
Check if one of the components of complex64 values are infinite.
Definition: numeric.h:198
bool isNaN(_Tp value)
method returns whether a given variable is NaN / not a Number but maybe Inf.
Definition: numeric.h:130
bool isNotZero< float32 >(float32 value)
Check if a value is equal to zero for float32.
Definition: numeric.h:53
bool isFinite(_Tp)
method returns whether a given variable is finite.
Definition: numeric.h:81
bool isNotZero< float64 >(float64 value)
Check if a value is equal to zero for float64.
Definition: numeric.h:62
bool isInf(_Tp)
method returns whether a given variable is Inf / not may be NaN.
Definition: numeric.h:178
bool isNaN< float64 >(float64 value)
Check if a value is isNaN float64 values.
Definition: numeric.h:142
bool isInf< complex128 >(complex128 value)
Check if one of the components of complex128 values are infinite.
Definition: numeric.h:208
bool isFinite< complex128 >(complex128 value)
Check if both components of complex128 value are finite.
Definition: numeric.h:111
bool isZeroValue(_Tp v, _Tp)
method returns whether a given variable is equal to zero.
Definition: numeric.h:228
Definition: apiFunctionsGraph.cpp:39
bool isNaN< float32 >(float32 value)
Check if a value is isNaN float32 values.
Definition: numeric.h:136
bool isInf< float32 >(float32 value)
Check if a value is infinite float32 values.
Definition: numeric.h:184
bool isFinite< float32 >(float32 value)
Check if a value is finite float32 values.
Definition: numeric.h:87
bool isNaN< complex64 >(complex64 value)
Check if one of the components of complex64 values are not a number.
Definition: numeric.h:149
bool isInf< float64 >(float64 value)
Check if a value is infinite float64 values.
Definition: numeric.h:191
bool isNaN< complex128 >(complex128 value)
Check if one of the components of complex128 values are not a number.
Definition: numeric.h:159
bool isFinite< complex64 >(complex64 value)
Check if both components of complex64 value are finite.
Definition: numeric.h:101
bool isFinite< float64 >(float64 value)
Check if a value is finite float64 values.
Definition: numeric.h:94
bool areEqual(_Tp a, _Tp b)
method returns whether two given numbers of the same type are equal.
Definition: numeric.h:263