My Project
|
00001 #ifndef DIST_H 00002 #define DIST_H 00003 00004 #include "MyTools.h" 00005 #include "MySets.h" 00006 00013 class dist{ 00014 public: 00018 dist(){type = 0;}; 00019 00023 ~dist(){}; 00024 00034 template <typename T> 00035 double operator() (T C1, T C2, int N); 00036 00042 dist* Produce(string s); 00043 00044 int type; 00045 }; 00046 00054 class moves:public dist{ 00055 public: 00059 moves(){type = 1;}; 00060 00069 template <typename T> 00070 double operator() (T C1, T C2) { 00071 return C1.size() + C2.size() - (2 * (Intersection<T>(C1, C2)).size()); 00072 }; 00073 }; 00074 00081 class normalized:public dist{ 00082 public: 00086 normalized(){type = 2;}; 00087 00096 template <typename T> 00097 double operator() (T C1, T C2){ 00098 return (1 - ((double)(Intersection<T>(C1, C2).size()) / (double)(Union<T>(C1, C2).size()))); 00099 } 00100 }; 00101 00108 class entropy:public dist{ 00109 public: 00113 entropy(){type = 3;}; 00114 00124 template <typename T> 00125 double operator() (T C1, T C2, int N){ 00126 //double Px = (double)(C1.size()) / (double)N; 00127 //double Py = (double)(C2.size()) / (double)N; 00128 00129 T Int = Intersection(C1, C2); 00130 double a = N - (C1.size() + C2.size() - Int.size()); 00131 double b = C2.size() - Int.size(); 00132 double c = C1.size() - Int.size(); 00133 double d = Int.size(); 00134 00135 double H1 = h(a, N) + h(d, N); 00136 double H2 = h(b, N) + h(c, N); 00137 if (H1 >= H2) 00138 return (H1 + H2 - h(b+d, N) - h(a+c, N)); 00139 else 00140 return (h(c+d, N) + h(a+b, N)); 00141 } 00142 00149 double h(double a, double n){ 00150 if (a == 0) 00151 return 0; 00152 return -a*log2(a/n); 00153 }; 00154 int N; 00155 }; 00156 00163 /*class L2:public dist{ 00164 public: 00165 00166 **Constructor 00167 L2(){type = 4;}; 00168 ** 00169 * Compute the similarity 00170 * 00171 * @param C1 First cluster to compare 00172 * @param C2 Second cluster to compare 00173 * 00174 * @return L2 distance 00175 00176 template <typename T> 00177 double operator() (T C1, T C2){ 00178 typename T::iterator it_t, it_t2; 00179 00180 double sum = 0; 00181 00182 for (it_t = C1.begin(), it_t2 = C2.begin(); it_t != C1.end() && it_t2 != C2.end(); it_t++, it_t2++){ 00183 sum += (*it_t2 - *it_t) * (*it_t2 - *it_t); 00184 } 00185 00186 return sqrt(sum); 00187 } 00188 };*/ 00189 00229 dist* dist::Produce(string s){ 00230 if ((strcmp(s.c_str(), "moves")) == 0){ 00231 return new moves(); 00232 } else if ((strcmp(s.c_str(), "norm")) == 0) { 00233 return new normalized(); 00234 } else if ((strcmp(s.c_str(), "entropy")) == 0) { 00235 return new entropy(); 00236 } /*else if ((strcmp(s.c_str(), "kl")) == 0) { 00237 return new KL(); 00238 } */else { 00239 cerr << "Invalid distance measure chosen" << endl; 00240 exit(4); 00241 } 00242 }; 00243 00244 00254 template <typename T> 00255 double dist::operator() (T C1, T C2, int N){ 00256 switch (this->type){ 00257 case 1: 00258 return (*((moves*)(this)))(C1, C2); 00259 break; 00260 case 2: 00261 return (*((normalized*)(this)))(C1, C2); 00262 break; 00263 case 3: 00264 return (*((entropy*)(this)))(C1, C2, N); 00265 break; 00266 /*case 5: 00267 return (*((KL*)(this)))(C1, C2); 00268 break;*/ 00269 default: 00270 cerr << "Invalid Distance Specified" << endl; 00271 exit(5); 00272 00273 } 00274 } 00275 00276 00277 #endif