123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- /**
- * @file testCholeskySpeed.cpp
- * @brief test LinAl cholesky decomposition
- * @author Erik Rodner
- * @date 01/06/2010
- */
- #include "core/basics/numerictools.h"
- #include "core/vector/Algorithms.h"
- #include "core/basics/Timer.h"
- extern "C" {
- IppStatus ippmCholeskyDecomp_m_64f(const Ipp64f* pSrc, int srcStride1, int
- srcStride2, Ipp64f* pDst, int dstStride1, int dstStride2, int widthHeight);
- }
- using namespace std;
- using namespace NICE;
- double getInvError ( const Matrix & A, const Matrix & Ainv )
- {
- Matrix idapprox = Ainv*A;
- idapprox.addIdentity(-1.0);
- double error = idapprox.frobeniusNorm();
- cerr << "error = " << error << endl;
- return error;
- }
- /**
-
- test LinAl cholesky decomposition
-
- */
- int main (int argc, char **argv)
- {
- #ifndef WIN32
- #ifndef __clang__
- #ifndef __llvm__
- std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
- #endif
- #endif
- #endif
- int size = 500;
- if ( argc > 1 )
- size = atoi(argv[1]);
- cerr << "creating positive-definite random matrix with size " << size << endl;
- Matrix B ( size, size );
- initRand();
- for ( int i = 0 ; i < size; i++ )
- for ( int j = 0 ; j < size; j++ )
- B(i,j) = randDouble();
-
- Matrix A = B * B.transpose();
- Timer timer;
- /************* LinAl Cholesky (broken !!) ****/
- #ifdef NICE_USELIB_LINAL
- /*********** lapack direct ************/
- {
- timer.start();
- cerr << "cholesky decomposition (core/large scale/lapack)" << endl;
- Matrix G;
- choleskyDecompLargeScale ( A, G );
- timer.stop();
- if ( size < 11 )
- cerr << G << endl;
- cerr << "--- IPP or LAPACK/core(large-scale) chol: " << timer.getLast() << endl;
- cerr << "cholesky inversion" << endl;
- timer.start();
- Matrix Ainv;
- choleskyInvertLargeScale ( G, Ainv );
- timer.stop();
- cerr << "cholesky inversion finished." << endl;
-
- cerr << "--- LAPACK/core(large-scale) cholinv: " << timer.getLast() << endl;
- getInvError ( A, Ainv );
- }
- #endif
- {
- /************ NICE Cholesky *********/
- timer.start();
- cerr << "cholesky decomposition (core)" << endl;
- Matrix G;
- Matrix Ainv;
- choleskyDecomp ( A, G );
- timer.stop();
-
- cerr << "--- core chol: " << timer.getLast() << endl;
- if ( size < 11 )
- cerr << G << endl;
- cerr << "cholesky inversion" << endl;
- timer.start();
- choleskyInvert ( G, Ainv );
- timer.stop();
- cerr << "cholesky inversion finished." << endl;
-
- cerr << "--- core cholinv: " << timer.getLast() << endl;
- getInvError ( A, Ainv );
- }
- {
- #ifdef NICE_USELIB_IPP
- /********** IPP cholesky *********/
- cerr << "cholesky decomposition (IPP)" << endl;
- timer.start();
- Matrix G (A.rows(), A.cols());
- int stride = sizeof(double);
- int stride_m = A.rows() * sizeof(double);
- IppStatus ippStatus = ippmCholeskyDecomp_m_64f( (Ipp64f *)A.getDataPointer(), stride_m, stride,
- (Ipp64f *)G.getDataPointer(), stride_m, stride, A.rows());
- timer.stop();
- cerr << "--- IPP chol: " << timer.getLast() << endl;
- if ( ippStatus != ippStsOk )
- fthrow(Exception, ippGetStatusString(ippStatus));
- {
- timer.start();
- Matrix Gcorrected ( G.transpose() );
- for ( int i = 0 ; i < size ; i++ )
- Gcorrected(i,i) = 1.0 / Gcorrected(i,i);
- if ( size < 11 )
- {
- cerr << Gcorrected << endl;
- }
-
- Matrix Ainv (A.rows(), A.cols());
- choleskyInvertLargeScale ( Gcorrected, Ainv );
- timer.stop();
-
- cerr << "--- IPP->LargeScale(cholinv): " << timer.getLast() << endl;
- getInvError ( A, Ainv );
- }
-
- {
- timer.start();
- Matrix Ainv (A.rows(), A.cols());
- Matrix id ( A.rows(), A.cols() );
- id.setIdentity();
- ippStatus = ippmCholeskyBackSubst_mva_64f( (Ipp64f *)G.getDataPointer(), stride_m,
- stride, (Ipp64f *)id.getDataPointer(), stride_m, stride, Ainv.getDataPointer(), stride_m, stride,
- A.rows(), A.rows() );
- if ( ippStatus != ippStsOk )
- fthrow(Exception, ippGetStatusString(ippStatus));
- timer.stop();
- cerr << "--- IPP cholinv: " << timer.getLast() << endl;
- getInvError (A, Ainv);
- }
- #endif
- }
- // to slow :)
- #if 0
- {
- /*********** NICE invert () *******/
- timer.start();
- cerr << "matrix inversion (core/IPP)" << endl;
- Matrix Ainv;
- Ainv = invert ( A );
- timer.stop();
- cerr << "--- IPP/core invert: " << timer.getLast() << endl;
- getInvError (A, Ainv);
- }
- #endif
- #ifdef NICE_USELIB_LINAL
- /************* LinAl LU **************/
- {
- timer.start();
- Matrix inplaceLinAl ( A );
- LinAl::MatrixCF<double> Glinal ( inplaceLinAl.linal() );
- cerr << "LU decomposition and inversion (LinAl)" << endl;
- Glinal.LUinvert();
- timer.stop ();
-
- cerr << "--- LinAL/LUinvert cholinv: " << timer.getLast() << endl;
- getInvError ( A, inplaceLinAl );
- }
- #endif
- return 0;
- }
|