[issue33089] Add multi-dimensional Euclidean distance function to the math module

Tim Peters report at bugs.python.org
Sun Mar 18 21:51:51 EDT 2018


Tim Peters <tim at python.org> added the comment:

I'd be +1 on generalizing math.hypot to accept an arbitrary number of arguments.  It's the natural building block for computing distance, but the reverse is strained.  Both are useful.

Here's scaling code translated from the Fortran implementation of SNRM2 in LAPACK.  It only looks at each element once, so would work almost as-is for an argument that's an arbitrary iterable (just change the formal argument from `*xs` to `xs`):

    # http://www.netlib.org/lapack/explore-html/d7/df1/snrm2_8f_source.html
    def hypot(*xs):
        import math
        scale = 0.0
        sumsq = 1.0
        for x in xs:
            if x:
                absx = abs(x)
                if scale < absx:
                    sumsq = 1.0 + sumsq * (scale / absx)**2
                    scale = absx
                else:
                    sumsq += (absx / scale)**2
        return scale * math.sqrt(sumsq)

I believe it does the right with infinities by magic (return math.inf).  It returns 0.0 if no arguments are passed, which makes sense.  For one argument, it's a convoluted way to return its absolute value.  The "if x:" test is necessary to prevent division by 0.0 if the first argument is 0.0.  It would need another blob of code to give up (and return math.nan) if one of the arguments is a NaN (there's no guessing what various C compilers would do without special-casing NaN).

I doubt `fsum()` would add much value here:  all the addends have the same sign, so cancellation is impossible.

To get really gonzo, a single-rounding dot product would be the best building block (the vector norm is the square root of the dot product of a vector with itself).  `fsum()` is a special case of that (the dot product of a vector with a same-length vector of all ones).

----------

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue33089>
_______________________________________


More information about the Python-bugs-list mailing list