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