42 #ifndef __Belos_ProjectedLeastSquaresSolver_hpp
43 #define __Belos_ProjectedLeastSquaresSolver_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>
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;
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;
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);
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) {
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 =
1455 blockCosines, blockSines, startCol, endCol);
1461 for (
int startCol = 0; startCol < numCols; ++startCol) {
1462 residualNormBlockGivens =
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);
1500 const magnitude_type blockGivensSolutionError = testBlockGivens ?
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 = "
1544 if (testBlockGivens) {
1545 out <<
"||H y_blockGivens - z||_2 / ||H||_F = "
1548 out <<
"||H y_lapack - z||_2 / ||H||_F = "
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 = "
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") <<
".");
1773 Array<magnitude_type> rwork (1);
1775 rwork.resize (std::max (1, 5 * N));
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));
1798 &singularValues[0], rankTolerance, &rank,
1799 &work[0], lwork, &rwork[0], &info);
1801 "_GELSS returned INFO = " << info <<
" != 0.");
1817 const int numRows = curCol + 2;
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.");
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);
1939 "LAPACK _GESVD workspace query failed with INFO = "
1941 const int lwork =
static_cast<int> (
STS::real (lworkScalar));
1943 "LAPACK _GESVD workspace query returned LWORK = "
1944 << lwork <<
" < 0.");
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);
1955 "LAPACK _GESVD failed with INFO = " << info <<
".");
1965 std::pair<magnitude_type, magnitude_type>
1970 const int numRows = A.
numRows();
1971 const int numCols = A.
numCols();
1973 Array<magnitude_type> sigmas (std::min (numRows, numCols));
1975 return std::make_pair (sigmas[0], sigmas[std::min(numRows, numCols) - 1]);
1994 const std::pair<magnitude_type, magnitude_type> sigmaMaxMin =
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;
2032 return 2 * A_cond / cosTheta + tanTheta * A_cond * A_cond;
2047 return r.normFrobenius ();
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);
2132 const int numRows = curCol + 2;
2133 const int LDR = R.
stride();
2134 const bool extraDebug =
false;
2137 cerr <<
"updateColumnGivens: curCol = " << curCol << endl;
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;
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();
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();
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(),
2319 y_view.values(), y_view.stride(),
2320 (lwork > 0 ? &work[0] : (Scalar*) NULL),
2323 TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::logic_error,
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" :
"") <<
".");
2356 "updateColumnGivens: startCol = " << startCol
2357 <<
" > endCol = " << endCol <<
".");
2360 for (
int curCol = startCol; curCol <= endCol; ++curCol) {
2388 const int numRows = endCol + 2;
2389 const int numColsToUpdate = endCol - startCol + 1;
2390 const int LDR = R.
stride();
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;
2423 theCosine, theSine, result);
2424 theCosines[curCol] = theCosine;
2425 theSines[curCol] = theSine;
2430 R(curCol+1, curCol) = result;
2438 const int LDZ = z.
stride();
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.
void LARTG(const ScalarType &f, const ScalarType &g, MagnitudeType *c, ScalarType *s, ScalarType *r) const
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.
void computeGivensRotation(const Scalar &x, const Scalar &y, Scalar &theCosine, Scalar &theSine, Scalar &result)
Compute the Givens rotation corresponding to [x; y].
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.
Teuchos::ScalarTraits< scalar_type > STS
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.
magnitude_type updateColumnGivens(const mat_type &H, mat_type &R, mat_type &y, mat_type &z, Teuchos::ArrayView< scalar_type > theCosines, Teuchos::ArrayView< scalar_type > theSines, const int curCol)
Update current column using Givens rotations.
#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
std::pair< magnitude_type, magnitude_type > extremeSingularValues(const mat_type &A)
The (largest, smallest) singular values of the given matrix.
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
Teuchos::ScalarTraits< scalar_type > STS
Methods for solving GMRES' projected least-squares problem.
std::ostream & warn_
Stream to which to output warnings.
ERobustness defaultRobustness_
Default robustness level, for things like triangular solves.
magnitude_type updateColumnsGivens(const mat_type &H, mat_type &R, mat_type &y, mat_type &z, Teuchos::ArrayView< scalar_type > theCosines, Teuchos::ArrayView< scalar_type > theSines, const int startCol, const int endCol)
Update columns [startCol,endCol] of the projected least-squares problem.
Teuchos::BLAS< int, scalar_type > blas_type
void zeroOutStrictLowerTriangle(mat_type &A) const
Zero out everything below the diagonal of A.
Teuchos::LAPACK< int, scalar_type > lapack_type
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.
void solveGivens(mat_type &y, mat_type &R, const mat_type &z, const int curCol)
Solve the projected least-squares problem, assuming Givens rotations updates.
void makeRandomProblem(mat_type &H, mat_type &z)
Make a random 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.
Teuchos::ScalarTraits< magnitude_type > STM
magnitude_type updateColumnsGivensBlock(const mat_type &H, mat_type &R, mat_type &y, mat_type &z, Teuchos::ArrayView< scalar_type > theCosines, Teuchos::ArrayView< scalar_type > theSines, const int startCol, const int endCol)
Update columns [startCol,endCol] of the projected least-squares problem.
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)
magnitude_type solutionError(const mat_type &x_approx, const mat_type &x_exact)
||x_approx - x_exact||_2 // ||x_exact||_2.
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.
magnitude_type leastSquaresConditionNumber(const mat_type &A, const mat_type &b, const magnitude_type &residualNorm)
Normwise 2-norm condition number of the least-squares problem.
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.
magnitude_type solveLapack(const mat_type &H, mat_type &R, mat_type &y, mat_type &z, const int curCol)
Solve the least-squares problem using LAPACK.
void GESVD(const char &JOBU, const char &JOBVT, const OrdinalType &m, const OrdinalType &n, ScalarType *A, const OrdinalType &lda, MagnitudeType *S, ScalarType *U, const OrdinalType &ldu, ScalarType *V, const OrdinalType &ldv, ScalarType *WORK, const OrdinalType &lwork, MagnitudeType *RWORK, OrdinalType *info) const
int solveLeastSquaresUsingSVD(mat_type &A, mat_type &X)
Solve using the SVD.
void ROTG(ScalarType *da, ScalarType *db, rotg_c_type *c, ScalarType *s) const
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 GELS(const char &TRANS, const OrdinalType &m, const OrdinalType &n, const OrdinalType &nrhs, ScalarType *A, const OrdinalType &lda, ScalarType *B, const OrdinalType &ldb, ScalarType *WORK, const OrdinalType &lwork, OrdinalType *info) const
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?
Teuchos::ScalarTraits< magnitude_type > STM
Teuchos::BLAS< int, scalar_type > blas_type
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.
magnitude_type leastSquaresResidualNorm(const mat_type &A, const mat_type &x, const mat_type &b)
(Frobenius norm if b has more than one column).
void singularValues(const mat_type &A, Teuchos::ArrayView< magnitude_type > sigmas)
Compute the singular values of A. Store them in the sigmas array.
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.
Teuchos::LAPACK< int, scalar_type > lapack_type