Julia: isapproxzero

Created on 21 Aug 2017  Â·  9Comments  Â·  Source: JuliaLang/julia

It would be convenient to have an isapproxzero method which is to ≈ what iszero is to ==.
In addition to being slighly more efficient than isapprox, isapproxzero would work out of the box with the default parameters.
Indeed, since atol is zero by default we have for example:

julia> 1e-100 ≈ 0
false

An implementation if isapproxzero could be

function isapproxzero(x::Number; rtol::Real=0, atol::Real=rtoldefault(typeof(x)), nans::Bool=false)
    iszero(x) || (isfinite(x) && abs(x) <= atol) || (nans && isnan(x))
end

It might be helpful to accept an rtol parameter even if it is not used since it allows to write functions like

function f(a, b, c; kws...)
    ... # do stuff
    isapprox(a, b; kws...)
    ... # do stuff
    isapproxzero(c; kws...)
    ... # do stuff
end

Indeed if isapproxzero was not accepting rtol, this function would fail when rtol is given as a keyword to f.

speculative

Most helpful comment

There is no nonzero default atol that makes sense, because atol is dimensionful (in that it depends on the overall scaling/units of the quantities under consideration).

Because of that, I don't think this function makes sense. If you want approximate equality to zero, you will always have to pass an application-appropriate atol, in which case you might as well call norm(x) ≤ atol.

All 9 comments

function isapproxzero(x::Number; rtol::Real=0, atol::Real=rtoldefault(x,y), nans::Bool=false)

y is not defined? Fundamentally what does it mean for a number to be small? Compared to what?

y is not defined?

Thanks ! I have corrected it

Fundamentally what does it mean for a number to be small? Compared to what?

We can say that isapproxzero(x::T) is defined as the equivalent of isapprox(x, zero(x)) with atol being rtoldefault(T). Being small here means being close to zero(x) and close means with a small distance where the distance is the same than the one used for isapprox, i.e. d(x, y) = abs(x - y) for numbers and d(x, y) == norm(x - y) for vectors.

Not sure that's a good idea, because isapprox(x,y) would be very different from isapproxzero(x-y).

isapprox(x, y) would still correspond to isapproxzero(x-y, rtol=atol + rtol * max(abs(x), abs(y))). We need to manipulate the keyword arguments but that is to be expected for approximate comparison I suppose.

There is no nonzero default atol that makes sense, because atol is dimensionful (in that it depends on the overall scaling/units of the quantities under consideration).

Because of that, I don't think this function makes sense. If you want approximate equality to zero, you will always have to pass an application-appropriate atol, in which case you might as well call norm(x) ≤ atol.

What might make some sense is to implement something which effectively does isapproxzero(x) = isapprox(x + one(x), one(x))?

So, the "absolute error for zero" compares to "the relative error for one" or something.

(Note: while it seems unintuitive for isapproxzero require one() to work, if one(x) doesn't exist I can't see any sensible default "scale" to set the absolute tolerance to.)

From working with optimization algorithms, I have had many bitter experiences with code that assumes that all quantities are of order unity (oneunit(x)) and does comparisons with that assumption in mind. I don't think we should build it into the standard library.

100% agree. If someone wants x + one(x) ≈ one(x) they can write that.

Doesn't look like this will happen.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

omus picture omus  Â·  3Comments

sbromberger picture sbromberger  Â·  3Comments

Keno picture Keno  Â·  3Comments

wilburtownsend picture wilburtownsend  Â·  3Comments

TotalVerb picture TotalVerb  Â·  3Comments