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