My Project
distance.h
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
 All Classes Files Functions Variables Typedefs