pythonnumpy

What is rtol for in numpy's allclose function?


In numpy.allclose() there are two tolerance factors used to determine if two arrays are close enough to count as the same. There is the relative tolerance rtol and absolute tolerance atol. From the docs:

numpy.allclose(a, b, rtol=1e-05, atol=1e-08)

Also from the docs:

If the following equation is element-wise True, then allclose returns True.
absolute(a - b) <= (atol + rtol * absolute(b))

Mathematically I understand this, but I am confused about the point of rtol. Why not just use a single tolerance value tol, and if |a-b| < tol, then return False? Obviously, following the above equation, I could just do this manually by setting rtol to zero, thereby making everything symmetric. What is the point of the symmetry-breaking rtol factor?

Related question
How allclose() works?


Solution

  • The confusing part is that the equation shows both parameters being used at the same time. Look at it like this instead:

    An alternative way to implement both with a single tolerance parameter would be to add a flag that determines if the toerance is relative or absolute. Separating the use-cases like that breaks down in the usecase where array values can be both large and zero. If only one array can have zeros, make that one a and use the asymmetrical equation to your benefit without atol. If either one can have zeros, simply set rtol to some acceptable value for large elements, and set atol to the value you want to kick in for zeros.

    You generally want to use rtol: since the precision of numbers and calculations is very much finite, larger numbers will almost always be less precise than smaller ones, and the difference scales linearly (again, in general). The only time you use atol is for numbers that are so close to zero that rounding errors are liable to be larger than the number itself.

    Another way to look at it is atol compares fixed decimal places, while rtol compares significant figures.

    A caveat is that both of the default values of the function are non-zero: rtol=1e-05 and atol=1e-08. That means that if you want to use only one or the other of them, you must explicitly set the other to zero.