-
Notifications
You must be signed in to change notification settings - Fork 42
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
Prevent overflow in mean(::AbstractRange)
and relax type constraint
#115
Conversation
(first(r) + last(r)) / 2 | ||
function mean(r::AbstractRange{T}) where T | ||
isempty(r) && return zero(T)/0 | ||
return first(r)/2 + last(r)/2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return first(r)/2 + last(r)/2 | |
return middle(r) |
This method is already defined appropriately for ranges and behaves as desired when the input is non-empty:
julia> middle(typemax(Int):typemax(Int)) ≈ typemax(Int)
true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be less performant to call middle
because it currently doesn't elide bounds checks and a[end]
is unfortunately slow for StepRange
(it calls lastindex
, which calls length
, which requires a division). In contrast, first
and last
simply accesses fields of the range struct (except for StepRangeLen
).
I've just opened a PR (#116) to have middle
call mean
instead. Would you mind taking a look?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that both mean
here and middle
at #116 check that the input is not empty, better not have one call the other and instead duplicate the (very short) computation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, sounds good to me. I'll update #116 to not call mean
.
Thanks for the PR! Great first contribution to the package. 🙂 |
Do you want to finish this @vyu? |
Codecov ReportBase: 96.93% // Head: 96.93% // No change to project coverage 👍
Additional details and impacted files@@ Coverage Diff @@
## master #115 +/- ##
=======================================
Coverage 96.93% 96.93%
=======================================
Files 1 1
Lines 424 424
=======================================
Hits 411 411
Misses 13 13
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
Hello , what is the status of this issue is it solved............ |
Thanks for proposing your help. I think you can start from the current state of the PR and the last round of comments. You probably won't be able to push to this branch but you can start a new PR and post a link here. |
Closing in favor of #150. |
Currently,
mean(::AbstractRange)
can overflow:This PR prevents this overflow.
In addition, I've relaxed the type constraint from
AbstractRange{<:Real}
toAbstractRange{<:Any}
, since the computation here is correct for any type that implements addition and numerical division (unlike the median, which requires an order). Currently, the mean of non-real ranges falls back tomean(::AbstractVector)
, which also requires addition and numerical division.In line with this,
oftype([...], NaN)
is changed tozero(T)/0
so thatmean(LinRange(2im, 1im, 0))
isNaN + NaN*im
(consistent withmean(ComplexF64[])
) instead ofNaN + 0.0im
.