testCholeskySpeed.cpp 4.6 KB

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