-
-
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
fixed hypot(x::Number...) for under/overflow #27251
Changes from all commits
6ccd313
1af76d9
242c94c
6959b71
fef8b1f
74a0a4c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -472,6 +472,7 @@ Stacktrace: | |||||||||||||||||||||||||||||||||||||||||||||||||||
[...] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
hypot() = throw(ArgumentError("at least one argument is required")) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
hypot(x::Number, y::Number) = hypot(promote(x, y)...) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
function hypot(x::T, y::T) where T<:Number | ||||||||||||||||||||||||||||||||||||||||||||||||||||
ax = abs(x) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -503,7 +504,45 @@ end | |||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
Compute the hypotenuse ``\\sqrt{\\sum x_i^2}`` avoiding overflow and underflow. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
hypot(x::Number...) = sqrt(sum(abs2(y) for y in x)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
hypot(x::Number...) = hypot(promote(x...)...) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
function hypot(x::T...) where T<:Number | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
# compute infnorm x (modeled on generic_vecnormMinusInf(x) in LinearAlgebra/generic.gl) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
(v, s) = iterate(x)::Tuple | ||||||||||||||||||||||||||||||||||||||||||||||||||||
maxabs = abs(v) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
while true | ||||||||||||||||||||||||||||||||||||||||||||||||||||
y = iterate(x, s) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
y === nothing && break | ||||||||||||||||||||||||||||||||||||||||||||||||||||
(v, s) = y | ||||||||||||||||||||||||||||||||||||||||||||||||||||
vnorm = abs(v) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
maxabs = ifelse(isnan(maxabs) | (maxabs > vnorm), maxabs, vnorm) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||||||||||||||||||
maxabsf = float(maxabs) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
# compute vecnorm2(x) (modeled on generic_vecnorm2(x) in LinearAlgebra/generic.gl) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
(maxabsf == 0 || isinf(maxabsf)) && return maxabsf | ||||||||||||||||||||||||||||||||||||||||||||||||||||
(v, s) = iterate(x)::Tuple | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Tfloat = typeof(maxabsf) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
if isfinite(length(x)*maxabsf*maxabsf) && maxabsf*maxabsf != 0 # Scaling not necessary | ||||||||||||||||||||||||||||||||||||||||||||||||||||
sum::promote_type(Float64, Tfloat) = abs2(v) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
while true | ||||||||||||||||||||||||||||||||||||||||||||||||||||
y = iterate(x, s) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
y === nothing && break | ||||||||||||||||||||||||||||||||||||||||||||||||||||
(v, s) = y | ||||||||||||||||||||||||||||||||||||||||||||||||||||
sum += abs2(v) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||||||||||||||||||
return convert(Tfloat, sqrt(sum)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why write out the loop, instead of just doing
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
else | ||||||||||||||||||||||||||||||||||||||||||||||||||||
sum = (abs(v)/maxabsf)^2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
while true | ||||||||||||||||||||||||||||||||||||||||||||||||||||
y = iterate(x, s) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
y === nothing && break | ||||||||||||||||||||||||||||||||||||||||||||||||||||
(v, s) = y | ||||||||||||||||||||||||||||||||||||||||||||||||||||
sum += (abs(v)/maxabsf)^2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||||||||||||||||||
return convert(Tfloat, maxabsf*sqrt(sum)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similarly, why not just:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I copied julia/stdlib/LinearAlgebra/src/generic.jl Lines 298 to 322 in 1d3de4c
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unrolling the loops as in the PR is faster and smaller in memory than calling
for code
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't benchmark calls involving a splatted global. Try
etcetera There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Still a factor of sixteen (I misplaced a decimal when I reported 10^3).
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
An alternative, if no one likes adding this function to |
||||||||||||||||||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
atan2(y, x) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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.
What is the advantage of this over: