15#ifndef BELOS_IMGS_ORTHOMANAGER_HPP
16#define BELOS_IMGS_ORTHOMANAGER_HPP
35#include "Teuchos_as.hpp"
36#ifdef BELOS_TEUCHOS_TIME_MONITOR
37#include "Teuchos_TimeMonitor.hpp"
43 template<
class ScalarType,
class MV,
class OP,
class DM = DefaultDenseMatrix<
int,ScalarType>>
47 template<
class ScalarType,
class MV,
class OP,
class DM = DefaultDenseMatrix<
int,ScalarType>>
50 template<
class ScalarType,
class MV,
class OP,
class DM = DefaultDenseMatrix<
int,ScalarType>>
55 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
56 typedef typename Teuchos::ScalarTraits<MagnitudeType> MGT;
57 typedef Teuchos::ScalarTraits<ScalarType> SCT;
68 Teuchos::RCP<const OP> Op = Teuchos::null,
73 max_ortho_steps_( max_ortho_steps ),
75 sing_tol_( sing_tol ),
78#ifdef BELOS_TEUCHOS_TIME_MONITOR
80 ss << label_ +
": IMGS[" << max_ortho_steps_ <<
"]";
82 std::string orthoLabel = ss.str() +
": Orthogonalization";
83 timerOrtho_ = Teuchos::TimeMonitor::getNewCounter(orthoLabel);
85 std::string updateLabel = ss.str() +
": Ortho (Update)";
86 timerUpdate_ = Teuchos::TimeMonitor::getNewCounter(updateLabel);
88 std::string normLabel = ss.str() +
": Ortho (Norm)";
89 timerNorm_ = Teuchos::TimeMonitor::getNewCounter(normLabel);
91 std::string ipLabel = ss.str() +
": Ortho (Inner Product)";
92 timerInnerProd_ = Teuchos::TimeMonitor::getNewCounter(ipLabel);
98 const std::string& label =
"Belos",
99 Teuchos::RCP<const OP> Op = Teuchos::null) :
108#ifdef BELOS_TEUCHOS_TIME_MONITOR
109 std::stringstream ss;
110 ss << label_ +
": IMGS[" << max_ortho_steps_ <<
"]";
112 std::string orthoLabel = ss.str() +
": Orthogonalization";
113 timerOrtho_ = Teuchos::TimeMonitor::getNewCounter(orthoLabel);
115 std::string updateLabel = ss.str() +
": Ortho (Update)";
116 timerUpdate_ = Teuchos::TimeMonitor::getNewCounter(updateLabel);
118 std::string normLabel = ss.str() +
": Ortho (Norm)";
119 timerNorm_ = Teuchos::TimeMonitor::getNewCounter(normLabel);
121 std::string ipLabel = ss.str() +
": Ortho (Inner Product)";
122 timerInnerProd_ = Teuchos::TimeMonitor::getNewCounter(ipLabel);
135 using Teuchos::Exceptions::InvalidParameterName;
136 using Teuchos::ParameterList;
137 using Teuchos::parameterList;
141 RCP<ParameterList> params;
142 if (plist.is_null()) {
143 params = parameterList (*defaultParams);
158 int maxNumOrthogPasses;
159 MagnitudeType blkTol;
160 MagnitudeType singTol;
163 maxNumOrthogPasses = params->get<
int> (
"maxNumOrthogPasses");
164 }
catch (InvalidParameterName&) {
165 maxNumOrthogPasses = defaultParams->get<
int> (
"maxNumOrthogPasses");
166 params->set (
"maxNumOrthogPasses", maxNumOrthogPasses);
177 blkTol = params->get<MagnitudeType> (
"blkTol");
178 }
catch (InvalidParameterName&) {
180 blkTol = params->get<MagnitudeType> (
"depTol");
183 params->remove (
"depTol");
184 }
catch (InvalidParameterName&) {
185 blkTol = defaultParams->get<MagnitudeType> (
"blkTol");
187 params->set (
"blkTol", blkTol);
191 singTol = params->get<MagnitudeType> (
"singTol");
192 }
catch (InvalidParameterName&) {
193 singTol = defaultParams->get<MagnitudeType> (
"singTol");
194 params->set (
"singTol", singTol);
197 max_ortho_steps_ = maxNumOrthogPasses;
201 this->setMyParamList (params);
204 Teuchos::RCP<const Teuchos::ParameterList>
207 if (defaultParams_.is_null()) {
211 return defaultParams_;
220 void setBlkTol(
const MagnitudeType blk_tol ) { blk_tol_ = blk_tol; }
223 void setSingTol(
const MagnitudeType sing_tol ) { sing_tol_ = sing_tol; }
264 void project ( MV &X, Teuchos::RCP<MV> MX,
265 Teuchos::Array<Teuchos::RCP<DM> > C,
266 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const;
272 Teuchos::Array<Teuchos::RCP<DM> > C,
273 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const {
303 int normalize ( MV &X, Teuchos::RCP<MV> MX,
304 Teuchos::RCP<DM> B)
const;
358 Teuchos::Array<Teuchos::RCP<DM>> C,
360 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const;
370 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
379 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
385 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
394 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
395 orthogError(
const MV &X1, Teuchos::RCP<const MV> MX1,
const MV &X2)
const;
404 void setLabel(
const std::string& label);
408 const std::string&
getLabel()
const {
return label_; }
434 int max_ortho_steps_;
436 MagnitudeType blk_tol_;
438 MagnitudeType sing_tol_;
442#ifdef BELOS_TEUCHOS_TIME_MONITOR
443 Teuchos::RCP<Teuchos::Time> timerOrtho_, timerUpdate_, timerNorm_, timerInnerProd_;
447 mutable Teuchos::RCP<Teuchos::ParameterList> defaultParams_;
450 int findBasis(MV &X, Teuchos::RCP<MV> MX,
452 bool completeBasis,
int howMany = -1 )
const;
455 bool blkOrtho1 ( MV &X, Teuchos::RCP<MV> MX,
456 Teuchos::Array<Teuchos::RCP<DM> > C,
457 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const;
460 bool blkOrtho ( MV &X, Teuchos::RCP<MV> MX,
461 Teuchos::Array<Teuchos::RCP<DM> > C,
462 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const;
477 int blkOrthoSing ( MV &X, Teuchos::RCP<MV> MX,
478 Teuchos::Array<Teuchos::RCP<DM> > C,
480 Teuchos::ArrayView<Teuchos::RCP<const MV> > QQ)
const;
484 template<
class ScalarType,
class MV,
class OP,
class DM>
487 template<
class ScalarType,
class MV,
class OP,
class DM>
488 const typename IMGSOrthoManager<ScalarType,MV,OP,DM>::MagnitudeType
490 = 10*Teuchos::ScalarTraits<typename IMGSOrthoManager<ScalarType,MV,OP,DM>::MagnitudeType>::squareroot(
491 Teuchos::ScalarTraits<
typename IMGSOrthoManager<ScalarType,MV,OP,DM>::MagnitudeType>::eps() );
493 template<
class ScalarType,
class MV,
class OP,
class DM>
494 const typename IMGSOrthoManager<ScalarType,MV,OP,DM>::MagnitudeType
496 = 10*Teuchos::ScalarTraits<typename IMGSOrthoManager<ScalarType,MV,OP,DM>::MagnitudeType>::eps();
498 template<
class ScalarType,
class MV,
class OP,
class DM>
501 template<
class ScalarType,
class MV,
class OP,
class DM>
502 const typename IMGSOrthoManager<ScalarType,MV,OP,DM>::MagnitudeType
504 = Teuchos::ScalarTraits<typename IMGSOrthoManager<ScalarType,MV,OP,DM>::MagnitudeType>::zero();
506 template<
class ScalarType,
class MV,
class OP,
class DM>
507 const typename IMGSOrthoManager<ScalarType,MV,OP,DM>::MagnitudeType
509 = Teuchos::ScalarTraits<typename IMGSOrthoManager<ScalarType,MV,OP,DM>::MagnitudeType>::zero();
513 template<
class ScalarType,
class MV,
class OP,
class DM>
516 if (label != label_) {
518#ifdef BELOS_TEUCHOS_TIME_MONITOR
519 std::stringstream ss;
520 ss << label_ +
": IMGS[" << max_ortho_steps_ <<
"]";
522 std::string orthoLabel = ss.str() +
": Orthogonalization";
523 timerOrtho_ = Teuchos::TimeMonitor::getNewCounter(orthoLabel);
525 std::string updateLabel = ss.str() +
": Ortho (Update)";
526 timerUpdate_ = Teuchos::TimeMonitor::getNewCounter(updateLabel);
528 std::string normLabel = ss.str() +
": Ortho (Norm)";
529 timerNorm_ = Teuchos::TimeMonitor::getNewCounter(normLabel);
531 std::string ipLabel = ss.str() +
": Ortho (Inner Product)";
532 timerInnerProd_ = Teuchos::TimeMonitor::getNewCounter(ipLabel);
539 template<
class ScalarType,
class MV,
class OP,
class DM>
540 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
542 const ScalarType ONE = SCT::one();
547 for (
int i=0; i<rank; i++) {
556 template<
class ScalarType,
class MV,
class OP,
class DM>
557 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
568 template<
class ScalarType,
class MV,
class OP,
class DM>
573 Teuchos::Array<Teuchos::RCP<DM>> C,
575 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const
577 using Teuchos::Array;
579 using Teuchos::is_null;
582 typedef typename Array< RCP< const MV > >::size_type size_type;
584#ifdef BELOS_TEUCHOS_TIME_MONITOR
585 Teuchos::TimeMonitor orthotimer(*timerOrtho_);
588 ScalarType ONE = SCT::one();
589 const MagnitudeType ZERO = MGT::zero();
610 for (size_type k = 0; k < nq; ++k)
613 const int numCols = xc;
625 if (MX == Teuchos::null) {
633 MX = Teuchos::rcp( &X,
false );
640 TEUCHOS_TEST_FOR_EXCEPTION( xc == 0 || xr == 0, std::invalid_argument,
"Belos::IMGSOrthoManager::projectAndNormalize(): X must be non-empty" );
643 for (
int i=0; i<nq; i++) {
649 "Belos::IMGSOrthoManager::projectAndNormalize(): Size of X must be consistant with size of B" );
651 TEUCHOS_TEST_FOR_EXCEPTION( xc<0 || xr<0 || mxc<0 || mxr<0, std::invalid_argument,
652 "Belos::IMGSOrthoManager::projectAndNormalize(): MVT returned negative dimensions for X,MX" );
654 TEUCHOS_TEST_FOR_EXCEPTION( xc!=mxc || xr!=mxr, std::invalid_argument,
655 "Belos::IMGSOrthoManager::projectAndNormalize(): Size of X must be consistant with size of MX" );
661 bool dep_flg =
false;
664 Teuchos::RCP<MV> tmpX, tmpMX;
674 dep_flg = blkOrtho1( X, MX, C, Q );
677 if ( B == Teuchos::null ) {
680 std::vector<ScalarType> dot(xc);
682#ifdef BELOS_TEUCHOS_TIME_MONITOR
683 Teuchos::TimeMonitor normTimer( *timerNorm_ );
688 ScalarType diag = SCT::squareroot(SCT::magnitude(dot[0]));
689 if (SCT::magnitude(diag) > ZERO) {
704 dep_flg = blkOrtho( X, MX, C, Q );
710 rank = blkOrthoSing( *tmpX, tmpMX, C, B, Q );
720 rank = findBasis( X, MX, B,
false );
725 rank = blkOrthoSing( *tmpX, tmpMX, C, B, Q );
737 TEUCHOS_TEST_FOR_EXCEPTION( rank > xc || rank < 0, std::logic_error,
738 "Belos::IMGSOrthoManager::projectAndNormalize(): Debug error in rank variable." );
748 template<
class ScalarType,
class MV,
class OP,
class DM>
750 MV &X, Teuchos::RCP<MV> MX,
751 Teuchos::RCP<DM> B )
const {
753#ifdef BELOS_TEUCHOS_TIME_MONITOR
754 Teuchos::TimeMonitor orthotimer(*timerOrtho_);
758 return findBasis(X, MX, B,
true);
764 template<
class ScalarType,
class MV,
class OP,
class DM>
766 MV &X, Teuchos::RCP<MV> MX,
767 Teuchos::Array<Teuchos::RCP<DM>> C,
768 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const {
784#ifdef BELOS_TEUCHOS_TIME_MONITOR
785 Teuchos::TimeMonitor orthotimer(*timerOrtho_);
791 std::vector<int> qcs(nq);
793 if (nq == 0 || xc == 0 || xr == 0) {
805 if (MX == Teuchos::null) {
813 MX = Teuchos::rcp( &X,
false );
819 TEUCHOS_TEST_FOR_EXCEPTION( xc<0 || xr<0 || mxc<0 || mxr<0, std::invalid_argument,
820 "Belos::IMGSOrthoManager::project(): MVT returned negative dimensions for X,MX" );
822 TEUCHOS_TEST_FOR_EXCEPTION( xc!=mxc || xr!=mxr || xr!=qr, std::invalid_argument,
823 "Belos::IMGSOrthoManager::project(): Size of X not consistant with MX,Q" );
826 for (
int i=0; i<nq; i++) {
828 "Belos::IMGSOrthoManager::project(): Q lengths not mutually consistant" );
830 TEUCHOS_TEST_FOR_EXCEPTION( qr < qcs[i], std::invalid_argument,
831 "Belos::IMGSOrthoManager::project(): Q has less rows than columns" );
834 if ( C[i] == Teuchos::null ) {
839 "Belos::IMGSOrthoManager::project(): Size of Q not consistant with size of C" );
844 blkOrtho( X, MX, C, Q );
851 template<
class ScalarType,
class MV,
class OP,
class DM>
852 int IMGSOrthoManager<ScalarType, MV, OP, DM>::findBasis(
853 MV &X, Teuchos::RCP<MV> MX,
855 bool completeBasis,
int howMany )
const {
872 const ScalarType ONE = SCT::one();
873 const MagnitudeType ZERO = SCT::magnitude(SCT::zero());
875 int xc = MVT::GetNumberVecs( X );
876 ptrdiff_t xr = MVT::GetGlobalLength( X );
889 if (MX == Teuchos::null) {
891 MX = MVT::Clone(X,xc);
892 OPT::Apply(*(this->_Op),X,*MX);
899 if ( B == Teuchos::null ) {
900 B = DMT::Create(xc,xc);
903 int mxc = (this->_hasOp) ? MVT::GetNumberVecs( *MX ) : xc;
904 ptrdiff_t mxr = (this->_hasOp) ? MVT::GetGlobalLength( *MX ) : xr;
907 TEUCHOS_TEST_FOR_EXCEPTION( xc == 0 || xr == 0, std::invalid_argument,
908 "Belos::IMGSOrthoManager::findBasis(): X must be non-empty" );
909 TEUCHOS_TEST_FOR_EXCEPTION( DMT::GetNumRows(*B) != xc || DMT::GetNumCols(*B) != xc, std::invalid_argument,
910 "Belos::IMGSOrthoManager::findBasis(): Size of X not consistant with size of B" );
911 TEUCHOS_TEST_FOR_EXCEPTION( xc != mxc || xr != mxr, std::invalid_argument,
912 "Belos::IMGSOrthoManager::findBasis(): Size of X not consistant with size of MX" );
913 TEUCHOS_TEST_FOR_EXCEPTION( xc > xr, std::invalid_argument,
914 "Belos::IMGSOrthoManager::findBasis(): Size of X not feasible for normalization" );
915 TEUCHOS_TEST_FOR_EXCEPTION( howMany < 0 || howMany > xc, std::invalid_argument,
916 "Belos::IMGSOrthoManager::findBasis(): Invalid howMany parameter" );
921 int xstart = xc - howMany;
923 for (
int j = xstart; j < xc; j++) {
932 std::vector<int> index(1);
934 Teuchos::RCP<MV> Xj = MVT::CloneViewNonConst( X, index );
935 Teuchos::RCP<MV> MXj;
936 if ((this->_hasOp)) {
938 MXj = MVT::CloneViewNonConst( *MX, index );
945 Teuchos::RCP<MV> oldMXj;
947 oldMXj = MVT::CloneCopy( *MXj );
951 Teuchos::RCP<DM> product = DMT::Create(numX,1);
952 Teuchos::RCP<DM> P2 = DMT::Create(1,1);
953 Teuchos::RCP<const MV> prevX, prevMX;
955 std::vector<ScalarType> oldDot( 1 ), newDot( 1 );
960#ifdef BELOS_TEUCHOS_TIME_MONITOR
961 Teuchos::TimeMonitor normTimer( *timerNorm_ );
963 MVT::MvDot( *Xj, *MXj, oldDot );
966 TEUCHOS_TEST_FOR_EXCEPTION( SCT::real(oldDot[0]) < ZERO,
OrthoError,
967 "Belos::IMGSOrthoManager::findBasis(): Negative definiteness discovered in inner product" );
970 for (
int ii=0; ii<numX; ii++) {
973 prevX = MVT::CloneView( X, index );
975 prevMX = MVT::CloneView( *MX, index );
978 for (
int i=0; i<max_ortho_steps_; ++i) {
982#ifdef BELOS_TEUCHOS_TIME_MONITOR
983 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
991#ifdef BELOS_TEUCHOS_TIME_MONITOR
992 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
994 MVT::MvTimesMatAddMv( -ONE, *prevX, *P2, ONE, *Xj );
1002#ifdef BELOS_TEUCHOS_TIME_MONITOR
1003 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1005 MVT::MvTimesMatAddMv( -ONE, *prevMX, *P2, ONE, *MXj );
1009 Teuchos::RCP<DM> product_ii = DMT::Subview(*product,1,1,ii,0);
1011 DMT::Assign(*product_ii, *P2);
1013 DMT::Add(*product_ii, *P2);
1021#ifdef BELOS_TEUCHOS_TIME_MONITOR
1022 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1024 MVT::MvDot( *Xj, *oldMXj, newDot );
1027 newDot[0] = oldDot[0];
1031 if (completeBasis) {
1035 if ( SCT::magnitude(newDot[0]) < SCT::magnitude(sing_tol_*oldDot[0]) ) {
1040 std::cout <<
"Belos::IMGSOrthoManager::findBasis() --> Random for column " << numX << std::endl;
1043 Teuchos::RCP<MV> tempXj = MVT::Clone( X, 1 );
1044 Teuchos::RCP<MV> tempMXj;
1045 MVT::MvRandom( *tempXj );
1047 tempMXj = MVT::Clone( X, 1 );
1048 OPT::Apply( *(this->_Op), *tempXj, *tempMXj );
1054#ifdef BELOS_TEUCHOS_TIME_MONITOR
1055 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1057 MVT::MvDot( *tempXj, *tempMXj, oldDot );
1061 for (
int ii=0; ii<numX; ii++) {
1064 prevX = MVT::CloneView( X, index );
1066 prevMX = MVT::CloneView( *MX, index );
1069 for (
int num_orth=0; num_orth<max_ortho_steps_; num_orth++){
1071#ifdef BELOS_TEUCHOS_TIME_MONITOR
1072 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1077#ifdef BELOS_TEUCHOS_TIME_MONITOR
1078 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1080 MVT::MvTimesMatAddMv( -ONE, *prevX, *P2, ONE, *tempXj );
1083#ifdef BELOS_TEUCHOS_TIME_MONITOR
1084 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1086 MVT::MvTimesMatAddMv( -ONE, *prevMX, *P2, ONE, *tempMXj );
1090 Teuchos::RCP<DM> product_ii = DMT::Subview(*product,1,1,ii,0);
1092 DMT::Assign(*product_ii, *P2);
1094 DMT::Add(*product_ii, *P2);
1100#ifdef BELOS_TEUCHOS_TIME_MONITOR
1101 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1103 MVT::MvDot( *tempXj, *tempMXj, newDot );
1106 if ( SCT::magnitude(newDot[0]) >= SCT::magnitude(oldDot[0]*sing_tol_) ) {
1108 MVT::Assign( *tempXj, *Xj );
1110 MVT::Assign( *tempMXj, *MXj );
1122 if ( SCT::magnitude(newDot[0]) < SCT::magnitude(oldDot[0]*blk_tol_) ) {
1131 ScalarType diag = SCT::squareroot(SCT::magnitude(newDot[0]));
1132 if (SCT::magnitude(diag) > ZERO) {
1133 MVT::MvScale( *Xj, ONE/diag );
1136 MVT::MvScale( *MXj, ONE/diag );
1141 Teuchos::RCP<DM> Bjj = DMT::Subview(*B,1,1,j,j);
1143 DMT::PutScalar(*Bjj, ZERO);
1146 DMT::PutScalar(*Bjj, diag);
1151 Teuchos::RCP<DM> Bcolj = DMT::Subview(*B,numX,1,0,j);
1152 DMT::Assign(*Bcolj,*product);
1162 template<
class ScalarType,
class MV,
class OP,
class DM>
1164 IMGSOrthoManager<ScalarType, MV, OP, DM>::blkOrtho1 ( MV &X, Teuchos::RCP<MV> MX,
1165 Teuchos::Array<Teuchos::RCP<DM>> C,
1166 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const
1169 int xc = MVT::GetNumberVecs( X );
1170 const ScalarType ONE = SCT::one();
1172 std::vector<int> qcs( nq );
1173 for (
int i=0; i<nq; i++) {
1174 qcs[i] = MVT::GetNumberVecs( *Q[i] );
1178 std::vector<int> index(1);
1179 Teuchos::RCP<const MV> tempQ;
1181 Teuchos::Array<Teuchos::RCP<MV> > MQ(nq);
1183 for (
int i=0; i<nq; i++) {
1186 for (
int ii=0; ii<qcs[i]; ii++) {
1189 tempQ = MVT::CloneView( *Q[i], index );
1190 Teuchos::RCP tempC = DMT::Subview(*C[i], 1, 1, ii, 0);
1194#ifdef BELOS_TEUCHOS_TIME_MONITOR
1195 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1201#ifdef BELOS_TEUCHOS_TIME_MONITOR
1202 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1204 MVT::MvTimesMatAddMv( -ONE, *tempQ, *tempC, ONE, X );
1211 OPT::Apply( *(this->_Op), X, *MX);
1215 MQ[i] = MVT::Clone( *Q[i], qcs[i] );
1216 OPT::Apply( *(this->_Op), *Q[i], *MQ[i] );
1217 MVT::MvTimesMatAddMv( -ONE, *MQ[i], *C[i], ONE, *MX );
1223 for (
int j = 1; j < max_ortho_steps_; ++j) {
1225 for (
int i=0; i<nq; i++) {
1227 Teuchos::RCP<DM> C2 = DMT::Create(qcs[i],1);
1230 for (
int ii=0; ii<qcs[i]; ii++) {
1233 tempQ = MVT::CloneView( *Q[i], index );
1234 Teuchos::RCP tempC = DMT::Subview(*C[i], 1, 1, ii, 0);
1235 Teuchos::RCP tempC2 = DMT::Subview(*C2, 1, 1, ii, 0);
1239#ifdef BELOS_TEUCHOS_TIME_MONITOR
1240 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1244 DMT::Add(*tempC,*tempC2);
1246#ifdef BELOS_TEUCHOS_TIME_MONITOR
1247 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1249 MVT::MvTimesMatAddMv( -ONE, *tempQ, *tempC2, ONE, X );
1258 MVT::MvTimesMatAddMv( -ONE, *MQ[i], *C2, ONE, *MX );
1260 else if (xc <= qcs[i]) {
1262 OPT::Apply( *(this->_Op), X, *MX);
1273 template<
class ScalarType,
class MV,
class OP,
class DM>
1275 IMGSOrthoManager<ScalarType, MV, OP, DM>::blkOrtho ( MV &X, Teuchos::RCP<MV> MX,
1276 Teuchos::Array<Teuchos::RCP<DM> > C,
1277 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const
1280 int xc = MVT::GetNumberVecs( X );
1281 bool dep_flg =
false;
1282 const ScalarType ONE = SCT::one();
1284 std::vector<int> qcs( nq );
1285 for (
int i=0; i<nq; i++) {
1286 qcs[i] = MVT::GetNumberVecs( *Q[i] );
1292 std::vector<ScalarType> oldDot( xc );
1294#ifdef BELOS_TEUCHOS_TIME_MONITOR
1295 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1297 MVT::MvDot( X, *MX, oldDot );
1300 std::vector<int> index(1);
1301 Teuchos::Array<Teuchos::RCP<MV> > MQ(nq);
1302 Teuchos::RCP<const MV> tempQ;
1305 for (
int i=0; i<nq; i++) {
1308 for (
int ii=0; ii<qcs[i]; ii++) {
1311 tempQ = MVT::CloneView( *Q[i], index );
1312 Teuchos::RCP tempC = DMT::Subview(*C[i], 1, xc, ii, 0);
1316#ifdef BELOS_TEUCHOS_TIME_MONITOR
1317 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1323#ifdef BELOS_TEUCHOS_TIME_MONITOR
1324 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1326 MVT::MvTimesMatAddMv( -ONE, *tempQ, *tempC, ONE, X );
1333 OPT::Apply( *(this->_Op), X, *MX);
1337 MQ[i] = MVT::Clone( *Q[i], qcs[i] );
1338 OPT::Apply( *(this->_Op), *Q[i], *MQ[i] );
1339 MVT::MvTimesMatAddMv( -ONE, *MQ[i], *C[i], ONE, *MX );
1345 for (
int j = 1; j < max_ortho_steps_; ++j) {
1347 for (
int i=0; i<nq; i++) {
1348 Teuchos::RCP C2 = DMT::Create(qcs[i],xc);
1351 for (
int ii=0; ii<qcs[i]; ii++) {
1354 tempQ = MVT::CloneView( *Q[i], index );
1355 Teuchos::RCP tempC = DMT::Subview(*C[i], 1, xc, ii, 0);
1356 Teuchos::RCP tempC2 = DMT::Subview(*C2, 1, xc, ii, 0);
1360#ifdef BELOS_TEUCHOS_TIME_MONITOR
1361 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1365 DMT::Add(*tempC,*tempC2);
1367#ifdef BELOS_TEUCHOS_TIME_MONITOR
1368 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1370 MVT::MvTimesMatAddMv( -ONE, *tempQ, *tempC2, ONE, X );
1378 MVT::MvTimesMatAddMv( -ONE, *MQ[i], *C2, ONE, *MX );
1380 else if (xc <= qcs[i]) {
1382 OPT::Apply( *(this->_Op), X, *MX);
1389 std::vector<ScalarType> newDot(xc);
1391#ifdef BELOS_TEUCHOS_TIME_MONITOR
1392 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1394 MVT::MvDot( X, *MX, newDot );
1398 for (
int i=0; i<xc; i++){
1399 if (SCT::magnitude(newDot[i]) < SCT::magnitude(oldDot[i] * blk_tol_)) {
1408 template<
class ScalarType,
class MV,
class OP,
class DM>
1410 IMGSOrthoManager<ScalarType, MV, OP, DM>::blkOrthoSing ( MV &X, Teuchos::RCP<MV> MX,
1411 Teuchos::Array<Teuchos::RCP<DM> > C,
1413 Teuchos::ArrayView<Teuchos::RCP<const MV> > QQ)
const
1415 Teuchos::Array<Teuchos::RCP<const MV> > Q (QQ);
1417 const ScalarType ONE = SCT::one();
1418 const ScalarType ZERO = SCT::zero();
1421 int xc = MVT::GetNumberVecs( X );
1422 std::vector<int> indX( 1 );
1423 std::vector<ScalarType> oldDot( 1 ), newDot( 1 );
1425 std::vector<int> qcs( nq );
1426 for (
int i=0; i<nq; i++) {
1427 qcs[i] = MVT::GetNumberVecs( *Q[i] );
1431 Teuchos::RCP<const MV> lastQ;
1432 Teuchos::RCP<MV> Xj, MXj;
1435 for (
int j=0; j<xc; j++) {
1437 bool dep_flg =
false;
1441 std::vector<int> index( j );
1442 for (
int ind=0; ind<j; ind++) {
1445 lastQ = MVT::CloneView( X, index );
1448 Q.push_back( lastQ );
1450 qcs.push_back( MVT::GetNumberVecs( *lastQ ) );
1455 Xj = MVT::CloneViewNonConst( X, indX );
1457 MXj = MVT::CloneViewNonConst( *MX, indX );
1465#ifdef BELOS_TEUCHOS_TIME_MONITOR
1466 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1468 MVT::MvDot( *Xj, *MXj, oldDot );
1471 Teuchos::Array<Teuchos::RCP<MV> > MQ(Q.size());
1472 Teuchos::RCP<const MV> tempQ;
1475 for (
int i=0; i<Q.size(); i++) {
1478 for (
int ii=0; ii<qcs[i]; ii++) {
1481 tempQ = MVT::CloneView( *Q[i], indX );
1483 Teuchos::RCP tempC = DMT::Subview(*C[i], 1, 1, ii, j);
1489 MVT::MvTimesMatAddMv( -ONE, *tempQ, *tempC, ONE, *Xj );
1495 OPT::Apply( *(this->_Op), *Xj, *MXj);
1499 MQ[i] = MVT::Clone( *Q[i], qcs[i] );
1500 OPT::Apply( *(this->_Op), *Q[i], *MQ[i] );
1501 Teuchos::RCP tempC = DMT::Subview(*C[i], qcs[i], 1, 0, j);
1502 MVT::MvTimesMatAddMv( -ONE, *MQ[i], *tempC, ONE, *MXj );
1508 for (
int num_ortho_steps=1; num_ortho_steps < max_ortho_steps_; ++num_ortho_steps) {
1510 for (
int i=0; i<Q.size(); i++) {
1511 Teuchos::RCP<DM> C2 = DMT::Create(qcs[i],1);
1514 for (
int ii=0; ii<qcs[i]; ii++) {
1517 tempQ = MVT::CloneView( *Q[i], indX );
1519 Teuchos::RCP tempC2 = DMT::Subview(*C2, 1, 1, ii);
1523 MVT::MvTimesMatAddMv( -ONE, *tempQ, *tempC2, ONE, *Xj );
1527 Teuchos::RCP tempC = DMT::Subview(*C[i], qcs[i], 1, 0, j);
1528 DMT::Add(*tempC,*C2);
1534 MVT::MvTimesMatAddMv( -ONE, *MQ[i], *C2, ONE, *MXj );
1536 else if (xc <= qcs[i]) {
1538 OPT::Apply( *(this->_Op), *Xj, *MXj);
1547#ifdef BELOS_TEUCHOS_TIME_MONITOR
1548 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1550 MVT::MvDot( *Xj, *MXj, newDot );
1554 if (SCT::magnitude(newDot[0]) < SCT::magnitude(oldDot[0]*sing_tol_)) {
1560 ScalarType diag = SCT::squareroot(SCT::magnitude(newDot[0]));
1561 MVT::MvScale( *Xj, ONE/diag );
1564 MVT::MvScale( *MXj, ONE/diag );
1568 Teuchos::RCP<DM> Bjj = DMT::Subview(*B,1,1,j,j);
1569 DMT::PutScalar(*Bjj, diag);
1573 Teuchos::RCP<MV> tempXj = MVT::Clone( X, 1 );
1574 Teuchos::RCP<MV> tempMXj;
1575 MVT::MvRandom( *tempXj );
1577 tempMXj = MVT::Clone( X, 1 );
1578 OPT::Apply( *(this->_Op), *tempXj, *tempMXj );
1584#ifdef BELOS_TEUCHOS_TIME_MONITOR
1585 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1587 MVT::MvDot( *tempXj, *tempMXj, oldDot );
1590 for (
int num_orth=0; num_orth<max_ortho_steps_; num_orth++) {
1592 for (
int i=0; i<Q.size(); i++) {
1593 Teuchos::RCP<DM> product = DMT::Create(qcs[i], 1);
1596 for (
int ii=0; ii<qcs[i]; ii++) {
1599 tempQ = MVT::CloneView( *Q[i], indX );
1600 Teuchos::RCP tempC = DMT::Subview(*product, 1, 1, ii);
1604 MVT::MvTimesMatAddMv( -ONE, *tempQ, *tempC, ONE, *tempXj );
1612 MVT::MvTimesMatAddMv( -ONE, *MQ[i], *product, ONE, *tempMXj );
1614 else if (xc <= qcs[i]) {
1616 OPT::Apply( *(this->_Op), *tempXj, *tempMXj);
1624#ifdef BELOS_TEUCHOS_TIME_MONITOR
1625 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1627 MVT::MvDot( *tempXj, *tempMXj, newDot );
1631 if ( SCT::magnitude(newDot[0]) >= SCT::magnitude(oldDot[0]*sing_tol_) ) {
1632 ScalarType diag = SCT::squareroot(SCT::magnitude(newDot[0]));
1635 Teuchos::RCP<DM> Bjj = DMT::Subview(*B,1,1,j,j);
1636 DMT::PutScalar(*Bjj, ZERO);
1639 MVT::MvAddMv( ONE/diag, *tempXj, ZERO, *tempXj, *Xj );
1641 MVT::MvAddMv( ONE/diag, *tempMXj, ZERO, *tempMXj, *MXj );
1661 template<
class ScalarType,
class MV,
class OP,
class DM>
1664 using Teuchos::ParameterList;
1665 using Teuchos::parameterList;
1668 RCP<ParameterList> params = parameterList (
"IMGS");
1673 "Maximum number of orthogonalization passes (includes the "
1674 "first). Default is 2, since \"twice is enough\" for Krylov "
1677 "Block reorthogonalization threshold.");
1679 "Singular block detection threshold.");
1684 template<
class ScalarType,
class MV,
class OP,
class DM>
1687 using Teuchos::ParameterList;
1692 params->set (
"maxNumOrthogPasses",
1694 params->set (
"blkTol",
1696 params->set (
"singTol",
1704#ifdef HAVE_BELOS_TPETRA
1707#define BELOS_TPETRA_IMGSORTHOMANAGER_NOEXTERN_CALL(SC, LO, GO, NT) \
1708 BELOS_TPETRA_CALL(Belos::IMGSOrthoManager, SC, LO, GO, NT)
1710#define BELOS_TPETRA_IMGSORTHOMANAGER_EXTERN_CALL(SC, LO, GO, NT) \
1711 BELOS_TPETRA_EXTERN_CALL(Belos::IMGSOrthoManager, SC, LO, GO, NT)
1713TPETRA_INSTANTIATE_SLGN_NO_ORDINAL_SCALAR(BELOS_TPETRA_IMGSORTHOMANAGER_EXTERN_CALL)
Belos header file which uses auto-configuration information to include necessary C++ headers.
Full specialization of Belos::DenseMatTraits for Kokkos::DualView with arbitrary scalarType....
Templated virtual class for providing orthogonalization/orthonormalization methods with matrix-based ...
Declaration of basic traits for the multivector type.
Class which defines basic traits for the operator type.
Full specialization of Belos::DenseMatTraits for Teuchos::SerialDenseMatrix with ordinal type int and...
Virtual base class which defines basic traits for the multi-vector type.
static Teuchos::RCP< DM > Subview(DM &source, int numRows, int numCols, int startRow=0, int startCol=0)
Marks host data modified to avoid device sync errors.
static void SyncHostToDevice(DM &dm)
static void PutScalar(DM &dm, ScalarType value=Teuchos::ScalarTraits< ScalarType >::zero())
Fill all entries with value. Value is zero if not specified.
static int GetNumRows(const DM &dm)
Obtain the number of rows of dm.
static void SyncDeviceToHost(DM &dm)
static void Reshape(DM &dm, const int numrows, const int numcols, bool initZero=false)
static ScalarType & Value(DM &dm, const int i, const int j)
Access a reference to the (i,j) entry of dm, e_i^T dm e_j.
static Teuchos::ScalarTraits< ScalarType >::magnitudeType NormFrobenius(const DM &dm)
Returns the Frobenius norm of the dense matrix.
static Teuchos::RCP< DM > Create()
Creates a new empty DM with no dimension.
static int GetNumCols(const DM &dm)
Obtain the number of columns of dm.
virtual int projectAndNormalizeWithMxImpl(MV &X, Teuchos::RCP< MV > MX, Teuchos::Array< Teuchos::RCP< DM > > C, Teuchos::RCP< DM > B, Teuchos::ArrayView< Teuchos::RCP< const MV > > Q) const
Given a set of bases Q[i] and a multivector X, this method computes an orthonormal basis for .
static const MagnitudeType sing_tol_fast_
Singular block detection threshold (fast).
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
static const MagnitudeType sing_tol_default_
Singular block detection threshold (default).
MagnitudeType getSingTol() const
Return parameter for singular block detection.
MagnitudeType getBlkTol() const
Return parameter for block re-orthogonalization threshhold.
static const int max_ortho_steps_default_
Max number of (re)orthogonalization steps, including the first (default).
Teuchos::ScalarTraits< ScalarType >::magnitudeType orthonormError(const MV &X) const
This method computes the error in orthonormality of a multivector, measured as the Frobenius norm of ...
~IMGSOrthoManager()
Destructor.
static const MagnitudeType blk_tol_default_
Block reorthogonalization threshold (default).
static const int max_ortho_steps_fast_
Max number of (re)orthogonalization steps, including the first (fast).
Teuchos::ScalarTraits< ScalarType >::magnitudeType orthogError(const MV &X1, const MV &X2) const
This method computes the error in orthogonality of two multivectors, measured as the Frobenius norm o...
int normalize(MV &X, Teuchos::RCP< MV > MX, Teuchos::RCP< DM > B) const
This method takes a multivector X and attempts to compute an orthonormal basis for ,...
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &plist)
void setLabel(const std::string &label)
This method sets the label used by the timers in the orthogonalization manager.
IMGSOrthoManager(const Teuchos::RCP< Teuchos::ParameterList > &plist, const std::string &label="Belos", Teuchos::RCP< const OP > Op=Teuchos::null)
Constructor that takes a list of parameters.
void project(MV &X, Teuchos::Array< Teuchos::RCP< DM > > C, Teuchos::ArrayView< Teuchos::RCP< const MV > > Q) const
This method calls project(X,Teuchos::null,C,Q); see documentation for that function.
void project(MV &X, Teuchos::RCP< MV > MX, Teuchos::Array< Teuchos::RCP< DM > > C, Teuchos::ArrayView< Teuchos::RCP< const MV > > Q) const
Given a list of (mutually and internally) orthonormal bases Q, this method takes a multivector X and ...
void setBlkTol(const MagnitudeType blk_tol)
Set parameter for block re-orthogonalization threshhold.
void setSingTol(const MagnitudeType sing_tol)
Set parameter for singular block detection.
const std::string & getLabel() const
This method returns the label being used by the timers in the orthogonalization manager.
static const MagnitudeType blk_tol_fast_
Block reorthogonalization threshold (fast).
int normalize(MV &X, Teuchos::RCP< DM > B) const
This method calls normalize(X,Teuchos::null,B); see documentation for that function.
IMGSOrthoManager(const std::string &label="Belos", Teuchos::RCP< const OP > Op=Teuchos::null, const int max_ortho_steps=max_ortho_steps_default_, const MagnitudeType blk_tol=blk_tol_default_, const MagnitudeType sing_tol=sing_tol_default_)
Constructor specifying re-orthogonalization tolerance.
void innerProd(const MV &X, const MV &Y, DM &Z) const
Provides the inner product defining the orthogonality concepts, using the provided operator.
MatOrthoManager(Teuchos::RCP< const OP > Op=Teuchos::null)
Default constructor.
Teuchos::RCP< const OP > _Op
Traits class which defines basic operations on multivectors.
static Teuchos::RCP< MV > CloneCopy(const MV &mv)
static Teuchos::RCP< MV > Clone(const MV &mv, const int numvecs)
static void Assign(const MV &A, MV &mv)
static ptrdiff_t GetGlobalLength(const MV &mv)
static void MvDot(const MV &mv, const MV &A, std::vector< ScalarType > &b)
static void MvScale(MV &mv, const ScalarType alpha)
static int GetNumberVecs(const MV &mv)
Class which defines basic traits for the operator type.
static void Apply(const OP &Op, const MV &x, MV &y, ETrans trans=NOTRANS)
Apply Op to x, putting the result into y.
Exception thrown to signal error in an orthogonalization manager method.
Teuchos::RCP< Teuchos::ParameterList > getIMGSFastParameters()
"Fast" but possibly unsafe or less accurate parameters.
Teuchos::RCP< Teuchos::ParameterList > getIMGSDefaultParameters()
"Default" parameters for robustness and accuracy.