10 #ifndef __Belos_ProjectedLeastSquaresSolver_hpp
11 #define __Belos_ProjectedLeastSquaresSolver_hpp
43 template<
class Scalar>
45 printMatrix (std::ostream& out,
46 const std::string& name,
51 const int numRows = A.
numRows();
52 const int numCols = A.
numCols();
54 out << name <<
" = " << endl <<
'[';
57 for (
int i = 0; i < numRows; ++i) {
64 for (
int i = 0; i < numRows; ++i) {
65 for (
int j = 0; j < numCols; ++j) {
69 }
else if (i < numRows-1) {
80 template<
class Scalar>
82 print (std::ostream& out,
84 const std::string& linePrefix)
88 const int numRows = A.
numRows();
89 const int numCols = A.
numCols();
91 out << linePrefix <<
'[';
94 for (
int i = 0; i < numRows; ++i) {
101 for (
int i = 0; i < numRows; ++i) {
102 for (
int j = 0; j < numCols; ++j) {
104 out << linePrefix <<
" ";
109 }
else if (i < numRows-1) {
115 out << linePrefix <<
']' << endl;
126 template<
class Scalar>
206 H (maxNumIterations+1, maxNumIterations),
207 R (maxNumIterations+1, maxNumIterations),
208 y (maxNumIterations+1, 1),
209 z (maxNumIterations+1, 1),
242 const Scalar initialResidualNorm (beta);
243 z(0,0) = initialResidualNorm;
261 const int maxNumIterations)
267 "ProjectedLeastSquaresProblem::reset: initial "
268 "residual beta = " << beta <<
" < 0.");
270 "ProjectedLeastSquaresProblem::reset: maximum number "
271 "of iterations " << maxNumIterations <<
" <= 0.");
274 const int errcode =
H.
reshape (maxNumIterations+1, maxNumIterations);
276 "Failed to reshape H into a " << (maxNumIterations+1)
277 <<
" x " << maxNumIterations <<
" matrix.");
282 const int errcode =
R.
reshape (maxNumIterations+1, maxNumIterations);
284 "Failed to reshape R into a " << (maxNumIterations+1)
285 <<
" x " << maxNumIterations <<
" matrix.");
290 const int errcode =
y.
reshape (maxNumIterations+1, 1);
292 "Failed to reshape y into a " << (maxNumIterations+1)
293 <<
" x " << 1 <<
" matrix.");
298 const int errcode =
z.
reshape (maxNumIterations+1, 1);
300 "Failed to reshape z into a " << (maxNumIterations+1)
301 <<
" x " << 1 <<
" matrix.");
316 template<
class Scalar>
340 for (
int i = 0; i < A.
numRows(); ++i) {
341 for (
int j = 0; j < A.
numCols(); ++j) {
353 for (
int j = 0; j < N; ++j) {
354 for (
int i = 0; i <= j; ++i) {
366 for (
int j = 0; j < N; ++j) {
367 for (
int i = j+1; i < A.
numRows(); ++i) {
398 A_22 =
rcp (
new mat_type (
View, A, numRows2, numCols2, numRows1, numCols1));
406 const int numRows = A.
numRows();
407 const int numCols = A.
numCols();
409 if (numRows == 0 || numCols == 0) {
412 for (
int j = 0; j < numCols; ++j) {
415 for (
int i = 0; i < numRows; ++i) {
431 const int numRows = Y.
numRows();
432 const int numCols = Y.
numCols();
435 std::invalid_argument,
"Dimensions of X and Y don't "
437 <<
", and Y is " << numRows <<
" x " << numCols <<
".");
438 for (
int j = 0; j < numCols; ++j) {
439 for (
int i = 0; i < numRows; ++i) {
440 Y(i,j) += alpha * X(i,j);
449 const int numRows = A.
numRows();
450 const int numCols = A.
numCols();
454 std::invalid_argument,
455 "matAdd: The input matrices A and B have incompatible dimensions. "
456 "A is " << numRows <<
" x " << numCols <<
", but B is " <<
458 if (numRows == 0 || numCols == 0) {
461 for (
int j = 0; j < numCols; ++j) {
465 for (
int i = 0; i < numRows; ++i) {
476 const int numRows = A.
numRows();
477 const int numCols = A.
numCols();
481 std::invalid_argument,
482 "matSub: The input matrices A and B have incompatible dimensions. "
483 "A is " << numRows <<
" x " << numCols <<
", but B is " <<
485 if (numRows == 0 || numCols == 0) {
488 for (
int j = 0; j < numCols; ++j) {
492 for (
int i = 0; i < numRows; ++i) {
508 std::invalid_argument,
509 "rightUpperTriSolve: R and B have incompatible "
510 "dimensions. B has " << B.
numCols() <<
" columns, "
511 "but R has " << R.
numRows() <<
" rows.");
535 std::invalid_argument,
536 "matMatMult: The input matrices A and B have "
537 "incompatible dimensions. A is " << A.
numRows()
538 <<
" x " << A.
numCols() <<
", but B is "
541 std::invalid_argument,
542 "matMatMult: The input matrix A and the output "
543 "matrix C have incompatible dimensions. A has "
547 std::invalid_argument,
548 "matMatMult: The input matrix B and the output "
549 "matrix C have incompatible dimensions. B has "
550 << B.
numCols() <<
" columns, but C has "
551 << C.
numCols() <<
" columns.");
569 for (
int j = 0; j < A.
numCols(); ++j) {
570 if (upperTriangular) {
571 for (
int i = 0; i <= j && i < A.
numRows(); ++i) {
577 for (
int i = 0; i < A.
numRows(); ++i) {
592 std::pair<bool, std::pair<magnitude_type, magnitude_type> >
599 for (
int j = 0; j < A.
numCols(); ++j) {
603 for (
int i = 0; i <= j && i < A.
numRows(); ++i) {
605 upperTri += A_ij_mag * A_ij_mag;
608 for (
int i = j+1; i < A.
numRows(); ++i) {
610 lowerTri += A_ij_mag * A_ij_mag;
616 return std::make_pair (count == 0, std::make_pair (lowerTri, upperTri));
625 std::pair<bool, std::pair<magnitude_type, magnitude_type> >
632 for (
int j = 0; j < A.
numCols(); ++j) {
636 for (
int i = 0; i <= j+1 && i < A.
numRows(); ++i) {
638 upper += A_ij_mag * A_ij_mag;
641 for (
int i = j+2; i < A.
numRows(); ++i) {
643 lower += A_ij_mag * A_ij_mag;
649 return std::make_pair (count == 0, std::make_pair (lower, upper));
660 const char*
const matrixName)
const
662 std::pair<bool, std::pair<magnitude_type, magnitude_type> > result =
667 <<
" matrix " << matrixName <<
" is not upper "
668 "triangular. ||tril(A)||_F = "
669 << result.second.first <<
" and ||A||_F = "
670 << result.second.second <<
".");
681 const char*
const matrixName)
const
683 std::pair<bool, std::pair<magnitude_type, magnitude_type> > result =
688 <<
" matrix " << matrixName <<
" is not upper "
689 "triangular. ||tril(A(2:end, :))||_F = "
690 << result.second.first <<
" and ||A||_F = "
691 << result.second.second <<
".");
711 const char*
const matrixName,
714 std::pair<bool, std::pair<magnitude_type, magnitude_type> > result =
720 result.second.first :
721 result.second.first / result.second.second);
724 <<
" matrix " << matrixName <<
" is not upper "
725 "triangular. ||tril(A(2:end, :))||_F "
726 << (result.second.second ==
STM::zero() ?
"" :
" / ||A||_F")
727 <<
" = " << err <<
" > " << relativeTolerance <<
".");
744 const char*
const matrixName,
745 const int minNumRows,
746 const int minNumCols)
const
749 std::invalid_argument,
750 "The matrix " << matrixName <<
" is " << A.
numRows()
751 <<
" x " << A.
numCols() <<
", and therefore does not "
752 "satisfy the minimum dimensions " << minNumRows
753 <<
" x " << minNumCols <<
".");
769 const char*
const matrixName,
771 const int numCols)
const
774 std::invalid_argument,
775 "The matrix " << matrixName <<
" is supposed to be "
776 << numRows <<
" x " << numCols <<
", but is "
811 const char* strings[] = {
"None",
"Some",
"Lots"};
813 std::invalid_argument,
814 "Invalid enum value " << x <<
".");
815 return std::string (strings[x]);
822 const char* strings[] = {
"None",
"Some",
"Lots"};
824 if (x == strings[r]) {
829 "Invalid robustness string " << x <<
".");
845 using Teuchos::stringToIntegralParameterEntryValidator;
852 docs[0] =
"Use the BLAS' triangular solve. This may result in Inf or "
853 "NaN output if the triangular matrix is rank deficient.";
854 docs[1] =
"Robustness somewhere between \"None\" and \"Lots\".";
855 docs[2] =
"Solve the triangular system in a least-squares sense, using "
856 "an SVD-based algorithm. This will always succeed, though the "
857 "solution may not make sense for GMRES.";
862 const std::string pname (
"Robustness of Projected Least-Squares Solve");
864 return stringToIntegralParameterEntryValidator<ERobustness> (strs, docs,
930 template<
class Scalar>
1044 std::pair<int, bool>
1091 std::pair<int, bool>
1099 "The output X and right-hand side B have different "
1100 "numbers of rows. X has " << X.
numRows() <<
" rows"
1101 ", and B has " << B.
numRows() <<
" rows.");
1107 "The output X has more columns than the "
1108 "right-hand side B. X has " << X.
numCols()
1109 <<
" columns and B has " << B.
numCols()
1127 std::pair<int, bool>
1142 std::pair<int, bool>
1157 "The input matrix R has fewer columns than rows. "
1158 "R is " << M <<
" x " << N <<
".");
1164 "The input/output matrix X has only "
1165 << X.
numRows() <<
" rows, but needs at least "
1166 << N <<
" rows to match the matrix for a "
1167 "left-side solve R \\ X.");
1170 "The input/output matrix X has only "
1171 << X.
numCols() <<
" columns, but needs at least "
1172 << N <<
" columns to match the matrix for a "
1173 "right-side solve X / R.");
1177 std::invalid_argument,
1178 "Invalid robustness value " << robustness <<
".");
1186 "There " << (count != 1 ?
"are" :
"is")
1187 <<
" " << count <<
" Inf or NaN entr"
1188 << (count != 1 ?
"ies" :
"y")
1189 <<
" in the upper triangle of R.");
1192 "There " << (count != 1 ?
"are" :
"is")
1193 <<
" " << count <<
" Inf or NaN entr"
1194 << (count != 1 ?
"ies" :
"y") <<
" in the "
1195 "right-hand side(s) X.");
1200 bool foundRankDeficiency =
false;
1228 warn_ <<
"Upper triangular solve: Found Infs and/or NaNs in the "
1229 "solution after using the fast algorithm. Retrying using a more "
1230 "robust algorithm." << std::endl;
1271 foundRankDeficiency =
true;
1276 "Should never get here! Invalid robustness value "
1277 << robustness <<
". Please report this bug to the "
1278 "Belos developers.");
1280 return std::make_pair (rank, foundRankDeficiency);
1298 out <<
"Testing Givens rotations:" << endl;
1301 out <<
" x = " << x <<
", y = " << y << endl;
1303 Scalar theCosine, theSine, result;
1306 out <<
"-- After computing rotation:" << endl;
1307 out <<
"---- cos,sin = " << theCosine <<
"," << theSine << endl;
1308 out <<
"---- x = " << x <<
", y = " << y
1309 <<
", result = " << result << endl;
1311 blas.
ROT (1, &x, 1, &y, 1, &theCosine, &theSine);
1312 out <<
"-- After applying rotation:" << endl;
1313 out <<
"---- cos,sin = " << theCosine <<
"," << theSine << endl;
1314 out <<
"---- x = " << x <<
", y = " << y << endl;
1355 const bool testBlockGivens=
false,
1356 const bool extraVerbose=
false)
1362 "numCols = " << numCols <<
" <= 0.");
1363 const int numRows = numCols + 1;
1368 mat_type R_givens (numRows, numCols);
1371 Array<Scalar> theCosines (numCols);
1372 Array<Scalar> theSines (numCols);
1374 mat_type R_blockGivens (numRows, numCols);
1375 mat_type y_blockGivens (numRows, 1);
1376 mat_type z_blockGivens (numRows, 1);
1377 Array<Scalar> blockCosines (numCols);
1378 Array<Scalar> blockSines (numCols);
1379 const int panelWidth = std::min (3, numCols);
1381 mat_type R_lapack (numRows, numCols);
1388 printMatrix<Scalar> (out,
"H", H);
1389 printMatrix<Scalar> (out,
"z", z);
1395 if (testBlockGivens) {
1396 z_blockGivens.
assign (z);
1406 for (
int curCol = 0; curCol < numCols; ++curCol) {
1408 theCosines, theSines, curCol);
1410 solveGivens (y_givens, R_givens, z_givens, numCols-1);
1415 if (testBlockGivens) {
1416 const bool testBlocksAtATime =
true;
1417 if (testBlocksAtATime) {
1419 for (
int startCol = 0; startCol < numCols; startCol += panelWidth) {
1420 int endCol = std::min (startCol + panelWidth - 1, numCols - 1);
1421 residualNormBlockGivens =
1423 blockCosines, blockSines, startCol, endCol);
1429 for (
int startCol = 0; startCol < numCols; ++startCol) {
1430 residualNormBlockGivens =
1432 blockCosines, blockSines, startCol, startCol);
1439 solveGivens (y_blockGivens, R_blockGivens, z_blockGivens, numCols-1);
1444 solveLapack (H, R_lapack, y_lapack, z_lapack, numCols-1);
1468 const magnitude_type blockGivensSolutionError = testBlockGivens ?
1476 mat_type R_factorFromGivens (numCols, numCols);
1477 mat_type R_factorFromBlockGivens (numCols, numCols);
1478 mat_type R_factorFromLapack (numCols, numCols);
1480 for (
int j = 0; j < numCols; ++j) {
1481 for (
int i = 0; i <= j; ++i) {
1482 R_factorFromGivens(i,j) = R_givens(i,j);
1483 if (testBlockGivens) {
1484 R_factorFromBlockGivens(i,j) = R_blockGivens(i,j);
1486 R_factorFromLapack(i,j) = R_lapack(i,j);
1490 printMatrix<Scalar> (out,
"R_givens", R_factorFromGivens);
1491 printMatrix<Scalar> (out,
"y_givens", y_givens_view);
1492 printMatrix<Scalar> (out,
"z_givens", z_givens);
1494 if (testBlockGivens) {
1495 printMatrix<Scalar> (out,
"R_blockGivens", R_factorFromBlockGivens);
1496 printMatrix<Scalar> (out,
"y_blockGivens", y_blockGivens_view);
1497 printMatrix<Scalar> (out,
"z_blockGivens", z_blockGivens);
1500 printMatrix<Scalar> (out,
"R_lapack", R_factorFromLapack);
1501 printMatrix<Scalar> (out,
"y_lapack", y_lapack_view);
1502 printMatrix<Scalar> (out,
"z_lapack", z_lapack);
1508 out <<
"||H||_F = " << H_norm << endl;
1510 out <<
"||H y_givens - z||_2 / ||H||_F = "
1512 if (testBlockGivens) {
1513 out <<
"||H y_blockGivens - z||_2 / ||H||_F = "
1516 out <<
"||H y_lapack - z||_2 / ||H||_F = "
1519 out <<
"||y_givens - y_lapack||_2 / ||y_lapack||_2 = "
1520 << givensSolutionError << endl;
1521 if (testBlockGivens) {
1522 out <<
"||y_blockGivens - y_lapack||_2 / ||y_lapack||_2 = "
1523 << blockGivensSolutionError << endl;
1526 out <<
"Least-squares condition number = "
1527 << leastSquaresCondNum << endl;
1545 wiggleFactor * leastSquaresCondNum;
1547 solutionErrorBoundFactor *
STS::eps();
1548 out <<
"Solution error bound: " << solutionErrorBoundFactor
1549 <<
" * eps = " << solutionErrorBound << endl;
1562 }
else if (givensSolutionError > solutionErrorBound) {
1564 }
else if (testBlockGivens) {
1567 }
else if (blockGivensSolutionError > solutionErrorBound) {
1595 const int testProblemSize,
1597 const bool verbose=
false)
1605 std::ostream& verboseOut = verbose ? out : blackHole;
1607 verboseOut <<
"Testing upper triangular solves" << endl;
1611 verboseOut <<
"-- Generating test matrix" << endl;
1612 const int N = testProblemSize;
1615 for (
int j = 0; j < N; ++j) {
1616 for (
int i = 0; i <= j; ++i) {
1636 verboseOut <<
"-- Solving RX=B" << endl;
1640 mat_type Resid (N, 1);
1644 verboseOut <<
"---- ||R*X - B||_F = " << Resid.
normFrobenius() << endl;
1645 verboseOut <<
"---- ||R||_F ||X||_F + ||B||_F = "
1657 mat_type B_star (1, N);
1659 mat_type B_star_copy (1, N);
1660 B_star_copy.
assign (B_star);
1662 verboseOut <<
"-- Solving YR=B^*" << endl;
1666 mat_type Resid2 (1, N);
1667 Resid2.
assign (B_star_copy);
1669 verboseOut <<
"---- ||Y*R - B^*||_F = " << Resid2.
normFrobenius() << endl;
1670 verboseOut <<
"---- ||Y||_F ||R||_F + ||B^*||_F = "
1713 "solveLeastSquaresUsingSVD: The input matrix A "
1714 "contains " << count <<
"Inf and/or NaN entr"
1715 << (count != 1 ?
"ies" :
"y") <<
".");
1718 "solveLeastSquaresUsingSVD: The input matrix X "
1719 "contains " << count <<
"Inf and/or NaN entr"
1720 << (count != 1 ?
"ies" :
"y") <<
".");
1741 Array<magnitude_type> rwork (1);
1743 rwork.resize (std::max (1, 5 * N));
1752 &singularValues[0], rankTolerance, &rank,
1753 &lworkScalar, -1, &rwork[0], &info);
1755 "_GELSS workspace query returned INFO = "
1756 << info <<
" != 0.");
1757 const int lwork =
static_cast<int> (
STS::real (lworkScalar));
1759 "_GELSS workspace query returned LWORK = "
1760 << lwork <<
" < 0.");
1762 Array<Scalar> work (std::max (1, lwork));
1766 &singularValues[0], rankTolerance, &rank,
1767 &work[0], lwork, &rwork[0], &info);
1769 "_GELSS returned INFO = " << info <<
" != 0.");
1785 const int numRows = curCol + 2;
1809 for (
int j = 0; j < H.
numCols(); ++j) {
1810 for (
int i = j+2; i < H.
numRows(); ++i) {
1822 const int numTrials = 1000;
1824 for (
int trial = 0; trial < numTrials && z_init ==
STM::zero(); ++trial) {
1828 "After " << numTrials <<
" trial"
1829 << (numTrials != 1 ?
"s" :
"")
1830 <<
", we were unable to generate a nonzero pseudo"
1831 "random real number. This most likely indicates a "
1832 "broken pseudorandom number generator.");
1853 const bool useLartg =
false;
1858 lapack.
LARTG (x, y, &theCosine, &theSine, &result);
1867 blas.
ROTG (&x_temp, &y_temp, &theCosine, &theSine);
1880 const int numRows = A.
numRows();
1881 const int numCols = A.
numCols();
1883 std::invalid_argument,
1884 "The sigmas array is only of length " << sigmas.
size()
1885 <<
", but must be of length at least "
1886 << std::min (numRows, numCols)
1887 <<
" in order to hold all the singular values of the "
1893 mat_type A_copy (numRows, numCols);
1900 Array<magnitude_type> rwork (std::max (std::min (numRows, numCols) - 1, 1));
1901 lapack.
GESVD (
'N',
'N', numRows, numCols,
1902 A_copy.values(), A_copy.stride(), &sigmas[0],
1903 (Scalar*) NULL, 1, (Scalar*) NULL, 1,
1904 &lworkScalar, -1, &rwork[0], &info);
1907 "LAPACK _GESVD workspace query failed with INFO = "
1909 const int lwork =
static_cast<int> (
STS::real (lworkScalar));
1911 "LAPACK _GESVD workspace query returned LWORK = "
1912 << lwork <<
" < 0.");
1918 lapack.
GESVD (
'N',
'N', numRows, numCols,
1919 A_copy.values(), A_copy.stride(), &sigmas[0],
1920 (Scalar*) NULL, 1, (Scalar*) NULL, 1,
1921 &work[0], lwork, &rwork[0], &info);
1923 "LAPACK _GESVD failed with INFO = " << info <<
".");
1933 std::pair<magnitude_type, magnitude_type>
1938 const int numRows = A.
numRows();
1939 const int numCols = A.
numCols();
1941 Array<magnitude_type> sigmas (std::min (numRows, numCols));
1943 return std::make_pair (sigmas[0], sigmas[std::min(numRows, numCols) - 1]);
1962 const std::pair<magnitude_type, magnitude_type> sigmaMaxMin =
1968 "The test matrix is rank deficient; LAPACK's _GESVD "
1969 "routine reports that its smallest singular value is "
1973 const magnitude_type A_cond = sigmaMaxMin.first / sigmaMaxMin.second;
2000 return 2 * A_cond / cosTheta + tanTheta * A_cond * A_cond;
2015 return r.normFrobenius ();
2026 const int numRows = x_exact.
numRows();
2027 const int numCols = x_exact.
numCols();
2029 mat_type x_diff (numRows, numCols);
2030 for (
int j = 0; j < numCols; ++j) {
2031 for (
int i = 0; i < numRows; ++i) {
2032 x_diff(i,j) = x_exact(i,j) - x_approx(i,j);
2100 const int numRows = curCol + 2;
2101 const int LDR = R.
stride();
2102 const bool extraDebug =
false;
2105 cerr <<
"updateColumnGivens: curCol = " << curCol << endl;
2122 printMatrix<Scalar> (cerr,
"R_col before ", R_col);
2128 for (
int j = 0; j < curCol; ++j) {
2131 Scalar theCosine = theCosines[j];
2132 Scalar theSine = theSines[j];
2135 cerr <<
" j = " << j <<
": (cos,sin) = "
2136 << theCosines[j] <<
"," << theSines[j] << endl;
2138 blas.
ROT (1, &R_col(j,0), LDR, &R_col(j+1,0), LDR,
2139 &theCosine, &theSine);
2141 if (extraDebug && curCol > 0) {
2142 printMatrix<Scalar> (cerr,
"R_col after applying previous "
2143 "Givens rotations", R_col);
2148 Scalar theCosine, theSine, result;
2150 theCosine, theSine, result);
2151 theCosines[curCol] = theCosine;
2152 theSines[curCol] = theSine;
2155 cerr <<
" New cos,sin = " << theCosine <<
"," << theSine << endl;
2161 R_col(curCol, 0) = result;
2165 printMatrix<Scalar> (cerr,
"R_col after applying current "
2166 "Givens rotation", R_col);
2174 const int LDZ = z.
stride();
2176 &z(curCol,0), LDZ, &z(curCol+1,0), LDZ,
2177 &theCosine, &theSine);
2183 printMatrix<Scalar> (cerr,
"z_after", z);
2232 const int numRows = curCol + 2;
2233 const int numCols = curCol + 1;
2234 const int LDR = R.
stride();
2251 lapack.
GELS (
'N', numRows, numCols, y_view.numCols(),
2252 NULL, LDR, NULL, y_view.stride(),
2253 &lworkScalar, -1, &info);
2255 "LAPACK _GELS workspace query failed with INFO = "
2256 << info <<
", for a " << numRows <<
" x " << numCols
2257 <<
" matrix with " << y_view.numCols()
2258 <<
" right hand side"
2259 << ((y_view.numCols() != 1) ?
"s" :
"") <<
".");
2262 "LAPACK _GELS workspace query returned an LWORK with "
2263 "negative real part: LWORK = " << lworkScalar
2264 <<
". That should never happen. Please report this "
2265 "to the Belos developers.");
2268 "LAPACK _GELS workspace query returned an LWORK with "
2269 "nonzero imaginary part: LWORK = " << lworkScalar
2270 <<
". That should never happen. Please report this "
2271 "to the Belos developers.");
2277 const int lwork = std::max (1, static_cast<int> (
STS::real (lworkScalar)));
2285 lapack.
GELS (
'N', numRows, numCols, y_view.numCols(),
2287 y_view.values(), y_view.stride(),
2288 (lwork > 0 ? &work[0] : (Scalar*) NULL),
2291 TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::logic_error,
2292 "Solving projected least-squares problem with LAPACK "
2293 "_GELS failed with INFO = " << info <<
", for a "
2294 << numRows <<
" x " << numCols <<
" matrix with "
2295 << y_view.numCols() <<
" right hand side"
2296 << (y_view.numCols() != 1 ?
"s" :
"") <<
".");
2324 "updateColumnGivens: startCol = " << startCol
2325 <<
" > endCol = " << endCol <<
".");
2328 for (
int curCol = startCol; curCol <= endCol; ++curCol) {
2356 const int numRows = endCol + 2;
2357 const int numColsToUpdate = endCol - startCol + 1;
2358 const int LDR = R.
stride();
2373 for (
int j = 0; j < startCol; ++j) {
2374 blas.
ROT (numColsToUpdate,
2375 &R(j, startCol), LDR, &R(j+1, startCol), LDR,
2376 &theCosines[j], &theSines[j]);
2380 for (
int curCol = startCol; curCol < endCol; ++curCol) {
2383 for (
int j = startCol; j < curCol; ++j) {
2384 blas.
ROT (1, &R(j, curCol), LDR, &R(j+1, curCol), LDR,
2385 &theCosines[j], &theSines[j]);
2389 Scalar theCosine, theSine, result;
2391 theCosine, theSine, result);
2392 theCosines[curCol] = theCosine;
2393 theSines[curCol] = theSine;
2398 R(curCol+1, curCol) = result;
2406 const int LDZ = z.
stride();
2408 &z(curCol,0), LDZ, &z(curCol+1,0), LDZ,
2409 &theCosine, &theSine);
2421 #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