Home | History | Annotate | Download | only in flann
      1 /***********************************************************************
      2  * Software License Agreement (BSD License)
      3  *
      4  * Copyright 2008-2009  Marius Muja (mariusm (at) cs.ubc.ca). All rights reserved.
      5  * Copyright 2008-2009  David G. Lowe (lowe (at) 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 #include <cmath>
     35 #include <cstdlib>
     36 #include <string.h>
     37 #ifdef _MSC_VER
     38 typedef unsigned __int32 uint32_t;
     39 typedef unsigned __int64 uint64_t;
     40 #else
     41 #include <stdint.h>
     42 #endif
     43 
     44 #include "defines.h"
     45 
     46 #if (defined WIN32 || defined _WIN32) && defined(_M_ARM)
     47 # include <Intrin.h>
     48 #endif
     49 
     50 #ifdef __ARM_NEON__
     51 # include "arm_neon.h"
     52 #endif
     53 
     54 namespace cvflann
     55 {
     56 
     57 template<typename T>
     58 inline T abs(T x) { return (x<0) ? -x : x; }
     59 
     60 template<>
     61 inline int abs<int>(int x) { return ::abs(x); }
     62 
     63 template<>
     64 inline float abs<float>(float x) { return fabsf(x); }
     65 
     66 template<>
     67 inline double abs<double>(double x) { return fabs(x); }
     68 
     69 template<typename T>
     70 struct Accumulator { typedef T Type; };
     71 template<>
     72 struct Accumulator<unsigned char>  { typedef float Type; };
     73 template<>
     74 struct Accumulator<unsigned short> { typedef float Type; };
     75 template<>
     76 struct Accumulator<unsigned int> { typedef float Type; };
     77 template<>
     78 struct Accumulator<char>   { typedef float Type; };
     79 template<>
     80 struct Accumulator<short>  { typedef float Type; };
     81 template<>
     82 struct Accumulator<int> { typedef float Type; };
     83 
     84 #undef True
     85 #undef False
     86 
     87 class True
     88 {
     89 };
     90 
     91 class False
     92 {
     93 };
     94 
     95 
     96 /**
     97  * Squared Euclidean distance functor.
     98  *
     99  * This is the simpler, unrolled version. This is preferable for
    100  * very low dimensionality data (eg 3D points)
    101  */
    102 template<class T>
    103 struct L2_Simple
    104 {
    105     typedef True is_kdtree_distance;
    106     typedef True is_vector_space_distance;
    107 
    108     typedef T ElementType;
    109     typedef typename Accumulator<T>::Type ResultType;
    110 
    111     template <typename Iterator1, typename Iterator2>
    112     ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType /*worst_dist*/ = -1) const
    113     {
    114         ResultType result = ResultType();
    115         ResultType diff;
    116         for(size_t i = 0; i < size; ++i ) {
    117             diff = *a++ - *b++;
    118             result += diff*diff;
    119         }
    120         return result;
    121     }
    122 
    123     template <typename U, typename V>
    124     inline ResultType accum_dist(const U& a, const V& b, int) const
    125     {
    126         return (a-b)*(a-b);
    127     }
    128 };
    129 
    130 
    131 
    132 /**
    133  * Squared Euclidean distance functor, optimized version
    134  */
    135 template<class T>
    136 struct L2
    137 {
    138     typedef True is_kdtree_distance;
    139     typedef True is_vector_space_distance;
    140 
    141     typedef T ElementType;
    142     typedef typename Accumulator<T>::Type ResultType;
    143 
    144     /**
    145      *  Compute the squared Euclidean distance between two vectors.
    146      *
    147      *	This is highly optimised, with loop unrolling, as it is one
    148      *	of the most expensive inner loops.
    149      *
    150      *	The computation of squared root at the end is omitted for
    151      *	efficiency.
    152      */
    153     template <typename Iterator1, typename Iterator2>
    154     ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
    155     {
    156         ResultType result = ResultType();
    157         ResultType diff0, diff1, diff2, diff3;
    158         Iterator1 last = a + size;
    159         Iterator1 lastgroup = last - 3;
    160 
    161         /* Process 4 items with each loop for efficiency. */
    162         while (a < lastgroup) {
    163             diff0 = (ResultType)(a[0] - b[0]);
    164             diff1 = (ResultType)(a[1] - b[1]);
    165             diff2 = (ResultType)(a[2] - b[2]);
    166             diff3 = (ResultType)(a[3] - b[3]);
    167             result += diff0 * diff0 + diff1 * diff1 + diff2 * diff2 + diff3 * diff3;
    168             a += 4;
    169             b += 4;
    170 
    171             if ((worst_dist>0)&&(result>worst_dist)) {
    172                 return result;
    173             }
    174         }
    175         /* Process last 0-3 pixels.  Not needed for standard vector lengths. */
    176         while (a < last) {
    177             diff0 = (ResultType)(*a++ - *b++);
    178             result += diff0 * diff0;
    179         }
    180         return result;
    181     }
    182 
    183     /**
    184      *	Partial euclidean distance, using just one dimension. This is used by the
    185      *	kd-tree when computing partial distances while traversing the tree.
    186      *
    187      *	Squared root is omitted for efficiency.
    188      */
    189     template <typename U, typename V>
    190     inline ResultType accum_dist(const U& a, const V& b, int) const
    191     {
    192         return (a-b)*(a-b);
    193     }
    194 };
    195 
    196 
    197 /*
    198  * Manhattan distance functor, optimized version
    199  */
    200 template<class T>
    201 struct L1
    202 {
    203     typedef True is_kdtree_distance;
    204     typedef True is_vector_space_distance;
    205 
    206     typedef T ElementType;
    207     typedef typename Accumulator<T>::Type ResultType;
    208 
    209     /**
    210      *  Compute the Manhattan (L_1) distance between two vectors.
    211      *
    212      *	This is highly optimised, with loop unrolling, as it is one
    213      *	of the most expensive inner loops.
    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 diff0, diff1, diff2, diff3;
    220         Iterator1 last = a + size;
    221         Iterator1 lastgroup = last - 3;
    222 
    223         /* Process 4 items with each loop for efficiency. */
    224         while (a < lastgroup) {
    225             diff0 = (ResultType)abs(a[0] - b[0]);
    226             diff1 = (ResultType)abs(a[1] - b[1]);
    227             diff2 = (ResultType)abs(a[2] - b[2]);
    228             diff3 = (ResultType)abs(a[3] - b[3]);
    229             result += diff0 + diff1 + diff2 + diff3;
    230             a += 4;
    231             b += 4;
    232 
    233             if ((worst_dist>0)&&(result>worst_dist)) {
    234                 return result;
    235             }
    236         }
    237         /* Process last 0-3 pixels.  Not needed for standard vector lengths. */
    238         while (a < last) {
    239             diff0 = (ResultType)abs(*a++ - *b++);
    240             result += diff0;
    241         }
    242         return result;
    243     }
    244 
    245     /**
    246      * Partial distance, used by the kd-tree.
    247      */
    248     template <typename U, typename V>
    249     inline ResultType accum_dist(const U& a, const V& b, int) const
    250     {
    251         return abs(a-b);
    252     }
    253 };
    254 
    255 
    256 
    257 template<class T>
    258 struct MinkowskiDistance
    259 {
    260     typedef True is_kdtree_distance;
    261     typedef True is_vector_space_distance;
    262 
    263     typedef T ElementType;
    264     typedef typename Accumulator<T>::Type ResultType;
    265 
    266     int order;
    267 
    268     MinkowskiDistance(int order_) : order(order_) {}
    269 
    270     /**
    271      *  Compute the Minkowsky (L_p) distance between two vectors.
    272      *
    273      *	This is highly optimised, with loop unrolling, as it is one
    274      *	of the most expensive inner loops.
    275      *
    276      *	The computation of squared root at the end is omitted for
    277      *	efficiency.
    278      */
    279     template <typename Iterator1, typename Iterator2>
    280     ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
    281     {
    282         ResultType result = ResultType();
    283         ResultType diff0, diff1, diff2, diff3;
    284         Iterator1 last = a + size;
    285         Iterator1 lastgroup = last - 3;
    286 
    287         /* Process 4 items with each loop for efficiency. */
    288         while (a < lastgroup) {
    289             diff0 = (ResultType)abs(a[0] - b[0]);
    290             diff1 = (ResultType)abs(a[1] - b[1]);
    291             diff2 = (ResultType)abs(a[2] - b[2]);
    292             diff3 = (ResultType)abs(a[3] - b[3]);
    293             result += pow(diff0,order) + pow(diff1,order) + pow(diff2,order) + pow(diff3,order);
    294             a += 4;
    295             b += 4;
    296 
    297             if ((worst_dist>0)&&(result>worst_dist)) {
    298                 return result;
    299             }
    300         }
    301         /* Process last 0-3 pixels.  Not needed for standard vector lengths. */
    302         while (a < last) {
    303             diff0 = (ResultType)abs(*a++ - *b++);
    304             result += pow(diff0,order);
    305         }
    306         return result;
    307     }
    308 
    309     /**
    310      * Partial distance, used by the kd-tree.
    311      */
    312     template <typename U, typename V>
    313     inline ResultType accum_dist(const U& a, const V& b, int) const
    314     {
    315         return pow(static_cast<ResultType>(abs(a-b)),order);
    316     }
    317 };
    318 
    319 
    320 
    321 template<class T>
    322 struct MaxDistance
    323 {
    324     typedef False is_kdtree_distance;
    325     typedef True is_vector_space_distance;
    326 
    327     typedef T ElementType;
    328     typedef typename Accumulator<T>::Type ResultType;
    329 
    330     /**
    331      *  Compute the max distance (L_infinity) between two vectors.
    332      *
    333      *  This distance is not a valid kdtree distance, it's not dimensionwise additive.
    334      */
    335     template <typename Iterator1, typename Iterator2>
    336     ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
    337     {
    338         ResultType result = ResultType();
    339         ResultType diff0, diff1, diff2, diff3;
    340         Iterator1 last = a + size;
    341         Iterator1 lastgroup = last - 3;
    342 
    343         /* Process 4 items with each loop for efficiency. */
    344         while (a < lastgroup) {
    345             diff0 = abs(a[0] - b[0]);
    346             diff1 = abs(a[1] - b[1]);
    347             diff2 = abs(a[2] - b[2]);
    348             diff3 = abs(a[3] - b[3]);
    349             if (diff0>result) {result = diff0; }
    350             if (diff1>result) {result = diff1; }
    351             if (diff2>result) {result = diff2; }
    352             if (diff3>result) {result = diff3; }
    353             a += 4;
    354             b += 4;
    355 
    356             if ((worst_dist>0)&&(result>worst_dist)) {
    357                 return result;
    358             }
    359         }
    360         /* Process last 0-3 pixels.  Not needed for standard vector lengths. */
    361         while (a < last) {
    362             diff0 = abs(*a++ - *b++);
    363             result = (diff0>result) ? diff0 : result;
    364         }
    365         return result;
    366     }
    367 
    368     /* This distance functor is not dimension-wise additive, which
    369      * makes it an invalid kd-tree distance, not implementing the accum_dist method */
    370 
    371 };
    372 
    373 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    374 
    375 /**
    376  * Hamming distance functor - counts the bit differences between two strings - useful for the Brief descriptor
    377  * bit count of A exclusive XOR'ed with B
    378  */
    379 struct HammingLUT
    380 {
    381     typedef False is_kdtree_distance;
    382     typedef False is_vector_space_distance;
    383 
    384     typedef unsigned char ElementType;
    385     typedef int ResultType;
    386 
    387     /** this will count the bits in a ^ b
    388      */
    389     ResultType operator()(const unsigned char* a, const unsigned char* b, size_t size) const
    390     {
    391         static const uchar popCountTable[] =
    392         {
    393             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,
    394             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,
    395             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,
    396             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,
    397             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,
    398             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,
    399             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,
    400             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
    401         };
    402         ResultType result = 0;
    403         for (size_t i = 0; i < size; i++) {
    404             result += popCountTable[a[i] ^ b[i]];
    405         }
    406         return result;
    407     }
    408 };
    409 
    410 /**
    411  * Hamming distance functor (pop count between two binary vectors, i.e. xor them and count the number of bits set)
    412  * That code was taken from brief.cpp in OpenCV
    413  */
    414 template<class T>
    415 struct Hamming
    416 {
    417     typedef False is_kdtree_distance;
    418     typedef False is_vector_space_distance;
    419 
    420 
    421     typedef T ElementType;
    422     typedef int ResultType;
    423 
    424     template<typename Iterator1, typename Iterator2>
    425     ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType /*worst_dist*/ = -1) const
    426     {
    427         ResultType result = 0;
    428 #ifdef __ARM_NEON__
    429         {
    430             uint32x4_t bits = vmovq_n_u32(0);
    431             for (size_t i = 0; i < size; i += 16) {
    432                 uint8x16_t A_vec = vld1q_u8 (a + i);
    433                 uint8x16_t B_vec = vld1q_u8 (b + i);
    434                 uint8x16_t AxorB = veorq_u8 (A_vec, B_vec);
    435                 uint8x16_t bitsSet = vcntq_u8 (AxorB);
    436                 uint16x8_t bitSet8 = vpaddlq_u8 (bitsSet);
    437                 uint32x4_t bitSet4 = vpaddlq_u16 (bitSet8);
    438                 bits = vaddq_u32(bits, bitSet4);
    439             }
    440             uint64x2_t bitSet2 = vpaddlq_u32 (bits);
    441             result = vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),0);
    442             result += vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),2);
    443         }
    444 #elif __GNUC__
    445         {
    446             //for portability just use unsigned long -- and use the __builtin_popcountll (see docs for __builtin_popcountll)
    447             typedef unsigned long long pop_t;
    448             const size_t modulo = size % sizeof(pop_t);
    449             const pop_t* a2 = reinterpret_cast<const pop_t*> (a);
    450             const pop_t* b2 = reinterpret_cast<const pop_t*> (b);
    451             const pop_t* a2_end = a2 + (size / sizeof(pop_t));
    452 
    453             for (; a2 != a2_end; ++a2, ++b2) result += __builtin_popcountll((*a2) ^ (*b2));
    454 
    455             if (modulo) {
    456                 //in the case where size is not dividable by sizeof(size_t)
    457                 //need to mask off the bits at the end
    458                 pop_t a_final = 0, b_final = 0;
    459                 memcpy(&a_final, a2, modulo);
    460                 memcpy(&b_final, b2, modulo);
    461                 result += __builtin_popcountll(a_final ^ b_final);
    462             }
    463         }
    464 #else // NO NEON and NOT GNUC
    465         typedef unsigned long long pop_t;
    466         HammingLUT lut;
    467         result = lut(reinterpret_cast<const unsigned char*> (a),
    468                      reinterpret_cast<const unsigned char*> (b), size * sizeof(pop_t));
    469 #endif
    470         return result;
    471     }
    472 };
    473 
    474 template<typename T>
    475 struct Hamming2
    476 {
    477     typedef False is_kdtree_distance;
    478     typedef False is_vector_space_distance;
    479 
    480     typedef T ElementType;
    481     typedef int ResultType;
    482 
    483     /** This is popcount_3() from:
    484      * http://en.wikipedia.org/wiki/Hamming_weight */
    485     unsigned int popcnt32(uint32_t n) const
    486     {
    487         n -= ((n >> 1) & 0x55555555);
    488         n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
    489         return (((n + (n >> 4))& 0xF0F0F0F)* 0x1010101) >> 24;
    490     }
    491 
    492 #ifdef FLANN_PLATFORM_64_BIT
    493     unsigned int popcnt64(uint64_t n) const
    494     {
    495         n -= ((n >> 1) & 0x5555555555555555);
    496         n = (n & 0x3333333333333333) + ((n >> 2) & 0x3333333333333333);
    497         return (((n + (n >> 4))& 0x0f0f0f0f0f0f0f0f)* 0x0101010101010101) >> 56;
    498     }
    499 #endif
    500 
    501     template <typename Iterator1, typename Iterator2>
    502     ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType /*worst_dist*/ = -1) const
    503     {
    504 #ifdef FLANN_PLATFORM_64_BIT
    505         const uint64_t* pa = reinterpret_cast<const uint64_t*>(a);
    506         const uint64_t* pb = reinterpret_cast<const uint64_t*>(b);
    507         ResultType result = 0;
    508         size /= (sizeof(uint64_t)/sizeof(unsigned char));
    509         for(size_t i = 0; i < size; ++i ) {
    510             result += popcnt64(*pa ^ *pb);
    511             ++pa;
    512             ++pb;
    513         }
    514 #else
    515         const uint32_t* pa = reinterpret_cast<const uint32_t*>(a);
    516         const uint32_t* pb = reinterpret_cast<const uint32_t*>(b);
    517         ResultType result = 0;
    518         size /= (sizeof(uint32_t)/sizeof(unsigned char));
    519         for(size_t i = 0; i < size; ++i ) {
    520             result += popcnt32(*pa ^ *pb);
    521             ++pa;
    522             ++pb;
    523         }
    524 #endif
    525         return result;
    526     }
    527 };
    528 
    529 
    530 
    531 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    532 
    533 template<class T>
    534 struct HistIntersectionDistance
    535 {
    536     typedef True is_kdtree_distance;
    537     typedef True is_vector_space_distance;
    538 
    539     typedef T ElementType;
    540     typedef typename Accumulator<T>::Type ResultType;
    541 
    542     /**
    543      *  Compute the histogram intersection distance
    544      */
    545     template <typename Iterator1, typename Iterator2>
    546     ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
    547     {
    548         ResultType result = ResultType();
    549         ResultType min0, min1, min2, min3;
    550         Iterator1 last = a + size;
    551         Iterator1 lastgroup = last - 3;
    552 
    553         /* Process 4 items with each loop for efficiency. */
    554         while (a < lastgroup) {
    555             min0 = (ResultType)(a[0] < b[0] ? a[0] : b[0]);
    556             min1 = (ResultType)(a[1] < b[1] ? a[1] : b[1]);
    557             min2 = (ResultType)(a[2] < b[2] ? a[2] : b[2]);
    558             min3 = (ResultType)(a[3] < b[3] ? a[3] : b[3]);
    559             result += min0 + min1 + min2 + min3;
    560             a += 4;
    561             b += 4;
    562             if ((worst_dist>0)&&(result>worst_dist)) {
    563                 return result;
    564             }
    565         }
    566         /* Process last 0-3 pixels.  Not needed for standard vector lengths. */
    567         while (a < last) {
    568             min0 = (ResultType)(*a < *b ? *a : *b);
    569             result += min0;
    570             ++a;
    571             ++b;
    572         }
    573         return result;
    574     }
    575 
    576     /**
    577      * Partial distance, used by the kd-tree.
    578      */
    579     template <typename U, typename V>
    580     inline ResultType accum_dist(const U& a, const V& b, int) const
    581     {
    582         return a<b ? a : b;
    583     }
    584 };
    585 
    586 
    587 
    588 template<class T>
    589 struct HellingerDistance
    590 {
    591     typedef True is_kdtree_distance;
    592     typedef True is_vector_space_distance;
    593 
    594     typedef T ElementType;
    595     typedef typename Accumulator<T>::Type ResultType;
    596 
    597     /**
    598      *  Compute the Hellinger distance
    599      */
    600     template <typename Iterator1, typename Iterator2>
    601     ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType /*worst_dist*/ = -1) const
    602     {
    603         ResultType result = ResultType();
    604         ResultType diff0, diff1, diff2, diff3;
    605         Iterator1 last = a + size;
    606         Iterator1 lastgroup = last - 3;
    607 
    608         /* Process 4 items with each loop for efficiency. */
    609         while (a < lastgroup) {
    610             diff0 = sqrt(static_cast<ResultType>(a[0])) - sqrt(static_cast<ResultType>(b[0]));
    611             diff1 = sqrt(static_cast<ResultType>(a[1])) - sqrt(static_cast<ResultType>(b[1]));
    612             diff2 = sqrt(static_cast<ResultType>(a[2])) - sqrt(static_cast<ResultType>(b[2]));
    613             diff3 = sqrt(static_cast<ResultType>(a[3])) - sqrt(static_cast<ResultType>(b[3]));
    614             result += diff0 * diff0 + diff1 * diff1 + diff2 * diff2 + diff3 * diff3;
    615             a += 4;
    616             b += 4;
    617         }
    618         while (a < last) {
    619             diff0 = sqrt(static_cast<ResultType>(*a++)) - sqrt(static_cast<ResultType>(*b++));
    620             result += diff0 * diff0;
    621         }
    622         return result;
    623     }
    624 
    625     /**
    626      * Partial distance, used by the kd-tree.
    627      */
    628     template <typename U, typename V>
    629     inline ResultType accum_dist(const U& a, const V& b, int) const
    630     {
    631         ResultType diff = sqrt(static_cast<ResultType>(a)) - sqrt(static_cast<ResultType>(b));
    632         return diff * diff;
    633     }
    634 };
    635 
    636 
    637 template<class T>
    638 struct ChiSquareDistance
    639 {
    640     typedef True is_kdtree_distance;
    641     typedef True is_vector_space_distance;
    642 
    643     typedef T ElementType;
    644     typedef typename Accumulator<T>::Type ResultType;
    645 
    646     /**
    647      *  Compute the chi-square distance
    648      */
    649     template <typename Iterator1, typename Iterator2>
    650     ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
    651     {
    652         ResultType result = ResultType();
    653         ResultType sum, diff;
    654         Iterator1 last = a + size;
    655 
    656         while (a < last) {
    657             sum = (ResultType)(*a + *b);
    658             if (sum>0) {
    659                 diff = (ResultType)(*a - *b);
    660                 result += diff*diff/sum;
    661             }
    662             ++a;
    663             ++b;
    664 
    665             if ((worst_dist>0)&&(result>worst_dist)) {
    666                 return result;
    667             }
    668         }
    669         return result;
    670     }
    671 
    672     /**
    673      * Partial distance, used by the kd-tree.
    674      */
    675     template <typename U, typename V>
    676     inline ResultType accum_dist(const U& a, const V& b, int) const
    677     {
    678         ResultType result = ResultType();
    679         ResultType sum, diff;
    680 
    681         sum = (ResultType)(a+b);
    682         if (sum>0) {
    683             diff = (ResultType)(a-b);
    684             result = diff*diff/sum;
    685         }
    686         return result;
    687     }
    688 };
    689 
    690 
    691 template<class T>
    692 struct KL_Divergence
    693 {
    694     typedef True is_kdtree_distance;
    695     typedef True is_vector_space_distance;
    696 
    697     typedef T ElementType;
    698     typedef typename Accumulator<T>::Type ResultType;
    699 
    700     /**
    701      *  Compute the KullbackLeibler divergence
    702      */
    703     template <typename Iterator1, typename Iterator2>
    704     ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const
    705     {
    706         ResultType result = ResultType();
    707         Iterator1 last = a + size;
    708 
    709         while (a < last) {
    710             if (* b != 0) {
    711                 ResultType ratio = (ResultType)(*a / *b);
    712                 if (ratio>0) {
    713                     result += *a * log(ratio);
    714                 }
    715             }
    716             ++a;
    717             ++b;
    718 
    719             if ((worst_dist>0)&&(result>worst_dist)) {
    720                 return result;
    721             }
    722         }
    723         return result;
    724     }
    725 
    726     /**
    727      * Partial distance, used by the kd-tree.
    728      */
    729     template <typename U, typename V>
    730     inline ResultType accum_dist(const U& a, const V& b, int) const
    731     {
    732         ResultType result = ResultType();
    733         if( *b != 0 ) {
    734             ResultType ratio = (ResultType)(a / b);
    735             if (ratio>0) {
    736                 result = a * log(ratio);
    737             }
    738         }
    739         return result;
    740     }
    741 };
    742 
    743 
    744 
    745 /*
    746  * This is a "zero iterator". It basically behaves like a zero filled
    747  * array to all algorithms that use arrays as iterators (STL style).
    748  * It's useful when there's a need to compute the distance between feature
    749  * and origin it and allows for better compiler optimisation than using a
    750  * zero-filled array.
    751  */
    752 template <typename T>
    753 struct ZeroIterator
    754 {
    755 
    756     T operator*()
    757     {
    758         return 0;
    759     }
    760 
    761     T operator[](int)
    762     {
    763         return 0;
    764     }
    765 
    766     const ZeroIterator<T>& operator ++()
    767     {
    768         return *this;
    769     }
    770 
    771     ZeroIterator<T> operator ++(int)
    772     {
    773         return *this;
    774     }
    775 
    776     ZeroIterator<T>& operator+=(int)
    777     {
    778         return *this;
    779     }
    780 
    781 };
    782 
    783 
    784 /*
    785  * Depending on processed distances, some of them are already squared (e.g. L2)
    786  * and some are not (e.g.Hamming). In KMeans++ for instance we want to be sure
    787  * we are working on ^2 distances, thus following templates to ensure that.
    788  */
    789 template <typename Distance, typename ElementType>
    790 struct squareDistance
    791 {
    792     typedef typename Distance::ResultType ResultType;
    793     ResultType operator()( ResultType dist ) { return dist*dist; }
    794 };
    795 
    796 
    797 template <typename ElementType>
    798 struct squareDistance<L2_Simple<ElementType>, ElementType>
    799 {
    800     typedef typename L2_Simple<ElementType>::ResultType ResultType;
    801     ResultType operator()( ResultType dist ) { return dist; }
    802 };
    803 
    804 template <typename ElementType>
    805 struct squareDistance<L2<ElementType>, ElementType>
    806 {
    807     typedef typename L2<ElementType>::ResultType ResultType;
    808     ResultType operator()( ResultType dist ) { return dist; }
    809 };
    810 
    811 
    812 template <typename ElementType>
    813 struct squareDistance<MinkowskiDistance<ElementType>, ElementType>
    814 {
    815     typedef typename MinkowskiDistance<ElementType>::ResultType ResultType;
    816     ResultType operator()( ResultType dist ) { return dist; }
    817 };
    818 
    819 template <typename ElementType>
    820 struct squareDistance<HellingerDistance<ElementType>, ElementType>
    821 {
    822     typedef typename HellingerDistance<ElementType>::ResultType ResultType;
    823     ResultType operator()( ResultType dist ) { return dist; }
    824 };
    825 
    826 template <typename ElementType>
    827 struct squareDistance<ChiSquareDistance<ElementType>, ElementType>
    828 {
    829     typedef typename ChiSquareDistance<ElementType>::ResultType ResultType;
    830     ResultType operator()( ResultType dist ) { return dist; }
    831 };
    832 
    833 
    834 template <typename Distance>
    835 typename Distance::ResultType ensureSquareDistance( typename Distance::ResultType dist )
    836 {
    837     typedef typename Distance::ElementType ElementType;
    838 
    839     squareDistance<Distance, ElementType> dummy;
    840     return dummy( dist );
    841 }
    842 
    843 
    844 /*
    845  * ...and a template to ensure the user that he will process the normal distance,
    846  * and not squared distance, without loosing processing time calling sqrt(ensureSquareDistance)
    847  * that will result in doing actually sqrt(dist*dist) for L1 distance for instance.
    848  */
    849 template <typename Distance, typename ElementType>
    850 struct simpleDistance
    851 {
    852     typedef typename Distance::ResultType ResultType;
    853     ResultType operator()( ResultType dist ) { return dist; }
    854 };
    855 
    856 
    857 template <typename ElementType>
    858 struct simpleDistance<L2_Simple<ElementType>, ElementType>
    859 {
    860     typedef typename L2_Simple<ElementType>::ResultType ResultType;
    861     ResultType operator()( ResultType dist ) { return sqrt(dist); }
    862 };
    863 
    864 template <typename ElementType>
    865 struct simpleDistance<L2<ElementType>, ElementType>
    866 {
    867     typedef typename L2<ElementType>::ResultType ResultType;
    868     ResultType operator()( ResultType dist ) { return sqrt(dist); }
    869 };
    870 
    871 
    872 template <typename ElementType>
    873 struct simpleDistance<MinkowskiDistance<ElementType>, ElementType>
    874 {
    875     typedef typename MinkowskiDistance<ElementType>::ResultType ResultType;
    876     ResultType operator()( ResultType dist ) { return sqrt(dist); }
    877 };
    878 
    879 template <typename ElementType>
    880 struct simpleDistance<HellingerDistance<ElementType>, ElementType>
    881 {
    882     typedef typename HellingerDistance<ElementType>::ResultType ResultType;
    883     ResultType operator()( ResultType dist ) { return sqrt(dist); }
    884 };
    885 
    886 template <typename ElementType>
    887 struct simpleDistance<ChiSquareDistance<ElementType>, ElementType>
    888 {
    889     typedef typename ChiSquareDistance<ElementType>::ResultType ResultType;
    890     ResultType operator()( ResultType dist ) { return sqrt(dist); }
    891 };
    892 
    893 
    894 template <typename Distance>
    895 typename Distance::ResultType ensureSimpleDistance( typename Distance::ResultType dist )
    896 {
    897     typedef typename Distance::ElementType ElementType;
    898 
    899     simpleDistance<Distance, ElementType> dummy;
    900     return dummy( dist );
    901 }
    902 
    903 }
    904 
    905 #endif //OPENCV_FLANN_DIST_H_
    906