15#ifndef BELOS_ICGS_ORTHOMANAGER_HPP
16#define BELOS_ICGS_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_ +
": ICGS[" << 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_ +
": ICGS[" << 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);
136 using Teuchos::Exceptions::InvalidParameterName;
137 using Teuchos::ParameterList;
138 using Teuchos::parameterList;
142 RCP<ParameterList> params;
143 if (plist.is_null()) {
144 params = parameterList (*defaultParams);
159 int maxNumOrthogPasses;
160 MagnitudeType blkTol;
161 MagnitudeType singTol;
164 maxNumOrthogPasses = params->get<
int> (
"maxNumOrthogPasses");
165 }
catch (InvalidParameterName&) {
166 maxNumOrthogPasses = defaultParams->get<
int> (
"maxNumOrthogPasses");
167 params->set (
"maxNumOrthogPasses", maxNumOrthogPasses);
178 blkTol = params->get<MagnitudeType> (
"blkTol");
179 }
catch (InvalidParameterName&) {
181 blkTol = params->get<MagnitudeType> (
"depTol");
184 params->remove (
"depTol");
185 }
catch (InvalidParameterName&) {
186 blkTol = defaultParams->get<MagnitudeType> (
"blkTol");
188 params->set (
"blkTol", blkTol);
192 singTol = params->get<MagnitudeType> (
"singTol");
193 }
catch (InvalidParameterName&) {
194 singTol = defaultParams->get<MagnitudeType> (
"singTol");
195 params->set (
"singTol", singTol);
198 max_ortho_steps_ = maxNumOrthogPasses;
202 this->setMyParamList (params);
205 Teuchos::RCP<const Teuchos::ParameterList>
208 if (defaultParams_.is_null()) {
212 return defaultParams_;
221 Teuchos::RCP<const Teuchos::ParameterList>
225 using Teuchos::ParameterList;
226 using Teuchos::parameterList;
231 RCP<ParameterList> params = parameterList (*defaultParams);
246 Teuchos::RCP<Teuchos::ParameterList> params = this->getNonconstParameterList();
247 if (! params.is_null()) {
252 params->set (
"blkTol", blk_tol);
260 Teuchos::RCP<Teuchos::ParameterList> params = this->getNonconstParameterList();
261 if (! params.is_null()) {
266 params->set (
"singTol", sing_tol);
268 sing_tol_ = sing_tol;
310 void project ( MV &X, Teuchos::RCP<MV> MX,
311 Teuchos::Array<Teuchos::RCP<DM>> C,
312 Teuchos::ArrayView<Teuchos::RCP<const MV>> Q)
const;
318 Teuchos::Array<Teuchos::RCP<DM>> C,
319 Teuchos::ArrayView<Teuchos::RCP<const MV>> Q)
const {
349 int normalize ( MV &X, Teuchos::RCP<MV> MX,
350 Teuchos::RCP<DM> B)
const;
405 Teuchos::Array<Teuchos::RCP<DM> > C,
407 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const;
417 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
426 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
432 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
441 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
442 orthogError(
const MV &X1, Teuchos::RCP<const MV> MX1,
const MV &X2)
const;
451 void setLabel(
const std::string& label);
455 const std::string&
getLabel()
const {
return label_; }
481 int max_ortho_steps_;
483 MagnitudeType blk_tol_;
485 MagnitudeType sing_tol_;
489#ifdef BELOS_TEUCHOS_TIME_MONITOR
490 Teuchos::RCP<Teuchos::Time> timerOrtho_, timerUpdate_, timerNorm_, timerInnerProd_;
494 mutable Teuchos::RCP<Teuchos::ParameterList> defaultParams_;
497 int findBasis(MV &X, Teuchos::RCP<MV> MX,
499 bool completeBasis,
int howMany = -1 )
const;
502 bool blkOrtho1 ( MV &X, Teuchos::RCP<MV> MX,
503 Teuchos::Array<Teuchos::RCP<DM>> C,
504 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const;
507 bool blkOrtho ( MV &X, Teuchos::RCP<MV> MX,
508 Teuchos::Array<Teuchos::RCP<DM>> C,
509 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const;
524 int blkOrthoSing ( MV &X, Teuchos::RCP<MV> MX,
525 Teuchos::Array<Teuchos::RCP<DM> > C,
527 Teuchos::ArrayView<Teuchos::RCP<const MV> > QQ)
const;
531 template<
class ScalarType,
class MV,
class OP,
class DM >
534 template<
class ScalarType,
class MV,
class OP,
class DM >
535 const typename ICGSOrthoManager<ScalarType,MV,OP,DM>::MagnitudeType
537 = 10*Teuchos::ScalarTraits<typename ICGSOrthoManager<ScalarType,MV,OP,DM>::MagnitudeType>::squareroot(
538 Teuchos::ScalarTraits<
typename ICGSOrthoManager<ScalarType,MV,OP,DM>::MagnitudeType>::eps() );
540 template<
class ScalarType,
class MV,
class OP,
class DM >
541 const typename ICGSOrthoManager<ScalarType,MV,OP,DM>::MagnitudeType
543 = 10*Teuchos::ScalarTraits<typename ICGSOrthoManager<ScalarType,MV,OP,DM>::MagnitudeType>::eps();
545 template<
class ScalarType,
class MV,
class OP,
class DM >
548 template<
class ScalarType,
class MV,
class OP,
class DM >
549 const typename ICGSOrthoManager<ScalarType,MV,OP,DM>::MagnitudeType
551 = Teuchos::ScalarTraits<typename ICGSOrthoManager<ScalarType,MV,OP,DM>::MagnitudeType>::zero();
553 template<
class ScalarType,
class MV,
class OP,
class DM >
554 const typename ICGSOrthoManager<ScalarType,MV,OP,DM>::MagnitudeType
556 = Teuchos::ScalarTraits<typename ICGSOrthoManager<ScalarType,MV,OP,DM>::MagnitudeType>::zero();
560 template<
class ScalarType,
class MV,
class OP,
class DM >
563 if (label != label_) {
565#ifdef BELOS_TEUCHOS_TIME_MONITOR
566 std::stringstream ss;
567 ss << label_ +
": ICGS[" << max_ortho_steps_ <<
"]";
569 std::string orthoLabel = ss.str() +
": Orthogonalization";
570 timerOrtho_ = Teuchos::TimeMonitor::getNewCounter(orthoLabel);
572 std::string updateLabel = ss.str() +
": Ortho (Update)";
573 timerUpdate_ = Teuchos::TimeMonitor::getNewCounter(updateLabel);
575 std::string normLabel = ss.str() +
": Ortho (Norm)";
576 timerNorm_ = Teuchos::TimeMonitor::getNewCounter(normLabel);
578 std::string ipLabel = ss.str() +
": Ortho (Inner Product)";
579 timerInnerProd_ = Teuchos::TimeMonitor::getNewCounter(ipLabel);
586 template<
class ScalarType,
class MV,
class OP,
class DM >
587 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
589 const ScalarType ONE = SCT::one();
594 for (
int i=0; i<rank; i++) {
603 template<
class ScalarType,
class MV,
class OP,
class DM >
604 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
615 template<
class ScalarType,
class MV,
class OP,
class DM >
620 Teuchos::Array<Teuchos::RCP<DM> > C,
622 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const
624 using Teuchos::Array;
626 using Teuchos::is_null;
629 typedef typename Array< RCP< const MV > >::size_type size_type;
631#ifdef BELOS_TEUCHOS_TIME_MONITOR
632 Teuchos::TimeMonitor orthotimer(*timerOrtho_);
635 ScalarType ONE = SCT::one();
636 const MagnitudeType ZERO = MGT::zero();
657 for (size_type k = 0; k < nq; ++k) {
659 const int numCols = xc;
671 if (MX == Teuchos::null) {
679 MX = Teuchos::rcp( &X,
false );
686 TEUCHOS_TEST_FOR_EXCEPTION( xc == 0 || xr == 0, std::invalid_argument,
"Belos::ICGSOrthoManager::projectAndNormalize(): X must be non-empty" );
689 for (
int i=0; i<nq; i++) {
695 "Belos::ICGSOrthoManager::projectAndNormalize(): Size of X must be consistant with size of B" );
697 TEUCHOS_TEST_FOR_EXCEPTION( xc<0 || xr<0 || mxc<0 || mxr<0, std::invalid_argument,
698 "Belos::ICGSOrthoManager::projectAndNormalize(): MVT returned negative dimensions for X,MX" );
700 TEUCHOS_TEST_FOR_EXCEPTION( xc!=mxc || xr!=mxr, std::invalid_argument,
701 "Belos::ICGSOrthoManager::projectAndNormalize(): Size of X must be consistant with size of MX" );
707 bool dep_flg =
false;
713 dep_flg = blkOrtho1( X, MX, C, Q );
716 if ( B == Teuchos::null ) {
720 std::vector<ScalarType> dot(xc);
722#ifdef BELOS_TEUCHOS_TIME_MONITOR
723 Teuchos::TimeMonitor normTimer( *timerNorm_ );
728 ScalarType diag = SCT::squareroot(SCT::magnitude(dot[0]));
730 if (SCT::magnitude(diag) > ZERO) {
745 Teuchos::RCP<MV> tmpX, tmpMX;
752 dep_flg = blkOrtho( X, MX, C, Q );
758 rank = blkOrthoSing( *tmpX, tmpMX, C, B, Q );
768 rank = findBasis( X, MX, B,
false );
773 rank = blkOrthoSing( *tmpX, tmpMX, C, B, Q );
785 TEUCHOS_TEST_FOR_EXCEPTION( rank > xc || rank < 0, std::logic_error,
786 "Belos::ICGSOrthoManager::projectAndNormalize(): Debug error in rank variable." );
796 template<
class ScalarType,
class MV,
class OP,
class DM >
798 MV &X, Teuchos::RCP<MV> MX,
799 Teuchos::RCP<DM> B )
const {
801#ifdef BELOS_TEUCHOS_TIME_MONITOR
802 Teuchos::TimeMonitor orthotimer(*timerOrtho_);
806 return findBasis(X, MX, B,
true);
813 template<
class ScalarType,
class MV,
class OP,
class DM >
815 MV &X, Teuchos::RCP<MV> MX,
816 Teuchos::Array<Teuchos::RCP<DM> > C,
817 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const {
833#ifdef BELOS_TEUCHOS_TIME_MONITOR
834 Teuchos::TimeMonitor orthotimer(*timerOrtho_);
840 std::vector<int> qcs(nq);
842 if (nq == 0 || xc == 0 || xr == 0) {
854 if (MX == Teuchos::null) {
862 MX = Teuchos::rcp( &X,
false );
868 TEUCHOS_TEST_FOR_EXCEPTION( xc<0 || xr<0 || mxc<0 || mxr<0, std::invalid_argument,
869 "Belos::ICGSOrthoManager::project(): MVT returned negative dimensions for X,MX" );
871 TEUCHOS_TEST_FOR_EXCEPTION( xc!=mxc || xr!=mxr || xr!=qr, std::invalid_argument,
872 "Belos::ICGSOrthoManager::project(): Size of X not consistant with MX,Q" );
875 for (
int i=0; i<nq; i++) {
877 "Belos::ICGSOrthoManager::project(): Q lengths not mutually consistant" );
879 TEUCHOS_TEST_FOR_EXCEPTION( qr < qcs[i], std::invalid_argument,
880 "Belos::ICGSOrthoManager::project(): Q has less rows than columns" );
883 if ( C[i] == Teuchos::null ) {
888 "Belos::ICGSOrthoManager::project(): Size of Q not consistant with size of C" );
893 blkOrtho( X, MX, C, Q );
900 template<
class ScalarType,
class MV,
class OP,
class DM >
923 const ScalarType ONE = SCT::one ();
924 const MagnitudeType ZERO = SCT::magnitude (SCT::zero ());
926 const int xc = MVT::GetNumberVecs (X);
927 const ptrdiff_t xr = MVT::GetGlobalLength (X);
940 if (MX == Teuchos::null) {
942 MX = MVT::Clone(X,xc);
943 OPT::Apply(*(this->_Op),X,*MX);
950 if ( B == Teuchos::null ) {
951 B = DMT::Create(xc,xc);
954 const int mxc = (this->_hasOp) ? MVT::GetNumberVecs( *MX ) : xc;
955 const ptrdiff_t mxr = (this->_hasOp) ? MVT::GetGlobalLength( *MX ) : xr;
958 TEUCHOS_TEST_FOR_EXCEPTION( xc == 0 || xr == 0, std::invalid_argument,
959 "Belos::ICGSOrthoManager::findBasis(): X must be non-empty" );
960 TEUCHOS_TEST_FOR_EXCEPTION( DMT::GetNumRows(*B) != xc || DMT::GetNumCols(*B) != xc, std::invalid_argument,
961 "Belos::ICGSOrthoManager::findBasis(): Size of X not consistant with size of B" );
962 TEUCHOS_TEST_FOR_EXCEPTION( xc != mxc || xr != mxr, std::invalid_argument,
963 "Belos::ICGSOrthoManager::findBasis(): Size of X not consistant with size of MX" );
964 TEUCHOS_TEST_FOR_EXCEPTION( as<ptrdiff_t> (xc) > xr, std::invalid_argument,
965 "Belos::ICGSOrthoManager::findBasis(): Size of X not feasible for normalization" );
966 TEUCHOS_TEST_FOR_EXCEPTION( howMany < 0 || howMany > xc, std::invalid_argument,
967 "Belos::ICGSOrthoManager::findBasis(): Invalid howMany parameter" );
972 int xstart = xc - howMany;
974 for (
int j = xstart; j < xc; j++) {
983 std::vector<int> index(1);
985 Teuchos::RCP<MV> Xj = MVT::CloneViewNonConst( X, index );
986 Teuchos::RCP<MV> MXj;
989 MXj = MVT::CloneViewNonConst( *MX, index );
997 std::vector<int> prev_idx( numX );
998 Teuchos::RCP<const MV> prevX, prevMX;
999 Teuchos::RCP<MV> oldMXj;
1002 for (
int i=0; i<numX; i++) {
1005 prevX = MVT::CloneView( X, prev_idx );
1007 prevMX = MVT::CloneView( *MX, prev_idx );
1010 oldMXj = MVT::CloneCopy( *MXj );
1014 Teuchos::RCP<DM> product = DMT::Create(numX,1);
1015 std::vector<ScalarType> oldDot( 1 ), newDot( 1 );
1020#ifdef BELOS_TEUCHOS_TIME_MONITOR
1021 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1023 MVT::MvDot( *Xj, *MXj, oldDot );
1026 TEUCHOS_TEST_FOR_EXCEPTION( SCT::real(oldDot[0]) < ZERO,
OrthoError,
1027 "Belos::ICGSOrthoManager::findBasis(): Negative definiteness discovered in inner product" );
1031 Teuchos::RCP<DM> P2 = DMT::Create(numX,1);
1033 for (
int i=0; i<max_ortho_steps_; ++i) {
1037#ifdef BELOS_TEUCHOS_TIME_MONITOR
1038 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1046#ifdef BELOS_TEUCHOS_TIME_MONITOR
1047 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1049 MVT::MvTimesMatAddMv( -ONE, *prevX, *P2, ONE, *Xj );
1057#ifdef BELOS_TEUCHOS_TIME_MONITOR
1058 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1060 MVT::MvTimesMatAddMv( -ONE, *prevMX, *P2, ONE, *MXj );
1065 DMT::Assign(*product,*P2);
1067 DMT::Add(*product,*P2);
1074#ifdef BELOS_TEUCHOS_TIME_MONITOR
1075 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1077 MVT::MvDot( *Xj, *oldMXj, newDot );
1080 newDot[0] = oldDot[0];
1084 if (completeBasis) {
1088 if ( SCT::magnitude(newDot[0]) < SCT::magnitude(sing_tol_*oldDot[0]) ) {
1093 std::cout <<
"Belos::ICGSOrthoManager::findBasis() --> Random for column " << numX << std::endl;
1096 Teuchos::RCP<MV> tempXj = MVT::Clone( X, 1 );
1097 Teuchos::RCP<MV> tempMXj;
1098 MVT::MvRandom( *tempXj );
1100 tempMXj = MVT::Clone( X, 1 );
1101 OPT::Apply( *(this->_Op), *tempXj, *tempMXj );
1107#ifdef BELOS_TEUCHOS_TIME_MONITOR
1108 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1110 MVT::MvDot( *tempXj, *tempMXj, oldDot );
1113 for (
int num_orth=0; num_orth<max_ortho_steps_; num_orth++){
1115#ifdef BELOS_TEUCHOS_TIME_MONITOR
1116 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1121#ifdef BELOS_TEUCHOS_TIME_MONITOR
1122 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1124 MVT::MvTimesMatAddMv( -ONE, *prevX, *product, ONE, *tempXj );
1127#ifdef BELOS_TEUCHOS_TIME_MONITOR
1128 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1130 MVT::MvTimesMatAddMv( -ONE, *prevMX, *product, ONE, *tempMXj );
1135#ifdef BELOS_TEUCHOS_TIME_MONITOR
1136 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1138 MVT::MvDot( *tempXj, *tempMXj, newDot );
1141 if ( SCT::magnitude(newDot[0]) >= SCT::magnitude(oldDot[0]*sing_tol_) ) {
1143 MVT::Assign( *tempXj, *Xj );
1145 MVT::Assign( *tempMXj, *MXj );
1157 if ( SCT::magnitude(newDot[0]) < SCT::magnitude(oldDot[0]*blk_tol_) ) {
1165 ScalarType diag = SCT::squareroot(SCT::magnitude(newDot[0]));
1166 if (SCT::magnitude(diag) > ZERO) {
1167 MVT::MvScale( *Xj, ONE/diag );
1170 MVT::MvScale( *MXj, ONE/diag );
1175 Teuchos::RCP<DM> Bjj = DMT::Subview(*B,1,1,j,j);
1177 DMT::PutScalar(*Bjj, ZERO);
1180 DMT::PutScalar(*Bjj, diag);
1185 Teuchos::RCP<DM> Bcolj = DMT::Subview(*B,numX,1,0,j);
1186 DMT::Assign(*Bcolj,*product);
1196 template<
class ScalarType,
class MV,
class OP,
class DM >
1198 ICGSOrthoManager<ScalarType, MV, OP, DM>::blkOrtho1 ( MV &X, Teuchos::RCP<MV> MX,
1199 Teuchos::Array<Teuchos::RCP<DM> > C,
1200 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const
1203 int xc = MVT::GetNumberVecs( X );
1204 const ScalarType ONE = SCT::one();
1206 std::vector<int> qcs( nq );
1207 for (
int i=0; i<nq; i++) {
1208 qcs[i] = MVT::GetNumberVecs( *Q[i] );
1213 Teuchos::Array<Teuchos::RCP<MV> > MQ(nq);
1215 for (
int i=0; i<nq; i++) {
1218#ifdef BELOS_TEUCHOS_TIME_MONITOR
1219 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1225#ifdef BELOS_TEUCHOS_TIME_MONITOR
1226 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1228 MVT::MvTimesMatAddMv( -ONE, *Q[i], *C[i], ONE, X );
1234 OPT::Apply( *(this->_Op), X, *MX);
1238 MQ[i] = MVT::Clone( *Q[i], qcs[i] );
1239 OPT::Apply( *(this->_Op), *Q[i], *MQ[i] );
1241#ifdef BELOS_TEUCHOS_TIME_MONITOR
1242 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1244 MVT::MvTimesMatAddMv( -ONE, *MQ[i], *C[i], ONE, *MX );
1251 for (
int j = 1; j < max_ortho_steps_; ++j) {
1253 for (
int i=0; i<nq; i++) {
1254 Teuchos::RCP<DM> C2 = DMT::Create(DMT::GetNumRows(*C[i]),DMT::GetNumCols(*C[i]));
1258#ifdef BELOS_TEUCHOS_TIME_MONITOR
1259 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1263 DMT::Add(*C[i],*C2);
1265#ifdef BELOS_TEUCHOS_TIME_MONITOR
1266 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1268 MVT::MvTimesMatAddMv( -ONE, *Q[i], *C2, ONE, X );
1274#ifdef BELOS_TEUCHOS_TIME_MONITOR
1275 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1278 MVT::MvTimesMatAddMv( -ONE, *MQ[i], *C2, ONE, *MX );
1280 else if (xc <= qcs[i]) {
1282 OPT::Apply( *(this->_Op), X, *MX);
1293 template<
class ScalarType,
class MV,
class OP,
class DM >
1295 ICGSOrthoManager<ScalarType, MV, OP, DM>::blkOrtho ( MV &X, Teuchos::RCP<MV> MX,
1296 Teuchos::Array<Teuchos::RCP<DM> > C,
1297 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const
1300 int xc = MVT::GetNumberVecs( X );
1301 bool dep_flg =
false;
1302 const ScalarType ONE = SCT::one();
1304 std::vector<int> qcs( nq );
1305 for (
int i=0; i<nq; i++) {
1306 qcs[i] = MVT::GetNumberVecs( *Q[i] );
1312 std::vector<ScalarType> oldDot( xc );
1314#ifdef BELOS_TEUCHOS_TIME_MONITOR
1315 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1317 MVT::MvDot( X, *MX, oldDot );
1320 Teuchos::Array<Teuchos::RCP<MV> > MQ(nq);
1322 for (
int i=0; i<nq; i++) {
1325#ifdef BELOS_TEUCHOS_TIME_MONITOR
1326 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1332#ifdef BELOS_TEUCHOS_TIME_MONITOR
1333 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1335 MVT::MvTimesMatAddMv( -ONE, *Q[i], *C[i], ONE, X );
1340 OPT::Apply( *(this->_Op), X, *MX);
1344 MQ[i] = MVT::Clone( *Q[i], qcs[i] );
1345 OPT::Apply( *(this->_Op), *Q[i], *MQ[i] );
1347#ifdef BELOS_TEUCHOS_TIME_MONITOR
1348 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1350 MVT::MvTimesMatAddMv( -ONE, *MQ[i], *C[i], ONE, *MX );
1357 for (
int j = 1; j < max_ortho_steps_; ++j) {
1359 for (
int i=0; i<nq; i++) {
1360 Teuchos::RCP<DM> C2 = DMT::Create(DMT::GetNumRows(*C[i]),DMT::GetNumCols(*C[i]));
1364#ifdef BELOS_TEUCHOS_TIME_MONITOR
1365 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1369 DMT::Add(*C[i],*C2);
1371#ifdef BELOS_TEUCHOS_TIME_MONITOR
1372 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1374 MVT::MvTimesMatAddMv( -ONE, *Q[i], *C2, ONE, X );
1380#ifdef BELOS_TEUCHOS_TIME_MONITOR
1381 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1384 MVT::MvTimesMatAddMv( -ONE, *MQ[i], *C2, ONE, *MX );
1386 else if (xc <= qcs[i]) {
1388 OPT::Apply( *(this->_Op), X, *MX);
1395 std::vector<ScalarType> newDot(xc);
1397#ifdef BELOS_TEUCHOS_TIME_MONITOR
1398 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1400 MVT::MvDot( X, *MX, newDot );
1404 for (
int i=0; i<xc; i++){
1405 if (SCT::magnitude(newDot[i]) < SCT::magnitude(oldDot[i] * blk_tol_)) {
1414 template<
class ScalarType,
class MV,
class OP,
class DM >
1416 ICGSOrthoManager<ScalarType, MV, OP, DM>::blkOrthoSing ( MV &X, Teuchos::RCP<MV> MX,
1417 Teuchos::Array<Teuchos::RCP<DM> > C,
1419 Teuchos::ArrayView<Teuchos::RCP<const MV> > QQ)
const
1421 Teuchos::Array<Teuchos::RCP<const MV> > Q (QQ);
1423 const ScalarType ONE = SCT::one();
1424 const ScalarType ZERO = SCT::zero();
1427 int xc = MVT::GetNumberVecs( X );
1428 std::vector<int> indX( 1 );
1429 std::vector<ScalarType> oldDot( 1 ), newDot( 1 );
1431 std::vector<int> qcs( nq );
1432 for (
int i=0; i<nq; i++) {
1433 qcs[i] = MVT::GetNumberVecs( *Q[i] );
1437 Teuchos::RCP<const MV> lastQ;
1438 Teuchos::RCP<MV> Xj, MXj;
1441 for (
int j=0; j<xc; j++) {
1443 bool dep_flg =
false;
1447 std::vector<int> index( j );
1448 for (
int ind=0; ind<j; ind++) {
1451 lastQ = MVT::CloneView( X, index );
1454 Q.push_back( lastQ );
1456 qcs.push_back( MVT::GetNumberVecs( *lastQ ) );
1461 Xj = MVT::CloneViewNonConst( X, indX );
1463 MXj = MVT::CloneViewNonConst( *MX, indX );
1471#ifdef BELOS_TEUCHOS_TIME_MONITOR
1472 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1474 MVT::MvDot( *Xj, *MXj, oldDot );
1477 Teuchos::Array<Teuchos::RCP<MV> > MQ(Q.size());
1479 for (
int i=0; i<Q.size(); i++) {
1482 Teuchos::RCP<DM> tempC = DMT::Subview(*C[i], qcs[i], 1, 0, j);
1486#ifdef BELOS_TEUCHOS_TIME_MONITOR
1487 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1492#ifdef BELOS_TEUCHOS_TIME_MONITOR
1493 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1496 MVT::MvTimesMatAddMv( -ONE, *Q[i], *tempC, ONE, *Xj );
1501 OPT::Apply( *(this->_Op), *Xj, *MXj);
1505 MQ[i] = MVT::Clone( *Q[i], qcs[i] );
1506 OPT::Apply( *(this->_Op), *Q[i], *MQ[i] );
1508#ifdef BELOS_TEUCHOS_TIME_MONITOR
1509 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1511 MVT::MvTimesMatAddMv( -ONE, *MQ[i], *tempC, ONE, *MXj );
1518 for (
int num_ortho_steps=1; num_ortho_steps < max_ortho_steps_; ++num_ortho_steps) {
1520 for (
int i=0; i<Q.size(); i++) {
1521 Teuchos::RCP<DM> tempC = DMT::Subview(*C[i], qcs[i], 1, 0, j);
1522 Teuchos::RCP<DM> C2 = DMT::Create( qcs[i], 1 );
1526#ifdef BELOS_TEUCHOS_TIME_MONITOR
1527 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1531 DMT::Add(*tempC, *C2);
1533#ifdef BELOS_TEUCHOS_TIME_MONITOR
1534 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1536 MVT::MvTimesMatAddMv( -ONE, *Q[i], *C2, ONE, *Xj );
1543#ifdef BELOS_TEUCHOS_TIME_MONITOR
1544 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1546 MVT::MvTimesMatAddMv( -ONE, *MQ[i], *C2, ONE, *MXj );
1548 else if (xc <= qcs[i]) {
1550 OPT::Apply( *(this->_Op), *Xj, *MXj);
1559#ifdef BELOS_TEUCHOS_TIME_MONITOR
1560 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1562 MVT::MvDot( *Xj, *MXj, newDot );
1566 if (SCT::magnitude(newDot[0]) < SCT::magnitude(oldDot[0]*sing_tol_)) {
1572 ScalarType diag = SCT::squareroot(SCT::magnitude(newDot[0]));
1574 MVT::MvScale( *Xj, ONE/diag );
1577 MVT::MvScale( *MXj, ONE/diag );
1581 Teuchos::RCP<DM> Bjj = DMT::Subview(*B,1,1,j,j);
1582 DMT::PutScalar(*Bjj, diag);
1586 Teuchos::RCP<MV> tempXj = MVT::Clone( X, 1 );
1587 Teuchos::RCP<MV> tempMXj;
1588 MVT::MvRandom( *tempXj );
1590 tempMXj = MVT::Clone( X, 1 );
1591 OPT::Apply( *(this->_Op), *tempXj, *tempMXj );
1597#ifdef BELOS_TEUCHOS_TIME_MONITOR
1598 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1600 MVT::MvDot( *tempXj, *tempMXj, oldDot );
1603 for (
int num_orth=0; num_orth<max_ortho_steps_; num_orth++) {
1605 for (
int i=0; i<Q.size(); i++) {
1606 Teuchos::RCP<DM> product = DMT::Create(qcs[i],1);
1610#ifdef BELOS_TEUCHOS_TIME_MONITOR
1611 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1616#ifdef BELOS_TEUCHOS_TIME_MONITOR
1617 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1619 MVT::MvTimesMatAddMv( -ONE, *Q[i], *product, ONE, *tempXj );
1625#ifdef BELOS_TEUCHOS_TIME_MONITOR
1626 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1629 MVT::MvTimesMatAddMv( -ONE, *MQ[i], *product, ONE, *tempMXj );
1631 else if (xc <= qcs[i]) {
1633 OPT::Apply( *(this->_Op), *tempXj, *tempMXj);
1642#ifdef BELOS_TEUCHOS_TIME_MONITOR
1643 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1645 MVT::MvDot( *tempXj, *tempMXj, newDot );
1649 if ( SCT::magnitude(newDot[0]) >= SCT::magnitude(oldDot[0]*sing_tol_) ) {
1650 ScalarType diag = SCT::squareroot(SCT::magnitude(newDot[0]));
1653 Teuchos::RCP<DM> Bjj = DMT::Subview(*B,1,1,j,j);
1654 DMT::PutScalar(*Bjj, ZERO);
1657 MVT::MvAddMv( ONE/diag, *tempXj, ZERO, *tempXj, *Xj );
1659 MVT::MvAddMv( ONE/diag, *tempMXj, ZERO, *tempMXj, *MXj );
1679 template<
class ScalarType,
class MV,
class OP,
class DM>
1682 using Teuchos::ParameterList;
1683 using Teuchos::parameterList;
1686 RCP<ParameterList> params = parameterList (
"ICGS");
1691 "Maximum number of orthogonalization passes (includes the "
1692 "first). Default is 2, since \"twice is enough\" for Krylov "
1695 "Block reorthogonalization threshold.");
1697 "Singular block detection threshold.");
1702 template<
class ScalarType,
class MV,
class OP,
class DM>
1705 using Teuchos::ParameterList;
1710 params->set (
"maxNumOrthogPasses",
1712 params->set (
"blkTol",
1714 params->set (
"singTol",
1722#ifdef HAVE_BELOS_TPETRA
1725#define BELOS_TPETRA_ICGSORTHOMANAGER_NOEXTERN_CALL(SC, LO, GO, NT) \
1726 BELOS_TPETRA_CALL(Belos::ICGSOrthoManager, SC, LO, GO, NT)
1728#define BELOS_TPETRA_ICGSORTHOMANAGER_EXTERN_CALL(SC, LO, GO, NT) \
1729 BELOS_TPETRA_EXTERN_CALL(Belos::ICGSOrthoManager, SC, LO, GO, NT)
1731TPETRA_INSTANTIATE_SLGN_NO_ORDINAL_SCALAR(BELOS_TPETRA_ICGSORTHOMANAGER_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.
An implementation of the Belos::MatOrthoManager that performs orthogonalization using multiple steps ...
static const MagnitudeType blk_tol_default_
Block reorthogonalization threshold (default).
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 ,...
static const MagnitudeType sing_tol_fast_
Singular block detection threshold (fast).
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 ...
~ICGSOrthoManager()
Destructor.
Teuchos::RCP< const Teuchos::ParameterList > getFastParameters() const
"Fast" but possibly unsafe or less accurate parameters.
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 ...
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 .
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
const std::string & getLabel() const
This method returns the label being used by the timers in the orthogonalization manager.
static const int max_ortho_steps_fast_
Max number of (re)orthogonalization steps, including the first (fast).
static const int max_ortho_steps_default_
Max number of (re)orthogonalization steps, including the first (default).
static const MagnitudeType blk_tol_fast_
Block reorthogonalization threshold (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...
void setLabel(const std::string &label)
This method sets the label used by the timers in the orthogonalization manager.
void setSingTol(const MagnitudeType sing_tol)
Set parameter for singular block detection.
int normalize(MV &X, Teuchos::RCP< DM > B) const
This method calls normalize(X,Teuchos::null,B); see documentation for that function.
void setBlkTol(const MagnitudeType blk_tol)
Set parameter for block re-orthogonalization threshhold.
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 setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &plist)
static const MagnitudeType sing_tol_default_
Singular block detection threshold (default).
MagnitudeType getBlkTol() const
Return parameter for block re-orthogonalization threshhold.
ICGSOrthoManager(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.
ICGSOrthoManager(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.
MagnitudeType getSingTol() const
Return parameter for singular block detection.
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 > getICGSFastParameters()
"Fast" but possibly unsafe or less accurate parameters.
Teuchos::RCP< Teuchos::ParameterList > getICGSDefaultParameters()
"Default" parameters for robustness and accuracy.