42 #ifndef __Belos_ProjectedLeastSquaresSolver_hpp 
   43 #define __Belos_ProjectedLeastSquaresSolver_hpp 
   50 #include "Teuchos_oblackholestream.hpp" 
   53 #include "Teuchos_StandardParameterEntryValidators.hpp" 
   75       template<
class Scalar>
 
   77       printMatrix (std::ostream& out,
 
   78                    const std::string& name,
 
   83         const int numRows = A.
numRows();
 
   84         const int numCols = A.
numCols();
 
   86         out << name << 
" = " << endl << 
'[';
 
   89           for (
int i = 0; i < numRows; ++i) {
 
   96           for (
int i = 0; i < numRows; ++i) {
 
   97             for (
int j = 0; j < numCols; ++j) {
 
  101               } 
else if (i < numRows-1) {
 
  112       template<
class Scalar>
 
  114       print (std::ostream& out,
 
  116              const std::string& linePrefix)
 
  120         const int numRows = A.
numRows();
 
  121         const int numCols = A.
numCols();
 
  123         out << linePrefix << 
'[';
 
  126           for (
int i = 0; i < numRows; ++i) {
 
  133           for (
int i = 0; i < numRows; ++i) {
 
  134             for (
int j = 0; j < numCols; ++j) {
 
  136                 out << linePrefix << 
"  ";
 
  141               } 
else if (i < numRows-1) {
 
  147         out << linePrefix << 
']' << endl;
 
  158     template<
class Scalar>
 
  238         H (maxNumIterations+1, maxNumIterations),
 
  239         R (maxNumIterations+1, maxNumIterations),
 
  240         y (maxNumIterations+1, 1),
 
  241         z (maxNumIterations+1, 1),
 
  274         const Scalar initialResidualNorm (beta);
 
  275         z(0,0) = initialResidualNorm;
 
  293                           const int maxNumIterations)
 
  299                            "ProjectedLeastSquaresProblem::reset: initial " 
  300                            "residual beta = " << beta << 
" < 0.");
 
  302                            "ProjectedLeastSquaresProblem::reset: maximum number " 
  303                            "of iterations " << maxNumIterations << 
" <= 0.");
 
  306           const int errcode = 
H.
reshape (maxNumIterations+1, maxNumIterations);
 
  308                              "Failed to reshape H into a " << (maxNumIterations+1)
 
  309                              << 
" x " << maxNumIterations << 
" matrix.");
 
  314           const int errcode = 
R.
reshape (maxNumIterations+1, maxNumIterations);
 
  316                              "Failed to reshape R into a " << (maxNumIterations+1)
 
  317                              << 
" x " << maxNumIterations << 
" matrix.");
 
  322           const int errcode = 
y.
reshape (maxNumIterations+1, 1);
 
  324                              "Failed to reshape y into a " << (maxNumIterations+1)
 
  325                              << 
" x " << 1 << 
" matrix.");
 
  330           const int errcode = 
z.
reshape (maxNumIterations+1, 1);
 
  332                              "Failed to reshape z into a " << (maxNumIterations+1)
 
  333                              << 
" x " << 1 << 
" matrix.");
 
  348     template<
class Scalar>
 
  372         for (
int i = 0; i < A.
numRows(); ++i) {
 
  373           for (
int j = 0; j < A.
numCols(); ++j) {
 
  385         for (
int j = 0; j < N; ++j) {
 
  386           for (
int i = 0; i <= j; ++i) {
 
  398         for (
int j = 0; j < N; ++j) {
 
  399           for (
int i = j+1; i < A.
numRows(); ++i) {
 
  430         A_22 = 
rcp (
new mat_type (
View, A, numRows2, numCols2, numRows1, numCols1));
 
  438         const int numRows = A.
numRows();
 
  439         const int numCols = A.
numCols();
 
  441         if (numRows == 0 || numCols == 0) {
 
  444           for (
int j = 0; j < numCols; ++j) {
 
  447             for (
int i = 0; i < numRows; ++i) {
 
  463         const int numRows = Y.
numRows();
 
  464         const int numCols = Y.
numCols();
 
  467                            std::invalid_argument, 
"Dimensions of X and Y don't " 
  469                            << 
", and Y is " << numRows << 
" x " << numCols << 
".");
 
  470         for (
int j = 0; j < numCols; ++j) {
 
  471           for (
int i = 0; i < numRows; ++i) {
 
  472             Y(i,j) += alpha * X(i,j);
 
  481         const int numRows = A.
numRows();
 
  482         const int numCols = A.
numCols();
 
  486           std::invalid_argument,
 
  487           "matAdd: The input matrices A and B have incompatible dimensions.  " 
  488           "A is " << numRows << 
" x " << numCols << 
", but B is " <<
 
  490         if (numRows == 0 || numCols == 0) {
 
  493           for (
int j = 0; j < numCols; ++j) {
 
  497             for (
int i = 0; i < numRows; ++i) {
 
  508         const int numRows = A.
numRows();
 
  509         const int numCols = A.
numCols();
 
  513           std::invalid_argument,
 
  514           "matSub: The input matrices A and B have incompatible dimensions.  " 
  515           "A is " << numRows << 
" x " << numCols << 
", but B is " <<
 
  517         if (numRows == 0 || numCols == 0) {
 
  520           for (
int j = 0; j < numCols; ++j) {
 
  524             for (
int i = 0; i < numRows; ++i) {
 
  540                            std::invalid_argument,
 
  541                            "rightUpperTriSolve: R and B have incompatible " 
  542                            "dimensions.  B has " << B.
numCols() << 
" columns, " 
  543                            "but R has " << R.
numRows() << 
" rows.");
 
  567                            std::invalid_argument,
 
  568                            "matMatMult: The input matrices A and B have " 
  569                            "incompatible dimensions.  A is " << A.
numRows()
 
  570                            << 
" x " << A.
numCols() << 
", but B is " 
  573                            std::invalid_argument,
 
  574                            "matMatMult: The input matrix A and the output " 
  575                            "matrix C have incompatible dimensions.  A has " 
  579                            std::invalid_argument,
 
  580                            "matMatMult: The input matrix B and the output " 
  581                            "matrix C have incompatible dimensions.  B has " 
  582                            << B.
numCols() << 
" columns, but C has " 
  583                            << C.
numCols() << 
" columns.");
 
  601         for (
int j = 0; j < A.
numCols(); ++j) {
 
  602           if (upperTriangular) {
 
  603             for (
int i = 0; i <= j && i < A.
numRows(); ++i) {
 
  609             for (
int i = 0; i < A.
numRows(); ++i) {
 
  624       std::pair<bool, std::pair<magnitude_type, magnitude_type> >
 
  631         for (
int j = 0; j < A.
numCols(); ++j) {
 
  635           for (
int i = 0; i <= j && i < A.
numRows(); ++i) {
 
  637             upperTri += A_ij_mag * A_ij_mag;
 
  640           for (
int i = j+1; i < A.
numRows(); ++i) {
 
  642             lowerTri += A_ij_mag * A_ij_mag;
 
  648         return std::make_pair (count == 0, std::make_pair (lowerTri, upperTri));
 
  657       std::pair<bool, std::pair<magnitude_type, magnitude_type> >
 
  664         for (
int j = 0; j < A.
numCols(); ++j) {
 
  668           for (
int i = 0; i <= j+1 && i < A.
numRows(); ++i) {
 
  670             upper += A_ij_mag * A_ij_mag;
 
  673           for (
int i = j+2; i < A.
numRows(); ++i) {
 
  675             lower += A_ij_mag * A_ij_mag;
 
  681         return std::make_pair (count == 0, std::make_pair (lower, upper));
 
  692                              const char* 
const matrixName)
 const 
  694         std::pair<bool, std::pair<magnitude_type, magnitude_type> > result =
 
  699                            << 
" matrix " << matrixName << 
" is not upper " 
  700                            "triangular.  ||tril(A)||_F = " 
  701                            << result.second.first << 
" and ||A||_F = " 
  702                            << result.second.second << 
".");
 
  713                              const char* 
const matrixName)
 const 
  715         std::pair<bool, std::pair<magnitude_type, magnitude_type> > result =
 
  720                            << 
" matrix " << matrixName << 
" is not upper " 
  721                            "triangular.  ||tril(A(2:end, :))||_F = " 
  722                            << result.second.first << 
" and ||A||_F = " 
  723                            << result.second.second << 
".");
 
  743                              const char* 
const matrixName,
 
  746         std::pair<bool, std::pair<magnitude_type, magnitude_type> > result =
 
  752                                       result.second.first :
 
  753                                       result.second.first / result.second.second);
 
  756                              << 
" matrix " << matrixName << 
" is not upper " 
  757                              "triangular.  ||tril(A(2:end, :))||_F " 
  758                              << (result.second.second == 
STM::zero() ? 
"" : 
" / ||A||_F")
 
  759                              << 
" = " << err << 
" > " << relativeTolerance << 
".");
 
  776                                const char* 
const matrixName,
 
  777                                const int minNumRows,
 
  778                                const int minNumCols)
 const 
  781                            std::invalid_argument,
 
  782                            "The matrix " << matrixName << 
" is " << A.
numRows()
 
  783                            << 
" x " << A.
numCols() << 
", and therefore does not " 
  784                            "satisfy the minimum dimensions " << minNumRows
 
  785                            << 
" x " << minNumCols << 
".");
 
  801                              const char* 
const matrixName,
 
  803                              const int numCols)
 const 
  806                            std::invalid_argument,
 
  807                            "The matrix " << matrixName << 
" is supposed to be " 
  808                            << numRows << 
" x " << numCols << 
", but is " 
  843       const char* strings[] = {
"None", 
"Some", 
"Lots"};
 
  845                          std::invalid_argument,
 
  846                          "Invalid enum value " << x << 
".");
 
  847       return std::string (strings[x]);
 
  854       const char* strings[] = {
"None", 
"Some", 
"Lots"};
 
  856         if (x == strings[r]) {
 
  861                          "Invalid robustness string " << x << 
".");
 
  877       using Teuchos::stringToIntegralParameterEntryValidator;
 
  884       docs[0] = 
"Use the BLAS' triangular solve.  This may result in Inf or " 
  885         "NaN output if the triangular matrix is rank deficient.";
 
  886       docs[1] = 
"Robustness somewhere between \"None\" and \"Lots\".";
 
  887       docs[2] = 
"Solve the triangular system in a least-squares sense, using " 
  888         "an SVD-based algorithm.  This will always succeed, though the " 
  889         "solution may not make sense for GMRES.";
 
  894       const std::string pname (
"Robustness of Projected Least-Squares Solve");
 
  896       return stringToIntegralParameterEntryValidator<ERobustness> (strs, docs,
 
  962     template<
class Scalar>
 
 1004         defaultRobustness_ (defaultRobustness)
 
 1024         return updateColumnGivens (problem.
H, problem.
R, problem.
y, problem.
z,
 
 1047         return updateColumnsGivens (problem.
H, problem.
R, problem.
y, problem.
z,
 
 1069         solveGivens (problem.
y, problem.
R, problem.
z, curCol);
 
 1076       std::pair<int, bool>
 
 1123       std::pair<int, bool>
 
 1131                            "The output X and right-hand side B have different " 
 1132                            "numbers of rows.  X has " << X.
numRows() << 
" rows" 
 1133                            ", and B has " << B.
numRows() << 
" rows.");
 
 1139                            "The output X has more columns than the " 
 1140                            "right-hand side B.  X has " << X.
numCols()
 
 1141                            << 
" columns and B has " << B.
numCols()
 
 1159       std::pair<int, bool>
 
 1174       std::pair<int, bool>
 
 1189                            "The input matrix R has fewer columns than rows.  " 
 1190                            "R is " << M << 
" x " << N << 
".");
 
 1196                              "The input/output matrix X has only " 
 1197                              << X.
numRows() << 
" rows, but needs at least " 
 1198                              << N << 
" rows to match the matrix for a " 
 1199                              "left-side solve R \\ X.");
 
 1202                              "The input/output matrix X has only " 
 1203                              << X.
numCols() << 
" columns, but needs at least " 
 1204                              << N << 
" columns to match the matrix for a " 
 1205                              "right-side solve X / R.");
 
 1209                            std::invalid_argument,
 
 1210                            "Invalid robustness value " << robustness << 
".");
 
 1218                              "There " << (count != 1 ? 
"are" : 
"is")
 
 1219                              << 
" " << count << 
" Inf or NaN entr" 
 1220                              << (count != 1 ? 
"ies" : 
"y")
 
 1221                              << 
" in the upper triangle of R.");
 
 1224                              "There " << (count != 1 ? 
"are" : 
"is")
 
 1225                              << 
" " << count << 
" Inf or NaN entr" 
 1226                              << (count != 1 ? 
"ies" : 
"y") << 
" in the " 
 1227                              "right-hand side(s) X.");
 
 1232         bool foundRankDeficiency = 
false;
 
 1260             warn_ << 
"Upper triangular solve: Found Infs and/or NaNs in the " 
 1261               "solution after using the fast algorithm.  Retrying using a more " 
 1262               "robust algorithm." << std::endl;
 
 1282               rank = solveLeastSquaresUsingSVD (R_copy, X);
 
 1297               rank = solveLeastSquaresUsingSVD (R_star, X_star);
 
 1303               foundRankDeficiency = 
true;
 
 1308                              "Should never get here!  Invalid robustness value " 
 1309                              << robustness << 
".  Please report this bug to the " 
 1310                              "Belos developers.");
 
 1312         return std::make_pair (rank, foundRankDeficiency);
 
 1330         out << 
"Testing Givens rotations:" << endl;
 
 1333         out << 
"  x = " << x << 
", y = " << y << endl;
 
 1335         Scalar theCosine, theSine, result;
 
 1337         computeGivensRotation (x, y, theCosine, theSine, result);
 
 1338         out << 
"-- After computing rotation:" << endl;
 
 1339         out << 
"---- cos,sin = " << theCosine << 
"," << theSine << endl;
 
 1340         out << 
"---- x = " << x << 
", y = " << y
 
 1341             << 
", result = " << result << endl;
 
 1343         blas.
ROT (1, &x, 1, &y, 1, &theCosine, &theSine);
 
 1344         out << 
"-- After applying rotation:" << endl;
 
 1345         out << 
"---- cos,sin = " << theCosine << 
"," << theSine << endl;
 
 1346         out << 
"---- x = " << x << 
", y = " << y << endl;
 
 1387                         const bool testBlockGivens=
false,
 
 1388                         const bool extraVerbose=
false)
 
 1394                            "numCols = " << numCols << 
" <= 0.");
 
 1395         const int numRows = numCols + 1;
 
 1400         mat_type R_givens (numRows, numCols);
 
 1403         Array<Scalar> theCosines (numCols);
 
 1404         Array<Scalar> theSines (numCols);
 
 1406         mat_type R_blockGivens (numRows, numCols);
 
 1407         mat_type y_blockGivens (numRows, 1);
 
 1408         mat_type z_blockGivens (numRows, 1);
 
 1409         Array<Scalar> blockCosines (numCols);
 
 1410         Array<Scalar> blockSines (numCols);
 
 1411         const int panelWidth = std::min (3, numCols);
 
 1413         mat_type R_lapack (numRows, numCols);
 
 1418         makeRandomProblem (H, z);
 
 1420           printMatrix<Scalar> (out, 
"H", H);
 
 1421           printMatrix<Scalar> (out, 
"z", z);
 
 1427         if (testBlockGivens) {
 
 1428           z_blockGivens.
assign (z);
 
 1438         for (
int curCol = 0; curCol < numCols; ++curCol) {
 
 1439           residualNormGivens = updateColumnGivens (H, R_givens, y_givens, z_givens,
 
 1440                                                    theCosines, theSines, curCol);
 
 1442         solveGivens (y_givens, R_givens, z_givens, numCols-1);
 
 1447         if (testBlockGivens) {
 
 1448           const bool testBlocksAtATime = 
true;
 
 1449           if (testBlocksAtATime) {
 
 1451             for (
int startCol = 0; startCol < numCols; startCol += panelWidth) {
 
 1452               int endCol = std::min (startCol + panelWidth - 1, numCols - 1);
 
 1453               residualNormBlockGivens =
 
 1454                 updateColumnsGivens (H, R_blockGivens, y_blockGivens, z_blockGivens,
 
 1455                                      blockCosines, blockSines, startCol, endCol);
 
 1461             for (
int startCol = 0; startCol < numCols; ++startCol) {
 
 1462               residualNormBlockGivens =
 
 1463                 updateColumnsGivens (H, R_blockGivens, y_blockGivens, z_blockGivens,
 
 1464                                      blockCosines, blockSines, startCol, startCol);
 
 1471           solveGivens (y_blockGivens, R_blockGivens, z_blockGivens, numCols-1);
 
 1476           solveLapack (H, R_lapack, y_lapack, z_lapack, numCols-1);
 
 1483           leastSquaresConditionNumber (H, z, residualNormLapack);
 
 1499           solutionError (y_givens_view, y_lapack_view);
 
 1500         const magnitude_type blockGivensSolutionError = testBlockGivens ?
 
 1501           solutionError (y_blockGivens_view, y_lapack_view) :
 
 1508           mat_type R_factorFromGivens (numCols, numCols);
 
 1509           mat_type R_factorFromBlockGivens (numCols, numCols);
 
 1510           mat_type R_factorFromLapack (numCols, numCols);
 
 1512           for (
int j = 0; j < numCols; ++j) {
 
 1513             for (
int i = 0; i <= j; ++i) {
 
 1514               R_factorFromGivens(i,j) = R_givens(i,j);
 
 1515               if (testBlockGivens) {
 
 1516                 R_factorFromBlockGivens(i,j) = R_blockGivens(i,j);
 
 1518               R_factorFromLapack(i,j) = R_lapack(i,j);
 
 1522           printMatrix<Scalar> (out, 
"R_givens", R_factorFromGivens);
 
 1523           printMatrix<Scalar> (out, 
"y_givens", y_givens_view);
 
 1524           printMatrix<Scalar> (out, 
"z_givens", z_givens);
 
 1526           if (testBlockGivens) {
 
 1527             printMatrix<Scalar> (out, 
"R_blockGivens", R_factorFromBlockGivens);
 
 1528             printMatrix<Scalar> (out, 
"y_blockGivens", y_blockGivens_view);
 
 1529             printMatrix<Scalar> (out, 
"z_blockGivens", z_blockGivens);
 
 1532           printMatrix<Scalar> (out, 
"R_lapack", R_factorFromLapack);
 
 1533           printMatrix<Scalar> (out, 
"y_lapack", y_lapack_view);
 
 1534           printMatrix<Scalar> (out, 
"z_lapack", z_lapack);
 
 1540         out << 
"||H||_F = " << H_norm << endl;
 
 1542         out << 
"||H y_givens - z||_2 / ||H||_F = " 
 1543             << leastSquaresResidualNorm (H, y_givens_view, z) / H_norm << endl;
 
 1544         if (testBlockGivens) {
 
 1545           out << 
"||H y_blockGivens - z||_2 / ||H||_F = " 
 1546               << leastSquaresResidualNorm (H, y_blockGivens_view, z) / H_norm << endl;
 
 1548         out << 
"||H y_lapack - z||_2 / ||H||_F = " 
 1549             << leastSquaresResidualNorm (H, y_lapack_view, z) / H_norm << endl;
 
 1551         out << 
"||y_givens - y_lapack||_2 / ||y_lapack||_2 = " 
 1552             << givensSolutionError << endl;
 
 1553         if (testBlockGivens) {
 
 1554           out << 
"||y_blockGivens - y_lapack||_2 / ||y_lapack||_2 = " 
 1555               << blockGivensSolutionError << endl;
 
 1558         out << 
"Least-squares condition number = " 
 1559             << leastSquaresCondNum << endl;
 
 1577           wiggleFactor * leastSquaresCondNum;
 
 1579           solutionErrorBoundFactor * 
STS::eps();
 
 1580         out << 
"Solution error bound: " << solutionErrorBoundFactor
 
 1581             << 
" * eps = " << solutionErrorBound << endl;
 
 1594           } 
else if (givensSolutionError > solutionErrorBound) {
 
 1596           } 
else if (testBlockGivens) {
 
 1599             } 
else if (blockGivensSolutionError > solutionErrorBound) {
 
 1627                             const int testProblemSize,
 
 1629                             const bool verbose=
false)
 
 1637         std::ostream& verboseOut = verbose ? out : blackHole;
 
 1639         verboseOut << 
"Testing upper triangular solves" << endl;
 
 1643         verboseOut << 
"-- Generating test matrix" << endl;
 
 1644         const int N = testProblemSize;
 
 1647         for (
int j = 0; j < N; ++j) {
 
 1648           for (
int i = 0; i <= j; ++i) {
 
 1668         verboseOut << 
"-- Solving RX=B" << endl;
 
 1672         mat_type Resid (N, 1);
 
 1676         verboseOut << 
"---- ||R*X - B||_F = " << Resid.
normFrobenius() << endl;
 
 1677         verboseOut << 
"---- ||R||_F ||X||_F + ||B||_F = " 
 1689         mat_type B_star (1, N);
 
 1691         mat_type B_star_copy (1, N);
 
 1692         B_star_copy.
assign (B_star);
 
 1694         verboseOut << 
"-- Solving YR=B^*" << endl;
 
 1698         mat_type Resid2 (1, N);
 
 1699         Resid2.
assign (B_star_copy);
 
 1701         verboseOut << 
"---- ||Y*R - B^*||_F = " << Resid2.
normFrobenius() << endl;
 
 1702         verboseOut << 
"---- ||Y||_F ||R||_F + ||B^*||_F = " 
 1716       std::ostream& warn_;
 
 1745                              "solveLeastSquaresUsingSVD: The input matrix A " 
 1746                              "contains " << count << 
"Inf and/or NaN entr" 
 1747                              << (count != 1 ? 
"ies" : 
"y") << 
".");
 
 1750                              "solveLeastSquaresUsingSVD: The input matrix X " 
 1751                              "contains " << count << 
"Inf and/or NaN entr" 
 1752                              << (count != 1 ? 
"ies" : 
"y") << 
".");
 
 1754         const int N = std::min (A.numRows(), A.numCols());
 
 1765         Array<magnitude_type> singularValues (N);
 
 1773         Array<magnitude_type> rwork (1);
 
 1775           rwork.resize (std::max (1, 5 * N));
 
 1782         lapack.GELSS (A.numRows(), A.numCols(), X.numCols(),
 
 1783                       A.values(), A.stride(), X.values(), X.stride(),
 
 1784                       &singularValues[0], rankTolerance, &rank,
 
 1785                       &lworkScalar, -1, &rwork[0], &info);
 
 1787                            "_GELSS workspace query returned INFO = " 
 1788                            << info << 
" != 0.");
 
 1789         const int lwork = 
static_cast<int> (
STS::real (lworkScalar));
 
 1791                            "_GELSS workspace query returned LWORK = " 
 1792                            << lwork << 
" < 0.");
 
 1794         Array<Scalar> work (std::max (1, lwork));
 
 1796         lapack.GELSS (A.numRows(), A.numCols(), X.numCols(),
 
 1797                       A.values(), A.stride(), X.values(), X.stride(),
 
 1798                       &singularValues[0], rankTolerance, &rank,
 
 1799                       &work[0], lwork, &rwork[0], &info);
 
 1801                            "_GELSS returned INFO = " << info << 
" != 0.");
 
 1817         const int numRows = curCol + 2;
 
 1827                                            R_view, z_view, defaultRobustness_);
 
 1841         for (
int j = 0; j < H.numCols(); ++j) {
 
 1842           for (
int i = j+2; i < H.numRows(); ++i) {
 
 1854           const int numTrials = 1000;
 
 1856           for (
int trial = 0; trial < numTrials && z_init == 
STM::zero(); ++trial) {
 
 1860                              "After " << numTrials << 
" trial" 
 1861                              << (numTrials != 1 ? 
"s" : 
"")
 
 1862                              << 
", we were unable to generate a nonzero pseudo" 
 1863                              "random real number.  This most likely indicates a " 
 1864                              "broken pseudorandom number generator.");
 
 1877       computeGivensRotation (
const Scalar& x,
 
 1885         const bool useLartg = 
false;
 
 1890           lapack.LARTG (x, y, &theCosine, &theSine, &result);
 
 1899           blas.ROTG (&x_temp, &y_temp, &theCosine, &theSine);
 
 1912         const int numRows = A.numRows();
 
 1913         const int numCols = A.numCols();
 
 1915                            std::invalid_argument,
 
 1916                            "The sigmas array is only of length " << sigmas.
size()
 
 1917                            << 
", but must be of length at least " 
 1918                            << std::min (numRows, numCols)
 
 1919                            << 
" in order to hold all the singular values of the " 
 1925         mat_type A_copy (numRows, numCols);
 
 1932         Array<magnitude_type> rwork (std::max (std::min (numRows, numCols) - 1, 1));
 
 1933         lapack.GESVD (
'N', 
'N', numRows, numCols,
 
 1934                       A_copy.values(), A_copy.stride(), &sigmas[0],
 
 1935                       (Scalar*) NULL, 1, (Scalar*) NULL, 1,
 
 1936                       &lworkScalar, -1, &rwork[0], &info);
 
 1938         TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::logic_error,
 
 1939                            "LAPACK _GESVD workspace query failed with INFO = "
 
 1941         const 
int lwork = static_cast<
int> (STS::real (lworkScalar));
 
 1942         TEUCHOS_TEST_FOR_EXCEPTION(lwork < 0, std::logic_error,
 
 1943                            "LAPACK _GESVD workspace query returned LWORK = "
 
 1944                            << lwork << " < 0.");
 
 1947         Teuchos::Array<Scalar> work (std::max (1, lwork));
 
 1950         lapack.GESVD ('N', 'N', numRows, numCols,
 
 1951                       A_copy.values(), A_copy.stride(), &sigmas[0],
 
 1952                       (Scalar*) NULL, 1, (Scalar*) NULL, 1,
 
 1953                       &work[0], lwork, &rwork[0], &info);
 
 1954         TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::logic_error,
 
 1955                            "LAPACK _GESVD failed with INFO = " << info << ".");
 
 1966       extremeSingularValues (const 
mat_type& A)
 
 1970         const int numRows = A.numRows();
 
 1971         const int numCols = A.numCols();
 
 1973         Array<magnitude_type> sigmas (std::min (numRows, numCols));
 
 1974         singularValues (A, sigmas);
 
 1975         return std::make_pair (sigmas[0], sigmas[std::min(numRows, numCols) - 1]);
 
 1989       leastSquaresConditionNumber (
const mat_type& A,
 
 1991                                    const magnitude_type& residualNorm)
 
 1994         const std::pair<magnitude_type, magnitude_type> sigmaMaxMin =
 
 1995           extremeSingularValues (A);
 
 2000                            "The test matrix is rank deficient; LAPACK's _GESVD " 
 2001                            "routine reports that its smallest singular value is " 
 2005         const magnitude_type A_cond = sigmaMaxMin.first / sigmaMaxMin.second;
 
 2011         const magnitude_type sinTheta = residualNorm / b.normFrobenius();
 
 2023         const magnitude_type cosTheta = (sinTheta > 
STM::one()) ?
 
 2029         const magnitude_type tanTheta = sinTheta / cosTheta;
 
 2032         return 2 * A_cond / cosTheta + tanTheta * A_cond * A_cond;
 
 2037       leastSquaresResidualNorm (
const mat_type& A,
 
 2041         mat_type r (b.numRows(), b.numCols());
 
 2045         LocalDenseMatrixOps<Scalar> ops;
 
 2047         return r.normFrobenius ();
 
 2055       solutionError (
const mat_type& x_approx,
 
 2058         const int numRows = x_exact.numRows();
 
 2059         const int numCols = x_exact.numCols();
 
 2061         mat_type x_diff (numRows, numCols);
 
 2062         for (
int j = 0; j < numCols; ++j) {
 
 2063           for (
int i = 0; i < numRows; ++i) {
 
 2064             x_diff(i,j) = x_exact(i,j) - x_approx(i,j);
 
 2067         const magnitude_type scalingFactor = x_exact.normFrobenius();
 
 2070         return x_diff.normFrobenius() /
 
 2121       updateColumnGivens (
const mat_type& H,
 
 2132         const int numRows = curCol + 2; 
 
 2133         const int LDR = R.stride();
 
 2134         const bool extraDebug = 
false;
 
 2137           cerr << 
"updateColumnGivens: curCol = " << curCol << endl;
 
 2151         R_col.assign (H_col);
 
 2154           printMatrix<Scalar> (cerr, 
"R_col before ", R_col);
 
 2160         for (
int j = 0; j < curCol; ++j) {
 
 2163           Scalar theCosine = theCosines[j];
 
 2164           Scalar theSine = theSines[j];
 
 2167             cerr << 
"  j = " << j << 
": (cos,sin) = " 
 2168                  << theCosines[j] << 
"," << theSines[j] << endl;
 
 2170           blas.ROT (1, &R_col(j,0), LDR, &R_col(j+1,0), LDR,
 
 2171                     &theCosine, &theSine);
 
 2173         if (extraDebug && curCol > 0) {
 
 2174           printMatrix<Scalar> (cerr, 
"R_col after applying previous " 
 2175                                "Givens rotations", R_col);
 
 2180         Scalar theCosine, theSine, result;
 
 2181         computeGivensRotation (R_col(curCol,0), R_col(curCol+1,0),
 
 2182                                theCosine, theSine, result);
 
 2183         theCosines[curCol] = theCosine;
 
 2184         theSines[curCol] = theSine;
 
 2187           cerr << 
"  New cos,sin = " << theCosine << 
"," << theSine << endl;
 
 2193         R_col(curCol, 0) = result;
 
 2197           printMatrix<Scalar> (cerr, 
"R_col after applying current " 
 2198                                "Givens rotation", R_col);
 
 2206         const int LDZ = z.stride();
 
 2207         blas.ROT (z.numCols(),
 
 2208                   &z(curCol,0), LDZ, &z(curCol+1,0), LDZ,
 
 2209                   &theCosine, &theSine);
 
 2215           printMatrix<Scalar> (cerr, 
"z_after", z);
 
 2264         const int numRows = curCol + 2;
 
 2265         const int numCols = curCol + 1;
 
 2266         const int LDR = R.stride();
 
 2271         R_view.assign (H_view);
 
 2283         lapack.GELS (
'N', numRows, numCols, y_view.numCols(),
 
 2284                      NULL, LDR, NULL, y_view.stride(),
 
 2285                      &lworkScalar, -1, &info);
 
 2287                            "LAPACK _GELS workspace query failed with INFO = " 
 2288                            << info << 
", for a " << numRows << 
" x " << numCols
 
 2289                            << 
" matrix with " << y_view.numCols()
 
 2290                            << 
" right hand side" 
 2291                            << ((y_view.numCols() != 1) ? 
"s" : 
"") << 
".");
 
 2294                            "LAPACK _GELS workspace query returned an LWORK with " 
 2295                            "negative real part: LWORK = " << lworkScalar
 
 2296                            << 
".  That should never happen.  Please report this " 
 2297                            "to the Belos developers.");
 
 2300                            "LAPACK _GELS workspace query returned an LWORK with " 
 2301                            "nonzero imaginary part: LWORK = " << lworkScalar
 
 2302                            << 
".  That should never happen.  Please report this " 
 2303                            "to the Belos developers.");
 
 2309         const int lwork = std::max (1, static_cast<int> (
STS::real (lworkScalar)));
 
 2317         lapack.GELS (
'N', numRows, numCols, y_view.numCols(),
 
 2318                      R_view.values(), R_view.stride(),
 
 2319                      y_view.values(), y_view.stride(),
 
 2320                      (lwork > 0 ? &work[0] : (Scalar*) NULL),
 
 2324                            "Solving projected least-squares problem with LAPACK " 
 2325                            "_GELS failed with INFO = " << info << 
", for a " 
 2326                            << numRows << 
" x " << numCols << 
" matrix with " 
 2327                            << y_view.numCols() << 
" right hand side" 
 2328                            << (y_view.numCols() != 1 ? 
"s" : 
"") << 
".");
 
 2346       updateColumnsGivens (
const mat_type& H,
 
 2356                            "updateColumnGivens: startCol = " << startCol
 
 2357                            << 
" > endCol = " << endCol << 
".");
 
 2358         magnitude_type lastResult = 
STM::zero();
 
 2360         for (
int curCol = startCol; curCol <= endCol; ++curCol) {
 
 2361           lastResult = updateColumnGivens (H, R, y, z, theCosines, theSines, curCol);
 
 2379       updateColumnsGivensBlock (
const mat_type& H,
 
 2388         const int numRows = endCol + 2;
 
 2389         const int numColsToUpdate = endCol - startCol + 1;
 
 2390         const int LDR = R.stride();
 
 2397           R_view.assign (H_view);
 
 2405         for (
int j = 0; j < startCol; ++j) {
 
 2406           blas.ROT (numColsToUpdate,
 
 2407                     &R(j, startCol), LDR, &R(j+1, startCol), LDR,
 
 2408                     &theCosines[j], &theSines[j]);
 
 2412         for (
int curCol = startCol; curCol < endCol; ++curCol) {
 
 2415           for (
int j = startCol; j < curCol; ++j) {
 
 2416             blas.ROT (1, &R(j, curCol), LDR, &R(j+1, curCol), LDR,
 
 2417                       &theCosines[j], &theSines[j]);
 
 2421           Scalar theCosine, theSine, result;
 
 2422           computeGivensRotation (R(curCol, curCol), R(curCol+1, curCol),
 
 2423                                  theCosine, theSine, result);
 
 2424           theCosines[curCol] = theCosine;
 
 2425           theSines[curCol] = theSine;
 
 2430           R(curCol+1, curCol) = result;
 
 2438           const int LDZ = z.stride();
 
 2439           blas.ROT (z.numCols(),
 
 2440                     &z(curCol,0), LDZ, &z(curCol+1,0), LDZ,
 
 2441                     &theCosine, &theSine);
 
 2453 #endif // __Belos_ProjectedLeastSquaresSolver_hpp 
ScalarType * values() const 
 
Collection of types and exceptions used within the Belos solvers. 
 
Teuchos::SerialDenseMatrix< int, Scalar > z
Current right-hand side of the projected least-squares problem. 
 
void TRSM(ESide side, EUplo uplo, ETransp transa, EDiag diag, const OrdinalType &m, const OrdinalType &n, const alpha_type alpha, const A_type *A, const OrdinalType &lda, ScalarType *B, const OrdinalType &ldb) const 
 
Teuchos::SerialDenseMatrix< int, Scalar > y
Current solution of the projected least-squares problem. 
 
Teuchos::Array< Scalar > theCosines
Array of cosines from the computed Givens rotations. 
 
void ensureMinimumDimensions(const mat_type &A, const char *const matrixName, const int minNumRows, const int minNumCols) const 
Ensure that the matrix A is at least minNumRows by minNumCols. 
 
std::pair< int, bool > solveUpperTriangularSystemInPlace(Teuchos::ESide side, mat_type &X, const mat_type &R, const ERobustness robustness)
Solve square upper triangular linear system(s) in place. 
 
ProjectedLeastSquaresSolver(std::ostream &warnStream, const ERobustness defaultRobustness=ROBUSTNESS_NONE)
Constructor. 
 
void matSub(mat_type &A, const mat_type &B) const 
A := A - B. 
 
static magnitudeType eps()
 
void ROT(const OrdinalType &n, ScalarType *dx, const OrdinalType &incx, ScalarType *dy, const OrdinalType &incy, MagnitudeType *c, ScalarType *s) const 
 
void conjugateTransposeOfUpperTriangular(mat_type &L, const mat_type &R) const 
L := (conjugate) transpose of R (upper triangular). 
 
int infNaNCount(const mat_type &A, const bool upperTriangular=false) const 
Return the number of Inf or NaN entries in the matrix A. 
 
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
 
static magnitudeType real(T a)
 
std::string robustnessEnumToString(const ERobustness x)
Convert the given ERobustness enum value to a string. 
 
ERobustness robustnessStringToEnum(const std::string &x)
Convert the given robustness string value to an ERobustness enum. 
 
void GEMM(ETransp transa, ETransp transb, const OrdinalType &m, const OrdinalType &n, const OrdinalType &k, const alpha_type alpha, const A_type *A, const OrdinalType &lda, const B_type *B, const OrdinalType &ldb, const beta_type beta, ScalarType *C, const OrdinalType &ldc) const 
 
bool testGivensRotations(std::ostream &out)
Test Givens rotations. 
 
std::pair< int, bool > solveUpperTriangularSystem(Teuchos::ESide side, mat_type &X, const mat_type &R, const mat_type &B, const ERobustness robustness)
Solve the given square upper triangular linear system(s). 
 
ScalarTraits< ScalarType >::magnitudeType normFrobenius() const 
 
Methods for solving GMRES' projected least-squares problem. 
 
void zeroOutStrictLowerTriangle(mat_type &A) const 
Zero out everything below the diagonal of A. 
 
ProjectedLeastSquaresProblem(const int maxNumIterations)
Constructor. 
 
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
 
magnitude_type updateColumns(ProjectedLeastSquaresProblem< Scalar > &problem, const int startCol, const int endCol)
Update columns [startCol,endCol] of the projected least-squares problem. 
 
Teuchos::SerialDenseMatrix< int, Scalar > H
The upper Hessenberg matrix from GMRES. 
 
"Container" for the GMRES projected least-squares problem. 
 
int putScalar(const ScalarType value=Teuchos::ScalarTraits< ScalarType >::zero())
 
void reset(const typename Teuchos::ScalarTraits< Scalar >::magnitudeType beta)
Reset the projected least-squares problem. 
 
std::pair< int, bool > solveUpperTriangularSystemInPlace(Teuchos::ESide side, mat_type &X, const mat_type &R)
Solve square upper triangular linear system(s) in place. 
 
Scalar scalar_type
The template parameter of this class. 
 
void matScale(mat_type &A, const scalar_type &alpha) const 
A := alpha * A. 
 
void axpy(mat_type &Y, const scalar_type &alpha, const mat_type &X) const 
Y := Y + alpha * X. 
 
static magnitudeType imag(T a)
 
static bool isnaninf(const T &x)
 
Teuchos::ScalarTraits< Scalar >::magnitudeType magnitude_type
The type of the magnitude of scalar_type values. 
 
Teuchos::RCP< Teuchos::ParameterEntryValidator > robustnessValidator()
Make a ParameterList validator for ERobustness. 
 
void conjugateTranspose(mat_type &A_star, const mat_type &A) const 
A_star := (conjugate) transpose of A. 
 
static magnitudeType magnitude(T a)
 
OrdinalType numCols() const 
 
Teuchos::ScalarTraits< Scalar >::magnitudeType magnitude_type
The type of the magnitude of a scalar_type value. 
 
Teuchos::SerialDenseMatrix< int, Scalar > mat_type
The type of a dense matrix (or vector) of scalar_type. 
 
void solve(ProjectedLeastSquaresProblem< Scalar > &problem, const int curCol)
Solve the projected least-squares problem. 
 
bool testUpdateColumn(std::ostream &out, const int numCols, const bool testBlockGivens=false, const bool extraVerbose=false)
Test update and solve using Givens rotations. 
 
int reshape(OrdinalType numRows, OrdinalType numCols)
 
Teuchos::ScalarTraits< Scalar >::magnitudeType magnitude_type
The type of the magnitude of a scalar_type value. 
 
Teuchos::Array< Scalar > theSines
Array of sines from the computed Givens rotations. 
 
Scalar scalar_type
The type of the entries in the projected least-squares problem. 
 
std::pair< bool, std::pair< magnitude_type, magnitude_type > > isUpperHessenberg(const mat_type &A) const 
Is the matrix A upper Hessenberg? 
 
void matMatMult(const scalar_type &beta, mat_type &C, const scalar_type &alpha, const mat_type &A, const mat_type &B) const 
C := beta*C + alpha*A*B. 
 
void matAdd(mat_type &A, const mat_type &B) const 
A := A + B. 
 
Low-level operations on non-distributed dense matrices. 
 
void reallocateAndReset(const typename Teuchos::ScalarTraits< Scalar >::magnitudeType beta, const int maxNumIterations)
(Re)allocate and reset the projected least-squares problem. 
 
ERobustness
Robustness level of projected least-squares solver operations. 
 
bool testTriangularSolves(std::ostream &out, const int testProblemSize, const ERobustness robustness, const bool verbose=false)
Test upper triangular solves. 
 
static const bool isComplex
 
void ensureUpperHessenberg(const mat_type &A, const char *const matrixName) const 
Throw an exception if A is not (strictly) upper Hessenberg. 
 
std::pair< bool, std::pair< magnitude_type, magnitude_type > > isUpperTriangular(const mat_type &A) const 
Is the matrix A upper triangular / trapezoidal? 
 
std::pair< int, bool > solveUpperTriangularSystem(Teuchos::ESide side, mat_type &X, const mat_type &R, const mat_type &B)
Solve the given square upper triangular linear system(s). 
 
void partition(Teuchos::RCP< mat_type > &A_11, Teuchos::RCP< mat_type > &A_21, Teuchos::RCP< mat_type > &A_12, Teuchos::RCP< mat_type > &A_22, mat_type &A, const int numRows1, const int numRows2, const int numCols1, const int numCols2)
A -> [A_11, A_21, A_12, A_22]. 
 
Belos header file which uses auto-configuration information to include necessary C++ headers...
 
void rightUpperTriSolve(mat_type &B, const mat_type &R) const 
In Matlab notation: B = B / R, where R is upper triangular. 
 
void ensureUpperTriangular(const mat_type &A, const char *const matrixName) const 
Throw an exception if A is not upper triangular / trapezoidal. 
 
Teuchos::SerialDenseMatrix< int, Scalar > R
Upper triangular factor from the QR factorization of H. 
 
SerialDenseMatrix< OrdinalType, ScalarType > & assign(const SerialDenseMatrix< OrdinalType, ScalarType > &Source)
 
void ensureEqualDimensions(const mat_type &A, const char *const matrixName, const int numRows, const int numCols) const 
Ensure that the matrix A is exactly numRows by numCols. 
 
OrdinalType stride() const 
 
magnitude_type updateColumn(ProjectedLeastSquaresProblem< Scalar > &problem, const int curCol)
Update column curCol of the projected least-squares problem. 
 
OrdinalType numRows() const 
 
Scalar scalar_type
The template parameter of this class. 
 
Teuchos::SerialDenseMatrix< int, Scalar > mat_type
The type of a dense matrix (or vector) of scalar_type. 
 
void ensureUpperHessenberg(const mat_type &A, const char *const matrixName, const magnitude_type relativeTolerance) const 
Throw an exception if A is not "approximately" upper Hessenberg.