CholeskyRobust.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /**
  2. * @file CholeskyRobust.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 "CholeskyRobust.h"
  9. #include "core/vector/Algorithms.h"
  10. #ifdef NICE_USELIB_CUDACHOLESKY
  11. #include "cholesky-gpu/niceinterface/CudaCholeskyNICE.h"
  12. #endif
  13. using namespace std;
  14. using namespace NICE;
  15. using namespace NICE;
  16. CholeskyRobust::CholeskyRobust (const CholeskyRobust & src):m_verbose (src.m_verbose), m_noise (src.m_noise),
  17. m_useCuda (src.m_useCuda), m_logDetMatrix (src.m_logDetMatrix)
  18. {
  19. }
  20. double
  21. CholeskyRobust::robustChol (const Matrix & A, Matrix & cholA)
  22. {
  23. // this additional memory requirement could be skipped
  24. // with a modified cholesky routine
  25. Matrix ARegularized (A);
  26. if (m_verbose)
  27. cerr << "CholeskyRobust::robustChol: Adding noise " << m_noise << endl;
  28. // add a constant value to the diagonal
  29. ARegularized.addIdentity (m_noise);
  30. // check whether the cholesky-gpu sub-library is installed
  31. #ifdef NICE_USELIB_CUDACHOLESKY
  32. if (m_useCuda)
  33. try {
  34. CudaCholeskyNICE::choleskyDecomp (ARegularized, cholA);
  35. } catch (CudaError & e)
  36. {
  37. fthrow (CudaError, e.what ());
  38. }
  39. else
  40. #endif
  41. // use the cholesky decomposition available in core/vector/
  42. // we use the large scale version here, because we expect that if you use
  43. // CholeskyRobust, you do not have input matrices with a few elements
  44. choleskyDecompLargeScale (ARegularized, cholA);
  45. // compute the logarithm of the log determinant by
  46. // summing up logarithms of all diagonal elements
  47. // multiplication by 2 is necessary, because ARegularized = cholA'*cholA
  48. m_logDetMatrix = 2 * triangleMatrixLogDet (cholA);
  49. if (m_verbose)
  50. cerr << "CholeskyRobust::robustChol: Cholesky condition (logdet): " << m_logDetMatrix << endl;
  51. // if the log determinant is NaN or Inf, then we should warn!
  52. if (!finite (m_logDetMatrix))
  53. {
  54. fthrow (Exception,
  55. "The matrix has infinite or not defined log determinant !");
  56. }
  57. return m_noise;
  58. }
  59. double
  60. CholeskyRobust::robustCholInv (const Matrix & A, Matrix & invA)
  61. {
  62. Matrix G;
  63. double noise = robustChol (A, G);
  64. if (m_verbose)
  65. cerr << "CholeskyRobust::robustChol: Cholesky inversion" << endl;
  66. choleskyInvertLargeScale (G, invA);
  67. return noise;
  68. }
  69. CholeskyRobust::~CholeskyRobust ()
  70. {
  71. }
  72. CholeskyRobust::CholeskyRobust (bool verbose, double noise, bool useCuda):
  73. m_verbose (verbose), m_noise(noise), m_useCuda (useCuda)
  74. {
  75. m_logDetMatrix = - std::numeric_limits<double>::max();
  76. }
  77. CholeskyRobust *
  78. CholeskyRobust::clone (void) const
  79. {
  80. CholeskyRobust *dst = new CholeskyRobust (*this);
  81. return dst;
  82. }