Actual source code: mathclose.c

  1: #include <petscsys.h>

  3: /*@C
  4:     PetscIsCloseAtTol - Returns whether the two floating point numbers
  5:        are close at a given relative and absolute tolerances.

  7:     Input Parameters:
  8: +     a - first floating point number
  9: .     b - second floating point number
 10: .     rtol - relative tolerance
 11: -     atol - absolute tolerances

 13:     Reference:
 14: .   * -  https://www.python.org/dev/peps/pep-0485/

 16:     Level: beginner

 18: .seealso: `PetscEqualReal()`, `PetscEqualScalar()`
 19: @*/
 20: PetscBool PetscIsCloseAtTol(PetscReal a, PetscReal b, PetscReal rtol, PetscReal atol)
 21: {
 22:   PetscReal diff;
 23:   /* NaN is not considered close to any other value, including NaN */
 24:   if (PetscIsNanReal(a) || PetscIsNanReal(b)) return PETSC_FALSE;
 25:   /* Fast path for exact equality or two infinities of same sign */
 26:   if (a == b) return PETSC_TRUE;
 27:   /* Handle two infinities of opposite sign */
 28:   if (PetscIsInfReal(a) || PetscIsInfReal(b)) return PETSC_FALSE;
 29:   /* Cannot error if tolerances are negative */
 30:   rtol = PetscAbsReal(rtol);
 31:   atol = PetscAbsReal(atol);
 32:   /* The regular check for difference within tolerances */
 33:   diff = PetscAbsReal(b - a);
 34:   return ((diff <= PetscAbsReal(rtol * b)) || (diff <= PetscAbsReal(rtol * a)) || (diff <= atol)) ? PETSC_TRUE : PETSC_FALSE;
 35: }