41 typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType
magnitude_type;
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<Teuchos::RCP<DM>> 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<DM> >
C2;
255 allocateProjectionCoefficients (
C2,
Q,
X,
false);
256 for (
int k = 0;
k <
Q.size(); ++
k)
257 DMT::Add(*C[
k], *
C2[
k]);
264#ifdef BELOS_TEUCHOS_TIME_MONITOR
270 return normalizeMgs (
X, B);
272 return normalizeCgs (
X, B);
279 Teuchos::Array<Teuchos::RCP<DM>> C,
281 Teuchos::ArrayView<Teuchos::RCP<const MV> >
Q)
const
295 const int ncols = MVT::GetNumberVecs(
X);
298 DMT::SyncDeviceToHost(*
XTX);
302 DMT::SyncHostToDevice(*
XTX);
303 return DMT::NormFrobenius(*
XTX);
313 return DMT::NormFrobenius(*
X1_T_X2);
317 const std::string&
getLabel()
const {
return label_; }
322 normalizeMgs (MV &
X, Teuchos::RCP<DM> &B)
const
324 using Teuchos::Range1D;
329 const int numCols = MVT::GetNumberVecs (
X);
335 B = DMT::Create(numCols, numCols);
336 }
else if (DMT::GetNumRows(*B) != numCols || DMT::GetNumCols(*B) != numCols) {
337 DMT::Reshape(*B, numCols, numCols);
340 RCP<DM> tmpBij = DMT::Create(1,1);
343 std::vector<magnitude_type> normVec (1);
344 for (
int j = 0; j < numCols; ++j) {
345 RCP<MV> X_cur = MVT::CloneViewNonConst (X, Range1D(j, j));
347 for (
int i = 0; i < j; ++i) {
348 RCP<const MV> X_prv = MVT::CloneView (X, Range1D(i, i));
349 const MV& X_i = *X_prv;
350 RCP<DM> B_ij = DMT::Subview(*B, 1, 1, i, j);
352 MVT::MvTimesMatAddMv (-STS::one(), X_i, *B_ij, STS::one(), X_j);
353 if (reorthogonalize_) {
355 MVT::MvTimesMatAddMv (-STS::one(), X_i, *tmpBij, STS::one(), X_j);
356 DMT::Add( *B_ij, *tmpBij );
362 RCP<DM> B_jj = DMT::Subview(*B, 1, 1, j, j);
363 DMT::Value(*B_jj,0,0) = theNorm;
364 DMT::SyncHostToDevice(*B_jj);
365 if (normVec[0] != STM::zero()) {
366 MVT::MvScale (X_j, STS::one() / theNorm);
376 normalizeCgs (MV &X, Teuchos::RCP<DM> &B)
const
378 using Teuchos::Range1D;
383 const int numCols = MVT::GetNumberVecs (X);
389 B = DMT::Create( numCols, numCols );
390 }
else if (DMT::GetNumRows(*B) != numCols || DMT::GetNumCols(*B) != numCols) {
391 DMT::Reshape(*B, numCols, numCols);
395 std::vector<magnitude_type> normVec (1);
398 RCP<DM> B2 = DMT::Create(numCols, numCols);
402 RCP<MV> X_cur = MVT::CloneViewNonConst (X, Range1D(0, 0));
404 norm (*X_cur, normVec);
406 RCP<DM> B_00 = DMT::Subview(*B, 1, 1);
407 DMT::PutScalar(*B_00, theNorm);
408 if (theNorm != STM::zero ()) {
409 const Scalar invNorm = STS::one () / theNorm;
410 MVT::MvScale (*X_cur, invNorm);
418 for (
int j = 1; j < numCols; ++j) {
419 RCP<MV> X_cur = MVT::CloneViewNonConst (X, Range1D(j, j));
420 RCP<const MV> X_prv = MVT::CloneView (X, Range1D(0, j-1));
421 RCP<DM> B_prvcur = DMT::Subview(*B, j, 1, 0, j);
425 MVT::MvTimesMatAddMv (-STS::one(), *X_prv, *B_prvcur, STS::one(), *X_cur);
428 if (reorthogonalize_) {
429 RCP<DM> B2_prvcur = DMT::Subview(*B2, j, 1, 0, j);
431 MVT::MvTimesMatAddMv (-STS::one(), *X_prv, *B2_prvcur, STS::one(), *X_cur);
432 DMT::Add(*B_prvcur, *B2_prvcur);
435 norm (*X_cur, normVec);
437 RCP<DM> B_jj = DMT::Subview(*B, 1, 1, j, j);
438 DMT::PutScalar(*B_jj, theNorm);
439 if (theNorm != STM::zero ()) {
440 const Scalar invNorm = STS::one () / theNorm;
441 MVT::MvScale (*X_cur, invNorm);
452 allocateProjectionCoefficients (Teuchos::Array<Teuchos::RCP<DM>>& C,
453 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q,
455 const bool attemptToRecycle =
true)
const
459 const int num_Q_blocks = Q.size();
460 const int ncols_X = MVT::GetNumberVecs (X);
461 C.resize (num_Q_blocks);
464 int numAllocated = 0;
465 if (attemptToRecycle) {
466 for (
int i = 0; i < num_Q_blocks; ++i) {
467 const int ncols_Qi = MVT::GetNumberVecs (*Q[i]);
470 if (C[i].is_null ()) {
471 C[i] = DMT::Create(ncols_Qi, ncols_X);
476 if (DMT::GetNumRows(Ci) != ncols_Qi || DMT::GetNumCols(Ci) != ncols_X) {
477 DMT::Reshape(Ci, ncols_Qi, ncols_X);
481 DMT::PutScalar(Ci, STS::zero());
487 for (
int i = 0; i < num_Q_blocks; ++i) {
488 const int ncols_Qi = MVT::GetNumberVecs (*Q[i]);
489 C[i] = DMT::Create( ncols_Qi, ncols_X );
493 if (! outMan_.is_null()) {
495 std::ostream& dbg = outMan_->stream(
Debug);
496 dbg <<
"SimpleOrthoManager::allocateProjectionCoefficients: "
497 <<
"Allocated " << numAllocated <<
" blocks out of "
498 << num_Q_blocks << endl;
504 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q,
505 Teuchos::ArrayView<Teuchos::RCP<DM> > C)
const
508 const int num_Q_blocks = Q.size();
509 for (
int i = 0; i < num_Q_blocks; ++i) {
511 const MV& Qi = *Q[i];
513 MVT::MvTimesMatAddMv (-STS::one(), Qi, Ci, STS::one(), X);