15#ifndef BELOS_ICGS_ORTHOMANAGER_HPP
16#define BELOS_ICGS_ORTHOMANAGER_HPP
32#include "Teuchos_as.hpp"
33#ifdef BELOS_TEUCHOS_TIME_MONITOR
34#include "Teuchos_TimeMonitor.hpp"
40 template<
class ScalarType,
class MV,
class OP>
44 template<
class ScalarType,
class MV,
class OP>
47 template<
class ScalarType,
class MV,
class OP>
52 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
53 typedef typename Teuchos::ScalarTraits<MagnitudeType> MGT;
54 typedef Teuchos::ScalarTraits<ScalarType> SCT;
64 Teuchos::RCP<const OP> Op = Teuchos::null,
69 max_ortho_steps_( max_ortho_steps ),
71 sing_tol_( sing_tol ),
74#ifdef BELOS_TEUCHOS_TIME_MONITOR
76 ss << label_ +
": ICGS[" << max_ortho_steps_ <<
"]";
78 std::string orthoLabel = ss.str() +
": Orthogonalization";
79 timerOrtho_ = Teuchos::TimeMonitor::getNewCounter(orthoLabel);
81 std::string updateLabel = ss.str() +
": Ortho (Update)";
82 timerUpdate_ = Teuchos::TimeMonitor::getNewCounter(updateLabel);
84 std::string normLabel = ss.str() +
": Ortho (Norm)";
85 timerNorm_ = Teuchos::TimeMonitor::getNewCounter(normLabel);
87 std::string ipLabel = ss.str() +
": Ortho (Inner Product)";
88 timerInnerProd_ = Teuchos::TimeMonitor::getNewCounter(ipLabel);
94 const std::string& label =
"Belos",
95 Teuchos::RCP<const OP> Op = Teuchos::null) :
104#ifdef BELOS_TEUCHOS_TIME_MONITOR
105 std::stringstream ss;
106 ss << label_ +
": ICGS[" << max_ortho_steps_ <<
"]";
108 std::string orthoLabel = ss.str() +
": Orthogonalization";
109 timerOrtho_ = Teuchos::TimeMonitor::getNewCounter(orthoLabel);
111 std::string updateLabel = ss.str() +
": Ortho (Update)";
112 timerUpdate_ = Teuchos::TimeMonitor::getNewCounter(updateLabel);
114 std::string normLabel = ss.str() +
": Ortho (Norm)";
115 timerNorm_ = Teuchos::TimeMonitor::getNewCounter(normLabel);
117 std::string ipLabel = ss.str() +
": Ortho (Inner Product)";
118 timerInnerProd_ = Teuchos::TimeMonitor::getNewCounter(ipLabel);
132 using Teuchos::Exceptions::InvalidParameterName;
133 using Teuchos::ParameterList;
134 using Teuchos::parameterList;
138 RCP<ParameterList> params;
139 if (plist.is_null()) {
140 params = parameterList (*defaultParams);
155 int maxNumOrthogPasses;
156 MagnitudeType blkTol;
157 MagnitudeType singTol;
160 maxNumOrthogPasses = params->get<
int> (
"maxNumOrthogPasses");
161 }
catch (InvalidParameterName&) {
162 maxNumOrthogPasses = defaultParams->get<
int> (
"maxNumOrthogPasses");
163 params->set (
"maxNumOrthogPasses", maxNumOrthogPasses);
174 blkTol = params->get<MagnitudeType> (
"blkTol");
175 }
catch (InvalidParameterName&) {
177 blkTol = params->get<MagnitudeType> (
"depTol");
180 params->remove (
"depTol");
181 }
catch (InvalidParameterName&) {
182 blkTol = defaultParams->get<MagnitudeType> (
"blkTol");
184 params->set (
"blkTol", blkTol);
188 singTol = params->get<MagnitudeType> (
"singTol");
189 }
catch (InvalidParameterName&) {
190 singTol = defaultParams->get<MagnitudeType> (
"singTol");
191 params->set (
"singTol", singTol);
194 max_ortho_steps_ = maxNumOrthogPasses;
198 this->setMyParamList (params);
201 Teuchos::RCP<const Teuchos::ParameterList>
204 if (defaultParams_.is_null()) {
208 return defaultParams_;
217 Teuchos::RCP<const Teuchos::ParameterList>
221 using Teuchos::ParameterList;
222 using Teuchos::parameterList;
227 RCP<ParameterList> params = parameterList (*defaultParams);
242 Teuchos::RCP<Teuchos::ParameterList> params = this->getNonconstParameterList();
243 if (! params.is_null()) {
248 params->set (
"blkTol", blk_tol);
256 Teuchos::RCP<Teuchos::ParameterList> params = this->getNonconstParameterList();
257 if (! params.is_null()) {
262 params->set (
"singTol", sing_tol);
264 sing_tol_ = sing_tol;
306 void project ( MV &X, Teuchos::RCP<MV> MX,
307 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
308 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const;
314 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
315 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const {
345 int normalize ( MV &X, Teuchos::RCP<MV> MX,
346 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B)
const;
351 int normalize ( MV &X, Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B )
const {
401 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
402 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
403 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const;
413 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
422 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
428 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
437 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
438 orthogError(
const MV &X1, Teuchos::RCP<const MV> MX1,
const MV &X2)
const;
447 void setLabel(
const std::string& label);
451 const std::string&
getLabel()
const {
return label_; }
477 int max_ortho_steps_;
479 MagnitudeType blk_tol_;
481 MagnitudeType sing_tol_;
485#ifdef BELOS_TEUCHOS_TIME_MONITOR
486 Teuchos::RCP<Teuchos::Time> timerOrtho_, timerUpdate_, timerNorm_, timerInnerProd_;
490 mutable Teuchos::RCP<Teuchos::ParameterList> defaultParams_;
493 int findBasis(MV &X, Teuchos::RCP<MV> MX,
494 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > C,
495 bool completeBasis,
int howMany = -1 )
const;
498 bool blkOrtho1 ( MV &X, Teuchos::RCP<MV> MX,
499 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
500 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const;
503 bool blkOrtho ( MV &X, Teuchos::RCP<MV> MX,
504 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
505 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const;
520 int blkOrthoSing ( MV &X, Teuchos::RCP<MV> MX,
521 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
522 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
523 Teuchos::ArrayView<Teuchos::RCP<const MV> > QQ)
const;
527 template<
class ScalarType,
class MV,
class OP>
530 template<
class ScalarType,
class MV,
class OP>
531 const typename ICGSOrthoManager<ScalarType,MV,OP>::MagnitudeType
533 = 10*Teuchos::ScalarTraits<typename ICGSOrthoManager<ScalarType,MV,OP>::MagnitudeType>::squareroot(
534 Teuchos::ScalarTraits<
typename ICGSOrthoManager<ScalarType,MV,OP>::MagnitudeType>::eps() );
536 template<
class ScalarType,
class MV,
class OP>
537 const typename ICGSOrthoManager<ScalarType,MV,OP>::MagnitudeType
539 = 10*Teuchos::ScalarTraits<typename ICGSOrthoManager<ScalarType,MV,OP>::MagnitudeType>::eps();
541 template<
class ScalarType,
class MV,
class OP>
544 template<
class ScalarType,
class MV,
class OP>
545 const typename ICGSOrthoManager<ScalarType,MV,OP>::MagnitudeType
547 = Teuchos::ScalarTraits<typename ICGSOrthoManager<ScalarType,MV,OP>::MagnitudeType>::zero();
549 template<
class ScalarType,
class MV,
class OP>
550 const typename ICGSOrthoManager<ScalarType,MV,OP>::MagnitudeType
552 = Teuchos::ScalarTraits<typename ICGSOrthoManager<ScalarType,MV,OP>::MagnitudeType>::zero();
556 template<
class ScalarType,
class MV,
class OP>
559 if (label != label_) {
561#ifdef BELOS_TEUCHOS_TIME_MONITOR
562 std::stringstream ss;
563 ss << label_ +
": ICGS[" << max_ortho_steps_ <<
"]";
565 std::string orthoLabel = ss.str() +
": Orthogonalization";
566 timerOrtho_ = Teuchos::TimeMonitor::getNewCounter(orthoLabel);
568 std::string updateLabel = ss.str() +
": Ortho (Update)";
569 timerUpdate_ = Teuchos::TimeMonitor::getNewCounter(updateLabel);
571 std::string normLabel = ss.str() +
": Ortho (Norm)";
572 timerNorm_ = Teuchos::TimeMonitor::getNewCounter(normLabel);
574 std::string ipLabel = ss.str() +
": Ortho (Inner Product)";
575 timerInnerProd_ = Teuchos::TimeMonitor::getNewCounter(ipLabel);
582 template<
class ScalarType,
class MV,
class OP>
583 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
585 const ScalarType ONE = SCT::one();
587 Teuchos::SerialDenseMatrix<int,ScalarType> xTx(rank,rank);
589 for (
int i=0; i<rank; i++) {
592 return xTx.normFrobenius();
597 template<
class ScalarType,
class MV,
class OP>
598 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
602 Teuchos::SerialDenseMatrix<int,ScalarType> xTx(r2,r1);
604 return xTx.normFrobenius();
609 template<
class ScalarType,
class MV,
class OP>
614 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
615 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
616 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const
618 using Teuchos::Array;
620 using Teuchos::is_null;
623 using Teuchos::SerialDenseMatrix;
624 typedef SerialDenseMatrix< int, ScalarType > serial_dense_matrix_type;
625 typedef typename Array< RCP< const MV > >::size_type size_type;
627#ifdef BELOS_TEUCHOS_TIME_MONITOR
628 Teuchos::TimeMonitor orthotimer(*timerOrtho_);
631 ScalarType ONE = SCT::one();
632 const MagnitudeType ZERO = MGT::zero();
643 B = rcp (
new serial_dense_matrix_type (xc, xc));
653 for (size_type k = 0; k < nq; ++k)
656 const int numCols = xc;
659 C[k] = rcp (
new serial_dense_matrix_type (numRows, numCols));
660 else if (C[k]->numRows() != numRows || C[k]->numCols() != numCols)
662 int err = C[k]->reshape (numRows, numCols);
663 TEUCHOS_TEST_FOR_EXCEPTION(err != 0, std::runtime_error,
664 "IMGS orthogonalization: failed to reshape "
665 "C[" << k <<
"] (the array of block "
666 "coefficients resulting from projecting X "
667 "against Q[1:" << nq <<
"]).");
673 if (MX == Teuchos::null) {
681 MX = Teuchos::rcp( &X,
false );
688 TEUCHOS_TEST_FOR_EXCEPTION( xc == 0 || xr == 0, std::invalid_argument,
"Belos::ICGSOrthoManager::projectAndNormalize(): X must be non-empty" );
691 for (
int i=0; i<nq; i++) {
696 TEUCHOS_TEST_FOR_EXCEPTION( B->numRows() != xc || B->numCols() != xc, std::invalid_argument,
697 "Belos::ICGSOrthoManager::projectAndNormalize(): Size of X must be consistant with size of B" );
699 TEUCHOS_TEST_FOR_EXCEPTION( xc<0 || xr<0 || mxc<0 || mxr<0, std::invalid_argument,
700 "Belos::ICGSOrthoManager::projectAndNormalize(): MVT returned negative dimensions for X,MX" );
702 TEUCHOS_TEST_FOR_EXCEPTION( xc!=mxc || xr!=mxr, std::invalid_argument,
703 "Belos::ICGSOrthoManager::projectAndNormalize(): Size of X must be consistant with size of MX" );
709 bool dep_flg =
false;
715 dep_flg = blkOrtho1( X, MX, C, Q );
718 if ( B == Teuchos::null ) {
719 B = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(xc,xc) );
721 std::vector<ScalarType> diag(xc);
723#ifdef BELOS_TEUCHOS_TIME_MONITOR
724 Teuchos::TimeMonitor normTimer( *timerNorm_ );
728 (*B)(0,0) = SCT::squareroot(SCT::magnitude(diag[0]));
730 if (SCT::magnitude((*B)(0,0)) > ZERO) {
742 Teuchos::RCP<MV> tmpX, tmpMX;
749 dep_flg = blkOrtho( X, MX, C, Q );
755 rank = blkOrthoSing( *tmpX, tmpMX, C, B, Q );
765 rank = findBasis( X, MX, B,
false );
770 rank = blkOrthoSing( *tmpX, tmpMX, C, B, Q );
782 TEUCHOS_TEST_FOR_EXCEPTION( rank > xc || rank < 0, std::logic_error,
783 "Belos::ICGSOrthoManager::projectAndNormalize(): Debug error in rank variable." );
793 template<
class ScalarType,
class MV,
class OP>
795 MV &X, Teuchos::RCP<MV> MX,
796 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B )
const {
798#ifdef BELOS_TEUCHOS_TIME_MONITOR
799 Teuchos::TimeMonitor orthotimer(*timerOrtho_);
803 return findBasis(X, MX, B,
true);
810 template<
class ScalarType,
class MV,
class OP>
812 MV &X, Teuchos::RCP<MV> MX,
813 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
814 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const {
830#ifdef BELOS_TEUCHOS_TIME_MONITOR
831 Teuchos::TimeMonitor orthotimer(*timerOrtho_);
837 std::vector<int> qcs(nq);
839 if (nq == 0 || xc == 0 || xr == 0) {
851 if (MX == Teuchos::null) {
859 MX = Teuchos::rcp( &X,
false );
865 TEUCHOS_TEST_FOR_EXCEPTION( xc<0 || xr<0 || mxc<0 || mxr<0, std::invalid_argument,
866 "Belos::ICGSOrthoManager::project(): MVT returned negative dimensions for X,MX" );
868 TEUCHOS_TEST_FOR_EXCEPTION( xc!=mxc || xr!=mxr || xr!=qr, std::invalid_argument,
869 "Belos::ICGSOrthoManager::project(): Size of X not consistant with MX,Q" );
872 for (
int i=0; i<nq; i++) {
874 "Belos::ICGSOrthoManager::project(): Q lengths not mutually consistant" );
876 TEUCHOS_TEST_FOR_EXCEPTION( qr < qcs[i], std::invalid_argument,
877 "Belos::ICGSOrthoManager::project(): Q has less rows than columns" );
880 if ( C[i] == Teuchos::null ) {
881 C[i] = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(qcs[i],xc) );
884 TEUCHOS_TEST_FOR_EXCEPTION( C[i]->numRows() != qcs[i] || C[i]->numCols() != xc , std::invalid_argument,
885 "Belos::ICGSOrthoManager::project(): Size of Q not consistant with size of C" );
890 blkOrtho( X, MX, C, Q );
897 template<
class ScalarType,
class MV,
class OP>
902 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
920 const ScalarType ONE = SCT::one ();
921 const MagnitudeType ZERO = SCT::magnitude (SCT::zero ());
923 const int xc = MVT::GetNumberVecs (X);
924 const ptrdiff_t xr = MVT::GetGlobalLength (X);
937 if (MX == Teuchos::null) {
939 MX = MVT::Clone(X,xc);
940 OPT::Apply(*(this->_Op),X,*MX);
947 if ( B == Teuchos::null ) {
948 B = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(xc,xc) );
951 const int mxc = (this->_hasOp) ? MVT::GetNumberVecs( *MX ) : xc;
952 const ptrdiff_t mxr = (this->_hasOp) ? MVT::GetGlobalLength( *MX ) : xr;
955 TEUCHOS_TEST_FOR_EXCEPTION( xc == 0 || xr == 0, std::invalid_argument,
956 "Belos::ICGSOrthoManager::findBasis(): X must be non-empty" );
957 TEUCHOS_TEST_FOR_EXCEPTION( B->numRows() != xc || B->numCols() != xc, std::invalid_argument,
958 "Belos::ICGSOrthoManager::findBasis(): Size of X not consistant with size of B" );
959 TEUCHOS_TEST_FOR_EXCEPTION( xc != mxc || xr != mxr, std::invalid_argument,
960 "Belos::ICGSOrthoManager::findBasis(): Size of X not consistant with size of MX" );
961 TEUCHOS_TEST_FOR_EXCEPTION( as<ptrdiff_t> (xc) > xr, std::invalid_argument,
962 "Belos::ICGSOrthoManager::findBasis(): Size of X not feasible for normalization" );
963 TEUCHOS_TEST_FOR_EXCEPTION( howMany < 0 || howMany > xc, std::invalid_argument,
964 "Belos::ICGSOrthoManager::findBasis(): Invalid howMany parameter" );
969 int xstart = xc - howMany;
971 for (
int j = xstart; j < xc; j++) {
980 std::vector<int> index(1);
982 Teuchos::RCP<MV> Xj = MVT::CloneViewNonConst( X, index );
983 Teuchos::RCP<MV> MXj;
986 MXj = MVT::CloneViewNonConst( *MX, index );
994 std::vector<int> prev_idx( numX );
995 Teuchos::RCP<const MV> prevX, prevMX;
996 Teuchos::RCP<MV> oldMXj;
999 for (
int i=0; i<numX; i++) {
1002 prevX = MVT::CloneView( X, prev_idx );
1004 prevMX = MVT::CloneView( *MX, prev_idx );
1007 oldMXj = MVT::CloneCopy( *MXj );
1011 Teuchos::SerialDenseMatrix<int,ScalarType> product(numX, 1);
1012 std::vector<ScalarType> oldDot( 1 ), newDot( 1 );
1017#ifdef BELOS_TEUCHOS_TIME_MONITOR
1018 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1020 MVT::MvDot( *Xj, *MXj, oldDot );
1023 TEUCHOS_TEST_FOR_EXCEPTION( SCT::real(oldDot[0]) < ZERO,
OrthoError,
1024 "Belos::ICGSOrthoManager::findBasis(): Negative definiteness discovered in inner product" );
1028 Teuchos::SerialDenseMatrix<int,ScalarType> P2(numX,1);
1030 for (
int i=0; i<max_ortho_steps_; ++i) {
1034#ifdef BELOS_TEUCHOS_TIME_MONITOR
1035 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1043#ifdef BELOS_TEUCHOS_TIME_MONITOR
1044 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1046 MVT::MvTimesMatAddMv( -ONE, *prevX, P2, ONE, *Xj );
1054#ifdef BELOS_TEUCHOS_TIME_MONITOR
1055 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1057 MVT::MvTimesMatAddMv( -ONE, *prevMX, P2, ONE, *MXj );
1071#ifdef BELOS_TEUCHOS_TIME_MONITOR
1072 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1074 MVT::MvDot( *Xj, *oldMXj, newDot );
1077 newDot[0] = oldDot[0];
1081 if (completeBasis) {
1085 if ( SCT::magnitude(newDot[0]) < SCT::magnitude(sing_tol_*oldDot[0]) ) {
1090 std::cout <<
"Belos::ICGSOrthoManager::findBasis() --> Random for column " << numX << std::endl;
1093 Teuchos::RCP<MV> tempXj = MVT::Clone( X, 1 );
1094 Teuchos::RCP<MV> tempMXj;
1095 MVT::MvRandom( *tempXj );
1097 tempMXj = MVT::Clone( X, 1 );
1098 OPT::Apply( *(this->_Op), *tempXj, *tempMXj );
1104#ifdef BELOS_TEUCHOS_TIME_MONITOR
1105 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1107 MVT::MvDot( *tempXj, *tempMXj, oldDot );
1110 for (
int num_orth=0; num_orth<max_ortho_steps_; num_orth++){
1112#ifdef BELOS_TEUCHOS_TIME_MONITOR
1113 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1118#ifdef BELOS_TEUCHOS_TIME_MONITOR
1119 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1121 MVT::MvTimesMatAddMv( -ONE, *prevX, product, ONE, *tempXj );
1124#ifdef BELOS_TEUCHOS_TIME_MONITOR
1125 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1127 MVT::MvTimesMatAddMv( -ONE, *prevMX, product, ONE, *tempMXj );
1132#ifdef BELOS_TEUCHOS_TIME_MONITOR
1133 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1135 MVT::MvDot( *tempXj, *tempMXj, newDot );
1138 if ( SCT::magnitude(newDot[0]) >= SCT::magnitude(oldDot[0]*sing_tol_) ) {
1140 MVT::Assign( *tempXj, *Xj );
1142 MVT::Assign( *tempMXj, *MXj );
1154 if ( SCT::magnitude(newDot[0]) < SCT::magnitude(oldDot[0]*blk_tol_) ) {
1162 ScalarType diag = SCT::squareroot(SCT::magnitude(newDot[0]));
1163 if (SCT::magnitude(diag) > ZERO) {
1164 MVT::MvScale( *Xj, ONE/diag );
1167 MVT::MvScale( *MXj, ONE/diag );
1181 for (
int i=0; i<numX; i++) {
1182 (*B)(i,j) = product(i,0);
1193 template<
class ScalarType,
class MV,
class OP>
1195 ICGSOrthoManager<ScalarType, MV, OP>::blkOrtho1 ( MV &X, Teuchos::RCP<MV> MX,
1196 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
1197 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const
1200 int xc = MVT::GetNumberVecs( X );
1201 const ScalarType ONE = SCT::one();
1203 std::vector<int> qcs( nq );
1204 for (
int i=0; i<nq; i++) {
1205 qcs[i] = MVT::GetNumberVecs( *Q[i] );
1210 Teuchos::Array<Teuchos::RCP<MV> > MQ(nq);
1212 for (
int i=0; i<nq; i++) {
1215#ifdef BELOS_TEUCHOS_TIME_MONITOR
1216 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1222#ifdef BELOS_TEUCHOS_TIME_MONITOR
1223 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1225 MVT::MvTimesMatAddMv( -ONE, *Q[i], *C[i], ONE, X );
1231 OPT::Apply( *(this->_Op), X, *MX);
1235 MQ[i] = MVT::Clone( *Q[i], qcs[i] );
1236 OPT::Apply( *(this->_Op), *Q[i], *MQ[i] );
1238#ifdef BELOS_TEUCHOS_TIME_MONITOR
1239 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1241 MVT::MvTimesMatAddMv( -ONE, *MQ[i], *C[i], ONE, *MX );
1248 for (
int j = 1; j < max_ortho_steps_; ++j) {
1250 for (
int i=0; i<nq; i++) {
1251 Teuchos::SerialDenseMatrix<int,ScalarType> C2(C[i]->numRows(),C[i]->numCols());
1255#ifdef BELOS_TEUCHOS_TIME_MONITOR
1256 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1262#ifdef BELOS_TEUCHOS_TIME_MONITOR
1263 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1265 MVT::MvTimesMatAddMv( -ONE, *Q[i], C2, ONE, X );
1271#ifdef BELOS_TEUCHOS_TIME_MONITOR
1272 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1275 MVT::MvTimesMatAddMv( -ONE, *MQ[i], C2, ONE, *MX );
1277 else if (xc <= qcs[i]) {
1279 OPT::Apply( *(this->_Op), X, *MX);
1290 template<
class ScalarType,
class MV,
class OP>
1292 ICGSOrthoManager<ScalarType, MV, OP>::blkOrtho ( MV &X, Teuchos::RCP<MV> MX,
1293 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
1294 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const
1297 int xc = MVT::GetNumberVecs( X );
1298 bool dep_flg =
false;
1299 const ScalarType ONE = SCT::one();
1301 std::vector<int> qcs( nq );
1302 for (
int i=0; i<nq; i++) {
1303 qcs[i] = MVT::GetNumberVecs( *Q[i] );
1309 std::vector<ScalarType> oldDot( xc );
1311#ifdef BELOS_TEUCHOS_TIME_MONITOR
1312 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1314 MVT::MvDot( X, *MX, oldDot );
1317 Teuchos::Array<Teuchos::RCP<MV> > MQ(nq);
1319 for (
int i=0; i<nq; i++) {
1322#ifdef BELOS_TEUCHOS_TIME_MONITOR
1323 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1329#ifdef BELOS_TEUCHOS_TIME_MONITOR
1330 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1332 MVT::MvTimesMatAddMv( -ONE, *Q[i], *C[i], ONE, X );
1337 OPT::Apply( *(this->_Op), X, *MX);
1341 MQ[i] = MVT::Clone( *Q[i], qcs[i] );
1342 OPT::Apply( *(this->_Op), *Q[i], *MQ[i] );
1344#ifdef BELOS_TEUCHOS_TIME_MONITOR
1345 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1347 MVT::MvTimesMatAddMv( -ONE, *MQ[i], *C[i], ONE, *MX );
1354 for (
int j = 1; j < max_ortho_steps_; ++j) {
1356 for (
int i=0; i<nq; i++) {
1357 Teuchos::SerialDenseMatrix<int,ScalarType> C2(C[i]->numRows(),C[i]->numCols());
1361#ifdef BELOS_TEUCHOS_TIME_MONITOR
1362 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1368#ifdef BELOS_TEUCHOS_TIME_MONITOR
1369 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1371 MVT::MvTimesMatAddMv( -ONE, *Q[i], C2, ONE, X );
1377#ifdef BELOS_TEUCHOS_TIME_MONITOR
1378 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1381 MVT::MvTimesMatAddMv( -ONE, *MQ[i], C2, ONE, *MX );
1383 else if (xc <= qcs[i]) {
1385 OPT::Apply( *(this->_Op), X, *MX);
1392 std::vector<ScalarType> newDot(xc);
1394#ifdef BELOS_TEUCHOS_TIME_MONITOR
1395 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1397 MVT::MvDot( X, *MX, newDot );
1401 for (
int i=0; i<xc; i++){
1402 if (SCT::magnitude(newDot[i]) < SCT::magnitude(oldDot[i] * blk_tol_)) {
1411 template<
class ScalarType,
class MV,
class OP>
1413 ICGSOrthoManager<ScalarType, MV, OP>::blkOrthoSing ( MV &X, Teuchos::RCP<MV> MX,
1414 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
1415 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
1416 Teuchos::ArrayView<Teuchos::RCP<const MV> > QQ)
const
1418 Teuchos::Array<Teuchos::RCP<const MV> > Q (QQ);
1420 const ScalarType ONE = SCT::one();
1421 const ScalarType ZERO = SCT::zero();
1424 int xc = MVT::GetNumberVecs( X );
1425 std::vector<int> indX( 1 );
1426 std::vector<ScalarType> oldDot( 1 ), newDot( 1 );
1428 std::vector<int> qcs( nq );
1429 for (
int i=0; i<nq; i++) {
1430 qcs[i] = MVT::GetNumberVecs( *Q[i] );
1434 Teuchos::RCP<const MV> lastQ;
1435 Teuchos::RCP<MV> Xj, MXj;
1436 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > lastC;
1439 for (
int j=0; j<xc; j++) {
1441 bool dep_flg =
false;
1445 std::vector<int> index( j );
1446 for (
int ind=0; ind<j; ind++) {
1449 lastQ = MVT::CloneView( X, index );
1452 Q.push_back( lastQ );
1454 qcs.push_back( MVT::GetNumberVecs( *lastQ ) );
1459 Xj = MVT::CloneViewNonConst( X, indX );
1461 MXj = MVT::CloneViewNonConst( *MX, indX );
1469#ifdef BELOS_TEUCHOS_TIME_MONITOR
1470 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1472 MVT::MvDot( *Xj, *MXj, oldDot );
1475 Teuchos::Array<Teuchos::RCP<MV> > MQ(Q.size());
1477 for (
int i=0; i<Q.size(); i++) {
1480 Teuchos::SerialDenseMatrix<int,ScalarType> tempC( Teuchos::View, *C[i], qcs[i], 1, 0, j );
1484#ifdef BELOS_TEUCHOS_TIME_MONITOR
1485 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1490#ifdef BELOS_TEUCHOS_TIME_MONITOR
1491 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1494 MVT::MvTimesMatAddMv( -ONE, *Q[i], tempC, ONE, *Xj );
1499 OPT::Apply( *(this->_Op), *Xj, *MXj);
1503 MQ[i] = MVT::Clone( *Q[i], qcs[i] );
1504 OPT::Apply( *(this->_Op), *Q[i], *MQ[i] );
1506#ifdef BELOS_TEUCHOS_TIME_MONITOR
1507 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1509 MVT::MvTimesMatAddMv( -ONE, *MQ[i], tempC, ONE, *MXj );
1516 for (
int num_ortho_steps=1; num_ortho_steps < max_ortho_steps_; ++num_ortho_steps) {
1518 for (
int i=0; i<Q.size(); i++) {
1519 Teuchos::SerialDenseMatrix<int,ScalarType> tempC( Teuchos::View, *C[i], qcs[i], 1, 0, j );
1520 Teuchos::SerialDenseMatrix<int,ScalarType> C2( qcs[i], 1 );
1524#ifdef BELOS_TEUCHOS_TIME_MONITOR
1525 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1531#ifdef BELOS_TEUCHOS_TIME_MONITOR
1532 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1534 MVT::MvTimesMatAddMv( -ONE, *Q[i], C2, ONE, *Xj );
1541#ifdef BELOS_TEUCHOS_TIME_MONITOR
1542 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1544 MVT::MvTimesMatAddMv( -ONE, *MQ[i], C2, ONE, *MXj );
1546 else if (xc <= qcs[i]) {
1548 OPT::Apply( *(this->_Op), *Xj, *MXj);
1557#ifdef BELOS_TEUCHOS_TIME_MONITOR
1558 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1560 MVT::MvDot( *Xj, *MXj, newDot );
1564 if (SCT::magnitude(newDot[0]) < SCT::magnitude(oldDot[0]*sing_tol_)) {
1570 ScalarType diag = SCT::squareroot(SCT::magnitude(newDot[0]));
1572 MVT::MvScale( *Xj, ONE/diag );
1575 MVT::MvScale( *MXj, ONE/diag );
1583 Teuchos::RCP<MV> tempXj = MVT::Clone( X, 1 );
1584 Teuchos::RCP<MV> tempMXj;
1585 MVT::MvRandom( *tempXj );
1587 tempMXj = MVT::Clone( X, 1 );
1588 OPT::Apply( *(this->_Op), *tempXj, *tempMXj );
1594#ifdef BELOS_TEUCHOS_TIME_MONITOR
1595 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1597 MVT::MvDot( *tempXj, *tempMXj, oldDot );
1600 for (
int num_orth=0; num_orth<max_ortho_steps_; num_orth++) {
1602 for (
int i=0; i<Q.size(); i++) {
1603 Teuchos::SerialDenseMatrix<int,ScalarType> product( qcs[i], 1 );
1607#ifdef BELOS_TEUCHOS_TIME_MONITOR
1608 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1613#ifdef BELOS_TEUCHOS_TIME_MONITOR
1614 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1616 MVT::MvTimesMatAddMv( -ONE, *Q[i], product, ONE, *tempXj );
1622#ifdef BELOS_TEUCHOS_TIME_MONITOR
1623 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1626 MVT::MvTimesMatAddMv( -ONE, *MQ[i], product, ONE, *tempMXj );
1628 else if (xc <= qcs[i]) {
1630 OPT::Apply( *(this->_Op), *tempXj, *tempMXj);
1639#ifdef BELOS_TEUCHOS_TIME_MONITOR
1640 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1642 MVT::MvDot( *tempXj, *tempMXj, newDot );
1646 if ( SCT::magnitude(newDot[0]) >= SCT::magnitude(oldDot[0]*sing_tol_) ) {
1647 ScalarType diag = SCT::squareroot(SCT::magnitude(newDot[0]));
1653 MVT::MvAddMv( ONE/diag, *tempXj, ZERO, *tempXj, *Xj );
1655 MVT::MvAddMv( ONE/diag, *tempMXj, ZERO, *tempMXj, *MXj );
1675 template<
class ScalarType,
class MV,
class OP>
1678 using Teuchos::ParameterList;
1679 using Teuchos::parameterList;
1682 RCP<ParameterList> params = parameterList (
"ICGS");
1687 "Maximum number of orthogonalization passes (includes the "
1688 "first). Default is 2, since \"twice is enough\" for Krylov "
1691 "Block reorthogonalization threshold.");
1693 "Singular block detection threshold.");
1698 template<
class ScalarType,
class MV,
class OP>
1701 using Teuchos::ParameterList;
1706 params->set (
"maxNumOrthogPasses",
1708 params->set (
"blkTol",
1710 params->set (
"singTol",
Belos header file which uses auto-configuration information to include necessary C++ headers.
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.
An implementation of the Belos::MatOrthoManager that performs orthogonalization using multiple steps ...
MagnitudeType getSingTol() const
Return parameter for singular block detection.
MagnitudeType getBlkTol() const
Return parameter for block re-orthogonalization threshhold.
~ICGSOrthoManager()
Destructor.
int normalize(MV &X, Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > B) const
This method calls normalize(X,Teuchos::null,B); see documentation for that function.
void project(MV &X, Teuchos::Array< Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > > 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< Teuchos::SerialDenseMatrix< int, ScalarType > > > 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 ...
static const int max_ortho_steps_default_
Max number of (re)orthogonalization steps, including the first (default).
void setBlkTol(const MagnitudeType blk_tol)
Set parameter for block re-orthogonalization threshhold.
static const MagnitudeType sing_tol_fast_
Singular block detection threshold (fast).
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &plist)
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.
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
static const MagnitudeType blk_tol_fast_
Block reorthogonalization threshold (fast).
void setSingTol(const MagnitudeType sing_tol)
Set parameter for singular block detection.
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 ...
int normalize(MV &X, Teuchos::RCP< MV > MX, Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > B) const
This method takes a multivector X and attempts to compute an orthonormal basis for ,...
const std::string & getLabel() const
This method returns the label being used by the timers in the orthogonalization manager.
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.
static const MagnitudeType blk_tol_default_
Block reorthogonalization threshold (default).
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...
Teuchos::RCP< const Teuchos::ParameterList > getFastParameters() const
"Fast" but possibly unsafe or less accurate parameters.
static const MagnitudeType sing_tol_default_
Singular block detection threshold (default).
void setLabel(const std::string &label)
This method sets the label used by the timers in the orthogonalization manager.
virtual int projectAndNormalizeWithMxImpl(MV &X, Teuchos::RCP< MV > MX, Teuchos::Array< Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > > C, Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > 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 int max_ortho_steps_fast_
Max number of (re)orthogonalization steps, including the first (fast).
MatOrthoManager(Teuchos::RCP< const OP > Op=Teuchos::null)
Default constructor.
void innerProd(const MV &X, const MV &Y, Teuchos::SerialDenseMatrix< int, ScalarType > &Z) const
Provides the inner product defining the orthogonality concepts, using the provided operator.
Teuchos::RCP< const OP > _Op
Traits class which defines basic operations on multivectors.
static void MvScale(MV &mv, const ScalarType alpha)
Scale each element of the vectors in mv with alpha.
static Teuchos::RCP< MV > CloneCopy(const MV &mv)
Creates a new MV and copies contents of mv into the new vector (deep copy).
static ptrdiff_t GetGlobalLength(const MV &mv)
Return the number of rows in the given multivector mv.
static void MvDot(const MV &mv, const MV &A, std::vector< ScalarType > &b)
Compute a vector b where the components are the individual dot-products of the i-th columns of A and ...
static Teuchos::RCP< MV > Clone(const MV &mv, const int numvecs)
Creates a new empty MV containing numvecs columns.
static int GetNumberVecs(const MV &mv)
Obtain the number of vectors in mv.
static void Assign(const MV &A, MV &mv)
mv := A
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 > getICGSDefaultParameters()
"Default" parameters for robustness and accuracy.
Teuchos::RCP< Teuchos::ParameterList > getICGSFastParameters()
"Fast" but possibly unsafe or less accurate parameters.