| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #ifndef FLANN_DIST_H_ |
| | #define FLANN_DIST_H_ |
| |
|
| | #include <cmath> |
| | #include <cstdlib> |
| | #include <string.h> |
| | #ifdef _MSC_VER |
| | typedef unsigned __int32 uint32_t; |
| | typedef unsigned __int64 uint64_t; |
| | #else |
| | #include <stdint.h> |
| | #endif |
| |
|
| | #include "FLANN/defines.h" |
| |
|
| |
|
| | namespace flann |
| | { |
| |
|
| | template<typename T> |
| | struct Accumulator { typedef T Type; }; |
| | template<> |
| | struct Accumulator<unsigned char> { typedef float Type; }; |
| | template<> |
| | struct Accumulator<unsigned short> { typedef float Type; }; |
| | template<> |
| | struct Accumulator<unsigned int> { typedef float Type; }; |
| | template<> |
| | struct Accumulator<char> { typedef float Type; }; |
| | template<> |
| | struct Accumulator<short> { typedef float Type; }; |
| | template<> |
| | struct Accumulator<int> { typedef float Type; }; |
| |
|
| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | template<class T> |
| | struct L2_Simple |
| | { |
| | typedef bool is_kdtree_distance; |
| |
|
| | typedef T ElementType; |
| | typedef typename Accumulator<T>::Type ResultType; |
| |
|
| | template <typename Iterator1, typename Iterator2> |
| | ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType = -1) const |
| | { |
| | ResultType result = ResultType(); |
| | ResultType diff; |
| | for(size_t i = 0; i < size; ++i ) { |
| | diff = *a++ - *b++; |
| | result += diff*diff; |
| | } |
| | return result; |
| | } |
| |
|
| | template <typename U, typename V> |
| | inline ResultType accum_dist(const U& a, const V& b, int) const |
| | { |
| | return (a-b)*(a-b); |
| | } |
| | }; |
| |
|
| | template<class T> |
| | struct L2_3D |
| | { |
| | typedef bool is_kdtree_distance; |
| |
|
| | typedef T ElementType; |
| | typedef typename Accumulator<T>::Type ResultType; |
| |
|
| | template <typename Iterator1, typename Iterator2> |
| | ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType = -1) const |
| | { |
| | ResultType result = ResultType(); |
| | ResultType diff; |
| | diff = *a++ - *b++; |
| | result += diff*diff; |
| | diff = *a++ - *b++; |
| | result += diff*diff; |
| | diff = *a++ - *b++; |
| | result += diff*diff; |
| | return result; |
| | } |
| |
|
| | template <typename U, typename V> |
| | inline ResultType accum_dist(const U& a, const V& b, int) const |
| | { |
| | return (a-b)*(a-b); |
| | } |
| | }; |
| |
|
| | |
| | |
| | |
| | template<class T> |
| | struct L2 |
| | { |
| | typedef bool is_kdtree_distance; |
| |
|
| | typedef T ElementType; |
| | typedef typename Accumulator<T>::Type ResultType; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <typename Iterator1, typename Iterator2> |
| | ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const |
| | { |
| | ResultType result = ResultType(); |
| | ResultType diff0, diff1, diff2, diff3; |
| | Iterator1 last = a + size; |
| | Iterator1 lastgroup = last - 3; |
| |
|
| | |
| | while (a < lastgroup) { |
| | diff0 = (ResultType)(a[0] - b[0]); |
| | diff1 = (ResultType)(a[1] - b[1]); |
| | diff2 = (ResultType)(a[2] - b[2]); |
| | diff3 = (ResultType)(a[3] - b[3]); |
| | result += diff0 * diff0 + diff1 * diff1 + diff2 * diff2 + diff3 * diff3; |
| | a += 4; |
| | b += 4; |
| |
|
| | if ((worst_dist>0)&&(result>worst_dist)) { |
| | return result; |
| | } |
| | } |
| | |
| | while (a < last) { |
| | diff0 = (ResultType)(*a++ - *b++); |
| | result += diff0 * diff0; |
| | } |
| | return result; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | template <typename U, typename V> |
| | inline ResultType accum_dist(const U& a, const V& b, int) const |
| | { |
| | return (a-b)*(a-b); |
| | } |
| | }; |
| |
|
| |
|
| | |
| | |
| | |
| | template<class T> |
| | struct L1 |
| | { |
| | typedef bool is_kdtree_distance; |
| |
|
| | typedef T ElementType; |
| | typedef typename Accumulator<T>::Type ResultType; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | template <typename Iterator1, typename Iterator2> |
| | ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const |
| | { |
| | ResultType result = ResultType(); |
| | ResultType diff0, diff1, diff2, diff3; |
| | Iterator1 last = a + size; |
| | Iterator1 lastgroup = last - 3; |
| |
|
| | |
| | while (a < lastgroup) { |
| | diff0 = (ResultType)std::abs(a[0] - b[0]); |
| | diff1 = (ResultType)std::abs(a[1] - b[1]); |
| | diff2 = (ResultType)std::abs(a[2] - b[2]); |
| | diff3 = (ResultType)std::abs(a[3] - b[3]); |
| | result += diff0 + diff1 + diff2 + diff3; |
| | a += 4; |
| | b += 4; |
| |
|
| | if ((worst_dist>0)&&(result>worst_dist)) { |
| | return result; |
| | } |
| | } |
| | |
| | while (a < last) { |
| | diff0 = (ResultType)std::abs(*a++ - *b++); |
| | result += diff0; |
| | } |
| | return result; |
| | } |
| |
|
| | |
| | |
| | |
| | template <typename U, typename V> |
| | inline ResultType accum_dist(const U& a, const V& b, int) const |
| | { |
| | return std::abs(a-b); |
| | } |
| | }; |
| |
|
| |
|
| |
|
| | template<class T> |
| | struct MinkowskiDistance |
| | { |
| | typedef bool is_kdtree_distance; |
| |
|
| | typedef T ElementType; |
| | typedef typename Accumulator<T>::Type ResultType; |
| |
|
| | int order; |
| |
|
| | MinkowskiDistance(int order_) : order(order_) {} |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <typename Iterator1, typename Iterator2> |
| | ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const |
| | { |
| | ResultType result = ResultType(); |
| | ResultType diff0, diff1, diff2, diff3; |
| | Iterator1 last = a + size; |
| | Iterator1 lastgroup = last - 3; |
| |
|
| | |
| | while (a < lastgroup) { |
| | diff0 = (ResultType)std::abs(a[0] - b[0]); |
| | diff1 = (ResultType)std::abs(a[1] - b[1]); |
| | diff2 = (ResultType)std::abs(a[2] - b[2]); |
| | diff3 = (ResultType)std::abs(a[3] - b[3]); |
| | result += pow(diff0,order) + pow(diff1,order) + pow(diff2,order) + pow(diff3,order); |
| | a += 4; |
| | b += 4; |
| |
|
| | if ((worst_dist>0)&&(result>worst_dist)) { |
| | return result; |
| | } |
| | } |
| | |
| | while (a < last) { |
| | diff0 = (ResultType)std::abs(*a++ - *b++); |
| | result += pow(diff0,order); |
| | } |
| | return result; |
| | } |
| |
|
| | |
| | |
| | |
| | template <typename U, typename V> |
| | inline ResultType accum_dist(const U& a, const V& b, int) const |
| | { |
| | return pow(static_cast<ResultType>(std::abs(a-b)),order); |
| | } |
| | }; |
| |
|
| |
|
| |
|
| | template<class T> |
| | struct MaxDistance |
| | { |
| | typedef bool is_vector_space_distance; |
| |
|
| | typedef T ElementType; |
| | typedef typename Accumulator<T>::Type ResultType; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | template <typename Iterator1, typename Iterator2> |
| | ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const |
| | { |
| | ResultType result = ResultType(); |
| | ResultType diff0, diff1, diff2, diff3; |
| | Iterator1 last = a + size; |
| | Iterator1 lastgroup = last - 3; |
| |
|
| | |
| | while (a < lastgroup) { |
| | diff0 = std::abs(a[0] - b[0]); |
| | diff1 = std::abs(a[1] - b[1]); |
| | diff2 = std::abs(a[2] - b[2]); |
| | diff3 = std::abs(a[3] - b[3]); |
| | if (diff0>result) {result = diff0; } |
| | if (diff1>result) {result = diff1; } |
| | if (diff2>result) {result = diff2; } |
| | if (diff3>result) {result = diff3; } |
| | a += 4; |
| | b += 4; |
| |
|
| | if ((worst_dist>0)&&(result>worst_dist)) { |
| | return result; |
| | } |
| | } |
| | |
| | while (a < last) { |
| | diff0 = std::abs(*a++ - *b++); |
| | result = (diff0>result) ? diff0 : result; |
| | } |
| | return result; |
| | } |
| |
|
| | |
| | |
| |
|
| | }; |
| |
|
| | |
| |
|
| | |
| | |
| | |
| | |
| | struct HammingLUT |
| | { |
| | typedef unsigned char ElementType; |
| | typedef int ResultType; |
| |
|
| | |
| | |
| | ResultType operator()(const unsigned char* a, const unsigned char* b, int size) const |
| | { |
| | ResultType result = 0; |
| | for (int i = 0; i < size; i++) { |
| | result += byteBitsLookUp(a[i] ^ b[i]); |
| | } |
| | return result; |
| | } |
| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | static unsigned char byteBitsLookUp(unsigned char b) |
| | { |
| | static const unsigned char table[256] = { |
| | 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, |
| | 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, |
| | 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, |
| | 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, |
| | 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, |
| | 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, |
| | 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, |
| | 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 |
| | }; |
| | return table[b]; |
| | } |
| | }; |
| |
|
| | |
| | |
| | |
| | |
| | template<class T> |
| | struct HammingPopcnt |
| | { |
| | typedef T ElementType; |
| | typedef int ResultType; |
| |
|
| | template<typename Iterator1, typename Iterator2> |
| | ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType = -1) const |
| | { |
| | ResultType result = 0; |
| | #if __GNUC__ |
| | #if ANDROID && HAVE_NEON |
| | static uint64_t features = android_getCpuFeatures(); |
| | if ((features& ANDROID_CPU_ARM_FEATURE_NEON)) { |
| | for (size_t i = 0; i < size; i += 16) { |
| | uint8x16_t A_vec = vld1q_u8 (a + i); |
| | uint8x16_t B_vec = vld1q_u8 (b + i); |
| | |
| | uint8x16_t AxorB = veorq_u8 (A_vec, B_vec); |
| |
|
| | uint8x16_t bitsSet += vcntq_u8 (AxorB); |
| | |
| | uint16x8_t bitSet8 = vpaddlq_u8 (bitsSet); |
| | uint32x4_t bitSet4 = vpaddlq_u16 (bitSet8); |
| |
|
| | uint64x2_t bitSet2 = vpaddlq_u32 (bitSet4); |
| | result += vgetq_lane_u64 (bitSet2,0); |
| | result += vgetq_lane_u64 (bitSet2,1); |
| | } |
| | } |
| | else |
| | #endif |
| | |
| | typedef unsigned long long pop_t; |
| | const size_t modulo = size % sizeof(pop_t); |
| | const pop_t* a2 = reinterpret_cast<const pop_t*> (a); |
| | const pop_t* b2 = reinterpret_cast<const pop_t*> (b); |
| | const pop_t* a2_end = a2 + (size / sizeof(pop_t)); |
| |
|
| | for (; a2 != a2_end; ++a2, ++b2) result += __builtin_popcountll((*a2) ^ (*b2)); |
| |
|
| | if (modulo) { |
| | |
| | |
| | pop_t a_final = 0, b_final = 0; |
| | memcpy(&a_final, a2, modulo); |
| | memcpy(&b_final, b2, modulo); |
| | result += __builtin_popcountll(a_final ^ b_final); |
| | } |
| | #else |
| | HammingLUT lut; |
| | result = lut(reinterpret_cast<const unsigned char*> (a), |
| | reinterpret_cast<const unsigned char*> (b), size * sizeof(pop_t)); |
| | #endif |
| | return result; |
| | } |
| | }; |
| |
|
| | template<typename T> |
| | struct Hamming |
| | { |
| | typedef T ElementType; |
| | typedef unsigned int ResultType; |
| |
|
| | |
| | |
| | unsigned int popcnt32(uint32_t n) const |
| | { |
| | n -= ((n >> 1) & 0x55555555); |
| | n = (n & 0x33333333) + ((n >> 2) & 0x33333333); |
| | return (((n + (n >> 4))& 0xF0F0F0F)* 0x1010101) >> 24; |
| | } |
| |
|
| | unsigned int popcnt64(uint64_t n) const |
| | { |
| | n -= ((n >> 1) & 0x5555555555555555LL); |
| | n = (n & 0x3333333333333333LL) + ((n >> 2) & 0x3333333333333333LL); |
| | return (((n + (n >> 4))& 0x0f0f0f0f0f0f0f0fLL)* 0x0101010101010101LL) >> 56; |
| | } |
| |
|
| | template <typename Iterator1, typename Iterator2> |
| | ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType = 0) const |
| | { |
| | #ifdef FLANN_PLATFORM_64_BIT |
| | const uint64_t* pa = reinterpret_cast<const uint64_t*>(a); |
| | const uint64_t* pb = reinterpret_cast<const uint64_t*>(b); |
| | ResultType result = 0; |
| | size /= (sizeof(uint64_t)/sizeof(unsigned char)); |
| | for(size_t i = 0; i < size; ++i ) { |
| | result += popcnt64(*pa ^ *pb); |
| | ++pa; |
| | ++pb; |
| | } |
| | #else |
| | const uint32_t* pa = reinterpret_cast<const uint32_t*>(a); |
| | const uint32_t* pb = reinterpret_cast<const uint32_t*>(b); |
| | ResultType result = 0; |
| | size /= (sizeof(uint32_t)/sizeof(unsigned char)); |
| | for(size_t i = 0; i < size; ++i ) { |
| | result += popcnt32(*pa ^ *pb); |
| | ++pa; |
| | ++pb; |
| | } |
| | #endif |
| | return result; |
| | } |
| | }; |
| |
|
| |
|
| |
|
| | |
| |
|
| | template<class T> |
| | struct HistIntersectionDistance |
| | { |
| | typedef bool is_kdtree_distance; |
| |
|
| | typedef T ElementType; |
| | typedef typename Accumulator<T>::Type ResultType; |
| |
|
| | |
| | |
| | |
| | template <typename Iterator1, typename Iterator2> |
| | ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const |
| | { |
| | ResultType result = ResultType(); |
| | ResultType min0, min1, min2, min3; |
| | Iterator1 last = a + size; |
| | Iterator1 lastgroup = last - 3; |
| |
|
| | |
| | while (a < lastgroup) { |
| | min0 = (ResultType)(a[0] < b[0] ? a[0] : b[0]); |
| | min1 = (ResultType)(a[1] < b[1] ? a[1] : b[1]); |
| | min2 = (ResultType)(a[2] < b[2] ? a[2] : b[2]); |
| | min3 = (ResultType)(a[3] < b[3] ? a[3] : b[3]); |
| | result += min0 + min1 + min2 + min3; |
| | a += 4; |
| | b += 4; |
| | if ((worst_dist>0)&&(result>worst_dist)) { |
| | return result; |
| | } |
| | } |
| | |
| | while (a < last) { |
| | min0 = (ResultType)(*a < *b ? *a : *b); |
| | result += min0; |
| | ++a; |
| | ++b; |
| | } |
| | return result; |
| | } |
| |
|
| | |
| | |
| | |
| | template <typename U, typename V> |
| | inline ResultType accum_dist(const U& a, const V& b, int) const |
| | { |
| | return a<b ? a : b; |
| | } |
| | }; |
| |
|
| |
|
| |
|
| | template<class T> |
| | struct HellingerDistance |
| | { |
| | typedef bool is_kdtree_distance; |
| |
|
| | typedef T ElementType; |
| | typedef typename Accumulator<T>::Type ResultType; |
| |
|
| | |
| | |
| | |
| | template <typename Iterator1, typename Iterator2> |
| | ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType = -1) const |
| | { |
| | ResultType result = ResultType(); |
| | ResultType diff0, diff1, diff2, diff3; |
| | Iterator1 last = a + size; |
| | Iterator1 lastgroup = last - 3; |
| |
|
| | |
| | while (a < lastgroup) { |
| | diff0 = sqrt(static_cast<ResultType>(a[0])) - sqrt(static_cast<ResultType>(b[0])); |
| | diff1 = sqrt(static_cast<ResultType>(a[1])) - sqrt(static_cast<ResultType>(b[1])); |
| | diff2 = sqrt(static_cast<ResultType>(a[2])) - sqrt(static_cast<ResultType>(b[2])); |
| | diff3 = sqrt(static_cast<ResultType>(a[3])) - sqrt(static_cast<ResultType>(b[3])); |
| | result += diff0 * diff0 + diff1 * diff1 + diff2 * diff2 + diff3 * diff3; |
| | a += 4; |
| | b += 4; |
| | } |
| | while (a < last) { |
| | diff0 = sqrt(static_cast<ResultType>(*a++)) - sqrt(static_cast<ResultType>(*b++)); |
| | result += diff0 * diff0; |
| | } |
| | return result; |
| | } |
| |
|
| | |
| | |
| | |
| | template <typename U, typename V> |
| | inline ResultType accum_dist(const U& a, const V& b, int) const |
| | { |
| | ResultType dist = sqrt(static_cast<ResultType>(a)) - sqrt(static_cast<ResultType>(b)); |
| | return dist * dist; |
| | } |
| | }; |
| |
|
| |
|
| | template<class T> |
| | struct ChiSquareDistance |
| | { |
| | typedef bool is_kdtree_distance; |
| |
|
| | typedef T ElementType; |
| | typedef typename Accumulator<T>::Type ResultType; |
| |
|
| | |
| | |
| | |
| | template <typename Iterator1, typename Iterator2> |
| | ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const |
| | { |
| | ResultType result = ResultType(); |
| | ResultType sum, diff; |
| | Iterator1 last = a + size; |
| |
|
| | while (a < last) { |
| | sum = (ResultType)(*a + *b); |
| | if (sum>0) { |
| | diff = (ResultType)(*a - *b); |
| | result += diff*diff/sum; |
| | } |
| | ++a; |
| | ++b; |
| |
|
| | if ((worst_dist>0)&&(result>worst_dist)) { |
| | return result; |
| | } |
| | } |
| | return result; |
| | } |
| |
|
| | |
| | |
| | |
| | template <typename U, typename V> |
| | inline ResultType accum_dist(const U& a, const V& b, int) const |
| | { |
| | ResultType result = ResultType(); |
| | ResultType sum, diff; |
| |
|
| | sum = (ResultType)(a+b); |
| | if (sum>0) { |
| | diff = (ResultType)(a-b); |
| | result = diff*diff/sum; |
| | } |
| | return result; |
| | } |
| | }; |
| |
|
| |
|
| | template<class T> |
| | struct KL_Divergence |
| | { |
| | typedef bool is_kdtree_distance; |
| |
|
| | typedef T ElementType; |
| | typedef typename Accumulator<T>::Type ResultType; |
| |
|
| | |
| | |
| | |
| | template <typename Iterator1, typename Iterator2> |
| | ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const |
| | { |
| | ResultType result = ResultType(); |
| | Iterator1 last = a + size; |
| |
|
| | while (a < last) { |
| | if ( *a != 0 && *b != 0 ) { |
| | ResultType ratio = (ResultType)(*a / *b); |
| | if (ratio>0) { |
| | result += *a * log(ratio); |
| | } |
| | } |
| | ++a; |
| | ++b; |
| |
|
| | if ((worst_dist>0)&&(result>worst_dist)) { |
| | return result; |
| | } |
| | } |
| | return result; |
| | } |
| |
|
| | |
| | |
| | |
| | template <typename U, typename V> |
| | inline ResultType accum_dist(const U& a, const V& b, int) const |
| | { |
| | ResultType result = ResultType(); |
| | if( a != 0 && b != 0 ) { |
| | ResultType ratio = (ResultType)(a / b); |
| | if (ratio>0) { |
| | result = a * log(ratio); |
| | } |
| | } |
| | return result; |
| | } |
| | }; |
| |
|
| | } |
| |
|
| | #endif |
| |
|