45 #ifndef __BelosTsqrOrthoManagerImpl_hpp
46 #define __BelosTsqrOrthoManagerImpl_hpp
55 #include "Teuchos_ParameterListAcceptorDefaultBase.hpp"
56 #ifdef BELOS_TEUCHOS_TIME_MONITOR
58 #endif // BELOS_TEUCHOS_TIME_MONITOR
130 template<
class Scalar>
132 public std::binary_function<Teuchos::ArrayView<typename Teuchos::ScalarTraits<Scalar>::magnitudeType>,
133 Teuchos::ArrayView<typename Teuchos::ScalarTraits<Scalar>::magnitudeType>,
157 template<
class Scalar>
191 template<
class Scalar,
class MV>
206 typedef typename MVT::tsqr_adaptor_type tsqr_adaptor_type;
250 const std::string& label);
280 reorthogCallback_ = callback;
291 if (label != label_) {
294 #ifdef BELOS_TEUCHOS_TIME_MONITOR
295 clearTimer (label,
"All orthogonalization");
296 clearTimer (label,
"Projection");
297 clearTimer (label,
"Normalization");
299 timerOrtho_ = makeTimer (label,
"All orthogonalization");
300 timerProject_ = makeTimer (label,
"Projection");
301 timerNormalize_ = makeTimer (label,
"Normalization");
302 #endif // BELOS_TEUCHOS_TIME_MONITOR
307 const std::string&
getLabel ()
const {
return label_; }
341 norm (
const MV& X, std::vector<magnitude_type>& normVec)
const;
414 return projectAndNormalizeImpl (X, X,
false, C, B, Q);
445 return projectAndNormalizeImpl (X_in, X_out,
true, C, B, Q);
459 for (
int k = 0; k < ncols; ++k) {
472 mat_type X1_T_X2 (ncols_X1, ncols_X2);
497 tsqr_adaptor_type tsqrAdaptor_;
516 bool randomizeNullSpace_;
523 bool reorthogonalizeBlocks_;
528 bool throwOnReorthogFault_;
542 bool forceNonnegativeDiagonal_;
544 #ifdef BELOS_TEUCHOS_TIME_MONITOR
553 #endif // BELOS_TEUCHOS_TIME_MONITOR
558 #ifdef BELOS_TEUCHOS_TIME_MONITOR
568 makeTimer (
const std::string& prefix,
569 const std::string& timerName)
571 const std::string timerLabel =
572 prefix.empty() ? timerName : (prefix +
": " + timerName);
582 clearTimer (
const std::string& prefix,
583 const std::string& timerName)
585 const std::string timerLabel =
586 prefix.empty() ? timerName : (prefix +
": " + timerName);
589 #endif // BELOS_TEUCHOS_TIME_MONITOR
593 raiseReorthogFault (
const std::vector<magnitude_type>& normsAfterFirstPass,
594 const std::vector<magnitude_type>& normsAfterSecondPass,
595 const std::vector<int>& faultIndices);
607 checkProjectionDims (
int& ncols_X,
627 const bool attemptToRecycle =
true)
const;
638 projectAndNormalizeImpl (MV& X_in,
640 const bool outOfPlace,
687 int rawNormalize (MV& X, MV& Q,
mat_type& B);
706 int normalizeOne (MV& X,
mat_ptr B)
const;
735 int normalizeImpl (MV& X, MV& Q,
mat_ptr B,
const bool outOfPlace);
738 template<
class Scalar,
class MV>
744 using Teuchos::parameterList;
746 using Teuchos::sublist;
749 RCP<const ParameterList> defaultParams = getValidParameters ();
751 RCP<ParameterList> tsqrParams;
753 RCP<ParameterList> theParams;
755 theParams = parameterList (*defaultParams);
763 randomizeNullSpace_ =
764 theParams->
get<
bool> (
"randomizeNullSpace",
765 defaultParams->get<
bool> (
"randomizeNullSpace"));
766 reorthogonalizeBlocks_ =
767 theParams->get<
bool> (
"reorthogonalizeBlocks",
768 defaultParams->get<
bool> (
"reorthogonalizeBlocks"));
769 throwOnReorthogFault_ =
770 theParams->get<
bool> (
"throwOnReorthogFault",
771 defaultParams->get<
bool> (
"throwOnReorthogFault"));
772 blockReorthogThreshold_ =
773 theParams->get<M> (
"blockReorthogThreshold",
774 defaultParams->get<M> (
"blockReorthogThreshold"));
775 relativeRankTolerance_ =
776 theParams->get<M> (
"relativeRankTolerance",
777 defaultParams->get<M> (
"relativeRankTolerance"));
778 forceNonnegativeDiagonal_ =
779 theParams->get<
bool> (
"forceNonnegativeDiagonal",
780 defaultParams->get<
bool> (
"forceNonnegativeDiagonal"));
784 if (! theParams->isSublist (
"TSQR implementation")) {
785 theParams->set (
"TSQR implementation",
786 defaultParams->sublist (
"TSQR implementation"));
788 tsqrParams = sublist (theParams,
"TSQR implementation",
true);
792 tsqrAdaptor_.setParameterList (tsqrParams);
795 setMyParamList (theParams);
798 template<
class Scalar,
class MV>
801 const std::string& label) :
805 randomizeNullSpace_ (true),
806 reorthogonalizeBlocks_ (true),
807 throwOnReorthogFault_ (false),
808 blockReorthogThreshold_ (0),
809 relativeRankTolerance_ (0),
810 forceNonnegativeDiagonal_ (false)
814 #ifdef BELOS_TEUCHOS_TIME_MONITOR
815 timerOrtho_ = makeTimer (label,
"All orthogonalization");
816 timerProject_ = makeTimer (label,
"Projection");
817 timerNormalize_ = makeTimer (label,
"Normalization");
818 #endif // BELOS_TEUCHOS_TIME_MONITOR
821 template<
class Scalar,
class MV>
827 randomizeNullSpace_ (true),
828 reorthogonalizeBlocks_ (true),
829 throwOnReorthogFault_ (false),
830 blockReorthogThreshold_ (0),
831 relativeRankTolerance_ (0),
832 forceNonnegativeDiagonal_ (false)
836 #ifdef BELOS_TEUCHOS_TIME_MONITOR
837 timerOrtho_ = makeTimer (label,
"All orthogonalization");
838 timerProject_ = makeTimer (label,
"Projection");
839 timerNormalize_ = makeTimer (label,
"Normalization");
840 #endif // BELOS_TEUCHOS_TIME_MONITOR
843 template<
class Scalar,
class MV>
846 norm (
const MV& X, std::vector<magnitude_type>& normVec)
const
848 const int numCols = MVT::GetNumberVecs (X);
851 if (normVec.size() <
static_cast<size_t>(numCols))
852 normVec.resize (numCols);
853 MVT::MvNorm (X, normVec);
856 template<
class Scalar,
class MV>
862 #ifdef BELOS_TEUCHOS_TIME_MONITOR
871 #endif // BELOS_TEUCHOS_TIME_MONITOR
873 int ncols_X, num_Q_blocks, ncols_Q_total;
874 checkProjectionDims (ncols_X, num_Q_blocks, ncols_Q_total, X, Q);
878 if (ncols_X == 0 || num_Q_blocks == 0 || ncols_Q_total == 0)
882 allocateProjectionCoefficients (C, Q, X,
true);
886 std::vector<magnitude_type> columnNormsBefore (ncols_X,
magnitude_type(0));
887 if (reorthogonalizeBlocks_)
888 MVT::MvNorm (X, columnNormsBefore);
892 rawProject (X, Q, C);
896 if (reorthogonalizeBlocks_) {
897 std::vector<magnitude_type> columnNormsAfter (ncols_X,
magnitude_type(0));
898 MVT::MvNorm (X, columnNormsAfter);
906 bool reorthogonalize =
false;
907 for (
int j = 0; j < ncols_X; ++j) {
908 if (columnNormsAfter[j] < relThres * columnNormsBefore[j]) {
909 reorthogonalize =
true;
913 if (reorthogonalize) {
916 if (! reorthogCallback_.is_null()) {
917 reorthogCallback_->operator() (Teuchos::arrayViewFromVector (columnNormsBefore),
918 Teuchos::arrayViewFromVector (columnNormsAfter));
922 allocateProjectionCoefficients (C2, Q, X,
false);
926 rawProject (X, Q, C2);
928 for (
int k = 0; k < num_Q_blocks; ++k)
935 template<
class Scalar,
class MV>
942 #ifdef BELOS_TEUCHOS_TIME_MONITOR
949 #endif // BELOS_TEUCHOS_TIME_MONITOR
954 const int numCols = MVT::GetNumberVecs (X);
963 return normalizeOne (X, B);
993 MVT::GetGlobalLength(*Q_) != MVT::GetGlobalLength(X) ||
994 numCols > MVT::GetNumberVecs (*Q_)) {
995 Q_ = MVT::Clone (X, numCols);
1004 if (MVT::GetNumberVecs(*Q_) == numCols) {
1005 return normalizeImpl (X, *Q_, B,
false);
1007 RCP<MV> Q_view = MVT::CloneViewNonConst (*Q_, Range1D(0, numCols-1));
1008 return normalizeImpl (X, *Q_view, B,
false);
1012 template<
class Scalar,
class MV>
1018 const bool attemptToRecycle)
const
1020 const int num_Q_blocks = Q.size();
1021 const int ncols_X = MVT::GetNumberVecs (X);
1023 if (attemptToRecycle)
1025 for (
int i = 0; i < num_Q_blocks; ++i)
1027 const int ncols_Qi = MVT::GetNumberVecs (*Q[i]);
1031 C[i] =
Teuchos::rcp (
new mat_type (ncols_Qi, ncols_X));
1034 mat_type& Ci = *C[i];
1035 if (Ci.numRows() != ncols_Qi || Ci.numCols() != ncols_X)
1036 Ci.shape (ncols_Qi, ncols_X);
1038 Ci.putScalar (SCT::zero());
1044 for (
int i = 0; i < num_Q_blocks; ++i)
1046 const int ncols_Qi = MVT::GetNumberVecs (*Q[i]);
1047 C[i] =
Teuchos::rcp (
new mat_type (ncols_Qi, ncols_X));
1052 template<
class Scalar,
class MV>
1057 #ifdef BELOS_TEUCHOS_TIME_MONITOR
1060 #endif // BELOS_TEUCHOS_TIME_MONITOR
1062 const int numVecs = MVT::GetNumberVecs(X);
1065 }
else if (numVecs == 1) {
1072 const int rank = normalizeOne (X, B);
1074 RCP<MV> Q_0 = MVT::CloneViewNonConst (Q, Range1D(0,0));
1075 MVT::Assign (X, *Q_0);
1081 return normalizeImpl (X, Q, B,
true);
1085 template<
class Scalar,
class MV>
1090 const bool outOfPlace,
1099 #ifdef BELOS_TEUCHOS_TIME_MONITOR
1103 #endif // BELOS_TEUCHOS_TIME_MONITOR
1108 std::invalid_argument,
1109 "Belos::TsqrOrthoManagerImpl::"
1110 "projectAndNormalizeImpl(..., outOfPlace=true, ...):"
1111 "X_out has " << MVT::GetNumberVecs(X_out)
1112 <<
" columns, but X_in has "
1113 << MVT::GetNumberVecs(X_in) <<
" columns.");
1117 int ncols_X, num_Q_blocks, ncols_Q_total;
1118 checkProjectionDims (ncols_X, num_Q_blocks, ncols_Q_total, X_in, Q);
1125 if (num_Q_blocks == 0 || ncols_Q_total == 0) {
1127 return normalizeOutOfPlace (X_in, X_out, B);
1129 return normalize (X_in, B);
1136 allocateProjectionCoefficients (C, Q, X_in,
true);
1141 std::vector<magnitude_type> normsBeforeFirstPass (ncols_X, SCTM::zero());
1142 if (reorthogonalizeBlocks_) {
1143 MVT::MvNorm (X_in, normsBeforeFirstPass);
1147 rawProject (X_in, Q, C);
1160 B_out =
rcp (
new mat_type (ncols_X, ncols_X));
1164 std::invalid_argument,
1165 "normalizeOne: Input matrix B must be at "
1166 "least " << ncols_X <<
" x " << ncols_X
1167 <<
", but is instead " << B->numRows()
1168 <<
" x " << B->numCols() <<
".");
1178 const int firstPassRank = outOfPlace ?
1179 normalizeOutOfPlace (X_in, X_out, B_out) :
1180 normalize (X_in, B_out);
1189 int rank = firstPassRank;
1205 if (firstPassRank < ncols_X && randomizeNullSpace_) {
1206 const int numNullSpaceCols = ncols_X - firstPassRank;
1207 const Range1D nullSpaceIndices (firstPassRank, ncols_X - 1);
1211 for (
int k = 0; k < num_Q_blocks; ++k) {
1212 const int numColsQk = MVT::GetNumberVecs(*Q[k]);
1213 C_null[k] =
rcp (
new mat_type (numColsQk, numNullSpaceCols));
1216 RCP<mat_type> B_null (
new mat_type (numNullSpaceCols, numNullSpaceCols));
1218 int randomVectorsRank;
1222 RCP<MV> X_out_null = MVT::CloneViewNonConst (X_out, nullSpaceIndices);
1227 RCP<MV> X_in_null = MVT::CloneViewNonConst (X_in, nullSpaceIndices);
1228 MVT::Assign (*X_out_null, *X_in_null);
1231 rawProject (*X_in_null, Q, C_null);
1232 randomVectorsRank = normalizeOutOfPlace (*X_in_null, *X_out_null, B_null);
1236 RCP<MV> X_null = MVT::CloneViewNonConst (X_in, nullSpaceIndices);
1239 rawProject (*X_null, Q, C_null);
1240 randomVectorsRank = normalize (*X_null, B_null);
1248 "Belos::TsqrOrthoManagerImpl::projectAndNormalize"
1249 "OutOfPlace(): After projecting and normalizing the "
1250 "random vectors (used to replace the null space "
1251 "basis vectors from normalizing X), they have rank "
1252 << randomVectorsRank <<
", but should have full "
1253 "rank " << numNullSpaceCols <<
".");
1258 if (reorthogonalizeBlocks_) {
1261 std::vector<magnitude_type>
1262 normsAfterFirstPass (firstPassRank, SCTM::zero());
1263 std::vector<magnitude_type>
1264 normsAfterSecondPass (firstPassRank, SCTM::zero());
1279 for (
int j = 0; j < firstPassRank; ++j) {
1280 const Scalar*
const B_j = &(*B_out)(0,j);
1283 normsAfterFirstPass[j] = blas.
NRM2 (firstPassRank, B_j, 1);
1287 bool reorthogonalize =
false;
1288 for (
int j = 0; j < firstPassRank; ++j) {
1295 const magnitude_type curThreshold =
1296 blockReorthogThreshold() * normsBeforeFirstPass[j];
1297 if (normsAfterFirstPass[j] < curThreshold) {
1298 reorthogonalize =
true;
1305 if (! reorthogCallback_.is_null()) {
1306 using Teuchos::arrayViewFromVector;
1307 (*reorthogCallback_) (arrayViewFromVector (normsBeforeFirstPass),
1308 arrayViewFromVector (normsAfterFirstPass));
1322 bool reorthogFault =
false;
1324 std::vector<int> faultIndices;
1325 if (reorthogonalize) {
1333 MVT::Assign (X_out, X_in);
1340 allocateProjectionCoefficients (C2, Q, X_in,
false);
1345 rawProject (X_in, Q, C2);
1348 RCP<mat_type> B2 (
new mat_type (ncols_X, ncols_X));
1351 const int secondPassRank = outOfPlace ?
1352 normalizeOutOfPlace (X_in, X_out, B2) :
1353 normalize (X_in, B2);
1354 rank = secondPassRank;
1359 mat_type B_copy (Copy, *B_out, B_out->numRows(), B_out->numCols());
1361 const int err = B_out->multiply (NO_TRANS, NO_TRANS, SCT::one(),
1362 *B2, B_copy, SCT::zero());
1364 "Teuchos::SerialDenseMatrix::multiply "
1365 "returned err = " << err <<
" != 0");
1369 for (
int k = 0; k < num_Q_blocks; ++k) {
1370 mat_type C_k_copy (Copy, *C[k], C[k]->numRows(), C[k]->numCols());
1373 const int err1 = C[k]->multiply (NO_TRANS, NO_TRANS, SCT::one(),
1374 *C2[k], B_copy, SCT::one());
1376 "Teuchos::SerialDenseMatrix::multiply "
1377 "returned err = " << err1 <<
" != 0");
1382 for (
int j = 0; j < rank; ++j) {
1383 const Scalar*
const B2_j = &(*B2)(0,j);
1384 normsAfterSecondPass[j] = blas.
NRM2 (rank, B2_j, 1);
1389 reorthogFault =
false;
1390 for (
int j = 0; j < rank; ++j) {
1391 const magnitude_type relativeLowerBound =
1392 blockReorthogThreshold() * normsAfterFirstPass[j];
1393 if (normsAfterSecondPass[j] < relativeLowerBound) {
1394 reorthogFault =
true;
1395 faultIndices.push_back (j);
1400 if (reorthogFault) {
1401 if (throwOnReorthogFault_) {
1402 raiseReorthogFault (normsAfterFirstPass,
1403 normsAfterSecondPass,
1412 "TsqrOrthoManagerImpl has not yet implemented"
1413 " recovery from an orthogonalization fault.");
1421 template<
class Scalar,
class MV>
1423 TsqrOrthoManagerImpl<Scalar, MV>::
1424 raiseReorthogFault (
const std::vector<magnitude_type>& normsAfterFirstPass,
1425 const std::vector<magnitude_type>& normsAfterSecondPass,
1426 const std::vector<int>& faultIndices)
1429 typedef std::vector<int>::size_type size_type;
1430 std::ostringstream os;
1432 os <<
"Orthogonalization fault at the following column(s) of X:" << endl;
1433 os <<
"Column\tNorm decrease factor" << endl;
1434 for (size_type k = 0; k < faultIndices.size(); ++k) {
1435 const int index = faultIndices[k];
1436 const magnitude_type decreaseFactor =
1437 normsAfterSecondPass[index] / normsAfterFirstPass[index];
1438 os << index <<
"\t" << decreaseFactor << endl;
1440 throw TsqrOrthoFault (os.str());
1443 template<
class Scalar,
class MV>
1448 using Teuchos::parameterList;
1451 if (defaultParams_.is_null()) {
1452 RCP<ParameterList> params = parameterList (
"TsqrOrthoManagerImpl");
1456 params->set (
"TSQR implementation", *(tsqrAdaptor_.getValidParameters()),
1457 "TSQR implementation parameters.");
1461 const bool defaultRandomizeNullSpace =
true;
1462 params->set (
"randomizeNullSpace", defaultRandomizeNullSpace,
1463 "Whether to fill in null space vectors with random data.");
1465 const bool defaultReorthogonalizeBlocks =
true;
1466 params->set (
"reorthogonalizeBlocks", defaultReorthogonalizeBlocks,
1467 "Whether to do block reorthogonalization as necessary.");
1473 params->set (
"blockReorthogThreshold", defaultBlockReorthogThreshold,
1474 "If reorthogonalizeBlocks==true, and if the norm of "
1475 "any column within a block decreases by this much or "
1476 "more after orthogonalization, we reorthogonalize.");
1481 Teuchos::as<magnitude_type>(10) * SCTM::eps();
1486 params->set (
"relativeRankTolerance", defaultRelativeRankTolerance,
1487 "Relative tolerance to determine the numerical rank of a "
1488 "block when normalizing.");
1492 const bool defaultThrowOnReorthogFault =
true;
1493 params->set (
"throwOnReorthogFault", defaultThrowOnReorthogFault,
1494 "Whether to throw an exception if an orthogonalization "
1495 "fault occurs. This only matters if reorthogonalization "
1496 "is enabled (reorthogonalizeBlocks==true).");
1498 const bool defaultForceNonnegativeDiagonal =
false;
1499 params->set (
"forceNonnegativeDiagonal", defaultForceNonnegativeDiagonal,
1500 "Whether to force the R factor produced by the normalization "
1501 "step to have a nonnegative diagonal.");
1503 defaultParams_ = params;
1505 return defaultParams_;
1508 template<
class Scalar,
class MV>
1516 RCP<const ParameterList> defaultParams = getValidParameters();
1518 RCP<ParameterList> params =
rcp (
new ParameterList (*defaultParams));
1527 const bool randomizeNullSpace =
false;
1528 params->set (
"randomizeNullSpace", randomizeNullSpace);
1529 const bool reorthogonalizeBlocks =
false;
1530 params->set (
"reorthogonalizeBlocks", reorthogonalizeBlocks);
1535 template<
class Scalar,
class MV>
1547 tsqrAdaptor_.factorExplicit (X, Q, B, forceNonnegativeDiagonal_);
1550 rank = tsqrAdaptor_.revealRank (Q, B, relativeRankTolerance_);
1551 }
catch (std::exception& e) {
1552 throw TsqrOrthoError (e.what());
1557 template<
class Scalar,
class MV>
1559 TsqrOrthoManagerImpl<Scalar, MV>::
1560 normalizeOne (MV& X,
1570 const int theNumRows = B->
numRows ();
1571 const int theNumCols = B->
numCols ();
1573 theNumRows < 1 || theNumCols < 1, std::invalid_argument,
1574 "normalizeOne: Input matrix B must be at least 1 x 1, but "
1575 "is instead " << theNumRows <<
" x " << theNumCols <<
".");
1581 std::vector<magnitude_type> theNorm (1, SCTM::zero());
1582 MVT::MvNorm (X, theNorm);
1583 (*B_out)(0,0) = theNorm[0];
1597 if (theNorm[0] == SCTM::zero()) {
1600 if (randomizeNullSpace_) {
1602 MVT::MvNorm (X, theNorm);
1603 if (theNorm[0] == SCTM::zero()) {
1608 throw TsqrOrthoError(
"normalizeOne: a supposedly random "
1609 "vector has norm zero!");
1614 const Scalar alpha = SCT::one() / theNorm[0];
1615 MVT::MvScale (X, alpha);
1622 const Scalar alpha = SCT::one() / theNorm[0];
1623 MVT::MvScale (X, alpha);
1629 template<
class Scalar,
class MV>
1631 TsqrOrthoManagerImpl<Scalar, MV>::
1636 #ifdef BELOS_TEUCHOS_TIME_MONITOR
1638 #endif // BELOS_TEUCHOS_TIME_MONITOR
1641 const int num_Q_blocks = Q.size();
1642 for (
int i = 0; i < num_Q_blocks; ++i)
1650 mat_type& Ci = *C[i];
1651 const MV& Qi = *Q[i];
1652 innerProd (Qi, X, Ci);
1653 MVT::MvTimesMatAddMv (-SCT::one(), Qi, Ci, SCT::one(), X);
1658 template<
class Scalar,
class MV>
1660 TsqrOrthoManagerImpl<Scalar, MV>::
1665 #ifdef BELOS_TEUCHOS_TIME_MONITOR
1667 #endif // BELOS_TEUCHOS_TIME_MONITOR
1670 innerProd (*Q, X, *C);
1671 MVT::MvTimesMatAddMv (-SCT::one(), *Q, *C, SCT::one(), X);
1674 template<
class Scalar,
class MV>
1676 TsqrOrthoManagerImpl<Scalar, MV>::
1677 normalizeImpl (MV& X,
1680 const bool outOfPlace)
1686 using Teuchos::tuple;
1688 const int numCols = MVT::GetNumberVecs (X);
1696 MVT::GetNumberVecs (Q) < numCols, std::invalid_argument,
1697 "TsqrOrthoManagerImpl::normalizeImpl: Q has "
1698 << MVT::GetNumberVecs(Q) <<
" columns. This is too "
1699 "few, since X has " << numCols <<
" columns.");
1703 RCP<MV> Q_view = MVT::CloneViewNonConst (Q, Range1D (0, numCols-1));
1711 B_out =
rcp (
new mat_type (numCols, numCols));
1715 B->
numRows() < numCols || B->
numCols() < numCols, std::invalid_argument,
1716 "TsqrOrthoManagerImpl::normalizeImpl: Input matrix B must be at least "
1717 << numCols <<
" x " << numCols <<
", but is instead " << B->
numRows ()
1718 <<
" x " << B->
numCols() <<
".");
1733 const int rank = rawNormalize (X, *Q_view, *B_out);
1744 rank < 0 || rank > numCols, std::logic_error,
1745 "Belos::TsqrOrthoManagerImpl::normalizeImpl: rawNormalize returned rank "
1746 " = " << rank <<
" for a matrix X with " << numCols <<
" columns. "
1747 "Please report this bug to the Belos developers.");
1751 if (rank == numCols || ! randomizeNullSpace_) {
1755 MVT::Assign (*Q_view, X);
1760 if (randomizeNullSpace_ && rank < numCols) {
1767 const int nullSpaceNumCols = numCols - rank;
1770 Range1D nullSpaceIndices (rank, numCols-1);
1777 RCP<MV> Q_null = MVT::CloneViewNonConst (*Q_view, nullSpaceIndices);
1779 MVT::MvRandom (*Q_null);
1785 std::vector<magnitude_type> norms (MVT::GetNumberVecs (*Q_null));
1786 MVT::MvNorm (*Q_null, norms);
1788 bool anyZero =
false;
1789 typedef typename std::vector<magnitude_type>::const_iterator iter_type;
1790 for (iter_type it = norms.begin(); it != norms.end(); ++it) {
1791 if (*it == SCTM::zero()) {
1796 std::ostringstream os;
1797 os <<
"TsqrOrthoManagerImpl::normalizeImpl: "
1798 "We are being asked to randomize the null space, for a matrix "
1799 "with " << numCols <<
" columns and reported column rank "
1800 << rank <<
". The inclusive range of columns to fill with "
1801 "random data is [" << nullSpaceIndices.lbound() <<
","
1802 << nullSpaceIndices.ubound() <<
"]. After filling the null "
1803 "space vectors with random numbers, at least one of the vectors"
1804 " has norm zero. Here are the norms of all the null space "
1806 for (iter_type it = norms.begin(); it != norms.end(); ++it) {
1808 if (it+1 != norms.end())
1811 os <<
"].) There is a tiny probability that this could happen "
1812 "randomly, but it is likely a bug. Please report it to the "
1813 "Belos developers, especially if you are able to reproduce the "
1826 RCP<const MV> Q_col = MVT::CloneView (*Q_view, Range1D (0, rank-1));
1831 mat_ptr C_null (
new mat_type (rank, nullSpaceNumCols));
1832 rawProject (*Q_null, Q_col, C_null);
1841 RCP<MV> X_null = MVT::CloneViewNonConst (X, nullSpaceIndices);
1844 mat_type B_null (nullSpaceNumCols, nullSpaceNumCols);
1846 const int nullSpaceBasisRank = rawNormalize (*Q_null, *X_null, B_null);
1860 if (nullSpaceBasisRank < nullSpaceNumCols) {
1861 std::vector<magnitude_type> norms (MVT::GetNumberVecs(*X_null));
1862 MVT::MvNorm (*X_null, norms);
1863 std::ostringstream os;
1864 os <<
"TsqrOrthoManagerImpl::normalizeImpl: "
1865 <<
"We are being asked to randomize the null space, "
1866 <<
"for a matrix with " << numCols <<
" columns and "
1867 <<
"column rank " << rank <<
". After projecting and "
1868 <<
"normalizing the generated random vectors, they "
1869 <<
"only have rank " << nullSpaceBasisRank <<
". They"
1870 <<
" should have full rank " << nullSpaceNumCols
1871 <<
". (The inclusive range of columns to fill with "
1872 <<
"random data is [" << nullSpaceIndices.lbound()
1873 <<
"," << nullSpaceIndices.ubound() <<
"]. The "
1874 <<
"column norms of the resulting Q factor are: [";
1875 for (
typename std::vector<magnitude_type>::size_type k = 0;
1876 k < norms.size(); ++k) {
1878 if (k != norms.size()-1) {
1882 os <<
"].) There is a tiny probability that this could "
1883 <<
"happen randomly, but it is likely a bug. Please "
1884 <<
"report it to the Belos developers, especially if "
1885 <<
"you are able to reproduce the behavior.";
1888 TsqrOrthoError, os.str ());
1898 MVT::Assign (*X_null, *Q_null);
1899 }
else if (rank > 0) {
1901 RCP<const MV> Q_col = MVT::CloneView (*Q_view, Range1D (0, rank-1));
1902 RCP<MV> X_col = MVT::CloneViewNonConst (X, Range1D (0, rank-1));
1903 MVT::Assign (*Q_col, *X_col);
1910 template<
class Scalar,
class MV>
1912 TsqrOrthoManagerImpl<Scalar, MV>::
1913 checkProjectionDims (
int& ncols_X,
1925 int the_ncols_X, the_num_Q_blocks, the_ncols_Q_total;
1926 the_num_Q_blocks = Q.size();
1927 the_ncols_X = MVT::GetNumberVecs (X);
1930 the_ncols_Q_total = 0;
1935 typedef typename ArrayView<RCP<const MV> >::const_iterator iter_type;
1936 for (iter_type it = Q.begin(); it != Q.end(); ++it) {
1937 const MV& Qi = **it;
1938 the_ncols_Q_total += MVT::GetNumberVecs (Qi);
1942 ncols_X = the_ncols_X;
1943 num_Q_blocks = the_num_Q_blocks;
1944 ncols_Q_total = the_ncols_Q_total;
1949 #endif // __BelosTsqrOrthoManagerImpl_hpp
int projectAndNormalize(MV &X, Teuchos::Array< mat_ptr > C, mat_ptr B, Teuchos::ArrayView< Teuchos::RCP< const MV > > Q)
Project X against Q and normalize X.
Interface of callback invoked by TsqrOrthoManager on reorthogonalization.
bool is_null(const boost::shared_ptr< T > &p)
void project(MV &X, Teuchos::Array< mat_ptr > C, Teuchos::ArrayView< Teuchos::RCP< const MV > > Q)
Compute and .
void norm(const MV &X, std::vector< magnitude_type > &normVec) const
Compute the 2-norm of each column j of X.
TsqrOrthoManagerImpl(const Teuchos::RCP< Teuchos::ParameterList > ¶ms, const std::string &label)
Constructor (that sets user-specified parameters).
magnitude_type orthogError(const MV &X1, const MV &X2) const
Return the Frobenius norm of the inner product of X1 with itself.
Teuchos::SerialDenseMatrix< int, Scalar > mat_type
Type of the projection and normalization coefficients.
T & get(const std::string &name, T def_value)
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > ¶ms)
Set parameters from the given parameter list.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Teuchos::RCP< const Teuchos::ParameterList > getFastParameters()
Get "fast" parameters for TsqrOrthoManagerImpl.
TSQR-based OrthoManager subclass implementation.
Declaration of basic traits for the multivector type.
void setReorthogonalizationCallback(const Teuchos::RCP< ReorthogonalizationCallback< Scalar > > &callback)
Set callback to be invoked on reorthogonalization.
Error in TsqrOrthoManager or TsqrOrthoManagerImpl.
ScalarTraits< ScalarType >::magnitudeType NRM2(const OrdinalType &n, const ScalarType *x, const OrdinalType &incx) const
int normalize(MV &X, mat_ptr B)
Orthogonalize the columns of X in place.
void setLabel(const std::string &label)
Set the label for timers.
Teuchos::RCP< mat_type > mat_ptr
static void MvTransMv(const ScalarType alpha, const MV &A, const MV &mv, Teuchos::SerialDenseMatrix< int, ScalarType > &B)
Compute a dense matrix B through the matrix-matrix multiply .
ScalarTraits< ScalarType >::magnitudeType normFrobenius() const
static int GetNumberVecs(const MV &mv)
Obtain the number of vectors in mv.
Teuchos::ScalarTraits< Scalar >::magnitudeType magnitude_type
The type of a norm result.
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Default valid parameter list.
Traits class which defines basic operations on multivectors.
Scalar scalar_type
The template parameter of this class; the type of an inner product result.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
virtual void operator()(Teuchos::ArrayView< magnitude_type > normsBeforeFirstPass, Teuchos::ArrayView< magnitude_type > normsAfterFirstPass)=0
Callback invoked by TsqrOrthoManager on reorthogonalization.
const std::string & getLabel() const
Get the label for timers (if timers are enabled).
magnitude_type orthonormError(const MV &X) const
Return .
Exception thrown to signal error in an orthogonalization manager method.
Teuchos::ScalarTraits< Scalar >::magnitudeType magnitude_type
magnitude_type relativeRankTolerance() const
Relative tolerance for determining (via the SVD) whether a block is of full numerical rank...
void resize(size_type new_size, const value_type &x=value_type())
TsqrOrthoError(const std::string &what_arg)
OrdinalType numCols() const
virtual ~ReorthogonalizationCallback()
Destructor (virtual for memory safety of derived classes)
Templated virtual class for providing orthogonalization/orthonormalization methods.
TsqrOrthoFault(const std::string &what_arg)
magnitude_type blockReorthogThreshold() const
Relative tolerance for triggering a block reorthogonalization.
int projectAndNormalizeOutOfPlace(MV &X_in, MV &X_out, Teuchos::Array< mat_ptr > C, mat_ptr B, Teuchos::ArrayView< Teuchos::RCP< const MV > > Q)
Project and normalize X_in into X_out; overwrite X_in.
int normalizeOutOfPlace(MV &X, MV &Q, mat_ptr B)
Normalize X into Q*B, overwriting X.
void innerProd(const MV &X, const MV &Y, mat_type &Z) const
Euclidean inner product.
Belos header file which uses auto-configuration information to include necessary C++ headers...
OrdinalType numRows() const