00001 #define PSEUDOZERO 0.0000001
00002
00003 #include <iostream>
00004
00005 template<class Numeric>
00006 double HistogramDistance<Numeric>::distance(const std::vector< std::vector<Numeric> >& first, const std::vector< std::vector<Numeric> >& last) const{
00007 if (first.size() != last.size()) return 10e16;
00008 double accumulator = 0.;
00009 for (unsigned int i = 0; i < first.size(); i++){
00010 accumulator += distance(first[i], last[i]);
00011 }
00012 return accumulator;
00013 }
00014
00016 template<class Numeric>
00017 double EuclideanDistance<Numeric>::distance(const std::vector< std::vector<Numeric> >& first, const std::vector< std::vector<Numeric> >& last) const{
00018 if (first.size() != last.size()) return 10e16;
00019 double accumulator = 0.;
00020 for (unsigned int i = 0; i < first.size(); i++){
00021 accumulator += distance(first[i], last[i]) * distance(first[i], last[i]);
00022 }
00023 return sqrt(accumulator);
00024 }
00025
00026 template<class Numeric>
00027 double EuclideanDistance<Numeric>::distance(const std::vector<Numeric>& first, const std::vector<Numeric>& last) const{
00028 if (first.size() != last.size()) return 10e16;
00029 double accumulator = 0.;
00030 for (unsigned int i = 0; i < first.size(); i++){
00031 accumulator += (first[i] - last[i])*(first[i] - last[i]);
00032 }
00033 return sqrt(accumulator * 0.5);
00034 }
00035
00037 template<class Numeric>
00038 double Chi2Distance<Numeric>::distance(const std::vector<Numeric>& first, const std::vector<Numeric>& last) const{
00039 if (first.size() != last.size()) return 10e16;
00040 double accumulator = 0.;
00041 for (unsigned int i = 0; i < first.size(); i++){
00042 double p = last[i] == 0 ? PSEUDOZERO : last[i];
00043 double q = first[i] == 0 ? PSEUDOZERO : first[i];
00044 accumulator += (q - p)*(q - p)/q;
00045 }
00046 return accumulator;
00047 }
00048
00050 template<class Numeric>
00051 double SymmetricChi2Distance<Numeric>::distance(const std::vector<Numeric>& first, const std::vector<Numeric>& last) const{
00052 if (first.size() != last.size()) return 10e16;
00053 double accumulator = 0.;
00054 for (unsigned int i = 0; i < first.size(); i++){
00055 double p = last[i] == 0 ? PSEUDOZERO : last[i];
00056 double q = first[i] == 0 ? PSEUDOZERO : first[i];
00057 accumulator += (q - p)*(q - p)/(q + p);
00058 }
00059 return 0.5 * accumulator;
00060 }
00061
00063 template<class Numeric>
00064 double BatthacharyyaDistance<Numeric>::distance(const std::vector< std::vector<Numeric> >& first, const std::vector< std::vector<Numeric> >& last) const{
00065 if (first.size() != last.size()) return 10e16;
00066 double accumulator = 0.;
00067 for (unsigned int i = 0; i < first.size(); i++){
00068 double current = distance(first[i], last[i]);
00069 accumulator += 1. - current * current;
00070 }
00071 return sqrt(1. - accumulator);
00072 }
00073
00074 template<class Numeric>
00075 double BatthacharyyaDistance<Numeric>::distance(const std::vector<Numeric>& first, const std::vector<Numeric>& last) const{
00076 if (first.size() != last.size()) return 10e16;
00077 double accumulator = 0.;
00078 for (unsigned int i = 0; i < first.size(); i++){
00079 double p = last[i];
00080 double q = first[i];
00081 accumulator += sqrt(q * p);
00082 }
00083 return sqrt(1. - accumulator);
00084 }
00085
00087 template<class Numeric>
00088 double KullbackLeiblerDistance<Numeric>::distance(const std::vector<Numeric>& first, const std::vector<Numeric>& last) const{
00089 if (first.size() != last.size()) return 10e16;
00090 double accumulator = 0.;
00091 for (unsigned int i = 0; i < first.size(); i++){
00092 double p = last[i] <= 0 ? PSEUDOZERO : last[i];;
00093 double q = first[i] <= 0 ? PSEUDOZERO : first[i];
00094 accumulator += p * log (p/q);
00095 }
00096 return accumulator;
00097 }
00098
00100 template<class Numeric>
00101 double JensenShannonDistance<Numeric>::distance(const std::vector<Numeric>& first, const std::vector<Numeric>& last) const{
00102 if (first.size() != last.size()) return 10e16;
00103 double accumulator = 0.;
00104 for (unsigned int i = 0; i < first.size(); i++){
00105 double p = last[i] <= 0 ? PSEUDOZERO : last[i];
00106 double q = first[i] <= 0 ? PSEUDOZERO : first[i];
00107 accumulator += p * log (2*p/(p + q)) + q * log (2*q/(p + q));
00108 }
00109 return 0.5 * accumulator / log(2);
00110 }