github.com/kaydxh/golang@v0.0.131/pkg/gocv/cgo/third_path/opencv4/include/opencv2/flann/dist.h (about)

     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  inline int abs<int>(int x) { return ::abs(x); }
    64  
    65  template<>
    66  inline float abs<float>(float x) { return fabsf(x); }
    67  
    68  template<>
    69  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  inline unsigned int round<unsigned int>(float x) { return static_cast<unsigned int>(x + 0.5f); }
    77  
    78  template<>
    79  inline unsigned short round<unsigned short>(float x) { return static_cast<unsigned short>(x + 0.5f); }
    80  
    81  template<>
    82  inline unsigned char round<unsigned char>(float x) { return static_cast<unsigned char>(x + 0.5f); }
    83  
    84  template<>
    85  inline long long round<long long>(float x) { return static_cast<long long>(x + 0.5f); }
    86  
    87  template<>
    88  inline long round<long>(float x) { return static_cast<long>(x + 0.5f); }
    89  
    90  template<>
    91  inline int round<int>(float x) { return static_cast<int>(x + 0.5f) - (x<0); }
    92  
    93  template<>
    94  inline short round<short>(float x) { return static_cast<short>(x + 0.5f) - (x<0); }
    95  
    96  template<>
    97  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  inline unsigned int round<unsigned int>(double x) { return static_cast<unsigned int>(x + 0.5); }
   105  
   106  template<>
   107  inline unsigned short round<unsigned short>(double x) { return static_cast<unsigned short>(x + 0.5); }
   108  
   109  template<>
   110  inline unsigned char round<unsigned char>(double x) { return static_cast<unsigned char>(x + 0.5); }
   111  
   112  template<>
   113  inline long long round<long long>(double x) { return static_cast<long long>(x + 0.5); }
   114  
   115  template<>
   116  inline long round<long>(double x) { return static_cast<long>(x + 0.5); }
   117  
   118  template<>
   119  inline int round<int>(double x) { return static_cast<int>(x + 0.5) - (x<0); }
   120  
   121  template<>
   122  inline short round<short>(double x) { return static_cast<short>(x + 0.5) - (x<0); }
   123  
   124  template<>
   125  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 Minkowsky (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      {
   523          (void)b;
   524          static const uchar popCountTable[] =
   525          {
   526              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              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              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              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              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              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              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              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          };
   535          ResultType result = 0;
   536          for (size_t i = 0; i < size; i++) {
   537              result += popCountTable[a[i]];
   538          }
   539          return result;
   540      }
   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      {
   787          (void)b;
   788          static const uchar popCountTable[] =
   789          {
   790              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              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              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              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              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              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              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              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          };
   799          ResultType result = 0;
   800          for (size_t i = 0; i < size; i++) {
   801              result += popCountTable[a[i]];
   802          }
   803          return result;
   804      }
   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_