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