On 11/06/15 23:51, Sturla Molden wrote: > On 11/06/15 23:29, Jacob Vanderplas wrote: > >> It's not ideal, but I don't see any way around it short of creating >> explicit flags for every metric. Any thoughts? > > Computed goto? But you need to get the code into C or C++. I was > thinking about adding that was of dispatching between distance metrics > to cKDTree in SciPy.
The code below did not make any difference to SciPy, neither faster nor slower, so I am not going to use it. But if you have a lot of different distance metrics, it will still be about as fast as inlining the distance metric callback at compile time. Sturla /* requires __GNUC__ */ inline npy_float64 _distance_p(const npy_float64 *x, const npy_float64 *y, const npy_float64 p, const npy_intp k, const npy_float64 upperbound) { void *jmptab[] = {&&minkowski, &&max_coordinate_difference, &&manhattan, NULL, &&euclid}; int dispatch = (p == infinity) | ((p == 1.)<<1) | ((p == 2.)<<2); goto *jmptab[dispatch]; euclid: { const npy_float64 *u = x; const npy_float64 *v = y; const npy_intp n = k; npy_float64 s; npy_intp i; npy_float64 acc[4] = {0., 0., 0., 0.}; for (i = 0; i < n/4; i += 4) { npy_float64 _u[4] = {u[i], u[i + 1], u[i + 2], u[i + 3]}; npy_float64 _v[4] = {v[i], v[i + 1], v[i + 2], v[i + 3]}; npy_float64 diff[4] = {_u[0] - _v[0], _u[1] - _v[1], _u[2] - _v[2], _u[3] - _v[3]}; acc[0] += diff[0] * diff[0]; acc[1] += diff[1] * diff[1]; acc[2] += diff[2] * diff[2]; acc[3] += diff[3] * diff[3]; } s = acc[0] + acc[1] + acc[2] + acc[3]; if (i < n) { for(; i<n; ++i) { npy_float64 d = u[i] - v[i]; s += d * d; } } return s; } max_coordinate_difference: { npy_intp i; npy_float64 r = 0; for (i=0; i<k; ++i) { r = dmax(r,dabs(x[i]-y[i])); if (r>upperbound) return r; } return r; } manhattan: { npy_intp i; npy_float64 r = 0; for (i=0; i<k; ++i) { r += dabs(x[i]-y[i]); if (r>upperbound) return r; } return r; } minkowski: { npy_intp i; npy_float64 r = 0; for (i=0; i<k; ++i) { r += std::pow(dabs(x[i]-y[i]),p); if (r>upperbound) return r; } return r; } } ------------------------------------------------------------------------------ _______________________________________________ Scikit-learn-general mailing list Scikit-learn-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/scikit-learn-general