Coverage Report

Created: 2023-06-07 08:11

/work/install-coverage/include/opencv4/opencv2/flann/dist.h
Line
Count
Source (jump to first uncovered line)
1
/***********************************************************************
2
 * Software License Agreement (BSD License)
3
 *
4
 * Copyright 2008-2009  Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
5
 * Copyright 2008-2009  David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
6
 *
7
 * THE BSD LICENSE
8
 *
9
 * Redistribution and use in source and binary forms, with or without
10
 * modification, are permitted provided that the following conditions
11
 * are met:
12
 *
13
 * 1. Redistributions of source code must retain the above copyright
14
 *    notice, this list of conditions and the following disclaimer.
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in the
17
 *    documentation and/or other materials provided with the distribution.
18
 *
19
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
 *************************************************************************/
30
31
#ifndef OPENCV_FLANN_DIST_H_
32
#define OPENCV_FLANN_DIST_H_
33
34
//! @cond IGNORED
35
36
#include <cmath>
37
#include <cstdlib>
38
#include <string.h>
39
#ifdef _MSC_VER
40
typedef unsigned __int32 uint32_t;
41
typedef unsigned __int64 uint64_t;
42
#else
43
#include <stdint.h>
44
#endif
45
46
#include "defines.h"
47
48
#if defined _WIN32 && (defined(_M_ARM) || defined(_M_ARM64))
49
# include <Intrin.h>
50
#endif
51
52
#if defined(__ARM_NEON__) && !defined(__CUDACC__)
53
# include "arm_neon.h"
54
#endif
55
56
namespace cvflann
57
{
58
59
template<typename T>
60
inline T abs(T x) { return (x<0) ? -x : x; }
61
62
template<>
63
0
inline int abs<int>(int x) { return ::abs(x); }
64
65
template<>
66
0
inline float abs<float>(float x) { return fabsf(x); }
67
68
template<>
69
0
inline double abs<double>(double x) { return fabs(x); }
70
71
72
template<typename TargetType>
73
inline TargetType round(float x) { return static_cast<TargetType>(x); }
74
75
template<>
76
0
inline unsigned int round<unsigned int>(float x) { return static_cast<unsigned int>(x + 0.5f); }
77
78
template<>
79
0
inline unsigned short round<unsigned short>(float x) { return static_cast<unsigned short>(x + 0.5f); }
80
81
template<>
82
0
inline unsigned char round<unsigned char>(float x) { return static_cast<unsigned char>(x + 0.5f); }
83
84
template<>
85
0
inline long long round<long long>(float x) { return static_cast<long long>(x + 0.5f); }
86
87
template<>
88
0
inline long round<long>(float x) { return static_cast<long>(x + 0.5f); }
89
90
template<>
91
0
inline int round<int>(float x) { return static_cast<int>(x + 0.5f) - (x<0); }
92
93
template<>
94
0
inline short round<short>(float x) { return static_cast<short>(x + 0.5f) - (x<0); }
95
96
template<>
97
0
inline char round<char>(float x) { return static_cast<char>(x + 0.5f) - (x<0); }
98
99
100
template<typename TargetType>
101
inline TargetType round(double x) { return static_cast<TargetType>(x); }
102
103
template<>
104
0
inline unsigned int round<unsigned int>(double x) { return static_cast<unsigned int>(x + 0.5); }
105
106
template<>
107
0
inline unsigned short round<unsigned short>(double x) { return static_cast<unsigned short>(x + 0.5); }
108
109
template<>
110
0
inline unsigned char round<unsigned char>(double x) { return static_cast<unsigned char>(x + 0.5); }
111
112
template<>
113
0
inline long long round<long long>(double x) { return static_cast<long long>(x + 0.5); }
114
115
template<>
116
0
inline long round<long>(double x) { return static_cast<long>(x + 0.5); }
117
118
template<>
119
0
inline int round<int>(double x) { return static_cast<int>(x + 0.5) - (x<0); }
120
121
template<>
122
0
inline short round<short>(double x) { return static_cast<short>(x + 0.5) - (x<0); }
123
124
template<>
125
0
inline char round<char>(double x) { return static_cast<char>(x + 0.5) - (x<0); }
126
127
128
template<typename T>
129
struct Accumulator { typedef T Type; };
130
template<>
131
struct Accumulator<unsigned char>  { typedef float Type; };
132
template<>
133
struct Accumulator<unsigned short> { typedef float Type; };
134
template<>
135
struct Accumulator<unsigned int> { typedef float Type; };
136
template<>
137
struct Accumulator<char>   { typedef float Type; };
138
template<>
139
struct Accumulator<short>  { typedef float Type; };
140
template<>
141
struct Accumulator<int> { typedef float Type; };
142
143
#undef True
144
#undef False
145
146
class True
147
{
148
public:
149
    static const bool val = true;
150
};
151
152
class False
153
{
154
public:
155
    static const bool val = false;
156
};
157
158
159
/*
160
 * This is a "zero iterator". It basically behaves like a zero filled
161
 * array to all algorithms that use arrays as iterators (STL style).
162
 * It's useful when there's a need to compute the distance between feature
163
 * and origin it and allows for better compiler optimisation than using a
164
 * zero-filled array.
165
 */
166
template <typename T>
167
struct ZeroIterator
168
{
169
170
    T operator*()
171
    {
172
        return 0;
173
    }
174
175
    T operator[](int)
176
    {
177
        return 0;
178
    }
179
180
    const ZeroIterator<T>& operator ++()
181
    {
182
        return *this;
183
    }
184
185
    ZeroIterator<T> operator ++(int)
186
    {
187
        return *this;
188
    }
189
190
    ZeroIterator<T>& operator+=(int)
191
    {
192
        return *this;
193
    }
194
195
};
196
197
198
199
/**
200
 * Squared Euclidean distance functor.
201
 *
202
 * This is the simpler, unrolled version. This is preferable for
203
 * very low dimensionality data (eg 3D points)
204
 */
205
template<class T>
206
struct L2_Simple
207
{
208
    typedef True is_kdtree_distance;
209
    typedef True is_vector_space_distance;
210
211
    typedef T ElementType;
212
    typedef typename Accumulator<T>::Type ResultType;
213
    typedef ResultType CentersType;
214
215
    template <typename Iterator1, typename Iterator2>
216
    ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType /*worst_dist*/ = -1) const
217
    {
218
        ResultType result = ResultType();
219
        ResultType diff;
220
        for(size_t i = 0; i < size; ++i ) {
221
            diff = (ResultType)(*a++ - *b++);
222
            result += diff*diff;
223
        }
224
        return result;
225
    }
226
227
    template <typename U, typename V>
228
    inline ResultType accum_dist(const U& a, const V& b, int) const
229
    {
230
        return (a-b)*(a-b);
231
    }
232
};
233
234
235
236
/**
237
 * Squared Euclidean distance functor, optimized version
238
 */
239
template<class T>
240
struct L2
241
{
242
    typedef True is_kdtree_distance;
243
    typedef True is_vector_space_distance;
244
245
    typedef T ElementType;
246
    typedef typename Accumulator<T>::Type ResultType;
247
    typedef ResultType CentersType;
248
249
    /**
250
     *  Compute the squared Euclidean distance between two vectors.
251
     *
252
     *  This is highly optimised, with loop unrolling, as it is one
253
     *  of the most expensive inner loops.
254
     *
255
     *  The computation of squared root at the end is omitted for
256
     *  efficiency.
257
     */
258
    template <typename Iterator1, typename Iterator2>
259
    ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
260
    {
261
        ResultType result = ResultType();
262
        ResultType diff0, diff1, diff2, diff3;
263
        Iterator1 last = a + size;
264
        Iterator1 lastgroup = last - 3;
265
266
        /* Process 4 items with each loop for efficiency. */
267
        while (a < lastgroup) {
268
            diff0 = (ResultType)(a[0] - b[0]);
269
            diff1 = (ResultType)(a[1] - b[1]);
270
            diff2 = (ResultType)(a[2] - b[2]);
271
            diff3 = (ResultType)(a[3] - b[3]);
272
            result += diff0 * diff0 + diff1 * diff1 + diff2 * diff2 + diff3 * diff3;
273
            a += 4;
274
            b += 4;
275
276
            if ((worst_dist>0)&&(result>worst_dist)) {
277
                return result;
278
            }
279
        }
280
        /* Process last 0-3 pixels.  Not needed for standard vector lengths. */
281
        while (a < last) {
282
            diff0 = (ResultType)(*a++ - *b++);
283
            result += diff0 * diff0;
284
        }
285
        return result;
286
    }
287
288
    /**
289
     *  Partial euclidean distance, using just one dimension. This is used by the
290
     *  kd-tree when computing partial distances while traversing the tree.
291
     *
292
     *  Squared root is omitted for efficiency.
293
     */
294
    template <typename U, typename V>
295
    inline ResultType accum_dist(const U& a, const V& b, int) const
296
    {
297
        return (a-b)*(a-b);
298
    }
299
};
300
301
302
/*
303
 * Manhattan distance functor, optimized version
304
 */
305
template<class T>
306
struct L1
307
{
308
    typedef True is_kdtree_distance;
309
    typedef True is_vector_space_distance;
310
311
    typedef T ElementType;
312
    typedef typename Accumulator<T>::Type ResultType;
313
    typedef ResultType CentersType;
314
315
    /**
316
     *  Compute the Manhattan (L_1) distance between two vectors.
317
     *
318
     *  This is highly optimised, with loop unrolling, as it is one
319
     *  of the most expensive inner loops.
320
     */
321
    template <typename Iterator1, typename Iterator2>
322
    ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
323
    {
324
        ResultType result = ResultType();
325
        ResultType diff0, diff1, diff2, diff3;
326
        Iterator1 last = a + size;
327
        Iterator1 lastgroup = last - 3;
328
329
        /* Process 4 items with each loop for efficiency. */
330
        while (a < lastgroup) {
331
            diff0 = (ResultType)abs(a[0] - b[0]);
332
            diff1 = (ResultType)abs(a[1] - b[1]);
333
            diff2 = (ResultType)abs(a[2] - b[2]);
334
            diff3 = (ResultType)abs(a[3] - b[3]);
335
            result += diff0 + diff1 + diff2 + diff3;
336
            a += 4;
337
            b += 4;
338
339
            if ((worst_dist>0)&&(result>worst_dist)) {
340
                return result;
341
            }
342
        }
343
        /* Process last 0-3 pixels.  Not needed for standard vector lengths. */
344
        while (a < last) {
345
            diff0 = (ResultType)abs(*a++ - *b++);
346
            result += diff0;
347
        }
348
        return result;
349
    }
350
351
    /**
352
     * Partial distance, used by the kd-tree.
353
     */
354
    template <typename U, typename V>
355
    inline ResultType accum_dist(const U& a, const V& b, int) const
356
    {
357
        return abs(a-b);
358
    }
359
};
360
361
362
363
template<class T>
364
struct MinkowskiDistance
365
{
366
    typedef True is_kdtree_distance;
367
    typedef True is_vector_space_distance;
368
369
    typedef T ElementType;
370
    typedef typename Accumulator<T>::Type ResultType;
371
    typedef ResultType CentersType;
372
373
    int order;
374
375
    MinkowskiDistance(int order_) : order(order_) {}
376
377
    /**
378
     *  Compute the Minkowski (L_p) distance between two vectors.
379
     *
380
     *  This is highly optimised, with loop unrolling, as it is one
381
     *  of the most expensive inner loops.
382
     *
383
     *  The computation of squared root at the end is omitted for
384
     *  efficiency.
385
     */
386
    template <typename Iterator1, typename Iterator2>
387
    ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
388
    {
389
        ResultType result = ResultType();
390
        ResultType diff0, diff1, diff2, diff3;
391
        Iterator1 last = a + size;
392
        Iterator1 lastgroup = last - 3;
393
394
        /* Process 4 items with each loop for efficiency. */
395
        while (a < lastgroup) {
396
            diff0 = (ResultType)abs(a[0] - b[0]);
397
            diff1 = (ResultType)abs(a[1] - b[1]);
398
            diff2 = (ResultType)abs(a[2] - b[2]);
399
            diff3 = (ResultType)abs(a[3] - b[3]);
400
            result += pow(diff0,order) + pow(diff1,order) + pow(diff2,order) + pow(diff3,order);
401
            a += 4;
402
            b += 4;
403
404
            if ((worst_dist>0)&&(result>worst_dist)) {
405
                return result;
406
            }
407
        }
408
        /* Process last 0-3 pixels.  Not needed for standard vector lengths. */
409
        while (a < last) {
410
            diff0 = (ResultType)abs(*a++ - *b++);
411
            result += pow(diff0,order);
412
        }
413
        return result;
414
    }
415
416
    /**
417
     * Partial distance, used by the kd-tree.
418
     */
419
    template <typename U, typename V>
420
    inline ResultType accum_dist(const U& a, const V& b, int) const
421
    {
422
        return pow(static_cast<ResultType>(abs(a-b)),order);
423
    }
424
};
425
426
427
428
template<class T>
429
struct MaxDistance
430
{
431
    typedef False is_kdtree_distance;
432
    typedef True is_vector_space_distance;
433
434
    typedef T ElementType;
435
    typedef typename Accumulator<T>::Type ResultType;
436
    typedef ResultType CentersType;
437
438
    /**
439
     *  Compute the max distance (L_infinity) between two vectors.
440
     *
441
     *  This distance is not a valid kdtree distance, it's not dimensionwise additive.
442
     */
443
    template <typename Iterator1, typename Iterator2>
444
    ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
445
    {
446
        ResultType result = ResultType();
447
        ResultType diff0, diff1, diff2, diff3;
448
        Iterator1 last = a + size;
449
        Iterator1 lastgroup = last - 3;
450
451
        /* Process 4 items with each loop for efficiency. */
452
        while (a < lastgroup) {
453
            diff0 = abs(a[0] - b[0]);
454
            diff1 = abs(a[1] - b[1]);
455
            diff2 = abs(a[2] - b[2]);
456
            diff3 = abs(a[3] - b[3]);
457
            if (diff0>result) {result = diff0; }
458
            if (diff1>result) {result = diff1; }
459
            if (diff2>result) {result = diff2; }
460
            if (diff3>result) {result = diff3; }
461
            a += 4;
462
            b += 4;
463
464
            if ((worst_dist>0)&&(result>worst_dist)) {
465
                return result;
466
            }
467
        }
468
        /* Process last 0-3 pixels.  Not needed for standard vector lengths. */
469
        while (a < last) {
470
            diff0 = abs(*a++ - *b++);
471
            result = (diff0>result) ? diff0 : result;
472
        }
473
        return result;
474
    }
475
476
    /* This distance functor is not dimension-wise additive, which
477
     * makes it an invalid kd-tree distance, not implementing the accum_dist method */
478
479
};
480
481
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
482
483
/**
484
 * Hamming distance functor - counts the bit differences between two strings - useful for the Brief descriptor
485
 * bit count of A exclusive XOR'ed with B
486
 */
487
struct HammingLUT
488
{
489
    typedef False is_kdtree_distance;
490
    typedef False is_vector_space_distance;
491
492
    typedef unsigned char ElementType;
493
    typedef int ResultType;
494
    typedef ElementType CentersType;
495
496
    /** this will count the bits in a ^ b
497
     */
498
    template<typename Iterator2>
499
    ResultType operator()(const unsigned char* a, const Iterator2 b, size_t size) const
500
    {
501
        static const uchar popCountTable[] =
502
        {
503
            0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
504
            1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
505
            1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
506
            2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
507
            1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
508
            2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
509
            2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
510
            3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
511
        };
512
        ResultType result = 0;
513
        const unsigned char* b2 = reinterpret_cast<const unsigned char*> (b);
514
        for (size_t i = 0; i < size; i++) {
515
            result += popCountTable[a[i] ^ b2[i]];
516
        }
517
        return result;
518
    }
519
520
521
    ResultType operator()(const unsigned char* a, const ZeroIterator<unsigned char> b, size_t size) const
522
0
    {
523
0
        (void)b;
524
0
        static const uchar popCountTable[] =
525
0
        {
526
0
            0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
527
0
            1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
528
0
            1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
529
0
            2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
530
0
            1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
531
0
            2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
532
0
            2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
533
0
            3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
534
0
        };
535
0
        ResultType result = 0;
536
0
        for (size_t i = 0; i < size; i++) {
537
0
            result += popCountTable[a[i]];
538
0
        }
539
0
        return result;
540
0
    }
541
};
542
543
/**
544
 * Hamming distance functor (pop count between two binary vectors, i.e. xor them and count the number of bits set)
545
 * That code was taken from brief.cpp in OpenCV
546
 */
547
template<class T>
548
struct Hamming
549
{
550
    typedef False is_kdtree_distance;
551
    typedef False is_vector_space_distance;
552
553
554
    typedef T ElementType;
555
    typedef int ResultType;
556
    typedef ElementType CentersType;
557
558
    template<typename Iterator1, typename Iterator2>
559
    ResultType operator()(const Iterator1 a, const Iterator2 b, size_t size, ResultType /*worst_dist*/ = -1) const
560
    {
561
        ResultType result = 0;
562
#if defined(__ARM_NEON__) && !defined(__CUDACC__)
563
        {
564
            const unsigned char* a2 = reinterpret_cast<const unsigned char*> (a);
565
            const unsigned char* b2 = reinterpret_cast<const unsigned char*> (b);
566
            uint32x4_t bits = vmovq_n_u32(0);
567
            for (size_t i = 0; i < size; i += 16) {
568
                uint8x16_t A_vec = vld1q_u8 (a2 + i);
569
                uint8x16_t B_vec = vld1q_u8 (b2 + i);
570
                uint8x16_t AxorB = veorq_u8 (A_vec, B_vec);
571
                uint8x16_t bitsSet = vcntq_u8 (AxorB);
572
                uint16x8_t bitSet8 = vpaddlq_u8 (bitsSet);
573
                uint32x4_t bitSet4 = vpaddlq_u16 (bitSet8);
574
                bits = vaddq_u32(bits, bitSet4);
575
            }
576
            uint64x2_t bitSet2 = vpaddlq_u32 (bits);
577
            result = vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),0);
578
            result += vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),2);
579
        }
580
#elif defined(__GNUC__)
581
        {
582
            //for portability just use unsigned long -- and use the __builtin_popcountll (see docs for __builtin_popcountll)
583
            typedef unsigned long long pop_t;
584
            const size_t modulo = size % sizeof(pop_t);
585
            const pop_t* a2 = reinterpret_cast<const pop_t*> (a);
586
            const pop_t* b2 = reinterpret_cast<const pop_t*> (b);
587
            const pop_t* a2_end = a2 + (size / sizeof(pop_t));
588
589
            for (; a2 != a2_end; ++a2, ++b2) result += __builtin_popcountll((*a2) ^ (*b2));
590
591
            if (modulo) {
592
                //in the case where size is not dividable by sizeof(size_t)
593
                //need to mask off the bits at the end
594
                pop_t a_final = 0, b_final = 0;
595
                memcpy(&a_final, a2, modulo);
596
                memcpy(&b_final, b2, modulo);
597
                result += __builtin_popcountll(a_final ^ b_final);
598
            }
599
        }
600
#else // NO NEON and NOT GNUC
601
        HammingLUT lut;
602
        result = lut(reinterpret_cast<const unsigned char*> (a),
603
                     reinterpret_cast<const unsigned char*> (b), size);
604
#endif
605
        return result;
606
    }
607
608
609
    template<typename Iterator1>
610
    ResultType operator()(const Iterator1 a, ZeroIterator<unsigned char> b, size_t size, ResultType /*worst_dist*/ = -1) const
611
    {
612
        (void)b;
613
        ResultType result = 0;
614
#if defined(__ARM_NEON__) && !defined(__CUDACC__)
615
        {
616
            const unsigned char* a2 = reinterpret_cast<const unsigned char*> (a);
617
            uint32x4_t bits = vmovq_n_u32(0);
618
            for (size_t i = 0; i < size; i += 16) {
619
                uint8x16_t A_vec = vld1q_u8 (a2 + i);
620
                uint8x16_t bitsSet = vcntq_u8 (A_vec);
621
                uint16x8_t bitSet8 = vpaddlq_u8 (bitsSet);
622
                uint32x4_t bitSet4 = vpaddlq_u16 (bitSet8);
623
                bits = vaddq_u32(bits, bitSet4);
624
            }
625
            uint64x2_t bitSet2 = vpaddlq_u32 (bits);
626
            result = vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),0);
627
            result += vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),2);
628
        }
629
#elif defined(__GNUC__)
630
        {
631
            //for portability just use unsigned long -- and use the __builtin_popcountll (see docs for __builtin_popcountll)
632
            typedef unsigned long long pop_t;
633
            const size_t modulo = size % sizeof(pop_t);
634
            const pop_t* a2 = reinterpret_cast<const pop_t*> (a);
635
            const pop_t* a2_end = a2 + (size / sizeof(pop_t));
636
637
            for (; a2 != a2_end; ++a2) result += __builtin_popcountll(*a2);
638
639
            if (modulo) {
640
                //in the case where size is not dividable by sizeof(size_t)
641
                //need to mask off the bits at the end
642
                pop_t a_final = 0;
643
                memcpy(&a_final, a2, modulo);
644
                result += __builtin_popcountll(a_final);
645
            }
646
        }
647
#else // NO NEON and NOT GNUC
648
        HammingLUT lut;
649
        result = lut(reinterpret_cast<const unsigned char*> (a), b, size);
650
#endif
651
        return result;
652
    }
653
};
654
655
template<typename T>
656
struct Hamming2
657
{
658
    typedef False is_kdtree_distance;
659
    typedef False is_vector_space_distance;
660
661
    typedef T ElementType;
662
    typedef int ResultType;
663
    typedef ElementType CentersType;
664
665
    /** This is popcount_3() from:
666
     * http://en.wikipedia.org/wiki/Hamming_weight */
667
    unsigned int popcnt32(uint32_t n) const
668
    {
669
        n -= ((n >> 1) & 0x55555555);
670
        n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
671
        return (((n + (n >> 4))& 0xF0F0F0F)* 0x1010101) >> 24;
672
    }
673
674
#ifdef FLANN_PLATFORM_64_BIT
675
    unsigned int popcnt64(uint64_t n) const
676
    {
677
        n -= ((n >> 1) & 0x5555555555555555);
678
        n = (n & 0x3333333333333333) + ((n >> 2) & 0x3333333333333333);
679
        return (((n + (n >> 4))& 0x0f0f0f0f0f0f0f0f)* 0x0101010101010101) >> 56;
680
    }
681
#endif
682
683
    template <typename Iterator1, typename Iterator2>
684
    ResultType operator()(const Iterator1 a, const Iterator2 b, size_t size, ResultType /*worst_dist*/ = -1) const
685
    {
686
        CV_DbgAssert(!(size % long_word_size_) && "vectors size must be multiple of long words size (i.e. 8)");
687
688
#ifdef FLANN_PLATFORM_64_BIT
689
        const uint64_t* pa = reinterpret_cast<const uint64_t*>(a);
690
        const uint64_t* pb = reinterpret_cast<const uint64_t*>(b);
691
        ResultType result = 0;
692
        size /= long_word_size_;
693
        for(size_t i = 0; i < size; ++i ) {
694
            result += popcnt64(*pa ^ *pb);
695
            ++pa;
696
            ++pb;
697
        }
698
#else
699
        const uint32_t* pa = reinterpret_cast<const uint32_t*>(a);
700
        const uint32_t* pb = reinterpret_cast<const uint32_t*>(b);
701
        ResultType result = 0;
702
        size /= long_word_size_;
703
        for(size_t i = 0; i < size; ++i ) {
704
            result += popcnt32(*pa ^ *pb);
705
            ++pa;
706
            ++pb;
707
        }
708
#endif
709
        return result;
710
    }
711
712
713
    template <typename Iterator1>
714
    ResultType operator()(const Iterator1 a, ZeroIterator<unsigned char> b, size_t size, ResultType /*worst_dist*/ = -1) const
715
    {
716
        CV_DbgAssert(!(size % long_word_size_) && "vectors size must be multiple of long words size (i.e. 8)");
717
718
        (void)b;
719
#ifdef FLANN_PLATFORM_64_BIT
720
        const uint64_t* pa = reinterpret_cast<const uint64_t*>(a);
721
        ResultType result = 0;
722
        size /= long_word_size_;
723
        for(size_t i = 0; i < size; ++i ) {
724
            result += popcnt64(*pa);
725
            ++pa;
726
        }
727
#else
728
        const uint32_t* pa = reinterpret_cast<const uint32_t*>(a);
729
        ResultType result = 0;
730
        size /= long_word_size_;
731
        for(size_t i = 0; i < size; ++i ) {
732
            result += popcnt32(*pa);
733
            ++pa;
734
        }
735
#endif
736
        return result;
737
    }
738
739
private:
740
#ifdef FLANN_PLATFORM_64_BIT
741
    static const size_t long_word_size_ = sizeof(uint64_t)/sizeof(unsigned char);
742
#else
743
    static const size_t long_word_size_ = sizeof(uint32_t)/sizeof(unsigned char);
744
#endif
745
};
746
747
748
749
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
750
751
struct DNAmmingLUT
752
{
753
    typedef False is_kdtree_distance;
754
    typedef False is_vector_space_distance;
755
756
    typedef unsigned char ElementType;
757
    typedef int ResultType;
758
    typedef ElementType CentersType;
759
760
    /** this will count the bits in a ^ b
761
     */
762
    template<typename Iterator2>
763
    ResultType operator()(const unsigned char* a, const Iterator2 b, size_t size) const
764
    {
765
        static const uchar popCountTable[] =
766
        {
767
            0, 1, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3,
768
            1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3,
769
            1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4,
770
            2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4,
771
            1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4,
772
            2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4,
773
            1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4,
774
            2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4
775
        };
776
        ResultType result = 0;
777
        const unsigned char* b2 = reinterpret_cast<const unsigned char*> (b);
778
        for (size_t i = 0; i < size; i++) {
779
            result += popCountTable[a[i] ^ b2[i]];
780
        }
781
        return result;
782
    }
783
784
785
    ResultType operator()(const unsigned char* a, const ZeroIterator<unsigned char> b, size_t size) const
786
0
    {
787
0
        (void)b;
788
0
        static const uchar popCountTable[] =
789
0
        {
790
0
            0, 1, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3,
791
0
            1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3,
792
0
            1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4,
793
0
            2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4,
794
0
            1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4,
795
0
            2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4,
796
0
            1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4,
797
0
            2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 2, 3, 3, 3, 3, 4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4
798
0
        };
799
0
        ResultType result = 0;
800
0
        for (size_t i = 0; i < size; i++) {
801
0
            result += popCountTable[a[i]];
802
0
        }
803
0
        return result;
804
0
    }
805
};
806
807
808
template<typename T>
809
struct DNAmming2
810
{
811
    typedef False is_kdtree_distance;
812
    typedef False is_vector_space_distance;
813
814
    typedef T ElementType;
815
    typedef int ResultType;
816
    typedef ElementType CentersType;
817
818
    /** This is popcount_3() from:
819
     * http://en.wikipedia.org/wiki/Hamming_weight */
820
    unsigned int popcnt32(uint32_t n) const
821
    {
822
        n = ((n >> 1) | n) & 0x55555555;
823
        n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
824
        return (((n + (n >> 4))& 0x0F0F0F0F)* 0x01010101) >> 24;
825
    }
826
827
#ifdef FLANN_PLATFORM_64_BIT
828
    unsigned int popcnt64(uint64_t n) const
829
    {
830
        n = ((n >> 1) | n) & 0x5555555555555555;
831
        n = (n & 0x3333333333333333) + ((n >> 2) & 0x3333333333333333);
832
        return (((n + (n >> 4))& 0x0f0f0f0f0f0f0f0f)* 0x0101010101010101) >> 56;
833
    }
834
#endif
835
836
    template <typename Iterator1, typename Iterator2>
837
    ResultType operator()(const Iterator1 a, const Iterator2 b, size_t size, ResultType /*worst_dist*/ = -1) const
838
    {
839
        CV_DbgAssert(!(size % long_word_size_) && "vectors size must be multiple of long words size (i.e. 8)");
840
841
#ifdef FLANN_PLATFORM_64_BIT
842
        const uint64_t* pa = reinterpret_cast<const uint64_t*>(a);
843
        const uint64_t* pb = reinterpret_cast<const uint64_t*>(b);
844
        ResultType result = 0;
845
        size /= long_word_size_;
846
        for(size_t i = 0; i < size; ++i ) {
847
            result += popcnt64(*pa ^ *pb);
848
            ++pa;
849
            ++pb;
850
        }
851
#else
852
        const uint32_t* pa = reinterpret_cast<const uint32_t*>(a);
853
        const uint32_t* pb = reinterpret_cast<const uint32_t*>(b);
854
        ResultType result = 0;
855
        size /= long_word_size_;
856
        for(size_t i = 0; i < size; ++i ) {
857
            result += popcnt32(*pa ^ *pb);
858
            ++pa;
859
            ++pb;
860
        }
861
#endif
862
        return result;
863
    }
864
865
866
    template <typename Iterator1>
867
    ResultType operator()(const Iterator1 a, ZeroIterator<unsigned char> b, size_t size, ResultType /*worst_dist*/ = -1) const
868
    {
869
        CV_DbgAssert(!(size % long_word_size_) && "vectors size must be multiple of long words size (i.e. 8)");
870
871
        (void)b;
872
#ifdef FLANN_PLATFORM_64_BIT
873
        const uint64_t* pa = reinterpret_cast<const uint64_t*>(a);
874
        ResultType result = 0;
875
        size /= long_word_size_;
876
        for(size_t i = 0; i < size; ++i ) {
877
            result += popcnt64(*pa);
878
            ++pa;
879
        }
880
#else
881
        const uint32_t* pa = reinterpret_cast<const uint32_t*>(a);
882
        ResultType result = 0;
883
        size /= long_word_size_;
884
        for(size_t i = 0; i < size; ++i ) {
885
            result += popcnt32(*pa);
886
            ++pa;
887
        }
888
#endif
889
        return result;
890
    }
891
892
private:
893
#ifdef FLANN_PLATFORM_64_BIT
894
    static const size_t long_word_size_= sizeof(uint64_t)/sizeof(unsigned char);
895
#else
896
    static const size_t long_word_size_= sizeof(uint32_t)/sizeof(unsigned char);
897
#endif
898
};
899
900
901
902
template<class T>
903
struct HistIntersectionDistance
904
{
905
    typedef True is_kdtree_distance;
906
    typedef True is_vector_space_distance;
907
908
    typedef T ElementType;
909
    typedef typename Accumulator<T>::Type ResultType;
910
    typedef ResultType CentersType;
911
912
    /**
913
     *  Compute the histogram intersection distance
914
     */
915
    template <typename Iterator1, typename Iterator2>
916
    ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
917
    {
918
        ResultType result = ResultType();
919
        ResultType min0, min1, min2, min3;
920
        Iterator1 last = a + size;
921
        Iterator1 lastgroup = last - 3;
922
923
        /* Process 4 items with each loop for efficiency. */
924
        while (a < lastgroup) {
925
            min0 = (ResultType)(a[0] < b[0] ? a[0] : b[0]);
926
            min1 = (ResultType)(a[1] < b[1] ? a[1] : b[1]);
927
            min2 = (ResultType)(a[2] < b[2] ? a[2] : b[2]);
928
            min3 = (ResultType)(a[3] < b[3] ? a[3] : b[3]);
929
            result += min0 + min1 + min2 + min3;
930
            a += 4;
931
            b += 4;
932
            if ((worst_dist>0)&&(result>worst_dist)) {
933
                return result;
934
            }
935
        }
936
        /* Process last 0-3 pixels.  Not needed for standard vector lengths. */
937
        while (a < last) {
938
            min0 = (ResultType)(*a < *b ? *a : *b);
939
            result += min0;
940
            ++a;
941
            ++b;
942
        }
943
        return result;
944
    }
945
946
    /**
947
     * Partial distance, used by the kd-tree.
948
     */
949
    template <typename U, typename V>
950
    inline ResultType accum_dist(const U& a, const V& b, int) const
951
    {
952
        return a<b ? a : b;
953
    }
954
};
955
956
957
958
template<class T>
959
struct HellingerDistance
960
{
961
    typedef True is_kdtree_distance;
962
    typedef True is_vector_space_distance;
963
964
    typedef T ElementType;
965
    typedef typename Accumulator<T>::Type ResultType;
966
    typedef ResultType CentersType;
967
968
    /**
969
     *  Compute the Hellinger distance
970
     */
971
    template <typename Iterator1, typename Iterator2>
972
    ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType /*worst_dist*/ = -1) const
973
    {
974
        ResultType result = ResultType();
975
        ResultType diff0, diff1, diff2, diff3;
976
        Iterator1 last = a + size;
977
        Iterator1 lastgroup = last - 3;
978
979
        /* Process 4 items with each loop for efficiency. */
980
        while (a < lastgroup) {
981
            diff0 = sqrt(static_cast<ResultType>(a[0])) - sqrt(static_cast<ResultType>(b[0]));
982
            diff1 = sqrt(static_cast<ResultType>(a[1])) - sqrt(static_cast<ResultType>(b[1]));
983
            diff2 = sqrt(static_cast<ResultType>(a[2])) - sqrt(static_cast<ResultType>(b[2]));
984
            diff3 = sqrt(static_cast<ResultType>(a[3])) - sqrt(static_cast<ResultType>(b[3]));
985
            result += diff0 * diff0 + diff1 * diff1 + diff2 * diff2 + diff3 * diff3;
986
            a += 4;
987
            b += 4;
988
        }
989
        while (a < last) {
990
            diff0 = sqrt(static_cast<ResultType>(*a++)) - sqrt(static_cast<ResultType>(*b++));
991
            result += diff0 * diff0;
992
        }
993
        return result;
994
    }
995
996
    /**
997
     * Partial distance, used by the kd-tree.
998
     */
999
    template <typename U, typename V>
1000
    inline ResultType accum_dist(const U& a, const V& b, int) const
1001
    {
1002
        ResultType diff = sqrt(static_cast<ResultType>(a)) - sqrt(static_cast<ResultType>(b));
1003
        return diff * diff;
1004
    }
1005
};
1006
1007
1008
template<class T>
1009
struct ChiSquareDistance
1010
{
1011
    typedef True is_kdtree_distance;
1012
    typedef True is_vector_space_distance;
1013
1014
    typedef T ElementType;
1015
    typedef typename Accumulator<T>::Type ResultType;
1016
    typedef ResultType CentersType;
1017
1018
    /**
1019
     *  Compute the chi-square distance
1020
     */
1021
    template <typename Iterator1, typename Iterator2>
1022
    ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
1023
    {
1024
        ResultType result = ResultType();
1025
        ResultType sum, diff;
1026
        Iterator1 last = a + size;
1027
1028
        while (a < last) {
1029
            sum = (ResultType)(*a + *b);
1030
            if (sum>0) {
1031
                diff = (ResultType)(*a - *b);
1032
                result += diff*diff/sum;
1033
            }
1034
            ++a;
1035
            ++b;
1036
1037
            if ((worst_dist>0)&&(result>worst_dist)) {
1038
                return result;
1039
            }
1040
        }
1041
        return result;
1042
    }
1043
1044
    /**
1045
     * Partial distance, used by the kd-tree.
1046
     */
1047
    template <typename U, typename V>
1048
    inline ResultType accum_dist(const U& a, const V& b, int) const
1049
    {
1050
        ResultType result = ResultType();
1051
        ResultType sum, diff;
1052
1053
        sum = (ResultType)(a+b);
1054
        if (sum>0) {
1055
            diff = (ResultType)(a-b);
1056
            result = diff*diff/sum;
1057
        }
1058
        return result;
1059
    }
1060
};
1061
1062
1063
template<class T>
1064
struct KL_Divergence
1065
{
1066
    typedef True is_kdtree_distance;
1067
    typedef True is_vector_space_distance;
1068
1069
    typedef T ElementType;
1070
    typedef typename Accumulator<T>::Type ResultType;
1071
    typedef ResultType CentersType;
1072
1073
    /**
1074
     *  Compute the Kullback-Leibler divergence
1075
     */
1076
    template <typename Iterator1, typename Iterator2>
1077
    ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
1078
    {
1079
        ResultType result = ResultType();
1080
        Iterator1 last = a + size;
1081
1082
        while (a < last) {
1083
            if ( *a != 0 && *b != 0 ) {
1084
                ResultType ratio = (ResultType)(*a / *b);
1085
                if (ratio>0) {
1086
                    result += *a * log(ratio);
1087
                }
1088
            }
1089
            ++a;
1090
            ++b;
1091
1092
            if ((worst_dist>0)&&(result>worst_dist)) {
1093
                return result;
1094
            }
1095
        }
1096
        return result;
1097
    }
1098
1099
    /**
1100
     * Partial distance, used by the kd-tree.
1101
     */
1102
    template <typename U, typename V>
1103
    inline ResultType accum_dist(const U& a, const V& b, int) const
1104
    {
1105
        ResultType result = ResultType();
1106
        if( a != 0 && b != 0 ) {
1107
            ResultType ratio = (ResultType)(a / b);
1108
            if (ratio>0) {
1109
                result = a * log(ratio);
1110
            }
1111
        }
1112
        return result;
1113
    }
1114
};
1115
1116
1117
/*
1118
 * Depending on processed distances, some of them are already squared (e.g. L2)
1119
 * and some are not (e.g.Hamming). In KMeans++ for instance we want to be sure
1120
 * we are working on ^2 distances, thus following templates to ensure that.
1121
 */
1122
template <typename Distance, typename ElementType>
1123
struct squareDistance
1124
{
1125
    typedef typename Distance::ResultType ResultType;
1126
    ResultType operator()( ResultType dist ) { return dist*dist; }
1127
};
1128
1129
1130
template <typename ElementType>
1131
struct squareDistance<L2_Simple<ElementType>, ElementType>
1132
{
1133
    typedef typename L2_Simple<ElementType>::ResultType ResultType;
1134
    ResultType operator()( ResultType dist ) { return dist; }
1135
};
1136
1137
template <typename ElementType>
1138
struct squareDistance<L2<ElementType>, ElementType>
1139
{
1140
    typedef typename L2<ElementType>::ResultType ResultType;
1141
    ResultType operator()( ResultType dist ) { return dist; }
1142
};
1143
1144
1145
template <typename ElementType>
1146
struct squareDistance<MinkowskiDistance<ElementType>, ElementType>
1147
{
1148
    typedef typename MinkowskiDistance<ElementType>::ResultType ResultType;
1149
    ResultType operator()( ResultType dist ) { return dist; }
1150
};
1151
1152
template <typename ElementType>
1153
struct squareDistance<HellingerDistance<ElementType>, ElementType>
1154
{
1155
    typedef typename HellingerDistance<ElementType>::ResultType ResultType;
1156
    ResultType operator()( ResultType dist ) { return dist; }
1157
};
1158
1159
template <typename ElementType>
1160
struct squareDistance<ChiSquareDistance<ElementType>, ElementType>
1161
{
1162
    typedef typename ChiSquareDistance<ElementType>::ResultType ResultType;
1163
    ResultType operator()( ResultType dist ) { return dist; }
1164
};
1165
1166
1167
template <typename Distance>
1168
typename Distance::ResultType ensureSquareDistance( typename Distance::ResultType dist )
1169
{
1170
    typedef typename Distance::ElementType ElementType;
1171
1172
    squareDistance<Distance, ElementType> dummy;
1173
    return dummy( dist );
1174
}
1175
1176
1177
/*
1178
 * ...a template to tell the user if the distance he is working with is actually squared
1179
 */
1180
1181
template <typename Distance, typename ElementType>
1182
struct isSquareDist
1183
{
1184
    bool operator()() { return false; }
1185
};
1186
1187
1188
template <typename ElementType>
1189
struct isSquareDist<L2_Simple<ElementType>, ElementType>
1190
{
1191
    bool operator()() { return true; }
1192
};
1193
1194
template <typename ElementType>
1195
struct isSquareDist<L2<ElementType>, ElementType>
1196
{
1197
    bool operator()() { return true; }
1198
};
1199
1200
1201
template <typename ElementType>
1202
struct isSquareDist<MinkowskiDistance<ElementType>, ElementType>
1203
{
1204
    bool operator()() { return true; }
1205
};
1206
1207
template <typename ElementType>
1208
struct isSquareDist<HellingerDistance<ElementType>, ElementType>
1209
{
1210
    bool operator()() { return true; }
1211
};
1212
1213
template <typename ElementType>
1214
struct isSquareDist<ChiSquareDistance<ElementType>, ElementType>
1215
{
1216
    bool operator()() { return true; }
1217
};
1218
1219
1220
template <typename Distance>
1221
bool isSquareDistance()
1222
{
1223
    typedef typename Distance::ElementType ElementType;
1224
1225
    isSquareDist<Distance, ElementType> dummy;
1226
    return dummy();
1227
}
1228
1229
/*
1230
 * ...and a template to ensure the user that he will process the normal distance,
1231
 * and not squared distance, without losing processing time calling sqrt(ensureSquareDistance)
1232
 * that will result in doing actually sqrt(dist*dist) for L1 distance for instance.
1233
 */
1234
template <typename Distance, typename ElementType>
1235
struct simpleDistance
1236
{
1237
    typedef typename Distance::ResultType ResultType;
1238
    ResultType operator()( ResultType dist ) { return dist; }
1239
};
1240
1241
1242
template <typename ElementType>
1243
struct simpleDistance<L2_Simple<ElementType>, ElementType>
1244
{
1245
    typedef typename L2_Simple<ElementType>::ResultType ResultType;
1246
    ResultType operator()( ResultType dist ) { return sqrt(dist); }
1247
};
1248
1249
template <typename ElementType>
1250
struct simpleDistance<L2<ElementType>, ElementType>
1251
{
1252
    typedef typename L2<ElementType>::ResultType ResultType;
1253
    ResultType operator()( ResultType dist ) { return sqrt(dist); }
1254
};
1255
1256
1257
template <typename ElementType>
1258
struct simpleDistance<MinkowskiDistance<ElementType>, ElementType>
1259
{
1260
    typedef typename MinkowskiDistance<ElementType>::ResultType ResultType;
1261
    ResultType operator()( ResultType dist ) { return sqrt(dist); }
1262
};
1263
1264
template <typename ElementType>
1265
struct simpleDistance<HellingerDistance<ElementType>, ElementType>
1266
{
1267
    typedef typename HellingerDistance<ElementType>::ResultType ResultType;
1268
    ResultType operator()( ResultType dist ) { return sqrt(dist); }
1269
};
1270
1271
template <typename ElementType>
1272
struct simpleDistance<ChiSquareDistance<ElementType>, ElementType>
1273
{
1274
    typedef typename ChiSquareDistance<ElementType>::ResultType ResultType;
1275
    ResultType operator()( ResultType dist ) { return sqrt(dist); }
1276
};
1277
1278
1279
template <typename Distance>
1280
typename Distance::ResultType ensureSimpleDistance( typename Distance::ResultType dist )
1281
{
1282
    typedef typename Distance::ElementType ElementType;
1283
1284
    simpleDistance<Distance, ElementType> dummy;
1285
    return dummy( dist );
1286
}
1287
1288
}
1289
1290
//! @endcond
1291
1292
#endif //OPENCV_FLANN_DIST_H_