1 //=================================================================================================
2 /*!
3 // \file blaze/math/shims/Equal.h
4 // \brief Header file for the equal shim
5 //
6 // Copyright (C) 2012-2020 Klaus Iglberger - All Rights Reserved
7 //
8 // This file is part of the Blaze library. You can redistribute it and/or modify it under
9 // the terms of the New (Revised) BSD License. Redistribution and use in source and binary
10 // forms, with or without modification, are permitted provided that the following conditions
11 // are met:
12 //
13 // 1. Redistributions of source code must retain the above copyright notice, this list of
14 // conditions and the following disclaimer.
15 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
16 // of conditions and the following disclaimer in the documentation and/or other materials
17 // provided with the distribution.
18 // 3. Neither the names of the Blaze development group nor the names of its contributors
19 // may be used to endorse or promote products derived from this software without specific
20 // prior written permission.
21 //
22 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
23 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
25 // SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 // BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 // DAMAGE.
32 */
33 //=================================================================================================
34
35 #ifndef _BLAZE_MATH_SHIMS_EQUAL_H_
36 #define _BLAZE_MATH_SHIMS_EQUAL_H_
37
38
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42
43 #include <cmath>
44 #include <blaze/math/Accuracy.h>
45 #include <blaze/math/RelaxationFlag.h>
46 #include <blaze/math/typetraits/IsScalar.h>
47 #include <blaze/util/algorithms/Max.h>
48 #include <blaze/util/Complex.h>
49 #include <blaze/util/EnableIf.h>
50
51
52 namespace blaze {
53
54 //=================================================================================================
55 //
56 // EQUAL SHIM
57 //
58 //=================================================================================================
59
60 //*************************************************************************************************
61 /*!\brief Generic equality comparison.
62 // \ingroup math_shims
63 //
64 // \param a First value/object.
65 // \param b Second value/object.
66 // \return \a true if the two values/objects are equal, \a false if not.
67 //
68 // The equal shim represents an abstract interface for testing two values/objects for equality.
69 // Based on the setting of the relaxation flag \a RF, the function either performs a comparison
70 // via the equality operator (\a blaze::strict) or or a special comparison is selected that takes
71 // the limited machine accuracy into account (\a blaze::relaxed). In case the two values/objects
72 // are equal, the function returns \a true, otherwise it returns \a false.
73 */
74 template< RelaxationFlag RF // Relaxation flag
75 , typename T1 // Type of the left-hand side value/object
76 , typename T2 // Type of the right-hand side value/object
77 , typename = EnableIf_t< IsScalar_v<T1> && IsScalar_v<T2> > >
equal(const T1 & a,const T2 & b)78 constexpr bool equal( const T1& a, const T2& b )
79 {
80 return a == b;
81 }
82 //*************************************************************************************************
83
84
85 //*************************************************************************************************
86 /*! \cond BLAZE_INTERNAL */
87 /*!\brief Equality check for two single precision floating point values.
88 // \ingroup math_shims
89 //
90 // \param a The left-hand side single precision floating point value.
91 // \param b The right-hand side single precision floating point value.
92 // \return \a true if the two values are equal, \a false if not.
93 //
94 // Equal function for the comparison of two single precision floating point numbers. Due to the
95 // limited machine accuracy, a direct comparison of two floating point numbers should be avoided.
96 // This function offers the possibility to compare two floating-point values with a certain
97 // accuracy margin.
98 //
99 // For more information on comparing float point numbers, see
100 //
101 // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
102 */
103 template< RelaxationFlag RF > // Relaxation flag
equal(float a,float b)104 inline bool equal( float a, float b )
105 {
106 if( RF == relaxed ) {
107 const float acc( static_cast<float>( accuracy ) );
108 return ( std::fabs( a - b ) <= max( acc, acc * std::fabs( a ) ) );
109 }
110 else {
111 return a == b;
112 }
113 }
114 /*! \endcond */
115 //*************************************************************************************************
116
117
118 //*************************************************************************************************
119 /*! \cond BLAZE_INTERNAL */
120 /*!\brief Equality check for a single precision and a double precision floating point value.
121 // \ingroup math_shims
122 //
123 // \param a The left-hand side single precision floating point value.
124 // \param b The right-hand side double precision floating point value.
125 // \return \a true if the two values are equal, \a false if not.
126 //
127 // Equal function for the comparison of a single precision and a double precision floating point
128 // number. Due to the limited machine accuracy, a direct comparison of two floating point numbers
129 // should be avoided. This function offers the possibility to compare two floating-point values
130 // with a certain accuracy margin.
131 //
132 // For more information on comparing float point numbers, see
133 //
134 // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
135 */
136 template< RelaxationFlag RF > // Relaxation flag
equal(float a,double b)137 inline bool equal( float a, double b )
138 {
139 return equal<RF>( a, static_cast<float>( b ) );
140 }
141 /*! \endcond */
142 //*************************************************************************************************
143
144
145 //*************************************************************************************************
146 /*! \cond BLAZE_INTERNAL */
147 /*!\brief Equality check for a single precision and an extended precision floating point value.
148 // \ingroup math_shims
149 //
150 // \param a The left-hand side single precision floating point value.
151 // \param b The right-hand side extended precision floating point value.
152 // \return \a true if the two values are equal, \a false if not.
153 //
154 // Equal function for the comparison of a single precision and an extended precision floating point
155 // number. Due to the limited machine accuracy, a direct comparison of two floating point numbers
156 // should be avoided. This function offers the possibility to compare two floating-point values
157 // with a certain accuracy margin.
158 //
159 // For more information on comparing float point numbers, see
160 //
161 // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
162 */
163 template< RelaxationFlag RF > // Relaxation flag
equal(float a,long double b)164 inline bool equal( float a, long double b )
165 {
166 return equal<RF>( a, static_cast<float>( b ) );
167 }
168 /*! \endcond */
169 //*************************************************************************************************
170
171
172 //*************************************************************************************************
173 /*! \cond BLAZE_INTERNAL */
174 /*!\brief Equality check for a double precision and a single precision floating point value.
175 // \ingroup math_shims
176 //
177 // \param a The left-hand side double precision floating point value.
178 // \param b The right-hand side single precision floating point value.
179 // \return \a true if the two values are equal, \a false if not.
180 //
181 // Equal function for the comparison of a double precision and a single precision floating point
182 // number. Due to the limited machine accuracy, a direct comparison of two floating point numbers
183 // should be avoided. This function offers the possibility to compare two floating-point values
184 // with a certain accuracy margin.
185 */
186 template< RelaxationFlag RF > // Relaxation flag
equal(double a,float b)187 inline bool equal( double a, float b )
188 {
189 return equal<RF>( static_cast<float>( a ), b );
190 }
191 /*! \endcond */
192 //*************************************************************************************************
193
194
195 //*************************************************************************************************
196 /*! \cond BLAZE_INTERNAL */
197 /*!\brief Equality check for two double precision floating point values.
198 // \ingroup math_shims
199 //
200 // \param a The left-hand side double precision floating point value.
201 // \param b The right-hand side double precision floating point value.
202 // \return \a true if the two values are equal, \a false if not.
203 //
204 // Equal function for the comparison of two double precision floating point numbers. Due to the
205 // limited machine accuracy, a direct comparison of two floating point numbers should be avoided.
206 // This function offers the possibility to compare two floating-point values with a certain
207 // accuracy margin.
208 //
209 // For more information on comparing float point numbers, see
210 //
211 // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
212 */
213 template< RelaxationFlag RF > // Relaxation flag
equal(double a,double b)214 inline bool equal( double a, double b )
215 {
216 if( RF == relaxed ) {
217 const double acc( static_cast<double>( accuracy ) );
218 return ( std::fabs( a - b ) <= max( acc, acc * std::fabs( a ) ) );
219 }
220 else {
221 return a == b;
222 }
223 }
224 /*! \endcond */
225 //*************************************************************************************************
226
227
228 //*************************************************************************************************
229 /*! \cond BLAZE_INTERNAL */
230 /*!\brief Equality check for a double precision and an extended precision floating point value.
231 // \ingroup math_shims
232 //
233 // \param a The left-hand side double precision floating point value.
234 // \param b The right-hand side extended precision floating point value.
235 // \return \a true if the two values are equal, \a false if not.
236 //
237 // Equal function for the comparison of a double precision and an extended precision floating point
238 // number. Due to the limited machine accuracy, a direct comparison of two floating point numbers
239 // should be avoided. This function offers the possibility to compare two floating-point values
240 // with a certain accuracy margin.
241 //
242 // For more information on comparing float point numbers, see
243 //
244 // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
245 */
246 template< RelaxationFlag RF > // Relaxation flag
equal(double a,long double b)247 inline bool equal( double a, long double b )
248 {
249 return equal<RF>( a, static_cast<double>( b ) );
250 }
251 /*! \endcond */
252 //*************************************************************************************************
253
254
255 //*************************************************************************************************
256 /*! \cond BLAZE_INTERNAL */
257 /*!\brief Equality check for an extended precision and a single precision floating point value.
258 // \ingroup math_shims
259 //
260 // \param a The left-hand side extended precision floating point value.
261 // \param b The right-hand side single precision floating point value.
262 // \return \a true if the two values are equal, \a false if not.
263 //
264 // Equal function for the comparison of an extended precision and a single precision floating point
265 // number. Due to the limited machine accuracy, a direct comparison of two floating point numbers
266 // should be avoided. This function offers the possibility to compare two floating-point values
267 // with a certain accuracy margin.
268 //
269 // For more information on comparing float point numbers, see
270 //
271 // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
272 */
273 template< RelaxationFlag RF > // Relaxation flag
equal(long double a,float b)274 inline bool equal( long double a, float b )
275 {
276 return equal<RF>( static_cast<float>( a ), b );
277 }
278 /*! \endcond */
279 //*************************************************************************************************
280
281
282 //*************************************************************************************************
283 /*! \cond BLAZE_INTERNAL */
284 /*!\brief Equality check for an extended precision and a double precision floating point value.
285 // \ingroup math_shims
286 //
287 // \param a The left-hand side extended precision floating point value.
288 // \param b The right-hand side double precision floating point value.
289 // \return \a true if the two values are equal, \a false if not.
290 //
291 // Equal function for the comparison of an extended precision and a double precision floating point
292 // number. Due to the limited machine accuracy, a direct comparison of two floating point numbers
293 // should be avoided. This function offers the possibility to compare two floating-point values
294 // with a certain accuracy margin.
295 //
296 // For more information on comparing float point numbers, see
297 //
298 // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
299 */
300 template< RelaxationFlag RF > // Relaxation flag
equal(long double a,double b)301 inline bool equal( long double a, double b )
302 {
303 return equal<RF>( static_cast<double>( a ), b );
304 }
305 /*! \endcond */
306 //*************************************************************************************************
307
308
309 //*************************************************************************************************
310 /*! \cond BLAZE_INTERNAL */
311 /*!\brief Equality check for two long double precision floating point values.
312 // \ingroup math_shims
313 //
314 // \param a The left-hand side extended precision floating point value.
315 // \param b The right-hand side extended precision floating point value.
316 // \return \a true if the two values are equal, \a false if not.
317 //
318 // Equal function for the comparison of two long double precision floating point numbers. Due
319 // to the limited machine accuracy, a direct comparison of two floating point numbers should be
320 // avoided. This function offers the possibility to compare two floating-point values with a
321 // certain accuracy margin.
322 //
323 // For more information on comparing float point numbers, see
324 //
325 // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
326 */
327 template< RelaxationFlag RF > // Relaxation flag
equal(long double a,long double b)328 inline bool equal( long double a, long double b )
329 {
330 if( RF == relaxed ) {
331 const long double acc( static_cast<long double>( accuracy ) );
332 return ( std::fabs( a - b ) <= max( acc, acc * std::fabs( a ) ) );
333 }
334 else {
335 return a == b;
336 }
337 }
338 /*! \endcond */
339 //*************************************************************************************************
340
341
342 //*************************************************************************************************
343 /*! \cond BLAZE_INTERNAL */
344 /*!\brief Equality check for a complex and a scalar value.
345 // \ingroup math_shims
346 //
347 // \param a The left-hand side complex value.
348 // \param b The right-hand side scalar value.
349 // \return \a true if the two values are equal, \a false if not.
350 //
351 // Equal function for the comparison of a complex and a scalar value. The function compares the
352 // real part of the complex value with the scalar. In case these two values match and in case
353 // the imaginary part is zero, the function returns \a true. Otherwise it returns \a false.
354 */
355 template< RelaxationFlag RF // Relaxation flag
356 , typename T1 // Type of the left-hand side complex value
357 , typename T2 > // Type of the right-hand side scalar value
equal(complex<T1> a,T2 b)358 inline bool equal( complex<T1> a, T2 b )
359 {
360 return equal<RF>( real( a ), b ) && equal<RF>( imag( a ), T1() );
361 }
362 /*! \endcond */
363 //*************************************************************************************************
364
365
366 //*************************************************************************************************
367 /*! \cond BLAZE_INTERNAL */
368 /*!\brief Equality check for a scalar and a complex value.
369 // \ingroup math_shims
370 //
371 // \param a The left-hand side scalar value.
372 // \param b The right-hand side complex value.
373 // \return \a true if the two values are equal, \a false if not.
374 //
375 // Equal function for the comparison of a scalar and a complex value. The function compares the
376 // scalar with the real part of the complex value. In case these two values match and in case
377 // the imaginary part is zero, the function returns \a true. Otherwise it returns \a false.
378 */
379 template< RelaxationFlag RF // Relaxation flag
380 , typename T1 // Type of the left-hand side scalar value
381 , typename T2 > // Type of the right-hand side complex value
equal(T1 a,complex<T2> b)382 inline bool equal( T1 a, complex<T2> b )
383 {
384 return equal<RF>( a, real( b ) ) && equal<RF>( imag( b ), T2() );
385 }
386 /*! \endcond */
387 //*************************************************************************************************
388
389
390 //*************************************************************************************************
391 /*! \cond BLAZE_INTERNAL */
392 /*!\brief Equality check for two complex values.
393 // \ingroup math_shims
394 //
395 // \param a The left-hand side complex value.
396 // \param b The right-hand side complex value.
397 // \return \a true if the two values are equal, \a false if not.
398 //
399 // Equal function for the comparison of two complex numbers. Due to the limited machine accuracy,
400 // a direct comparison of two floating point numbers should be avoided. This function offers the
401 // possibility to compare two floating-point values with a certain accuracy margin.
402 */
403 template< RelaxationFlag RF // Relaxation flag
404 , typename T1 // Type of the left-hand side complex value
405 , typename T2 > // Type of the right-hand side complex value
equal(complex<T1> a,complex<T2> b)406 inline bool equal( complex<T1> a, complex<T2> b )
407 {
408 return equal<RF>( real( a ), real( b ) ) && equal<RF>( imag( a ), imag( b ) );
409 }
410 /*! \endcond */
411 //*************************************************************************************************
412
413
414 //*************************************************************************************************
415 /*!\brief Generic equality check.
416 // \ingroup math_shims
417 //
418 // \param a First value/object.
419 // \param b Second value/object.
420 // \return \a true if the two values/objects are equal, \a false if not.
421 //
422 // The equal shim represents an abstract interface for testing two values/objects for equality.
423 // In case the two values/objects are equal, the function returns \a true, otherwise it returns
424 // \a false. Per default, the comparison of the two values/objects uses the equality operator
425 // operator==(). For built-in floating point data types a special comparison is selected that
426 // takes the limited machine accuracy into account.
427 */
428 template< typename T1 // Type of the left-hand side value/object
429 , typename T2 > // Type of the right-hand side value/object
equal(const T1 & a,const T2 & b)430 constexpr bool equal( const T1& a, const T2& b )
431 {
432 return equal<relaxed>( a, b );
433 }
434 //*************************************************************************************************
435
436 } // namespace blaze
437
438 #endif
439