CholeskyRobustAuto.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /**
  2. * @file CholeskyRobustAuto.cpp
  3. * @brief robust cholesky decomposition by adding some noise
  4. * @author Erik Rodner
  5. * @date 01/06/2010
  6. */
  7. #include <iostream>
  8. #include "CholeskyRobustAuto.h"
  9. #include "core/vector/Algorithms.h"
  10. #undef NICE_USELIB_CUDACHOLESKY
  11. #ifdef NICE_USELIB_CUDACHOLESKY
  12. #include "cholesky-gpu/niceinterface/CudaCholeskyNICE.h"
  13. #endif
  14. using namespace std;
  15. using namespace NICE;
  16. using namespace OBJREC;
  17. const int maxiterations = 30;
  18. const bool exponential_noise = true;
  19. CholeskyRobustAuto::CholeskyRobustAuto ( const CholeskyRobustAuto & src )
  20. : CholeskyRobust ( src )
  21. {
  22. }
  23. double CholeskyRobustAuto::robustChol ( const Matrix & A, Matrix & cholA )
  24. {
  25. // this additional memory requirement could be skipped
  26. // with a modified cholesky routine
  27. Matrix ARegularized (A);
  28. if ( m_verbose )
  29. cerr << "CholeskyRobustAuto::robustChol: A " << A.rows() << " x " << A.cols() << endl;
  30. int i = 0;
  31. double noise = 0.0;
  32. double noiseStepExp = m_noiseStep;
  33. bool robust = true;
  34. do {
  35. robust = true;
  36. if ( m_verbose )
  37. cerr << "CholeskyRobustAuto::robustChol: Cholesky decomposition" << endl;
  38. try {
  39. //choleskyDecomp ( ARegularized, cholA );
  40. #ifdef NICE_USELIB_CUDACHOLESKY
  41. if ( m_useCuda )
  42. CudaCholeskyNICE::choleskyDecomp ( ARegularized, cholA );
  43. else
  44. #endif
  45. choleskyDecompLargeScale ( ARegularized, cholA );
  46. #ifdef NICE_USELIB_CUDACHOLESKY
  47. } catch ( CudaError & e ) {
  48. fthrow(CudaError, e.what() );
  49. #endif
  50. } catch ( Exception ) {
  51. if ( m_verbose )
  52. cerr << "CholeskyRobustAuto::robustChol: failed!" << endl;
  53. robust = false;
  54. }
  55. if ( robust && cholA.containsNaN() )
  56. {
  57. if ( m_verbose )
  58. cerr << "CholeskyRobustAuto::robustChol: cholesky matrix contains NaN values" << endl;
  59. robust = false;
  60. }
  61. m_logDetMatrix = m_minMatrixLogDeterminant;
  62. if ( robust )
  63. {
  64. m_logDetMatrix = 2*triangleMatrixLogDet ( cholA );
  65. if ( m_verbose )
  66. cerr << "CholeskyRobustAuto::robustChol: Cholesky condition: " << m_logDetMatrix << endl;
  67. }
  68. if ( isnan(m_logDetMatrix) || (m_logDetMatrix < m_minMatrixLogDeterminant) ) {
  69. robust = false;
  70. }
  71. if ( !robust ) {
  72. robust = false;
  73. if ( m_verbose )
  74. cerr << "CholeskyRobustAuto::robustChol: Adding noise " << noiseStepExp << endl;
  75. ARegularized.addIdentity ( noiseStepExp );
  76. noise += noiseStepExp;
  77. if ( exponential_noise )
  78. noiseStepExp *= 10.0;
  79. }
  80. i++;
  81. } while ( !robust && (i < maxiterations) );
  82. if ( !robust )
  83. fthrow( Exception, "Inverse matrix is instable (please adjust the noise step term)" );
  84. return noise;
  85. }
  86. CholeskyRobustAuto::~CholeskyRobustAuto ()
  87. {
  88. }
  89. CholeskyRobustAuto::CholeskyRobustAuto ( bool verbose, double noiseStep, double minMatrixLogDeterminant, bool useCuda ) :
  90. CholeskyRobust ( verbose, noiseStep, minMatrixLogDeterminant, useCuda )
  91. {
  92. }
  93. CholeskyRobustAuto *CholeskyRobustAuto::clone(void) const
  94. {
  95. return new CholeskyRobustAuto ( *this );
  96. }