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
[email protected]
https://lists.sourceforge.net/lists/listinfo/scikit-learn-general