40 typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType
magnitude_type;
41 typedef Teuchos::SerialDenseMatrix<int, Scalar>
mat_type;
42 typedef Teuchos::RCP<Teuchos::SerialDenseMatrix<int, Scalar> >
mat_ptr;
46 typedef Teuchos::ScalarTraits<Scalar> STS;
47 typedef Teuchos::ScalarTraits<magnitude_type> STM;
52 Teuchos::RCP<OutputManager<Scalar> > outMan_;
54 bool reorthogonalize_;
58 mutable Teuchos::RCP<Teuchos::ParameterList> defaultParams_;
60#ifdef BELOS_TEUCHOS_TIME_MONITOR
76 static Teuchos::RCP<Teuchos::Time>
82 return Teuchos::TimeMonitor::getNewCounter (
timerLabel);
94 Teuchos::RCP<const Teuchos::ParameterList>
97 using Teuchos::ParameterList;
98 using Teuchos::parameterList;
104 if (defaultParams_.is_null()) {
107 "Which normalization method to use. Valid values are \"MGS\""
108 " (for Modified Gram-Schmidt) and \"CGS\" (for Classical "
111 "Whether to perform one (unconditional) reorthogonalization "
115 return defaultParams_;
123 Teuchos::RCP<const Teuchos::ParameterList>
126 using Teuchos::ParameterList;
127 using Teuchos::parameterList;
145 using Teuchos::ParameterList;
146 using Teuchos::parameterList;
148 using Teuchos::Exceptions::InvalidParameter;
152 if (
plist.is_null ()) {
158 const std::string normalizeImpl =
params->get<std::string>(
"Normalization");
161 if (normalizeImpl ==
"MGS" ||
162 normalizeImpl ==
"Mgs" ||
163 normalizeImpl ==
"mgs") {
165 params->set (
"Normalization", std::string (
"MGS"));
168 params->set (
"Normalization", std::string (
"CGS"));
186 const std::string&
label,
187 const Teuchos::RCP<Teuchos::ParameterList>&
params) :
191#ifdef BELOS_TEUCHOS_TIME_MONITOR
198 if (! outMan_.is_null ()) {
200 std::ostream&
dbg = outMan_->stream(
Debug);
201 dbg <<
"Belos::SimpleOrthoManager constructor:" << endl
202 <<
"-- Normalization method: "
203 << (useMgs_ ?
"MGS" :
"CGS") << endl
204 <<
"-- Reorthogonalize (unconditionally)? "
205 << (reorthogonalize_ ?
"Yes" :
"No") << endl;
215#ifdef BELOS_TEUCHOS_TIME_MONITOR
228 MVT::MvTransMv (STS::one (),
X, Y, Z);
232 const int numCols = MVT::GetNumberVecs (
X);
243 Teuchos::Array<mat_ptr> C,
244 Teuchos::ArrayView<Teuchos::RCP<const MV> >
Q)
const
246#ifdef BELOS_TEUCHOS_TIME_MONITOR
251 allocateProjectionCoefficients (C,
Q,
X,
true);
252 rawProject (
X,
Q, C);
253 if (reorthogonalize_) {
254 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,Scalar> > >
C2;
255 allocateProjectionCoefficients (
C2,
Q,
X,
false);
256 for (
int k = 0;
k <
Q.size(); ++
k)
264#ifdef BELOS_TEUCHOS_TIME_MONITOR
270 return normalizeMgs (
X, B);
272 return normalizeCgs (
X, B);
279 Teuchos::Array<mat_ptr> C,
281 Teuchos::ArrayView<Teuchos::RCP<const MV> >
Q)
const
295 const int ncols = MVT::GetNumberVecs(
X);
301 return XTX.normFrobenius();
311 return X1_T_X2.normFrobenius();
315 const std::string&
getLabel()
const {
return label_; }
321 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,Scalar> > B)
const
323 using Teuchos::Range1D;
328 const int numCols = MVT::GetNumberVecs (
X);
334 B = rcp (
new mat_type (numCols, numCols));
335 }
else if (B->numRows () != numCols || B->numCols () != numCols) {
336 B->shape (numCols, numCols);
340 std::vector<magnitude_type> normVec (1);
341 for (
int j = 0; j < numCols; ++j) {
342 RCP<MV> X_cur = MVT::CloneViewNonConst (X, Range1D(j, j));
344 for (
int i = 0; i < j; ++i) {
345 RCP<const MV> X_prv = MVT::CloneView (X, Range1D(i, i));
346 const MV& X_i = *X_prv;
347 mat_type B_ij (View, *B, 1, 1, i, j);
349 MVT::MvTimesMatAddMv (-STS::one(), X_i, B_ij, STS::one(), X_j);
350 if (reorthogonalize_) {
354 const Scalar B_ij_first = (*B)(i, j);
356 MVT::MvTimesMatAddMv (-STS::one(), X_i, B_ij, STS::one(), X_j);
357 (*B)(i, j) += B_ij_first;
363 (*B)(j, j) = theNorm;
364 if (normVec[0] != STM::zero()) {
365 MVT::MvScale (X_j, STS::one() / theNorm);
375 normalizeCgs (MV &X,
mat_ptr B)
const
377 using Teuchos::Range1D;
382 const int numCols = MVT::GetNumberVecs (X);
388 B = rcp (
new mat_type (numCols, numCols));
389 }
else if (B->numRows() != numCols || B->numCols() != numCols) {
390 B->shape (numCols, numCols);
395 std::vector<magnitude_type> normVec (1);
402 RCP<MV> X_cur = MVT::CloneViewNonConst (X, Range1D(0, 0));
404 norm (*X_cur, normVec);
406 B_ref(0,0) = theNorm;
407 if (theNorm != STM::zero ()) {
408 const Scalar invNorm = STS::one () / theNorm;
409 MVT::MvScale (*X_cur, invNorm);
417 for (
int j = 1; j < numCols; ++j) {
418 RCP<MV> X_cur = MVT::CloneViewNonConst (X, Range1D(j, j));
419 RCP<const MV> X_prv = MVT::CloneView (X, Range1D(0, j-1));
420 mat_type B_prvcur (View, B_ref, j, 1, 0, j);
424 MVT::MvTimesMatAddMv (-STS::one(), *X_prv, B_prvcur, STS::one(), *X_cur);
427 if (reorthogonalize_) {
428 mat_type B2_prvcur (View, B2, j, 1, 0, j);
430 MVT::MvTimesMatAddMv (-STS::one(), *X_prv, B2_prvcur, STS::one(), *X_cur);
431 B_prvcur += B2_prvcur;
434 norm (*X_cur, normVec);
436 B_ref(j,j) = theNorm;
437 if (theNorm != STM::zero ()) {
438 const Scalar invNorm = STS::one () / theNorm;
439 MVT::MvScale (*X_cur, invNorm);
450 allocateProjectionCoefficients (Teuchos::Array<mat_ptr>& C,
451 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q,
453 const bool attemptToRecycle =
true)
const
457 const int num_Q_blocks = Q.size();
458 const int ncols_X = MVT::GetNumberVecs (X);
459 C.resize (num_Q_blocks);
462 int numAllocated = 0;
463 if (attemptToRecycle) {
464 for (
int i = 0; i < num_Q_blocks; ++i) {
465 const int ncols_Qi = MVT::GetNumberVecs (*Q[i]);
468 if (C[i].is_null ()) {
469 C[i] = rcp (
new mat_type (ncols_Qi, ncols_X));
474 if (Ci.numRows() != ncols_Qi || Ci.numCols() != ncols_X) {
475 Ci.shape (ncols_Qi, ncols_X);
479 Ci.putScalar (STS::zero());
485 for (
int i = 0; i < num_Q_blocks; ++i) {
486 const int ncols_Qi = MVT::GetNumberVecs (*Q[i]);
487 C[i] = rcp (
new mat_type (ncols_Qi, ncols_X));
491 if (! outMan_.is_null()) {
493 std::ostream& dbg = outMan_->stream(
Debug);
494 dbg <<
"SimpleOrthoManager::allocateProjectionCoefficients: "
495 <<
"Allocated " << numAllocated <<
" blocks out of "
496 << num_Q_blocks << endl;
502 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q,
503 Teuchos::ArrayView<mat_ptr> C)
const
506 const int num_Q_blocks = Q.size();
507 for (
int i = 0; i < num_Q_blocks; ++i) {
509 const MV& Qi = *Q[i];
511 MVT::MvTimesMatAddMv (-STS::one(), Qi, Ci, STS::one(), X);