From c630e104401605af5dded8ffa4002fb6683da076 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sat, 11 Aug 2018 18:39:05 -0700 Subject: [PATCH] Factor-out common code. Also, optimize common cases by preallocating space on the stack. GH-8738 Improves speed by 9 to 10ns per call. --- Modules/mathmodule.c | 97 +++++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 41 deletions(-) diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index cd390f240d..896cf8dcd5 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2032,10 +2032,10 @@ math_fmod_impl(PyObject *module, double x, double y) } /* -Given an *n* length *vec* of non-negative, non-nan, non-inf values +Given an *n* length *vec* of non-negative values where *max* is the largest value in the vector, compute: - sum((x / max) ** 2 for x in vec) + max * sqrt(sum((x / max) ** 2 for x in vec)) When a maximum value is found, it is swapped to the end. This lets us skip one loop iteration and just add 1.0 at the end. @@ -2045,19 +2045,31 @@ Kahan summation is used to improve accuracy. The *csum* variable tracks the cumulative sum and *frac* tracks fractional round-off error for the most recent addition. +The value of the *max* variable must be present in *vec* +or should equal to 0.0 when n==0. Likewise, *max* will +be INF if an infinity is present in the vec. + +The *found_nan* variable indicates whether some member of +the *vec* is a NaN. */ static inline double -scaled_vector_squared(Py_ssize_t n, double *vec, double max) +vector_norm(Py_ssize_t n, double *vec, double max, int found_nan) { double x, csum = 0.0, oldcsum, frac = 0.0; Py_ssize_t i; + if (Py_IS_INFINITY(max)) { + return max; + } + if (found_nan) { + return Py_NAN; + } if (max == 0.0) { return 0.0; } assert(n > 0); - for (i=0 ; i NUM_STACK_ELEMS) { + diffs = (double *) PyObject_Malloc(n * sizeof(double)); + if (diffs == NULL) { + return NULL; + } } for (i=0 ; i NUM_STACK_ELEMS) { + coordinates = (double *) PyObject_Malloc(n * sizeof(double)); + if (coordinates == NULL) + return NULL; + } for (i=0 ; i value\n\n\ Multidimensional Euclidean distance from the origin to a point.\n\ -- 2.40.0