testCholeskySpeed.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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. #ifndef WIN32
  30. std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
  31. #endif
  32. int size = 500;
  33. if ( argc > 1 )
  34. size = atoi(argv[1]);
  35. cerr << "creating positive-definite random matrix with size " << size << endl;
  36. Matrix B ( size, size );
  37. initRand();
  38. for ( int i = 0 ; i < size; i++ )
  39. for ( int j = 0 ; j < size; j++ )
  40. B(i,j) = randDouble();
  41. Matrix A = B * B.transpose();
  42. Timer timer;
  43. /************* LinAl Cholesky (broken !!) ****/
  44. #ifdef NICE_USELIB_LINAL
  45. /*********** lapack direct ************/
  46. {
  47. timer.start();
  48. cerr << "cholesky decomposition (core/large scale/lapack)" << endl;
  49. Matrix G;
  50. choleskyDecompLargeScale ( A, G );
  51. timer.stop();
  52. if ( size < 11 )
  53. cerr << G << endl;
  54. cerr << "--- IPP or LAPACK/core(large-scale) chol: " << timer.getLast() << endl;
  55. cerr << "cholesky inversion" << endl;
  56. timer.start();
  57. Matrix Ainv;
  58. choleskyInvertLargeScale ( G, Ainv );
  59. timer.stop();
  60. cerr << "cholesky inversion finished." << endl;
  61. cerr << "--- LAPACK/core(large-scale) cholinv: " << timer.getLast() << endl;
  62. getInvError ( A, Ainv );
  63. }
  64. #endif
  65. {
  66. /************ NICE Cholesky *********/
  67. timer.start();
  68. cerr << "cholesky decomposition (core)" << endl;
  69. Matrix G;
  70. Matrix Ainv;
  71. choleskyDecomp ( A, G );
  72. timer.stop();
  73. cerr << "--- core chol: " << timer.getLast() << endl;
  74. if ( size < 11 )
  75. cerr << G << endl;
  76. cerr << "cholesky inversion" << endl;
  77. timer.start();
  78. choleskyInvert ( G, Ainv );
  79. timer.stop();
  80. cerr << "cholesky inversion finished." << endl;
  81. cerr << "--- core cholinv: " << timer.getLast() << endl;
  82. getInvError ( A, Ainv );
  83. }
  84. {
  85. #ifdef NICE_USELIB_IPP
  86. /********** IPP cholesky *********/
  87. cerr << "cholesky decomposition (IPP)" << endl;
  88. timer.start();
  89. Matrix G (A.rows(), A.cols());
  90. int stride = sizeof(double);
  91. int stride_m = A.rows() * sizeof(double);
  92. IppStatus ippStatus = ippmCholeskyDecomp_m_64f( (Ipp64f *)A.getDataPointer(), stride_m, stride,
  93. (Ipp64f *)G.getDataPointer(), stride_m, stride, A.rows());
  94. timer.stop();
  95. cerr << "--- IPP chol: " << timer.getLast() << endl;
  96. if ( ippStatus != ippStsOk )
  97. fthrow(Exception, ippGetStatusString(ippStatus));
  98. {
  99. timer.start();
  100. Matrix Gcorrected ( G.transpose() );
  101. for ( int i = 0 ; i < size ; i++ )
  102. Gcorrected(i,i) = 1.0 / Gcorrected(i,i);
  103. if ( size < 11 )
  104. {
  105. cerr << Gcorrected << endl;
  106. }
  107. Matrix Ainv (A.rows(), A.cols());
  108. choleskyInvertLargeScale ( Gcorrected, Ainv );
  109. timer.stop();
  110. cerr << "--- IPP->LargeScale(cholinv): " << timer.getLast() << endl;
  111. getInvError ( A, Ainv );
  112. }
  113. {
  114. timer.start();
  115. Matrix Ainv (A.rows(), A.cols());
  116. Matrix id ( A.rows(), A.cols() );
  117. id.setIdentity();
  118. ippStatus = ippmCholeskyBackSubst_mva_64f( (Ipp64f *)G.getDataPointer(), stride_m,
  119. stride, (Ipp64f *)id.getDataPointer(), stride_m, stride, Ainv.getDataPointer(), stride_m, stride,
  120. A.rows(), A.rows() );
  121. if ( ippStatus != ippStsOk )
  122. fthrow(Exception, ippGetStatusString(ippStatus));
  123. timer.stop();
  124. cerr << "--- IPP cholinv: " << timer.getLast() << endl;
  125. getInvError (A, Ainv);
  126. }
  127. #endif
  128. }
  129. // to slow :)
  130. #if 0
  131. {
  132. /*********** NICE invert () *******/
  133. timer.start();
  134. cerr << "matrix inversion (core/IPP)" << endl;
  135. Matrix Ainv;
  136. Ainv = invert ( A );
  137. timer.stop();
  138. cerr << "--- IPP/core invert: " << timer.getLast() << endl;
  139. getInvError (A, Ainv);
  140. }
  141. #endif
  142. #ifdef NICE_USELIB_LINAL
  143. /************* LinAl LU **************/
  144. {
  145. timer.start();
  146. Matrix inplaceLinAl ( A );
  147. LinAl::MatrixCF<double> Glinal ( inplaceLinAl.linal() );
  148. cerr << "LU decomposition and inversion (LinAl)" << endl;
  149. Glinal.LUinvert();
  150. timer.stop ();
  151. cerr << "--- LinAL/LUinvert cholinv: " << timer.getLast() << endl;
  152. getInvError ( A, inplaceLinAl );
  153. }
  154. #endif
  155. return 0;
  156. }