KernelLinCombNormalized.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /**
  2. * @file KernelLinCombNormalized.cpp
  3. * @brief Interface for the popular exponential mercer kernels
  4. * @author Erik Rodner
  5. * @date 10/24/2007
  6. */
  7. #ifdef NOVISUAL
  8. #include <vislearning/nice_nonvis.h>
  9. #else
  10. #include <vislearning/nice.h>
  11. #endif
  12. #include <iostream>
  13. #include <math.h>
  14. #include "KernelLinCombNormalized.h"
  15. using namespace OBJREC;
  16. using namespace std;
  17. using namespace NICE;
  18. KernelLinCombNormalized::KernelLinCombNormalized( uint num, bool _exponential )
  19. : alpha ( num ), exponential(_exponential)
  20. {
  21. for ( uint i = 0 ; i < num ; i++ )
  22. alpha[i] = - log(num);
  23. }
  24. KernelLinCombNormalized::KernelLinCombNormalized ( const KernelLinCombNormalized & src )
  25. {
  26. alpha.resize ( src.alpha.size() );
  27. alpha = src.alpha;
  28. exponential = src.exponential;
  29. }
  30. KernelLinCombNormalized::~KernelLinCombNormalized()
  31. {
  32. }
  33. KernelLinCombNormalized *KernelLinCombNormalized::clone(void) const
  34. {
  35. return new KernelLinCombNormalized ( *this );
  36. }
  37. double KernelLinCombNormalized::K (const NICE::Vector & x, const NICE::Vector & y) const
  38. {
  39. fthrow(Exception, "Unable to calculate kernel values directly.");
  40. }
  41. void KernelLinCombNormalized::updateKernelData ( KernelData *kernelData ) const
  42. {
  43. NICE::Matrix & kernelMatrix = kernelData->getKernelMatrix();
  44. double norm = 0.0;
  45. for ( uint k = 0 ; k < alpha.size(); k++ )
  46. norm += exp(alpha[k]);
  47. for ( uint k = 0 ; k < alpha.size(); k++ )
  48. {
  49. const NICE::Matrix & cachedMatrix = kernelData->getCachedMatrix ( k );
  50. if ( k == 0 ) {
  51. kernelMatrix.resize ( cachedMatrix.rows(), cachedMatrix.cols() );
  52. kernelMatrix.set(0.0);
  53. }
  54. kernelMatrix += exp(alpha[k])/norm * cachedMatrix;
  55. }
  56. if ( exponential ) {
  57. for ( uint i = 0 ; i < kernelMatrix.rows(); i++ )
  58. for ( uint j = 0 ; j < kernelMatrix.cols(); j++ )
  59. kernelMatrix(i,j) = exp(- kernelMatrix(i,j));
  60. }
  61. }
  62. void KernelLinCombNormalized::getKernelJacobi ( size_t parameter, const NICE::Vector & parameters, const KernelData *kernelData, NICE::Matrix & jacobiMatrix ) const
  63. {
  64. // double _gammasq = exp(2*parameters[0]);
  65. const NICE::Matrix & kernelMatrix = kernelData->getKernelMatrix();
  66. if ( parameter >= alpha.size() )
  67. fthrow(Exception, "Parameter index exceeds parameter vector size" );
  68. jacobiMatrix.resize ( kernelMatrix.rows(), kernelMatrix.cols() );
  69. #if 0
  70. if ( exponential ) {
  71. for ( uint i = 0 ; i < jacobiMatrix.rows(); i++ )
  72. for ( uint j = 0 ; j < jacobiMatrix.cols(); j++ )
  73. jacobiMatrix(i,j) = - kernelMatrixParameter(i,j) * exp(alpha[parameter]) * kernelMatrix(i,j);
  74. } else {
  75. jacobiMatrix = exp(alpha[parameter]) * kernelMatrixParameter;
  76. }
  77. #endif
  78. // derivation of \sum_k exp(alpha_k) / (sum_j exp(alpha_j)) * K_k = \sum_k exp(\alpha_k) / norm * K_k
  79. //
  80. // \sum_k (k==parameter) ...
  81. double norm = 0.0;
  82. for ( uint k = 0 ; k < alpha.size(); k++ )
  83. norm += exp(alpha[k]);
  84. Matrix tmp ( kernelMatrix.rows(), kernelMatrix.cols() );
  85. tmp.set(0.0);
  86. for ( uint k = 0 ; k < alpha.size(); k++ )
  87. {
  88. const Matrix & kernelMatrixSingle = kernelData->getCachedMatrix( k );
  89. for ( uint i = 0 ; i < tmp.rows(); i++ )
  90. for ( uint j = 0 ; j < tmp.cols(); j++ )
  91. if ( k == parameter ) {
  92. tmp(i,j) += (exp(alpha[k])/norm) * ( 1 - exp(alpha[k])/norm ) * kernelMatrixSingle(i,j);
  93. } else {
  94. tmp(i,j) -= (exp(alpha[k])/norm) * (exp(alpha[parameter])/norm) * kernelMatrixSingle(i,j);
  95. }
  96. }
  97. if ( exponential ) {
  98. for ( uint i = 0 ; i < jacobiMatrix.rows(); i++ )
  99. for ( uint j = 0 ; j < jacobiMatrix.cols(); j++ )
  100. jacobiMatrix(i,j) = - tmp(i,j) * kernelMatrix(i,j);
  101. } else {
  102. jacobiMatrix = tmp;
  103. }
  104. }
  105. void KernelLinCombNormalized::setParameters( const NICE::Vector & newParameters )
  106. {
  107. alpha = newParameters;
  108. }
  109. void KernelLinCombNormalized::getParameters( NICE::Vector & newParameters ) const
  110. {
  111. newParameters.resize ( alpha.size() );
  112. newParameters = alpha;
  113. }