/** * @file KernelExp.cpp * @brief Interface for the popular exponential mercer kernels * @author Erik Rodner * @date 10/24/2007 */ #include #include #include "KernelExp.h" using namespace OBJREC; using namespace std; using namespace NICE; KernelExp::KernelExp( double loggamma, double logsv, double _noise ) { gammasq = exp(2*loggamma); sv = exp(2*logsv); noise = _noise; } KernelExp::KernelExp ( const KernelExp & src ) { gammasq = src.gammasq; sv = src.sv; noise = src.noise; } KernelExp::~KernelExp() { } double KernelExp::K (const NICE::Vector & x, const NICE::Vector & y) const { if ( x.size() != y.size() ) fthrow(Exception, "Vector dimensions do not match!"); double dist = 0.0; for ( size_t i = 0 ; i < x.size() ; i++ ) { double d = x[i] - y[i]; dist += d*d; } return sv * exp( - dist / gammasq ); } void KernelExp::updateKernelData ( KernelData *kernelData ) const { const NICE::Matrix & quadraticDistances = kernelData->getCachedMatrix ( KernelData::QUADRATIC_DISTANCES ); NICE::Matrix & kernelMatrix = kernelData->getKernelMatrix(); kernelMatrix.resize ( quadraticDistances.rows(), quadraticDistances.cols() ); for ( size_t i = 0 ; i < kernelMatrix.rows(); i++ ) for ( size_t j = 0 ; j < kernelMatrix.cols(); j++ ) { double dist = quadraticDistances(i,j); kernelMatrix(i,j) = sv * exp ( - dist / gammasq ); } kernelMatrix.addIdentity ( noise ); } void KernelExp::calcKernelData ( const VVector & X, KernelData *kernelData ) const { CachedQuadraticDistances::calcKernelData ( X, kernelData ); if ( noise != 0.0 ) { cerr << "KernelExp: adding some noise" << endl; kernelData->getKernelMatrix().addIdentity(noise); } } void KernelExp::setParameters( const NICE::Vector & newParameters ) { gammasq = exp(2*newParameters[0]); sv = exp(2*newParameters[1]); } void KernelExp::getParameters( NICE::Vector & newParameters ) const { newParameters.resize(2); newParameters[0] = 0.5 * log(gammasq); newParameters[1] = 0.5 * log(sv); } void KernelExp::getKernelJacobi ( size_t parameter, const NICE::Vector & parameters, const KernelData *kernelData, NICE::Matrix & jacobiMatrix ) const { // double _gammasq = exp(2*parameters[0]); kernel jacobi is independent of gammasq double _sv = exp(2*parameters[1]); const NICE::Matrix & kernelMatrix = kernelData->getKernelMatrix(); jacobiMatrix.resize ( kernelMatrix.rows(), kernelMatrix.cols() ); if ( parameter == 0 ) { for ( size_t i = 0 ; i < kernelMatrix.rows(); i++ ) for ( size_t j = 0 ; j < kernelMatrix.cols(); j++ ) { double K = kernelMatrix(i,j); if ( almostZero(K) ) jacobiMatrix(i,j) = - 2.0 * K * log(_sv); else jacobiMatrix(i,j) = - K * 2.0 * log (K / _sv); } } else if ( parameter == 1 ) { for ( size_t i = 0 ; i < kernelMatrix.rows(); i++ ) for ( size_t j = 0 ; j < kernelMatrix.cols(); j++ ) { double K = kernelMatrix(i,j); jacobiMatrix(i,j) = 2 * K; } } else{ fthrow(Exception, "Wrong parameter index!"); } } KernelExp *KernelExp::clone(void) const { return new KernelExp(*this); }