[
https://issues.apache.org/jira/browse/GEOMETRY-50?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17145827#comment-17145827
]
Alex Herbert commented on GEOMETRY-50:
--------------------------------------
SafeNorm will not return the same value as Math.hypot. When there is no
overflow or underflow potential then SafeNorm reduces to a
sqrt(sum_of_squares). Math.hypot scales the input values, lossless, to avoid
over/underflow and computes the sum_of_squares using extended precision with a
quad length (128 bit) number for intermediate parts before reducing to a double
(64 bit) number to pass to the sqrt. The result is rescaled, again lossless.
This means it will have a lower average error and a lower max error to the true
value than a simple sum_of_squares. Note that not in every case is it more
accurate.
When SafeNorm has to scale numbers for under/overflow it is not lossless (scale
by an exponent change only). The rescale at the end is also not lossless. The
method's strength is that it can compute for any length vector. But the cost is
the potential for a relatively large error from the true result.
I would use Math.hypot over SafeNorm for 2D. I'd suggest benchmarking the 3D
variant suggested above against SafeNorm. It should have a lower error than
using SafeNorm but I do not know about the speed.
My conclusion in [Numbers-143] was that Math.hypot was slow, even from Java 9
onwards when it was rewritten to avoid a JNI call and run purely in Java. The
JDK are tied to using the computation from the fdlibm implementation for the
high precision sum of squares so that the method produces the same values as it
always has done. I changed this to a different computation for a noticeable
performance improvement and no loss of accuracy.
Currently the method is private in {{o.a.c.numbers.complex.Complex}}. That
package thus has the license from fdlibm in the NOTICE due to adaption of the
original source.
What do you think to the idea of promoting the method to a public API in
Numbers given it is of wider scope than just complex numbers? As a first step
it may be of some interest to borrow the code for a quick benchmark against
SafeNorm for 2D.
I'm going to ponder about how it could be adapted to 3D by accepting 3 args,
e.g. {{hypot(x, y, z)}}.
> Overflow in Vector norm and distance
> ------------------------------------
>
> Key: GEOMETRY-50
> URL: https://issues.apache.org/jira/browse/GEOMETRY-50
> Project: Apache Commons Geometry
> Issue Type: Bug
> Reporter: Baljit Singh
> Priority: Major
> Labels: beta1
>
> In Euclidean Vector classes (Vector2D, Vector3D), norm() and distance() rely
> on Math.sqrt(), which can overflow if the components of the vectors are
> large. Instead, they should rely on SafeNorm.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)