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 LU Decomposition methods in QVision",false);
00038
00039
00040 QVPropertyContainer arg_container(argv[0]);
00041 arg_container.addProperty<int>("Rows",QVPropertyContainer::inputFlag,100,
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>("RHS_size",QVPropertyContainer::inputFlag,0,
00046 "........................Number of right hand sides to solve for:\n"
00047 " "
00048 "If 0, only decompose, if <0 solve and also return decomposition)",-1000,1000);
00049 arg_container.addProperty<int>("n_tests",QVPropertyContainer::inputFlag,1,
00050 "Number of tests to average execution time",1,100);
00051 arg_container.addProperty<QString>("method",QVPropertyContainer::inputFlag,"GSL_LU",
00052 "..............................LU method (available methods follow):\n"
00053 " "
00054 "GSL_LU | LAPACK_DGETRF");
00055 arg_container.addProperty<bool>("verbose",QVPropertyContainer::inputFlag,false,
00056 "If true, print involved matrices and vectors");
00057 arg_container.addProperty<bool>("show_residuals",QVPropertyContainer::inputFlag,false,
00058 "If true, print test residuals");
00059
00060
00061 int ret_value = app.processArguments();
00062 if(ret_value != 1) exit(ret_value);
00063
00064
00065 const int Rows = arg_container.getPropertyValue<int>("Rows");
00066 const int Cols = arg_container.getPropertyValue<int>("Cols");
00067 const int RHS_size = arg_container.getPropertyValue<int>("RHS_size");
00068 const int n_tests = arg_container.getPropertyValue<int>("n_tests");
00069 const int verbose = arg_container.getPropertyValue<bool>("verbose");
00070 const int show_residuals = arg_container.getPropertyValue<bool>("show_residuals");
00071 const QString method = arg_container.getPropertyValue<QString>("method");
00072 TQVLU_Method lu_method;
00073 if(method == "GSL_LU")
00074 lu_method = GSL_LU;
00075 else if(method == "LAPACK_DGETRF")
00076 lu_method = LAPACK_DGETRF;
00077 else {
00078 std::cout << "Incorrect LU method. Use --help to see available methods.\n";
00079 exit(-1);
00080 }
00081
00082 std::cout << "Using values: Rows=" << Rows << " Cols=" << Cols << " RHS_size=" << RHS_size
00083 << " n_tests=" << n_tests << " LU method=" << qPrintable(method) << "\n";
00084
00085 double total_ms = 0.0;
00086
00087 for(int i=0;i<n_tests;i++) {
00088
00089 QVMatrix M = QVMatrix::random(Rows,Cols), P, L, U, X, B, X_sol;
00090 QVVector x, b, x_sol;
00091
00092
00093 if(qAbs(RHS_size) == 1) {
00094 x_sol = QVVector::random(Cols);
00095 b = M * x_sol;
00096 } else if (qAbs(RHS_size) > 1) {
00097 X_sol = QVMatrix::random(Cols,qAbs(RHS_size));
00098 B = M * X_sol;
00099 }
00100
00101 QTime t;
00102
00103 t.start();
00104
00105 if(RHS_size == 0)
00106 LUDecomposition(M, P, L, U, lu_method);
00107 else if(RHS_size == 1)
00108 SolveByLUDecomposition(M, x, b, lu_method);
00109 else if(RHS_size > 1)
00110 SolveByLUDecomposition(M, X, B, lu_method);
00111 else if (RHS_size == -1)
00112 SolveByLUDecomposition(M, x, b, P, L, U, lu_method);
00113 else if (RHS_size < -1)
00114 SolveByLUDecomposition(M, X, B, P, L, U, lu_method);
00115
00116 total_ms += t.elapsed();
00117
00118 if(verbose) {
00119 if(RHS_size <= 0) {
00120 std::cout << "*****************************************\n";
00121 std::cout << "M:" << M << "\n";
00122 std::cout << "P:" << P << "\n";
00123 std::cout << "L:" << L << "\n";
00124 std::cout << "U:" << U << "\n";
00125 std::cout << "P L U:" << P*L*U << "\n";
00126 std::cout << "*****************************************\n";
00127 }
00128 if(qAbs(RHS_size) == 1) {
00129 std::cout << "*****************************************\n";
00130 std::cout << "M:" << M << "\n";
00131 std::cout << "b:" << b << "\n";
00132 std::cout << "x:" << x << "\n";
00133 std::cout << "x_sol:" << x_sol << "\n";
00134 std::cout << "*****************************************\n";
00135 }
00136 if(qAbs(RHS_size) > 1){
00137 std::cout << "*****************************************\n";
00138 std::cout << "M:" << M << "\n";
00139 std::cout << "B:" << B << "\n";
00140 std::cout << "X:" << X << "\n";
00141 std::cout << "X_sol:" << X_sol << "\n";
00142 std::cout << "*****************************************\n";
00143 }
00144 }
00145
00146 if(show_residuals) {
00147 if(RHS_size <= 0) {
00148 std::cout << "LU residual = " << LUDecompositionResidual(M, P, L, U) << "\n";
00149 }
00150 if(qAbs(RHS_size) == 1) {
00151 std::cout << "Test solve residual = " << SolveResidual(M, x_sol, b) << "\n";
00152 std::cout << "LU solve residual = " << SolveResidual(M, x, b) << "\n";
00153 std::cout << "x - x_sol residual = " << (x-x_sol).norm2() << "\n";
00154 std::cout << "x norm = " << x.norm2() << "\n";
00155 std::cout << "x_sol norm = " << x_sol.norm2() << "\n";
00156 }
00157 if(qAbs(RHS_size) > 1) {
00158 std::cout << "Test solve residual = " << SolveResidual(M, X_sol, B) << "\n";
00159 std::cout << "LU solve residual = " << SolveResidual(M, X, B) << "\n";
00160 }
00161 }
00162 }
00163
00164 total_ms /= n_tests;
00165
00166 if(n_tests==1)
00167 std::cout << "Total time: " << total_ms << " ms.\n";
00168 else
00169 std::cout << "Average total time: " << total_ms << " ms.\n";
00170
00171 std::cout << "Finished.\n";
00172 }