more bicgstab information
david moloney <[email protected]> Tue, 09 Nov 2004 17:19:31 +0000
| Newsgroups | gmane.comp.lib.mtl.devel |
|---|---|
| Message-ID | <[email protected]> |
Matrix # Matrix Name nrows ncols nnz is_symmetric iter True Residual Converged error-code 0 bp__1600.mtx 822 822 4841 N 0 1.#QNAN0 N 0 2 gemat12.mtx 4929 4929 33111 N 0 1.#QNAN0 N 0 5 tub1000.mtx 1000 1000 3996 N 9 0.000005 N 0 6 utm300.mtx 300 300 3155 N 15 0.000012 N 0 8 bcsstm20.mtx 485 485 970 Y 8 0.000021 N 0 12 hor__131.mtx 434 434 4710 N 21 0.00002 N 0 13 psmigr_1.mtx 3140 3140 543162 N 0 1.#QNAN0 N 0 18 bp___800.mtx 822 822 4534 N 0 1.#QNAN0 N 0 1 cavity01.mtx 317 317 7327 N 60 131.827524 Y 1 3 s1rmq4m1.mtx 5489 5489 286600 Y 60 4117.281278 Y 1 4 shl__400.mtx 663 663 1712 N 60 7876.350876 Y 1 7 west2021.mtx 2021 2021 7353 N 60 3344.341296 Y 1 9 e20r5000.mtx 4241 4241 131556 N 60 5618.114418 Y 1 10 fidap037.mtx 3565 3565 67591 N 60 16.887688 Y 1 11 fidapm37.mtx 9152 9152 765944 N 60 95844.2395 Y 1 14 s1rmq4m1.mtx 5489 5489 286600 Y 60 4117.281278 Y 1 15 shl____0.mtx 663 663 1687 N 60 1948.317709 Y 1 16 west2021.mtx 2021 2021 7353 N 60 3344.341296 Y 1 17 af23560.mtx 23560 23560 484256 N 60 52209.26516 Y 1 19 dw8192.mtx 8192 8192 41746 N 60 1563.168486 Y 1 20 memplus.mtx 17758 17758 126150 N 60 11.250001 Y 1 21 orsreg_1.mtx 2205 2205 14133 N 60 0.068578 Y 1 Here is a more complete list of matrices from the Matrix-Market collection for which I obtain strange results using bicgstab. As you can see bicgstab reports with an error-code of 0 (non-convergence according to the ITL documentation). As you can also see 4 of the candidate non-converging solutions produce QNaNs. The convergence behaviour does not appear to be influenced by how the b vector is initialised (lower or higher than 1.0 for each element in b). Regards, - David [email protected] wrote: >Send mtl-devel mailing list submissions to > [email protected] > >To subscribe or unsubscribe via the World Wide Web, visit > http://www.osl.iu.edu/mailman/listinfo.cgi/mtl-devel >or, via email, send a message with subject or body 'help' to > [email protected] > >You can reach the person managing the list at > [email protected] > >When replying, please edit your Subject line so it is more specific >than "Re: Contents of mtl-devel digest..." > > >------------------------------------------------------------------------ > >Today's Topics: > > 1. strange bicg vs. bicgstab behaviour for same matrix > (david moloney) > > > > ------------------------------------------------------------------------ > > Subject: > MTL: strange bicg vs. bicgstab behaviour for same matrix > From: > david moloney <[email protected]> > Date: > Tue, 09 Nov 2004 15:02:49 +0000 > To: > [email protected], David Moloney <[email protected]> > > To: > [email protected], David Moloney <[email protected]> > > > Hi all, > > I am using a number of Matrix-Market matrices as test cases for some > work I am doing using mtl and itl. I have found that a number of > these matrices produce QNaNs from the two_norm() function in mtl when > bicgstab is used and behave correctly when the bicg solver from itl is > used. > The only way that a QNaN can be produced from mtl::two_norm() > according to the IEEE standard, is if the square-root of a negative > number is taken. This however is impossible as two_norm() is the sum > of the squares of the elements of a vector b and all of the elements > of b are set to 1 initially. On the first iteration the result > returned by two_norm should be sqrt(822), where 822 is the numbers of > columns and rows in the A matrix. Incidentally sqrt(822) = 28.67054 > as can be seen in the first iteration of both versions of the program > below. > > The summation on the other hand can produce a QNaN if one or other > element of b when squared is infinity, but the fact that bicgstab > succeeds suggests this is not the case. > > The matrix used is bp__1600.mtx from the matrix-market test-suite > (http://math.nist.gov/MatrixMarket/data/Harwell-Boeing/smtape/bp__1600.html) > and the code (modified from itl example code) is attached. > Any opinions welcome, > > - David > > > ************************************************************************************** > > bicg results > ************************************************************************************** > > > iteration 0: resid 28.6705 > finished! error code = 2 > 0 iterations > 28.6705 is actual final residual. > 1 is actual relative tolerance achieved. > Relative tol: 1e-006 Absolute tol: 0 > > Solving bp__1600.mtx using itl/bicg > > Summary of results for bp__1600.mtx > ----------------------------------------- > converged Y > # iterations 0 > normb 28.6705 > final residual 28.6705 > True Residual 28.6705 > Target relative tolerance 1e-006 > Target absolute tolerance 0 > Achieved relative tolerance 1 > ----------------------------------------- > > ************************************************************************************** > > bicgstab results > ************************************************************************************** > > > normr_ = 28.6705 > resid_[1] = r[28.6705]/normb[28.6705] > iteration 0: resid 28.6705 > normr_ = 1.#QNAN > resid_[1.#QNAN] = r[1.#QNAN]/normb[28.6705] > iteration 0: resid 1.#QNAN > finished! error code = 0 > 0 iterations > 1.#QNAN is actual final residual. > 1.#QNAN is actual relative tolerance achieved. > Relative tol: 1e-006 Absolute tol: 0 > > Solving bp__1600.mtx using itl/bicgstab > > Summary of results for bp__1600.mtx > ---------------------------------------- > converged N > # iterations 0 > normb 28.6705 > final residual 1.#QNAN > True Residual 1.#QNAN > Target relative tolerance 1e-006 > Target absolute tolerance 0 > Achieved relative tolerance 1.#QNAN > ----------------------------------------- > > > >------------------------------------------------------------------------ > >//========================================================================== >// CVS Information: >// >// $RCSfile: parser.cpp,v $ $Revision: 1.3 $ $State: Exp $ >// $Author: llee $ $Date: 2001/10/26 14:28:24 $ >// $Locker: $ >//--------------------------------------------------------------------------- >// >// DESCRIPTION >// >//--------------------------------------------------------------------------- >// >// LICENSE AGREEMENT >// $COPYRIGHT$ >//--------------------------------------------------------------------------- >// >// REVISION HISTORY: >// >// $Log: parser.cpp,v $ >// Revision 1.3 2001/10/26 14:28:24 llee >// *** empty log message *** >// >// Revision 1.2 2001/07/05 22:28:58 llee1 >// gcc 3.0 fix >// >// Revision 1.1 2000/07/26 21:49:58 llee1 >// change file extension from .cc to .cpp >// >// Revision 1.3 2000/07/18 14:30:44 llee1 >// *** empty log message *** >// >// Revision 1.2 2000/07/17 15:44:06 llee1 >// *** empty log message *** >// >// >//=========================================================================== >#include <iostream> >#include "parser.h" > >#if defined ITL_NO_SSTREAM >#include <stdio.h> >#else >#include <sstream> >#endif > >#include <assert.h> > >namespace std { > > parser::parser(int argc, char* argv[], const string& delim) { > string raw_data; > //copy argv to raw_data; > for (int i=1; i<argc; ++i) { > raw_data += argv[i]; > raw_data += " "; > } > > remove_special_character(raw_data, '='); > split(delim, raw_data); > } > > void parser::register_flag (const string& flag, int i, const string& mesg) { > registers[flag] = i; > messages[flag] = mesg; > } > > bool parser::flags_coexist (const string& flag1, const string& flag2, > bool coexist) { > bool found1 = seg.find(flag1) != seg.end(); > bool found2 = seg.find(flag2) != seg.end(); > > if ( coexist ) { > if ( found1 != found2 ) { > cerr << flag1 << " and " << flag2 > << " must be both in the comand line. Exiting ..." << endl; > assert(false); > } > } else if ( found1 && found2 ) { > cerr << flag1 << " and " << flag2 > << " cannot be both in the comand line. Exiting ..." << endl; > //exit > assert(false); > } > > return found1 && found2 != coexist; > } > >#if defined ITL_NO_SSTREAM > void parser::get(const string& flag, double& value, double d) { > if ( registers.find(flag) == registers.end() ) { > cerr << flag << " is not registered! Exiting..." << endl; > assert(false); > } > > map<string,string>::iterator i = seg.find(flag); > > if ( i == seg.end() ) > value = d; > else { > if ( registers[flag] == 0 ) > value = ! d; //not the default > else if ((*i).second.size()==0) { > cerr << flag << " requires a value." << endl > << " Please provid it right after the flag with whitespace " > << endl << " or equal sign between flag and value." << endl; > assert(false); > } else { > sscanf((*i).second.data(), "%lf", &value); > } > } > } > > void parser::get(const string& flag, int& value, int d) { > if ( registers.find(flag) == registers.end() ) { > cerr << flag << " is not registered! Exiting..." << endl; > assert(false); > } > > map<string,string>::iterator i = seg.find(flag); > > if ( i == seg.end() ) > value = d; > else { > if ( registers[flag] == 0 ) > value = ! d; //not the default > else if ((*i).second.size()==0) { > cerr << flag << " requires a value." << endl > << " Please provid it right after the flag with whitespace " > << endl << " or equal sign between flag and value." << endl; > assert(false); > } else { > sscanf((*i).second.data(), "%d", &value); > } > } > } > > // > // Added by David Moloney to allow string arguments to be extracted > // from argv[] ... for example filenames > // > void parser::get(const string& flag, char*& value, char* d) { > if ( registers.find(flag) == registers.end() ) { > cerr << flag << " is not registered! Exiting..." << endl; > assert(false); > } > map<string,string>::iterator i = seg.find(flag); > if (i==seg.end()) value = d; > else { > if (registers[flag]==0) > value = d; //not the default > else if ((*i).second.size()==0) { > cerr << flag << " requires a value." << endl > << " Please provid it right after the flag with whitespace " > << endl << " or equal sign between flag and value." << endl; > assert(false); > } > else { > sscanf((*i).second.data(), "%s", value); > } > } > } > >#else > template <typename T> > void parser::get(const string& flag, T& value, const T& d) { > if ( registers.find(flag) == registers.end() ) { > cerr << flag << " is not registered! Exiting..." << endl; > assert(false); > } > > map<string,string>::iterator i = seg.find(flag); > > if ( i == seg.end() ) > value = d; > else { > if ( registers[flag] == 0 ) > value = ! d; //not the default > else if ((*i).second.size()==0) { > cerr << flag << " requires a value." << endl > << " Please provid it right after the flag with whitespace " << endl > << " or equal sign between flag and value." << endl; > assert(false); > } else { > istringstream iss((*i).second); > iss >> value; > > if (iss.fail()) { > cerr << flag << " has an invalid value. Exit..." << endl; > //exit > assert(false); > } > } > } > } >#endif > > void parser::help(char *msg) { > string h("--help"); > bool found = seg.find(h) != seg.end(); > if ( found ) { > cout << endl << endl; > cout << msg << " Usage of flags: " << endl << endl; > for ( map<string,int>::iterator i = registers.begin(); > i != registers.end(); ++i) { > cout << " " << (*i).first; > if ( (*i).second ) > cout << " <value> "; > cout << ": " << messages[(*i).first] << endl; > } > cout << endl << endl; > } > } > > void parser::remove_special_character(string& raw_data, char c) { > char * temp = const_cast<char*>(raw_data.c_str()); > for (string::size_type i=0; i<raw_data.size(); ++i) > if ( temp[i] == c ) > temp[i] = ' '; > } > > void parser::split(const string& delim, const string& raw_data) { > > string::size_type pos = 0; > bool cond = true; > > while ( cond ) { > string::size_type prev = pos+2; > pos = raw_data.find(delim, prev); > > if ( pos == string::npos ) { > pos = raw_data.size(); > cond = false; > } > > string::size_type s = pos - prev + 2; > > halve( raw_data.substr(prev-2, s) ); > } > } > > //str is one unit include a flag and its (possible) value(s) > //it is not allowed that str is started " " > void parser::halve(const string& str) { > string::size_type pos = str.find(" "); > if ( pos == string::npos ) > seg[str] = ""; > else > seg[str.substr(0,pos)] = str.substr(pos, str.size()); > } > >#if !defined ITL_NO_SSTREAM > template > void parser::get(const string& flag, int& value, const int& d); > template > void parser::get(const string& flag, double& value, const double& d); > template > void parser::get(const string& flag, bool& value, const bool& d); >#endif >} > > > >------------------------------------------------------------------------ > >#include "mtl/matrix.h" >#include "mtl/mtl.h" >#include "mtl/utils.h" >#include <itl/interface/mtl.h> > >#define __DEBUG__ // itl debug on > >#define __BICGSTAB__ // Bi-Conjugate Gradient Stablilised Method >#ifdef __BICGSTAB__ > #include "itl/preconditioner/ilu.h" > #include "itl/krylov/bicgstab.h" >#endif > >//#define __BICG__ // Bi-Conjugate Gradient Method >#ifdef __BICG__ > #include "itl/preconditioner/ilu.h" > #include "itl/krylov/bicg.h" >#endif > >//#define __CG__ // Conjugate Gradient Method >#ifdef __CG__ > #include "itl/preconditioner/cholesky.h" > #include "itl/krylov/cg.h" >#endif > >#include "laplacian.h" >#include "parser.h" > >using namespace mtl; >using namespace itl; > >#include "mtl/matrix_market_stream.h" >#include <iostream> >#include <fstream> >#include <stdio.h> > >using std::cin; >using std::ios; >using std::ofstream; >using std::ifstream; >using std::cerr; >using std::cout; >using std::endl; >using std::parser; > >typedef double Type; >typedef matrix< Type, rectangle<>, array< compressed<> >, row_major >::type Matrix; > >int main (int argc, char* argv[]) { > > int converged; > int mx, my, max_it; > double ksp_atol, ksp_rtol; > int N; > int jj; > char *mtxfilename; > > if ( argc == 1 ) { > cout << argv[0] << " --help will get your the usage of flags." << endl; > } > > parser myparser(argc, argv); > > myparser.register_flag("-file", 1, "name of Matrix Market format input file"); > myparser.register_flag("-mx", 1, "number of points in x axis in the mesh"); > myparser.register_flag("-my", 1, "number of points in y axis in the mesh"); > myparser.register_flag("-max_it", 1, "maximal iteration allowed"); > myparser.register_flag("-ksp_atol", 1, "Absolute tolerance in KSP iteration"); > myparser.register_flag("-ksp_rtol", 1, "Relative tolerance in KSP iteration"); > > myparser.help(argv[0]); > > myparser.get("-file", mtxfilename, "bp__1600.mtx"); > myparser.get("-mx", mx, 16 ); > myparser.get("-my", my, mx ); > myparser.get("-max_it", max_it, 60 ); > myparser.get("-ksp_atol", ksp_atol ); > myparser.get("-ksp_rtol", ksp_rtol, 1.0e-6 ); > > N = mx * my; > > matrix_market_stream<Type> mms(mtxfilename); > Matrix A(mms); > > generate_laplacian_2D(A, mx, my); > dense1D<Type> x(A.nrows(), Type(0)); > dense1D<Type> b(A.ncols()); > for (dense1D<Type>::iterator i=b.begin(); i!=b.end(); i++) > *i = 1; // initialize all elements of b vector to 1 > > #ifdef __BICG__ > ILU<Matrix> precond(A); > noisy_iteration<Type> iter(b, max_it, ksp_rtol, ksp_atol); > converged = bicg(A, x, b, precond(), iter); //gmres algorithm > cout << endl << " Solving " << mtxfilename << " using itl/bicg" << endl; > #endif // __BICG__ > > #ifdef __CG__ > cholesky<Matrix> precond(A); > cholesky<Matrix>::Precond p = precond(); // identity_preconditioner p; > noisy_iteration<double> iter(b, max_it, ksp_rtol, ksp_atol); > converged = cg(A, x, b, p, iter); //gmres algorithm > cout << endl << " Solving " << mtxfilename << " using itl/cg" << endl; > #endif // __CG__ > > #ifdef __BICGSTAB__ > ILU<Matrix> precond(A); > noisy_iteration<double> iter(b, max_it, ksp_rtol, ksp_atol); > converged = bicgstab(A, x, b, precond(), iter); //gmres algorithm > cout << endl << " Solving " << mtxfilename << " using itl/bicgstab" << endl; > #endif // __BICGSTAB__ > > //verify the result > // > dense1D<Type> b1(A.ncols()); > itl::mult(A, x, b1); > itl::add(b1, itl::scaled(b, -1.), b1); > > // report results on VDU > // > cout << endl; > cout << " Summary of results for " << mtxfilename << endl; > cout << "-------------------------------------------------------- " << endl; > cout << " converged " << (converged ? "Y" : "N") << endl; > cout << " # iterations " << iter.iterations() << endl; > cout << " normb " << iter.normb() << endl; > cout << " final residual " << iter.resid() << endl; > cout << " True Residual " << itl::two_norm(b1) << endl; > cout << " Target relative tolerance " << ksp_rtol << endl; > cout << " Target absolute tolerance " << ksp_atol << endl; > cout << " Achieved relative tolerance " << iter.resid()/iter.normb() << endl; > cout << "-------------------------------------------------------- " << endl; > cout << endl; > > return 0; >} > > > > >------------------------------------------------------------------------ > >_______________________________________________ >This list is archived at http://www.lsc.nd.edu/MailArchives/mtl-devel/ > _______________________________________________ This list is archived at http://www.osl.iu.edu/MailArchives/mtl-devel/