00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00025 #ifndef __FERRET_METRIC__
00026 #define __FERRET_METRIC__
00027
00028
00029
00030 #include <functional>
00031
00032 namespace lshkit { namespace metric {
00033
00035 template <typename T >
00036 class l1 : public std::binary_function<T, T, float>
00037 {
00038 unsigned dim_;
00039 public:
00040 l1 (unsigned dim) : dim_(dim) {}
00041 float operator () (const T *first1, const T *first2) const
00042 {
00043 float r = 0.0;
00044 for (unsigned i = 0; i < dim_; ++i)
00045 {
00046 r += std::fabs(first1[i] - first2[i]);
00047 }
00048 return r;
00049 }
00050 };
00051
00053 template <typename T >
00054 class l2 : public std::binary_function<const T*, const T*, float>
00055 {
00056 unsigned dim_;
00057 public:
00058 l2 (unsigned dim) : dim_(dim) {}
00059 float operator () (const T *first1, const T *first2) const
00060 {
00061 float r = 0.0;
00062 for (unsigned i = 0; i < dim_; ++i)
00063 {
00064 r += sqr(first1[i] - first2[i]);
00065 }
00066 return std::sqrt(r);
00067 }
00068 };
00069
00071
00075 template <typename T >
00076 class l2sqr : public std::binary_function<const T*, const T*, float>
00077 {
00078 unsigned dim_;
00079 public:
00080 l2sqr (unsigned dim) : dim_(dim) {}
00081 float operator () (const T *first1, const T *first2) const
00082 {
00083 float r = 0.0;
00084 for (unsigned i = 0; i < dim_; ++i)
00085 {
00086 r += sqr(first1[i] - first2[i]);
00087 }
00088 return r;
00089 }
00090 };
00091
00093 template <typename T >
00094 class max : public std::binary_function<const T*, const T*, float>
00095 {
00096 unsigned dim_;
00097 public:
00098 max (unsigned dim) : dim_(dim) {}
00099 float operator () (const T *first1, const T *first2) const
00100 {
00101 double r = std::numeric_limits<T>::min();
00102 for (unsigned i = 0; i < dim_; ++i)
00103 {
00104 r += max(r, std::fabs(first1[i] - first2[i]));
00105 }
00106 return (float)std::sqrt(r);
00107 }
00108 };
00109
00111
00114 struct basic_hamming
00115 {
00116 static unsigned char_bit_cnt[];
00117
00118 template <typename B>
00119 unsigned __hamming (B a, B b)
00120 {
00121 B c = a ^ b;
00122 unsigned char *p = reinterpret_cast<unsigned char *>(&c);
00123 unsigned r = 0;
00124 for (unsigned i = 0; i < sizeof(B); i++)
00125 {
00126 r += char_bit_cnt[*p++];
00127 }
00128 return r;
00129 }
00130
00131 unsigned __hamming (unsigned char c1, unsigned char c2) const
00132 {
00133 return char_bit_cnt[c1 ^ c2];
00134 }
00135
00136 };
00137
00139
00145 template <typename T>
00146 struct hamming : public std::binary_function<const T*, const T*, float>, public basic_hamming
00147 {
00148 unsigned dim_;
00149 public:
00150
00151 hamming(unsigned dim): dim_(dim) {}
00152 float operator () (const T *first1, const T *first2) const
00153 {
00154 unsigned r = 0;
00155 for (unsigned i = 0; i < dim_; ++i)
00156 {
00157 r += __hamming(first1[i], first2[i]);
00158 }
00159 return r;
00160 }
00161 };
00162
00163
00164 }}
00165
00166 #endif
00167
00168