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