45 #ifndef __AnasaziTsqrOrthoManagerImpl_hpp
46 #define __AnasaziTsqrOrthoManagerImpl_hpp
55 #include "Teuchos_ParameterListAcceptorDefaultBase.hpp"
127 template<
class Scalar,
class MV>
131 typedef Scalar scalar_type;
133 typedef MV multivector_type;
143 typedef typename MVT::tsqr_adaptor_type tsqr_adaptor_type;
187 const std::string& label);
203 if (label != label_) {
209 const std::string&
getLabel ()
const {
return label_; }
243 norm (
const MV& X, std::vector<magnitude_type>& normvec)
const;
316 return projectAndNormalizeImpl (X, X,
false, C, B, Q);
347 return projectAndNormalizeImpl (X_in, X_out,
true, C, B, Q);
361 for (
int k = 0; k < ncols; ++k) {
374 mat_type X1_T_X2 (ncols_X1, ncols_X2);
399 tsqr_adaptor_type tsqrAdaptor_;
419 bool randomizeNullSpace_;
426 bool reorthogonalizeBlocks_;
431 bool throwOnReorthogFault_;
434 magnitude_type blockReorthogThreshold_;
437 magnitude_type relativeRankTolerance_;
445 bool forceNonnegativeDiagonal_;
449 raiseReorthogFault (
const std::vector<magnitude_type>& normsAfterFirstPass,
450 const std::vector<magnitude_type>& normsAfterSecondPass,
451 const std::vector<int>& faultIndices);
463 checkProjectionDims (
int& ncols_X,
483 const bool attemptToRecycle =
true)
const;
494 projectAndNormalizeImpl (MV& X_in,
496 const bool outOfPlace,
515 const mat_ptr& C)
const;
543 int rawNormalize (MV& X, MV& Q,
mat_type& B);
562 int normalizeOne (MV& X, mat_ptr B)
const;
591 int normalizeImpl (MV& X, MV& Q, mat_ptr B,
const bool outOfPlace);
594 template<
class Scalar,
class MV>
600 using Teuchos::parameterList;
602 using Teuchos::sublist;
603 typedef magnitude_type M;
605 RCP<const ParameterList> defaultParams = getValidParameters ();
607 RCP<ParameterList> tsqrParams;
609 RCP<ParameterList> theParams;
611 theParams = parameterList (*defaultParams);
619 randomizeNullSpace_ =
620 theParams->
get<
bool> (
"randomizeNullSpace",
621 defaultParams->get<
bool> (
"randomizeNullSpace"));
622 reorthogonalizeBlocks_ =
623 theParams->get<
bool> (
"reorthogonalizeBlocks",
624 defaultParams->get<
bool> (
"reorthogonalizeBlocks"));
625 throwOnReorthogFault_ =
626 theParams->get<
bool> (
"throwOnReorthogFault",
627 defaultParams->get<
bool> (
"throwOnReorthogFault"));
628 blockReorthogThreshold_ =
629 theParams->get<M> (
"blockReorthogThreshold",
630 defaultParams->get<M> (
"blockReorthogThreshold"));
631 relativeRankTolerance_ =
632 theParams->get<M> (
"relativeRankTolerance",
633 defaultParams->get<M> (
"relativeRankTolerance"));
634 forceNonnegativeDiagonal_ =
635 theParams->get<
bool> (
"forceNonnegativeDiagonal",
636 defaultParams->get<
bool> (
"forceNonnegativeDiagonal"));
640 if (! theParams->isSublist (
"TSQR implementation")) {
641 theParams->set (
"TSQR implementation",
642 defaultParams->sublist (
"TSQR implementation"));
644 tsqrParams = sublist (theParams,
"TSQR implementation",
true);
648 tsqrAdaptor_.setParameterList (tsqrParams);
651 setMyParamList (theParams);
654 template<
class Scalar,
class MV>
657 const std::string& label) :
661 randomizeNullSpace_ (true),
662 reorthogonalizeBlocks_ (true),
663 throwOnReorthogFault_ (false),
664 blockReorthogThreshold_ (0),
665 relativeRankTolerance_ (0),
666 forceNonnegativeDiagonal_ (false)
671 template<
class Scalar,
class MV>
677 randomizeNullSpace_ (true),
678 reorthogonalizeBlocks_ (true),
679 throwOnReorthogFault_ (false),
680 blockReorthogThreshold_ (0),
681 relativeRankTolerance_ (0),
682 forceNonnegativeDiagonal_ (false)
687 template<
class Scalar,
class MV>
690 norm (
const MV& X, std::vector<magnitude_type>& normVec)
const
692 const int numCols = MVT::GetNumberVecs (X);
695 if (normVec.size() <
static_cast<size_t>(numCols))
696 normVec.resize (numCols);
697 MVT::MvNorm (X, normVec);
700 template<
class Scalar,
class MV>
706 int ncols_X, num_Q_blocks, ncols_Q_total;
707 checkProjectionDims (ncols_X, num_Q_blocks, ncols_Q_total, X, Q);
711 if (ncols_X == 0 || num_Q_blocks == 0 || ncols_Q_total == 0)
715 allocateProjectionCoefficients (C, Q, X,
true);
719 std::vector<magnitude_type> columnNormsBefore (ncols_X, magnitude_type(0));
720 if (reorthogonalizeBlocks_)
721 MVT::MvNorm (X, columnNormsBefore);
725 rawProject (X, Q, C);
729 if (reorthogonalizeBlocks_)
731 std::vector<magnitude_type> columnNormsAfter (ncols_X, magnitude_type(0));
732 MVT::MvNorm (X, columnNormsAfter);
735 const magnitude_type relThres = blockReorthogThreshold();
741 bool reorthogonalize =
false;
742 for (
int j = 0; j < ncols_X; ++j)
743 if (columnNormsAfter[j] < relThres * columnNormsBefore[j])
745 reorthogonalize =
true;
752 allocateProjectionCoefficients (C2, Q, X,
false);
756 rawProject (X, Q, C2);
758 for (
int k = 0; k < num_Q_blocks; ++k)
766 template<
class Scalar,
class MV>
776 const int numCols = MVT::GetNumberVecs (X);
785 return normalizeOne (X, B);
815 MVT::GetGlobalLength(*Q_) != MVT::GetGlobalLength(X) ||
816 numCols > MVT::GetNumberVecs (*Q_)) {
817 Q_ = MVT::Clone (X, numCols);
826 if (MVT::GetNumberVecs(*Q_) == numCols) {
827 return normalizeImpl (X, *Q_, B,
false);
829 RCP<MV> Q_view = MVT::CloneViewNonConst (*Q_, Range1D(0, numCols-1));
830 return normalizeImpl (X, *Q_view, B,
false);
834 template<
class Scalar,
class MV>
840 const bool attemptToRecycle)
const
842 const int num_Q_blocks = Q.size();
843 const int ncols_X = MVT::GetNumberVecs (X);
845 if (attemptToRecycle)
847 for (
int i = 0; i < num_Q_blocks; ++i)
849 const int ncols_Qi = MVT::GetNumberVecs (*Q[i]);
853 C[i] =
rcp (
new mat_type (ncols_Qi, ncols_X));
856 mat_type& Ci = *C[i];
857 if (Ci.numRows() != ncols_Qi || Ci.numCols() != ncols_X)
858 Ci.shape (ncols_Qi, ncols_X);
860 Ci.putScalar (SCT::zero());
866 for (
int i = 0; i < num_Q_blocks; ++i)
868 const int ncols_Qi = MVT::GetNumberVecs (*Q[i]);
869 C[i] =
rcp (
new mat_type (ncols_Qi, ncols_X));
874 template<
class Scalar,
class MV>
879 const int numVecs = MVT::GetNumberVecs(X);
882 }
else if (numVecs == 1) {
889 const int rank = normalizeOne (X, B);
891 RCP<MV> Q_0 = MVT::CloneViewNonConst (Q, Range1D(0,0));
892 MVT::Assign (X, *Q_0);
898 return normalizeImpl (X, Q, B,
true);
902 template<
class Scalar,
class MV>
907 const bool outOfPlace,
919 std::invalid_argument,
920 "Belos::TsqrOrthoManagerImpl::"
921 "projectAndNormalizeOutOfPlace(...):"
922 "X_out has " << MVT::GetNumberVecs(X_out)
923 <<
" columns, but X_in has "
924 << MVT::GetNumberVecs(X_in) <<
" columns.");
928 int ncols_X, num_Q_blocks, ncols_Q_total;
929 checkProjectionDims (ncols_X, num_Q_blocks, ncols_Q_total, X_in, Q);
936 if (num_Q_blocks == 0 || ncols_Q_total == 0) {
938 return normalizeOutOfPlace (X_in, X_out, B);
940 return normalize (X_in, B);
947 allocateProjectionCoefficients (C, Q, X_in,
true);
952 std::vector<magnitude_type> normsBeforeFirstPass (ncols_X, SCTM::zero());
953 if (reorthogonalizeBlocks_) {
954 MVT::MvNorm (X_in, normsBeforeFirstPass);
958 rawProject (X_in, Q, C);
971 B_out =
rcp (
new mat_type (ncols_X, ncols_X));
975 std::invalid_argument,
976 "normalizeOne: Input matrix B must be at "
977 "least " << ncols_X <<
" x " << ncols_X
978 <<
", but is instead " << B->numRows()
979 <<
" x " << B->numCols() <<
".");
989 const int firstPassRank = outOfPlace ?
990 normalizeOutOfPlace (X_in, X_out, B_out) :
991 normalize (X_in, B_out);
1000 int rank = firstPassRank;
1016 if (firstPassRank < ncols_X && randomizeNullSpace_) {
1017 const int numNullSpaceCols = ncols_X - firstPassRank;
1018 const Range1D nullSpaceIndices (firstPassRank, ncols_X - 1);
1022 for (
int k = 0; k < num_Q_blocks; ++k) {
1023 const int numColsQk = MVT::GetNumberVecs(*Q[k]);
1024 C_null[k] =
rcp (
new mat_type (numColsQk, numNullSpaceCols));
1027 RCP<mat_type> B_null (
new mat_type (numNullSpaceCols, numNullSpaceCols));
1029 int randomVectorsRank;
1033 RCP<MV> X_out_null = MVT::CloneViewNonConst (X_out, nullSpaceIndices);
1038 RCP<MV> X_in_null = MVT::CloneViewNonConst (X_in, nullSpaceIndices);
1039 MVT::Assign (*X_out_null, *X_in_null);
1042 rawProject (*X_in_null, Q, C_null);
1043 randomVectorsRank = normalizeOutOfPlace (*X_in_null, *X_out_null, B_null);
1047 RCP<MV> X_null = MVT::CloneViewNonConst (X_in, nullSpaceIndices);
1050 rawProject (*X_null, Q, C_null);
1051 randomVectorsRank = normalize (*X_null, B_null);
1059 "Belos::TsqrOrthoManagerImpl::projectAndNormalize"
1060 "OutOfPlace(): After projecting and normalizing the "
1061 "random vectors (used to replace the null space "
1062 "basis vectors from normalizing X), they have rank "
1063 << randomVectorsRank <<
", but should have full "
1064 "rank " << numNullSpaceCols <<
".");
1069 if (reorthogonalizeBlocks_) {
1072 std::vector<magnitude_type>
1073 normsAfterFirstPass (firstPassRank, SCTM::zero());
1074 std::vector<magnitude_type>
1075 normsAfterSecondPass (firstPassRank, SCTM::zero());
1090 for (
int j = 0; j < firstPassRank; ++j) {
1091 const Scalar*
const B_j = &(*B_out)(0,j);
1094 normsAfterFirstPass[j] = blas.
NRM2 (firstPassRank, B_j, 1);
1098 bool reorthogonalize =
false;
1099 for (
int j = 0; j < firstPassRank; ++j) {
1106 const magnitude_type curThreshold =
1107 blockReorthogThreshold() * normsBeforeFirstPass[j];
1108 if (normsAfterFirstPass[j] < curThreshold) {
1109 reorthogonalize =
true;
1124 bool reorthogFault =
false;
1126 std::vector<int> faultIndices;
1127 if (reorthogonalize) {
1135 MVT::Assign (X_out, X_in);
1141 allocateProjectionCoefficients (C2, Q, X_in,
false);
1146 rawProject (X_in, Q, C2);
1149 RCP<mat_type> B2 (
new mat_type (ncols_X, ncols_X));
1152 const int secondPassRank = outOfPlace ?
1153 normalizeOutOfPlace (X_in, X_out, B2) :
1154 normalize (X_in, B2);
1155 rank = secondPassRank;
1160 mat_type B_copy (Copy, *B_out, B_out->numRows(), B_out->numCols());
1162 const int err = B_out->multiply (NO_TRANS, NO_TRANS, SCT::one(),
1163 *B2, B_copy, SCT::zero());
1165 "Teuchos::SerialDenseMatrix::multiply "
1166 "returned err = " << err <<
" != 0");
1170 for (
int k = 0; k < num_Q_blocks; ++k) {
1171 mat_type C_k_copy (Copy, *C[k], C[k]->numRows(), C[k]->numCols());
1174 const int err2 = C[k]->multiply (NO_TRANS, NO_TRANS, SCT::one(),
1175 *C2[k], B_copy, SCT::one());
1177 "Teuchos::SerialDenseMatrix::multiply "
1178 "returned err = " << err <<
" != 0");
1183 for (
int j = 0; j < rank; ++j) {
1184 const Scalar*
const B2_j = &(*B2)(0,j);
1185 normsAfterSecondPass[j] = blas.
NRM2 (rank, B2_j, 1);
1190 reorthogFault =
false;
1191 for (
int j = 0; j < rank; ++j) {
1192 const magnitude_type relativeLowerBound =
1193 blockReorthogThreshold() * normsAfterFirstPass[j];
1194 if (normsAfterSecondPass[j] < relativeLowerBound) {
1195 reorthogFault =
true;
1196 faultIndices.push_back (j);
1201 if (reorthogFault) {
1202 if (throwOnReorthogFault_) {
1203 raiseReorthogFault (normsAfterFirstPass,
1204 normsAfterSecondPass,
1213 "TsqrOrthoManagerImpl has not yet implemented"
1214 " recovery from an orthogonalization fault.");
1222 template<
class Scalar,
class MV>
1224 TsqrOrthoManagerImpl<Scalar, MV>::
1225 raiseReorthogFault (
const std::vector<magnitude_type>& normsAfterFirstPass,
1226 const std::vector<magnitude_type>& normsAfterSecondPass,
1227 const std::vector<int>& faultIndices)
1230 typedef std::vector<int>::size_type size_type;
1231 std::ostringstream os;
1233 os <<
"Orthogonalization fault at the following column(s) of X:" << endl;
1234 os <<
"Column\tNorm decrease factor" << endl;
1235 for (size_type k = 0; k < faultIndices.size(); ++k)
1237 const int index = faultIndices[k];
1238 const magnitude_type decreaseFactor =
1239 normsAfterSecondPass[index] / normsAfterFirstPass[index];
1240 os << index <<
"\t" << decreaseFactor << endl;
1242 throw TsqrOrthoFault (os.str());
1245 template<
class Scalar,
class MV>
1250 using Teuchos::parameterList;
1253 if (defaultParams_.is_null()) {
1254 RCP<ParameterList> params = parameterList (
"TsqrOrthoManagerImpl");
1258 params->set (
"TSQR implementation", *(tsqrAdaptor_.getValidParameters()),
1259 "TSQR implementation parameters.");
1263 const bool defaultRandomizeNullSpace =
true;
1264 params->set (
"randomizeNullSpace", defaultRandomizeNullSpace,
1265 "Whether to fill in null space vectors with random data.");
1267 const bool defaultReorthogonalizeBlocks =
true;
1268 params->set (
"reorthogonalizeBlocks", defaultReorthogonalizeBlocks,
1269 "Whether to do block reorthogonalization as necessary.");
1273 const magnitude_type defaultBlockReorthogThreshold =
1274 magnitude_type(10) * SCTM::squareroot (SCTM::eps());
1275 params->set (
"blockReorthogThreshold", defaultBlockReorthogThreshold,
1276 "If reorthogonalizeBlocks==true, and if the norm of "
1277 "any column within a block decreases by this much or "
1278 "more after orthogonalization, we reorthogonalize.");
1282 const magnitude_type defaultRelativeRankTolerance =
1283 Teuchos::as<magnitude_type>(10) * SCTM::eps();
1288 params->set (
"relativeRankTolerance", defaultRelativeRankTolerance,
1289 "Relative tolerance to determine the numerical rank of a "
1290 "block when normalizing.");
1294 const bool defaultThrowOnReorthogFault =
true;
1295 params->set (
"throwOnReorthogFault", defaultThrowOnReorthogFault,
1296 "Whether to throw an exception if an orthogonalization "
1297 "fault occurs. This only matters if reorthogonalization "
1298 "is enabled (reorthogonalizeBlocks==true).");
1300 const bool defaultForceNonnegativeDiagonal =
false;
1301 params->set (
"forceNonnegativeDiagonal", defaultForceNonnegativeDiagonal,
1302 "Whether to force the R factor produced by the normalization "
1303 "step to have a nonnegative diagonal.");
1305 defaultParams_ = params;
1307 return defaultParams_;
1310 template<
class Scalar,
class MV>
1318 RCP<const ParameterList> defaultParams = getValidParameters();
1320 RCP<ParameterList> params =
rcp (
new ParameterList (*defaultParams));
1329 const bool randomizeNullSpace =
false;
1330 params->set (
"randomizeNullSpace", randomizeNullSpace);
1331 const bool reorthogonalizeBlocks =
false;
1332 params->set (
"reorthogonalizeBlocks", reorthogonalizeBlocks);
1337 template<
class Scalar,
class MV>
1349 tsqrAdaptor_.factorExplicit (X, Q, B, forceNonnegativeDiagonal_);
1352 rank = tsqrAdaptor_.revealRank (Q, B, relativeRankTolerance_);
1353 }
catch (std::exception& e) {
1354 throw TsqrOrthoError (e.what());
1359 template<
class Scalar,
class MV>
1361 TsqrOrthoManagerImpl<Scalar, MV>::
1362 normalizeOne (MV& X,
1370 B_out =
rcp (
new mat_type (1, 1));
1372 const int numRows = B->
numRows();
1373 const int numCols = B->
numCols();
1375 std::invalid_argument,
1376 "normalizeOne: Input matrix B must be at "
1377 "least 1 x 1, but is instead " << numRows
1378 <<
" x " << numCols <<
".");
1384 std::vector<magnitude_type> theNorm (1, SCTM::zero());
1385 MVT::MvNorm (X, theNorm);
1386 (*B_out)(0,0) = theNorm[0];
1400 if (theNorm[0] == SCTM::zero()) {
1403 if (randomizeNullSpace_) {
1405 MVT::MvNorm (X, theNorm);
1406 if (theNorm[0] == SCTM::zero()) {
1411 throw TsqrOrthoError(
"normalizeOne: a supposedly random "
1412 "vector has norm zero!");
1417 const Scalar alpha = SCT::one() / theNorm[0];
1418 MVT::MvScale (X, alpha);
1425 const Scalar alpha = SCT::one() / theNorm[0];
1426 MVT::MvScale (X, alpha);
1432 template<
class Scalar,
class MV>
1434 TsqrOrthoManagerImpl<Scalar, MV>::
1440 const int num_Q_blocks = Q.size();
1441 for (
int i = 0; i < num_Q_blocks; ++i)
1449 mat_type& Ci = *C[i];
1450 const MV& Qi = *Q[i];
1451 innerProd (Qi, X, Ci);
1452 MVT::MvTimesMatAddMv (-SCT::one(), Qi, Ci, SCT::one(), X);
1457 template<
class Scalar,
class MV>
1459 TsqrOrthoManagerImpl<Scalar, MV>::
1465 innerProd (*Q, X, *C);
1466 MVT::MvTimesMatAddMv (-SCT::one(), *Q, *C, SCT::one(), X);
1469 template<
class Scalar,
class MV>
1471 TsqrOrthoManagerImpl<Scalar, MV>::
1472 normalizeImpl (MV& X,
1475 const bool outOfPlace)
1481 using Teuchos::tuple;
1486 const bool extraDebug =
false;
1488 const int numCols = MVT::GetNumberVecs (X);
1496 std::invalid_argument,
1497 "TsqrOrthoManagerImpl::normalizeImpl(X,Q,B): Q has "
1498 << MVT::GetNumberVecs(Q) <<
" columns. This is too "
1499 "few, since X has " << numCols <<
" columns.");
1503 RCP<MV> Q_view = MVT::CloneViewNonConst (Q, Range1D(0, numCols-1));
1511 B_out =
rcp (
new mat_type (numCols, numCols));
1515 std::invalid_argument,
1516 "normalizeOne: Input matrix B must be at "
1517 "least " << numCols <<
" x " << numCols
1518 <<
", but is instead " << B->
numRows()
1519 <<
" x " << B->
numCols() <<
".");
1526 std::vector<magnitude_type> norms (numCols);
1527 MVT::MvNorm (X, norms);
1528 cerr <<
"Column norms of X before orthogonalization: ";
1529 typedef typename std::vector<magnitude_type>::const_iterator iter_type;
1530 for (iter_type iter = norms.begin(); iter != norms.end(); ++iter) {
1532 if (iter+1 != norms.end())
1546 const int rank = rawNormalize (X, *Q_view, *B_out);
1557 std::vector<magnitude_type> norms (numCols);
1558 MVT::MvNorm (*Q_view, norms);
1559 cerr <<
"Column norms of Q_view after orthogonalization: ";
1560 for (
typename std::vector<magnitude_type>::const_iterator iter = norms.begin();
1561 iter != norms.end(); ++iter) {
1563 if (iter+1 != norms.end())
1568 "Belos::TsqrOrthoManagerImpl::normalizeImpl: "
1569 "rawNormalize() returned rank = " << rank <<
" for a "
1570 "matrix X with " << numCols <<
" columns. Please report"
1571 " this bug to the Belos developers.");
1572 if (extraDebug && rank == 0) {
1575 const mat_type& B_ref = *B;
1576 std::vector<magnitude_type> norms (B_ref.numCols());
1577 for (
typename mat_type::ordinalType j = 0; j < B_ref.numCols(); ++j) {
1578 typedef typename mat_type::scalarType mat_scalar_type;
1579 mat_scalar_type sumOfSquares = ScalarTraits<mat_scalar_type>::zero();
1580 for (
typename mat_type::ordinalType i = 0; i <= j; ++i) {
1581 const mat_scalar_type B_ij =
1582 ScalarTraits<mat_scalar_type>::magnitude (B_ref(i,j));
1583 sumOfSquares += B_ij*B_ij;
1585 norms[j] = ScalarTraits<mat_scalar_type>::squareroot (sumOfSquares);
1589 cerr <<
"Norms of columns of B after orthogonalization: ";
1590 for (
typename mat_type::ordinalType j = 0; j < B_ref.numCols(); ++j) {
1592 if (j != B_ref.numCols() - 1)
1600 if (rank == numCols || ! randomizeNullSpace_) {
1604 MVT::Assign (*Q_view, X);
1609 if (randomizeNullSpace_ && rank < numCols) {
1616 const int nullSpaceNumCols = numCols - rank;
1619 Range1D nullSpaceIndices (rank, numCols-1);
1626 RCP<MV> Q_null = MVT::CloneViewNonConst (*Q_view, nullSpaceIndices);
1628 MVT::MvRandom (*Q_null);
1634 std::vector<magnitude_type> norms (MVT::GetNumberVecs(*Q_null));
1635 MVT::MvNorm (*Q_null, norms);
1637 bool anyZero =
false;
1638 typedef typename std::vector<magnitude_type>::const_iterator iter_type;
1639 for (iter_type it = norms.begin(); it != norms.end(); ++it) {
1640 if (*it == SCTM::zero()) {
1645 std::ostringstream os;
1646 os <<
"TsqrOrthoManagerImpl::normalizeImpl: "
1647 "We are being asked to randomize the null space, for a matrix "
1648 "with " << numCols <<
" columns and reported column rank "
1649 << rank <<
". The inclusive range of columns to fill with "
1650 "random data is [" << nullSpaceIndices.lbound() <<
","
1651 << nullSpaceIndices.ubound() <<
"]. After filling the null "
1652 "space vectors with random numbers, at least one of the vectors"
1653 " has norm zero. Here are the norms of all the null space "
1655 for (iter_type it = norms.begin(); it != norms.end(); ++it) {
1657 if (it+1 != norms.end())
1660 os <<
"].) There is a tiny probability that this could happen "
1661 "randomly, but it is likely a bug. Please report it to the "
1662 "Belos developers, especially if you are able to reproduce the "
1675 RCP<const MV> Q_col = MVT::CloneView (*Q_view, Range1D(0, rank-1));
1680 mat_ptr C_null (
new mat_type (rank, nullSpaceNumCols));
1681 rawProject (*Q_null, Q_col, C_null);
1690 RCP<MV> X_null = MVT::CloneViewNonConst (X, nullSpaceIndices);
1693 mat_type B_null (nullSpaceNumCols, nullSpaceNumCols);
1695 const int nullSpaceBasisRank = rawNormalize (*Q_null, *X_null, B_null);
1709 if (nullSpaceBasisRank < nullSpaceNumCols) {
1710 std::vector<magnitude_type> norms (MVT::GetNumberVecs(*X_null));
1711 MVT::MvNorm (*X_null, norms);
1712 std::ostringstream os;
1713 os <<
"TsqrOrthoManagerImpl::normalizeImpl: "
1714 <<
"We are being asked to randomize the null space, "
1715 <<
"for a matrix with " << numCols <<
" columns and "
1716 <<
"column rank " << rank <<
". After projecting and "
1717 <<
"normalizing the generated random vectors, they "
1718 <<
"only have rank " << nullSpaceBasisRank <<
". They"
1719 <<
" should have full rank " << nullSpaceNumCols
1720 <<
". (The inclusive range of columns to fill with "
1721 <<
"random data is [" << nullSpaceIndices.lbound()
1722 <<
"," << nullSpaceIndices.ubound() <<
"]. The "
1723 <<
"column norms of the resulting Q factor are: [";
1724 for (
typename std::vector<magnitude_type>::size_type k = 0;
1725 k < norms.size(); ++k) {
1727 if (k != norms.size()-1) {
1731 os <<
"].) There is a tiny probability that this could "
1732 <<
"happen randomly, but it is likely a bug. Please "
1733 <<
"report it to the Belos developers, especially if "
1734 <<
"you are able to reproduce the behavior.";
1737 TsqrOrthoError, os.str());
1747 MVT::Assign (*X_null, *Q_null);
1748 }
else if (rank > 0) {
1750 RCP<const MV> Q_col = MVT::CloneView (*Q_view, Range1D(0, rank-1));
1751 RCP<MV> X_col = MVT::CloneViewNonConst (X, Range1D(0, rank-1));
1752 MVT::Assign (*Q_col, *X_col);
1759 template<
class Scalar,
class MV>
1761 TsqrOrthoManagerImpl<Scalar, MV>::
1762 checkProjectionDims (
int& ncols_X,
1774 int the_ncols_X, the_num_Q_blocks, the_ncols_Q_total;
1775 the_num_Q_blocks = Q.size();
1776 the_ncols_X = MVT::GetNumberVecs (X);
1779 the_ncols_Q_total = 0;
1784 typedef typename ArrayView<RCP<const MV> >::const_iterator iter_type;
1785 for (iter_type it = Q.begin(); it != Q.end(); ++it) {
1786 const MV& Qi = **it;
1787 the_ncols_Q_total += MVT::GetNumberVecs (Qi);
1791 ncols_X = the_ncols_X;
1792 num_Q_blocks = the_num_Q_blocks;
1793 ncols_Q_total = the_ncols_Q_total;
1798 #endif // __AnasaziTsqrOrthoManagerImpl_hpp
bool is_null(const boost::shared_ptr< T > &p)
TSQR-based OrthoManager subclass implementation.
Declaration of basic traits for the multivector type.
T & get(const std::string &name, T def_value)
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.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Teuchos::SerialDenseMatrix< int, Scalar > mat_type
ScalarTraits< ScalarType >::magnitudeType NRM2(const OrdinalType &n, const ScalarType *x, const OrdinalType &incx) const
magnitude_type blockReorthogThreshold() const
magnitude_type orthonormError(const MV &X) const
Return .
void innerProd(const MV &X, const MV &Y, mat_type &Z) const
Euclidean inner product.
void norm(const MV &X, std::vector< magnitude_type > &normvec) const
ScalarTraits< ScalarType >::magnitudeType normFrobenius() const
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > ¶ms)
Set parameters from the given parameter list.
TsqrOrthoManagerImpl(const Teuchos::RCP< Teuchos::ParameterList > ¶ms, const std::string &label)
Constructor (that sets user-specified parameters).
TsqrOrthoManager(Impl) error.
void setLabel(const std::string &label)
Set the label for timers.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Templated virtual class for providing orthogonalization/orthonormalization methods.
Traits class which defines basic operations on multivectors.
static void MvTransMv(const ScalarType alpha, const MV &A, const MV &B, Teuchos::SerialDenseMatrix< int, ScalarType > &C)
Compute C := alpha * A^H B.
const std::string & getLabel() const
Get the label for timers (if timers are enabled).
Teuchos::RCP< const Teuchos::ParameterList > getFastParameters()
Get "fast" parameters for TsqrOrthoManagerImpl.
void project(MV &X, Teuchos::Array< mat_ptr > C, Teuchos::ArrayView< Teuchos::RCP< const MV > > Q)
Compute and .
Anasazi header file which uses auto-configuration information to include necessary C++ headers...
void resize(size_type new_size, const value_type &x=value_type())
Exception thrown to signal error in an orthogonalization manager method.
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.
static int GetNumberVecs(const MV &mv)
Obtain the number of vectors in mv.
OrdinalType numCols() const
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Default valid parameter list.
magnitude_type relativeRankTolerance() const
magnitude_type orthogError(const MV &X1, const MV &X2) const
Return the Frobenius norm of the inner product of X1 with itself.
int normalize(MV &X, mat_ptr B)
Orthogonalize the columns of X in place.
OrdinalType numRows() const