How to add a tolerance to isapprox

I would strongly recommend using the vector form in general, i.e. isapprox(a,b) rather than all(isapprox.(a,b)).

Elementwise approximate comparison discards information about the scale that can be obtained from the other elements. For example, intuitively you would expect:

\begin{bmatrix} 1 \\ 0 \end{bmatrix} \approx \begin{bmatrix} 1 \\ 10^{-100} \end{bmatrix}

to return true, and indeed the vector form of isapprox does this:

julia> [1, 0] ≈ [1, 1e-100]
true

because the difference 1e-100 is small (according the default rtol=√ε) compared to the length of the vector (≈ 1). However, if you do an elementwise isapprox, then it fails:

julia> all([1, 0] .≈ [1, 1e-100])
false

because 0 ≈ 1e-100 correctly returns false: the two numbers have no significant digits in common, and there is no absolute reference scale by which we can say that 1e-100 is “small” (compared to what)? See also the isapprox docstring on x ≈ 0 comparisons.

As I wrote in another thread, people often get approximate equality wrong on their first try. Even NumPy got it wrong with their broken isclose.

PS. If you think this would be solved by having a default absolute tolerance, consider [1e100, 0] ≈ [1e100, 1], which should also be true in a relative-error sense.

10 Likes