xref: /petsc/src/sys/utils/mathclose.c (revision a69119a591a03a9d906b29c0a4e9802e4d7c9795)
1 #include <petscsys.h>
2 
3 /*@C
4     PetscIsCloseAtTol - Returns whether the two floating point numbers
5        are close at given relative and absolute tolerances.
6 
7     Input Parameters:
8 +     a - first floating point number
9 .     b - second floating point number
10 .     rtol - relative tolerance
11 -     atol - absolute tolerances
12 
13     Notes: https://www.python.org/dev/peps/pep-0485/
14 
15     Level: beginner
16 @*/
17 PetscBool PetscIsCloseAtTol(PetscReal a, PetscReal b, PetscReal rtol, PetscReal atol) {
18   PetscReal diff;
19   /* NaN is not considered close to any other value, including NaN */
20   if (PetscIsNanReal(a) || PetscIsNanReal(b)) return PETSC_FALSE;
21   /* Fast path for exact equality or two infinities of same sign */
22   if (a == b) return PETSC_TRUE;
23   /* Handle two infinities of opposite sign */
24   if (PetscIsInfReal(a) || PetscIsInfReal(b)) return PETSC_FALSE;
25   /* Cannot error if tolerances are negative */
26   rtol = PetscAbsReal(rtol);
27   atol = PetscAbsReal(atol);
28   /* The regular check for difference within tolerances */
29   diff = PetscAbsReal(b - a);
30   return ((diff <= PetscAbsReal(rtol * b)) || (diff <= PetscAbsReal(rtol * a)) || (diff <= atol)) ? PETSC_TRUE : PETSC_FALSE;
31 }
32