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 QR 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 for the test matrix",1,100000);
00043 arg_container.addProperty<int>("Cols",QVPropertyContainer::inputFlag,100,
00044 "Number of columns for the test matrix",1,100000);
00045 arg_container.addProperty<int>("n_tests",QVPropertyContainer::inputFlag,1,
00046 "Number of tests to average execution time",1,100);
00047 arg_container.addProperty<QString>("method",QVPropertyContainer::inputFlag,"GSL_HOUSEHOLDER_THIN_QR",
00048 ".............QR method (available methods follow):\n"
00049 " GSL_HOUSEHOLDER_THIN_QR | GSL_HOUSEHOLDER_FULL_QR | LAPACK_THIN_DGEQR2 | LAPACK_FULL_DGEQR2");
00050 arg_container.addProperty<QString>("decomposition",QVPropertyContainer::inputFlag,"QR",
00051 ".................type of decomposition (QR,QL,RQ,LQ)");
00052 arg_container.addProperty<bool>("verbose",QVPropertyContainer::inputFlag,false,
00053 "If true, print involved matrices and vectors");
00054 arg_container.addProperty<bool>("show_residuals",QVPropertyContainer::inputFlag,false,
00055 "If true, print test residuals");
00056
00057
00058 int ret_value = app.processArguments();
00059 if(ret_value != 1) exit(ret_value);
00060
00061
00062 int Rows = arg_container.getPropertyValue<int>("Rows");
00063 int Cols = arg_container.getPropertyValue<int>("Cols");
00064 const int n_tests = arg_container.getPropertyValue<int>("n_tests");
00065 const int verbose = arg_container.getPropertyValue<bool>("verbose");
00066 const int show_residuals = arg_container.getPropertyValue<bool>("show_residuals");
00067 const QString method = arg_container.getPropertyValue<QString>("method");
00068 const QString decomposition = arg_container.getPropertyValue<QString>("decomposition");
00069 TQVQR_Method qr_method;
00070 if(method == "GSL_HOUSEHOLDER_THIN_QR")
00071 qr_method = GSL_HOUSEHOLDER_THIN_QR;
00072 else if(method == "GSL_HOUSEHOLDER_FULL_QR")
00073 qr_method = GSL_HOUSEHOLDER_FULL_QR;
00074 else if(method == "LAPACK_THIN_DGEQR2")
00075 qr_method = LAPACK_THIN_DGEQR2;
00076 else if(method == "LAPACK_FULL_DGEQR2")
00077 qr_method = LAPACK_FULL_DGEQR2;
00078 else {
00079 std::cout << "Incorrect QR method. Use --help to see available methods.\n";
00080 exit(-1);
00081 }
00082
00083 std::cout << "Using values: Rows=" << Rows << " Cols=" << Cols
00084 << " n_tests=" << n_tests << " QR method=" << qPrintable(method)
00085 << " type of decomposition=" << qPrintable(decomposition) << "\n";
00086
00087 double total_ms = 0.0;
00088
00089 for(int i=0;i<n_tests;i++) {
00090
00091 QVMatrix M = QVMatrix::random(Rows,Cols), Q, R, L;
00092
00093 QTime t;
00094
00095 t.start();
00096
00097 if(decomposition == "QR")
00098 QRDecomposition(M, Q, R, qr_method);
00099 else if(decomposition == "QL")
00100 QLDecomposition(M, Q, L, qr_method);
00101 else if(decomposition == "RQ")
00102 RQDecomposition(M, R, Q, qr_method);
00103 else if (decomposition == "LQ")
00104 LQDecomposition(M, L, Q, qr_method);
00105 else {
00106 std::cout << "Incorrect decomposition type. Use --help to see available decompositions.\n";
00107 exit(-1);
00108 }
00109
00110 total_ms += t.elapsed();
00111
00112 if(verbose) {
00113 if(decomposition == "QR") {
00114 std::cout << "*****************************************\n";
00115 std::cout << "M:" << M << "\n";
00116 std::cout << "Q:" << Q << "\n";
00117 std::cout << "R:" << R << "\n";
00118 std::cout << "Q R:" << Q*R << "\n";
00119 std::cout << "Q^T Q:" << Q.transpose()*Q << "\n";
00120 std::cout << "*****************************************\n";
00121 } else if(decomposition == "QL") {
00122 std::cout << "*****************************************\n";
00123 std::cout << "M:" << M << "\n";
00124 std::cout << "Q:" << Q << "\n";
00125 std::cout << "L:" << L << "\n";
00126 std::cout << "Q L:" << Q*L << "\n";
00127 std::cout << "Q^T Q:" << Q.transpose()*Q << "\n";
00128 std::cout << "*****************************************\n";
00129 } else if(decomposition == "RQ") {
00130 std::cout << "*****************************************\n";
00131 std::cout << "M:" << M << "\n";
00132 std::cout << "R:" << R << "\n";
00133 std::cout << "Q:" << Q << "\n";
00134 std::cout << "R Q:" << R*Q << "\n";
00135 std::cout << "Q^T Q:" << Q*Q.transpose() << "\n";
00136 std::cout << "*****************************************\n";
00137 } else if(decomposition == "LQ") {
00138 std::cout << "*****************************************\n";
00139 std::cout << "M:" << M << "\n";
00140 std::cout << "L:" << L << "\n";
00141 std::cout << "Q:" << Q << "\n";
00142 std::cout << "L Q:" << L*Q << "\n";
00143 std::cout << "Q^T Q:" << Q*Q.transpose() << "\n";
00144 std::cout << "*****************************************\n";
00145 }
00146 }
00147
00148 if(show_residuals) {
00149 if(decomposition == "QR") {
00150 std::cout << "QR residual = " << QRDecompositionResidual(M, Q, R) << "\n";
00151 } else if(decomposition == "QL") {
00152 std::cout << "QL residual = " << QLDecompositionResidual(M, Q, L) << "\n";
00153 } else if(decomposition == "RQ") {
00154 std::cout << "RQ residual = " << RQDecompositionResidual(M, R, Q) << "\n";
00155 } else if(decomposition == "LQ") {
00156 std::cout << "LQ residual = " << LQDecompositionResidual(M, L, Q) << "\n";
00157 }
00158 }
00159 }
00160
00161 total_ms /= n_tests;
00162
00163 if(n_tests==1)
00164 std::cout << "Total time: " << total_ms << " ms.\n";
00165 else
00166 std::cout << "Average total time: " << total_ms << " ms.\n";
00167
00168 std::cout << "Finished.\n";
00169 }