-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Function(s) to express nearishness #652
Conversation
Nice idea. Two points:
isclose(x, y, rtol, atol) = abs(x-y) <= atol+rtol.*(abs(x)+abs(y)) (Otherwise, you'd get very different behavior for elements where y is zero but x is not.)
I'm assuming that the compiler will recognize that the powers-of-eps computations result in constants, so there shouldn't be any overhead. |
This does require some thought and needs to evolve. Also, support arrays, and be extensible. @pao, can you move it to extras for now? Preparing for a 1.0 release, I believe we will be moving more stuff out of base in any case... |
To be fair, his version supported arrays. My "eps cleanup" would need additional specifications for x::Array{T} and x::DArray{T}, however. |
The asymmetry is also present in the NumPy prototype, so I kept it. It's open for discussion, though. I've also considered the relative tolerance expression As @timholy observed, this does support arrays and scalar/array mixes; I intentionally used @ViralBShah extras/nearequal.jl sound good? |
Location sounds fine. -viral On 01-Apr-2012, at 7:31 PM, paoreply@reply.github.com wrote:
|
New version incorporating some of the above suggestions. I'm letting Alternatively, I could let |
@pao, let me know when you think this is ready for a merge. Would you like the pull request open for some more discussion? I hate those long Matlab function names, but they are actually quite clear about what they do. |
isclose(nan, nan) ought to be false, but for this purpose, I guess the behaviour you implemented is what we need. |
How about isclosen following MATLAB's isequaln? |
Agreed on the long function names; I didn't know about |
I didn't know that either - must be a new name. I like it better. Perhaps we can dispense with the "withequalnans" names? I don't think that anyone except Matlab geeks like us actually know about such things, but I could be wrong. :-) -viral On 02-Apr-2012, at 8:36 AM, pao wrote:
|
…lementations. Originally, isclose() treated NaNs as equal, but this conflicts with the conventional default. Since treating NaNs as equal is often useful, that ability is preserved by the implementation of isclosen(). Similarly, isequaln() is included as an equal-NaNs version of isequal().
Viral, let's bake this for a few more hours. I'll see if there are any further comments when I wake up in the morning. And if someone could check that I'm doing the UPDATE: I just checked the docs; |
@ViralBShah Go for merge. |
@JeffBezanson can check the macrology, as he calls it.. |
Function(s) to express nearishness
This reuses the machinery that gives good stacktraces when a user calls wait on a Task. Since bind internally uses _wait2, this machinery is bypassed currently. Currently, julia throws an uninformative stacktrace in this situation: julia> c = Channel(_ -> error("foo")) Channel{Any}(sz_max:0,sz_curr:0) julia> for i in c end ERROR: foo Stacktrace: [1] iterate(::Channel{Any}) at ./channels.jl:459 [2] top-level scope at ./REPL[2]:1 With this change, the stacktrace is much more informative: julia> for i in c end ERROR: TaskFailedException: foo Stacktrace: [1] error(::String) at ./error.jl:33 [2] (::var"JuliaLang#1#2")(::Channel{Any}) at ./REPL[4]:1 [3] (::Base.var"JuliaLang#652#653"{var"JuliaLang#1#2",Channel{Any}})() at ./channels.jl:129 Stacktrace: [1] check_channel_state at ./channels.jl:167 [inlined] [2] take_unbuffered(::Channel{Any}) at ./channels.jl:405 [3] take! at ./channels.jl:383 [inlined] [4] iterate(::Channel{Any}, ::Nothing) at ./channels.jl:449 [5] iterate(::Channel{Any}) at ./channels.jl:448 [6] top-level scope at ./REPL[5]:1
This reuses the machinery that gives good stacktraces when a user calls wait on a Task. Since bind internally uses _wait2, this machinery is bypassed currently. Currently, julia throws an uninformative stacktrace in this situation: julia> c = Channel(_ -> error("foo")) Channel{Any}(sz_max:0,sz_curr:0) julia> for i in c end ERROR: foo Stacktrace: [1] iterate(::Channel{Any}) at ./channels.jl:459 [2] top-level scope at ./REPL[2]:1 With this change, the stacktrace is much more informative: julia> for i in c end ERROR: TaskFailedException: foo Stacktrace: [1] error(::String) at ./error.jl:33 [2] (::var"#1#2")(::Channel{Any}) at ./REPL[4]:1 [3] (::Base.var"#652#653"{var"#1#2",Channel{Any}})() at ./channels.jl:129 Stacktrace: [1] check_channel_state at ./channels.jl:167 [inlined] [2] take_unbuffered(::Channel{Any}) at ./channels.jl:405 [3] take! at ./channels.jl:383 [inlined] [4] iterate(::Channel{Any}, ::Nothing) at ./channels.jl:449 [5] iterate(::Channel{Any}) at ./channels.jl:448 [6] top-level scope at ./REPL[5]:1
This is a first shot at expressing nearishness in Julia, taking as inspiration NumPy's
allclose()
function. It doesn't handle Inf/NaN the same asnumpy.allclose()
, and doesn't handle all the possible types that R'sall.equal()
can apparently handle.So, what is needed from those other functions here (or for specific types), noting that
isequal()
already exists to express actual equality? The single commit is the simplest thing that could possibly work, but I'll add optimized things (like mapping it toisequal()
for integer types) before merge if I'm on the right path and this is something we want.Whether this belongs in base/ is certainly up for discussion as well.
Input from everyone certainly helpful, but I do want to make sure @dmbates gets to see this, since he got me started thinking about it.
numpy.allclose()
is defined at https://github.com/numpy/numpy/blob/master/numpy/core/numeric.py#L1963