/** * @file GeneralizedIntersectionKernelFunction.cpp * @brief The generalized intersection kernel function as distance measure between two histograms interpreted as vectors (Implementation) * @author Alexander Freytag * @date 08-12-2011 (dd-mm-yyyy) */ #include #include "GeneralizedIntersectionKernelFunction.h" #include using namespace NICE; template GeneralizedIntersectionKernelFunction::GeneralizedIntersectionKernelFunction() { exponent = 1.0; } template GeneralizedIntersectionKernelFunction::GeneralizedIntersectionKernelFunction(const double & _exponent) { exponent = _exponent; } template GeneralizedIntersectionKernelFunction::~GeneralizedIntersectionKernelFunction() { } template void GeneralizedIntersectionKernelFunction::set_exponent(const double & _exponent) { exponent = _exponent; } template double GeneralizedIntersectionKernelFunction::get_exponent() { return exponent; } template double GeneralizedIntersectionKernelFunction::measureDistance ( const std::vector & a, const std::vector & b ) { int size( (int) a.size()); if ((int) b.size() < size) size = (int) b.size(); double distance(0.0); for (int i = 0; i < size; i++) { if ( a[i] < b[i]) distance += pow((double) a[i],exponent); else distance += pow((double) b[i],exponent); } return distance; } template NICE::Matrix GeneralizedIntersectionKernelFunction::computeKernelMatrix ( const std::vector > & X ) { NICE::Matrix K; K.resize((int) X.size(), (int) X.size()); for (int i = 0; i < (int) X.size(); i++) { for (int j = i; j < (int) X.size(); j++) { //Kernel matrix has to be symmetric K(i,j) = measureDistance(X[i],X[j]); K(j,i) = measureDistance(X[i],X[j]); } } return K; } template NICE::Matrix GeneralizedIntersectionKernelFunction::computeKernelMatrix ( const std::vector > & X , const double & noise) { NICE::Matrix K(computeKernelMatrix(X)); for (int i = 0; i < (int) X.size(); i++) K(i,i) += noise; return K; } template NICE::Matrix GeneralizedIntersectionKernelFunction::computeKernelMatrix ( const NICE::FeatureMatrixT & X , const double & noise) { NICE::Matrix K; K.resize(X.get_n(), X.get_n()); //run over every dimension and add the corresponding min-values to the entries in the kernel matrix for (int dim = 0; dim < X.get_d(); dim++) { const std::multimap< double, typename SortedVectorSparse::dataelement> & nonzeroElements = X.getFeatureValues(dim).nonzeroElements(); //compute the min-values (similarities) between every pair in this dimension, zero elements do not influence this SortedVectorSparse::const_elementpointer it1 = nonzeroElements.begin(); for (; it1 != nonzeroElements.end(); it1++) { int i(it1->second.first); SortedVectorSparse::const_elementpointer it2 = it1; for (; it2 != nonzeroElements.end(); it2++) { int j(it2->second.first); double val(pow(std::min(it1->second.second, it2->second.second),exponent)); K(i,j) += val; //kernel-matrix has to be symmetric, but avoid adding twice the value to the main-diagonal if ( i != j) K(j,i) += val; } // for-j-loop } // for-i-loop }//dim-loop //add noise on the main diagonal for (int i = 0; i < (int) X.get_n(); i++) K(i,i) += noise; return K; } template std::vector GeneralizedIntersectionKernelFunction::computeKernelVector ( const std::vector > & X , const std::vector & xstar) { std::vector kstar; kstar.resize((int) X.size()); for (int i = 0; i < (int) X.size(); i++) { kstar[i] = measureDistance(X[i], xstar); } return kstar; } template void GeneralizedIntersectionKernelFunction::sayYourName() { std::cerr << "I'm the Generalized Intersection Kernel." << std::endl; }