testCholeskySpeed.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /**
  2. * @file testCholeskySpeed.cpp
  3. * @brief test LinAl cholesky decomposition
  4. * @author Erik Rodner
  5. * @date 01/06/2010
  6. */
  7. #include "core/basics/numerictools.h"
  8. #include "core/vector/Algorithms.h"
  9. #include "core/basics/Timer.h"
  10. extern "C" {
  11. IppStatus ippmCholeskyDecomp_m_64f(const Ipp64f* pSrc, int srcStride1, int
  12. srcStride2, Ipp64f* pDst, int dstStride1, int dstStride2, int widthHeight);
  13. }
  14. using namespace std;
  15. using namespace NICE;
  16. double getInvError ( const Matrix & A, const Matrix & Ainv )
  17. {
  18. Matrix idapprox = Ainv*A;
  19. idapprox.addIdentity(-1.0);
  20. double error = idapprox.frobeniusNorm();
  21. cerr << "error = " << error << endl;
  22. return error;
  23. }
  24. /**
  25. test LinAl cholesky decomposition
  26. */
  27. int main (int argc, char **argv)
  28. {
  29. std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
  30. int size = 500;
  31. if ( argc > 1 )
  32. size = atoi(argv[1]);
  33. cerr << "creating positive-definite random matrix with size " << size << endl;
  34. Matrix B ( size, size );
  35. initRand();
  36. for ( int i = 0 ; i < size; i++ )
  37. for ( int j = 0 ; j < size; j++ )
  38. B(i,j) = randDouble();
  39. Matrix A = B * B.transpose();
  40. Timer timer;
  41. /************* LinAl Cholesky (broken !!) ****/
  42. #ifdef NICE_USELIB_LINAL
  43. /*********** lapack direct ************/
  44. {
  45. timer.start();
  46. cerr << "cholesky decomposition (core/large scale/lapack)" << endl;
  47. Matrix G;
  48. choleskyDecompLargeScale ( A, G );
  49. timer.stop();
  50. if ( size < 11 )
  51. cerr << G << endl;
  52. cerr << "--- IPP or LAPACK/core(large-scale) chol: " << timer.getLast() << endl;
  53. cerr << "cholesky inversion" << endl;
  54. timer.start();
  55. Matrix Ainv;
  56. choleskyInvertLargeScale ( G, Ainv );
  57. timer.stop();
  58. cerr << "cholesky inversion finished." << endl;
  59. cerr << "--- LAPACK/core(large-scale) cholinv: " << timer.getLast() << endl;
  60. getInvError ( A, Ainv );
  61. }
  62. #endif
  63. {
  64. /************ NICE Cholesky *********/
  65. timer.start();
  66. cerr << "cholesky decomposition (core)" << endl;
  67. Matrix G;
  68. Matrix Ainv;
  69. choleskyDecomp ( A, G );
  70. timer.stop();
  71. cerr << "--- core chol: " << timer.getLast() << endl;
  72. if ( size < 11 )
  73. cerr << G << endl;
  74. cerr << "cholesky inversion" << endl;
  75. timer.start();
  76. choleskyInvert ( G, Ainv );
  77. timer.stop();
  78. cerr << "cholesky inversion finished." << endl;
  79. cerr << "--- core cholinv: " << timer.getLast() << endl;
  80. getInvError ( A, Ainv );
  81. }
  82. {
  83. #ifdef NICE_USELIB_IPP
  84. /********** IPP cholesky *********/
  85. cerr << "cholesky decomposition (IPP)" << endl;
  86. timer.start();
  87. Matrix G (A.rows(), A.cols());
  88. int stride = sizeof(double);
  89. int stride_m = A.rows() * sizeof(double);
  90. IppStatus ippStatus = ippmCholeskyDecomp_m_64f( (Ipp64f *)A.getDataPointer(), stride_m, stride,
  91. (Ipp64f *)G.getDataPointer(), stride_m, stride, A.rows());
  92. timer.stop();
  93. cerr << "--- IPP chol: " << timer.getLast() << endl;
  94. if ( ippStatus != ippStsOk )
  95. fthrow(Exception, ippGetStatusString(ippStatus));
  96. {
  97. timer.start();
  98. Matrix Gcorrected ( G.transpose() );
  99. for ( int i = 0 ; i < size ; i++ )
  100. Gcorrected(i,i) = 1.0 / Gcorrected(i,i);
  101. if ( size < 11 )
  102. {
  103. cerr << Gcorrected << endl;
  104. }
  105. Matrix Ainv (A.rows(), A.cols());
  106. choleskyInvertLargeScale ( Gcorrected, Ainv );
  107. timer.stop();
  108. cerr << "--- IPP->LargeScale(cholinv): " << timer.getLast() << endl;
  109. getInvError ( A, Ainv );
  110. }
  111. {
  112. timer.start();
  113. Matrix Ainv (A.rows(), A.cols());
  114. Matrix id ( A.rows(), A.cols() );
  115. id.setIdentity();
  116. ippStatus = ippmCholeskyBackSubst_mva_64f( (Ipp64f *)G.getDataPointer(), stride_m,
  117. stride, (Ipp64f *)id.getDataPointer(), stride_m, stride, Ainv.getDataPointer(), stride_m, stride,
  118. A.rows(), A.rows() );
  119. if ( ippStatus != ippStsOk )
  120. fthrow(Exception, ippGetStatusString(ippStatus));
  121. timer.stop();
  122. cerr << "--- IPP cholinv: " << timer.getLast() << endl;
  123. getInvError (A, Ainv);
  124. }
  125. #endif
  126. }
  127. // to slow :)
  128. #if 0
  129. {
  130. /*********** NICE invert () *******/
  131. timer.start();
  132. cerr << "matrix inversion (core/IPP)" << endl;
  133. Matrix Ainv;
  134. Ainv = invert ( A );
  135. timer.stop();
  136. cerr << "--- IPP/core invert: " << timer.getLast() << endl;
  137. getInvError (A, Ainv);
  138. }
  139. #endif
  140. #ifdef NICE_USELIB_LINAL
  141. /************* LinAl LU **************/
  142. {
  143. timer.start();
  144. Matrix inplaceLinAl ( A );
  145. LinAl::MatrixCF<double> Glinal ( inplaceLinAl.linal() );
  146. cerr << "LU decomposition and inversion (LinAl)" << endl;
  147. Glinal.LUinvert();
  148. timer.stop ();
  149. cerr << "--- LinAL/LUinvert cholinv: " << timer.getLast() << endl;
  150. getInvError ( A, inplaceLinAl );
  151. }
  152. #endif
  153. return 0;
  154. }