IKMLinearCombination.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /**
  2. * @file IKMLinearCombination.cpp
  3. * @brief Combination of several (implicit) kernel matrices, such as noise matrix and gp-hik kernel matrix (Implementation)
  4. * @author Erik Rodner, Alexander Freytag
  5. * @date 02/14/2012
  6. */
  7. #include <iostream>
  8. #include "IKMLinearCombination.h"
  9. using namespace NICE;
  10. using namespace std;
  11. IKMLinearCombination::IKMLinearCombination()
  12. {
  13. verbose = false;
  14. }
  15. IKMLinearCombination::~IKMLinearCombination()
  16. {
  17. if (matrices.size() != 0)
  18. {
  19. for (int i = 0; i < matrices.size(); i++)
  20. delete matrices[i];
  21. }
  22. }
  23. void IKMLinearCombination::getDiagonalElements ( Vector & diagonalElements ) const
  24. {
  25. diagonalElements.resize ( rows() );
  26. diagonalElements.set(0.0);
  27. for ( vector<ImplicitKernelMatrix *>::const_iterator i = matrices.begin(); i != matrices.end(); i++ )
  28. {
  29. ImplicitKernelMatrix *ikm = *i;
  30. Vector diagonalElementsSingle;
  31. ikm->getDiagonalElements ( diagonalElementsSingle );
  32. diagonalElements += diagonalElementsSingle;
  33. }
  34. }
  35. void IKMLinearCombination::getFirstDiagonalElement ( double & diagonalElement ) const
  36. {
  37. diagonalElement = 0.0;
  38. for ( vector<ImplicitKernelMatrix *>::const_iterator i = matrices.begin(); i != matrices.end(); i++ )
  39. {
  40. ImplicitKernelMatrix *ikm = *i;
  41. double firstElem;
  42. ikm->getFirstDiagonalElement(firstElem);
  43. diagonalElement += firstElem;
  44. }
  45. }
  46. uint IKMLinearCombination::getNumParameters() const
  47. {
  48. return parameterRanges[ parameterRanges.size() - 1 ] + matrices[ parameterRanges.size() - 1 ]->getNumParameters();
  49. }
  50. void IKMLinearCombination::getParameters(Vector & parameters) const
  51. {
  52. uint ind = 0;
  53. parameters.resize ( getNumParameters() );
  54. if (verbose)
  55. cerr << "Number of total parameters: " << parameters.size() << endl;
  56. for ( vector<ImplicitKernelMatrix *>::const_iterator i = matrices.begin(); i != matrices.end(); i++, ind++ )
  57. {
  58. ImplicitKernelMatrix *ikm = *i;
  59. if (verbose)
  60. cerr << "Model " << ind << " has " << ikm->getNumParameters() << " parameters" << endl;
  61. if ( ikm->getNumParameters() == 0 ) continue;
  62. Vector singleParameterRef = parameters.getRangeRef( parameterRanges[ ind ], parameterRanges[ ind ] + ikm->getNumParameters() - 1 );
  63. ikm->getParameters ( singleParameterRef );
  64. }
  65. }
  66. void IKMLinearCombination::setParameters(const Vector & parameters)
  67. {
  68. uint ind = 0;
  69. for ( vector<ImplicitKernelMatrix *>::const_iterator i = matrices.begin(); i != matrices.end(); i++, ind++ )
  70. {
  71. ImplicitKernelMatrix *ikm = *i;
  72. if ( ikm->getNumParameters() == 0 ) continue;
  73. ikm->setParameters ( parameters.getRange( parameterRanges[ ind ], parameterRanges[ ind ] + ikm->getNumParameters() - 1) );
  74. }
  75. }
  76. void IKMLinearCombination::setVerbose(const bool& _verbose)
  77. {
  78. verbose = _verbose;
  79. }
  80. bool IKMLinearCombination::outOfBounds(const Vector & parameters) const
  81. {
  82. uint ind = 0;
  83. for ( vector<ImplicitKernelMatrix *>::const_iterator i = matrices.begin(); i != matrices.end(); i++, ind++ )
  84. {
  85. ImplicitKernelMatrix *ikm = *i;
  86. if ( ikm->getNumParameters() == 0 ) continue;
  87. if ( ikm->outOfBounds( parameters.getRange( parameterRanges[ ind ], parameterRanges[ ind ] + ikm->getNumParameters() - 1) ) )
  88. return true;
  89. }
  90. return false;
  91. }
  92. Vector IKMLinearCombination::getParameterLowerBounds() const
  93. {
  94. Vector lB;
  95. for ( vector<ImplicitKernelMatrix *>::const_iterator i = matrices.begin(); i != matrices.end(); i++ )
  96. {
  97. ImplicitKernelMatrix *ikm = *i;
  98. if ( ikm->getNumParameters() == 0 ) continue;
  99. lB.append( ikm->getParameterLowerBounds() );
  100. }
  101. return lB;
  102. }
  103. Vector IKMLinearCombination::getParameterUpperBounds() const
  104. {
  105. Vector uB;
  106. for ( vector<ImplicitKernelMatrix *>::const_iterator i = matrices.begin(); i != matrices.end(); i++ )
  107. {
  108. ImplicitKernelMatrix *ikm = *i;
  109. if ( ikm->getNumParameters() == 0 ) continue;
  110. uB.append( ikm->getParameterUpperBounds() );
  111. }
  112. return uB;
  113. }
  114. void IKMLinearCombination::updateParameterRanges()
  115. {
  116. if ( matrices.size() == 0 ) {
  117. parameterRanges.clear();
  118. } else {
  119. parameterRanges.resize(matrices.size());
  120. parameterRanges[0] = 0;
  121. if ( matrices.size() == 1 ) return;
  122. uint ind = 1;
  123. vector<ImplicitKernelMatrix *>::const_iterator i = matrices.begin();
  124. for ( ; ind < parameterRanges.size(); i++, ind++ )
  125. {
  126. ImplicitKernelMatrix *ikm = *i;
  127. if (verbose)
  128. cerr << "Parameter range: size is " << parameterRanges.size() << ", index is " << ind << endl;
  129. parameterRanges[ind] = parameterRanges[ind-1] + ikm->getNumParameters();
  130. if (verbose)
  131. cerr << "Value is " << parameterRanges[ind] << endl;
  132. }
  133. }
  134. }
  135. void IKMLinearCombination::addModel ( ImplicitKernelMatrix *ikm )
  136. {
  137. matrices.push_back ( ikm );
  138. updateParameterRanges();
  139. }
  140. void IKMLinearCombination::multiply (NICE::Vector & y, const NICE::Vector & x) const
  141. {
  142. y.resize( rows() );
  143. y.set(0.0);
  144. for ( vector<ImplicitKernelMatrix *>::const_iterator i = matrices.begin(); i != matrices.end(); i++ )
  145. {
  146. ImplicitKernelMatrix *ikm = *i;
  147. Vector ySingle;
  148. ikm->multiply ( ySingle, x );
  149. y += ySingle;
  150. }
  151. }
  152. uint IKMLinearCombination::rows () const
  153. {
  154. return cols();
  155. }
  156. uint IKMLinearCombination::cols () const
  157. {
  158. if ( matrices.empty() )
  159. fthrow(Exception, "No models stored, cols() and rows() are unavailable");
  160. return (* matrices.begin())->cols();
  161. }
  162. double IKMLinearCombination::approxFrobNorm() const
  163. {
  164. double frobNormApprox(0.0);
  165. if (verbose)
  166. std::cerr << "IKMLinCom: single approx: " ;
  167. for ( vector<ImplicitKernelMatrix *>::const_iterator i = matrices.begin(); i != matrices.end(); i++ )
  168. {
  169. ImplicitKernelMatrix *ikm = *i;
  170. frobNormApprox += ikm->approxFrobNorm();
  171. if (verbose)
  172. std::cerr << ikm->approxFrobNorm() << " ";
  173. }
  174. if (verbose)
  175. std::cerr << std::endl;
  176. return frobNormApprox;
  177. }
  178. void IKMLinearCombination::setApproximationScheme(const int & _approxScheme)
  179. {
  180. for ( std::vector<ImplicitKernelMatrix *>::const_iterator i = matrices.begin(); i != matrices.end(); i++ )
  181. {
  182. ImplicitKernelMatrix *ikm = *i;
  183. ikm->setApproximationScheme(_approxScheme);
  184. }
  185. }
  186. ImplicitKernelMatrix * IKMLinearCombination::getModel(const uint & idx) const
  187. {
  188. if ( idx <= matrices.size() )
  189. return matrices[idx];
  190. else
  191. return NULL;
  192. }