00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00024
00025 #include <iostream>
00026
00027 #include <QTime>
00028
00029 #include <QVApplication>
00030 #include <QVPropertyContainer>
00031 #include <QVMatrix>
00032 #include <QVVector>
00033
00034 int main(int argc, char *argv[])
00035 {
00036
00037 QVApplication app(argc,argv,"Performance test for eigendecomposition methods in QVision",false);
00038
00039
00040 QVPropertyContainer arg_container(argv[0]);
00041 arg_container.addProperty<int>("Rows",QVPropertyContainer::inputFlag,200,
00042 "Number of rows (=cols) for the square test matrix",1,100000);
00043 arg_container.addProperty<int>("n_tests",QVPropertyContainer::inputFlag,1,
00044 "Number of tests to average execution time",1,100);
00045 arg_container.addProperty<QString>("method",QVPropertyContainer::inputFlag,"GSL_EIGENSYMM",
00046 ".......Eigendecomposition method (available methods follow):\n"
00047 " GSL_EIGENSYMM | GSL_EIGENSYMM_ONLY | LAPACK_DSYEV | LAPACK_DSYEV_ONLY");
00048 arg_container.addProperty<bool>("verbose",QVPropertyContainer::inputFlag,false,
00049 "If true, print involved matrices and vectors");
00050 arg_container.addProperty<bool>("show_residuals",QVPropertyContainer::inputFlag,false,
00051 "If true, print test residuals");
00052
00053
00054 int ret_value = app.processArguments();
00055 if(ret_value != 1) exit(ret_value);
00056
00057
00058 const int Rows = arg_container.getPropertyValue<int>("Rows");
00059 const int n_tests = arg_container.getPropertyValue<int>("n_tests");
00060 const int verbose = arg_container.getPropertyValue<bool>("verbose");
00061 const int show_residuals = arg_container.getPropertyValue<bool>("show_residuals");
00062 const QString method = arg_container.getPropertyValue<QString>("method");
00063 TQVEigenDecomposition_Method eigen_method = GSL_EIGENSYMM;
00064 TQVEigenValues_Method eigenonly_method = GSL_EIGENSYMM_ONLY;
00065 bool only_ev = false;
00066 if(method == "GSL_EIGENSYMM")
00067 eigen_method = GSL_EIGENSYMM;
00068 else if(method == "LAPACK_DSYEV")
00069 eigen_method = LAPACK_DSYEV;
00070 else if(method == "GSL_EIGENSYMM_ONLY") {
00071 eigenonly_method = GSL_EIGENSYMM_ONLY;
00072 only_ev = true;
00073 } else if(method == "LAPACK_DSYEV_ONLY") {
00074 eigenonly_method = LAPACK_DSYEV_ONLY;
00075 only_ev = true;
00076 } else {
00077 std::cout << "Incorrect eigendecomposition method. Use --help to see available methods.\n";
00078 exit(-1);
00079 }
00080
00081 std::cout << "Using values: Rows=" << Rows
00082 << " n_tests=" << n_tests << " eigendecomposition method=" << qPrintable(method) << "\n";
00083
00084 double total_ms = 0.0;
00085
00086 for(int i=0;i<n_tests;i++) {
00087
00088 QVMatrix M = QVMatrix::random(Rows,Rows), Q;
00089 M = M + M.transpose();
00090 QVVector lambda;
00091
00092 QTime t;
00093
00094 t.start();
00095
00096 if(only_ev)
00097 EigenValues(M, lambda, eigenonly_method);
00098 else
00099 EigenDecomposition(M, lambda, Q, eigen_method);
00100
00101 total_ms += t.elapsed();
00102
00103 if(verbose) {
00104 if(only_ev) {
00105 std::cout << "*****************************************\n";
00106 std::cout << "M:" << M << "\n";
00107 std::cout << "lambda:" << lambda << "\n";
00108 std::cout << "*****************************************\n";
00109 } else {
00110 std::cout << "*****************************************\n";
00111 std::cout << "M:" << M << "\n";
00112 std::cout << "lambda:" << lambda << "\n";
00113 std::cout << "Q:" << Q << "\n";
00114 std::cout << "Q diag(lambda) Q^T:" << Q*QVMatrix::diagonal(lambda)*Q.transpose() << "\n";
00115 std::cout << "Q^T Q:" << Q.transpose()*Q << "\n";
00116 std::cout << "*****************************************\n";
00117 }
00118 }
00119
00120 if(show_residuals) {
00121 if(only_ev) {
00122 std::cout << "EigenValues residual = " << EigenValuesResidual(M, lambda) << "\n";
00123 } else {
00124 std::cout << "EigenDecomposition residual = " << EigenDecompositionResidual(M, lambda, Q) << "\n";
00125 }
00126 }
00127 }
00128
00129 total_ms /= n_tests;
00130
00131 if(n_tests==1)
00132 std::cout << "Total time: " << total_ms << " ms.\n";
00133 else
00134 std::cout << "Average total time: " << total_ms << " ms.\n";
00135
00136 std::cout << "Finished.\n";
00137 }