15#ifndef BELOS_DGKS_ORTHOMANAGER_HPP
16#define BELOS_DGKS_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,
70 max_blk_ortho_( max_blk_ortho ),
73 sing_tol_( sing_tol ),
76#ifdef BELOS_TEUCHOS_TIME_MONITOR
78 ss << label_ +
": DGKS[" << max_blk_ortho_ <<
"]";
80 std::string orthoLabel = ss.str() +
": Orthogonalization";
81 timerOrtho_ = Teuchos::TimeMonitor::getNewCounter(orthoLabel);
83 std::string updateLabel = ss.str() +
": Ortho (Update)";
84 timerUpdate_ = Teuchos::TimeMonitor::getNewCounter(updateLabel);
86 std::string normLabel = ss.str() +
": Ortho (Norm)";
87 timerNorm_ = Teuchos::TimeMonitor::getNewCounter(normLabel);
89 std::string ipLabel = ss.str() +
": Ortho (Inner Product)";
90 timerInnerProd_ = Teuchos::TimeMonitor::getNewCounter(ipLabel);
96 const std::string& label =
"Belos",
97 Teuchos::RCP<const OP> Op = Teuchos::null)
107#ifdef BELOS_TEUCHOS_TIME_MONITOR
108 std::stringstream ss;
109 ss << label_ +
": DGKS[" << max_blk_ortho_ <<
"]";
111 std::string orthoLabel = ss.str() +
": Orthogonalization";
112 timerOrtho_ = Teuchos::TimeMonitor::getNewCounter(orthoLabel);
114 std::string updateLabel = ss.str() +
": Ortho (Update)";
115 timerUpdate_ = Teuchos::TimeMonitor::getNewCounter(updateLabel);
117 std::string normLabel = ss.str() +
": Ortho (Norm)";
118 timerNorm_ = Teuchos::TimeMonitor::getNewCounter(normLabel);
120 std::string ipLabel = ss.str() +
": Ortho (Inner Product)";
121 timerInnerProd_ = Teuchos::TimeMonitor::getNewCounter(ipLabel);
135 using Teuchos::ParameterList;
136 using Teuchos::parameterList;
140 RCP<ParameterList> params;
141 if (plist.is_null()) {
143 params = parameterList (*defaultParams);
146 params->validateParametersAndSetDefaults (*defaultParams);
154 const int maxNumOrthogPasses = params->get<
int> (
"maxNumOrthogPasses");
155 const MagnitudeType blkTol = params->get<MagnitudeType> (
"blkTol");
156 const MagnitudeType depTol = params->get<MagnitudeType> (
"depTol");
157 const MagnitudeType singTol = params->get<MagnitudeType> (
"singTol");
159 max_blk_ortho_ = maxNumOrthogPasses;
164 this->setMyParamList (params);
167 Teuchos::RCP<const Teuchos::ParameterList>
170 if (defaultParams_.is_null()) {
174 return defaultParams_;
185 Teuchos::RCP<Teuchos::ParameterList> params = this->getNonconstParameterList();
186 if (! params.is_null()) {
191 params->set (
"blkTol", blk_tol);
199 Teuchos::RCP<Teuchos::ParameterList> params = this->getNonconstParameterList();
200 if (! params.is_null()) {
201 params->set (
"depTol", dep_tol);
209 Teuchos::RCP<Teuchos::ParameterList> params = this->getNonconstParameterList();
210 if (! params.is_null()) {
211 params->set (
"singTol", sing_tol);
213 sing_tol_ = sing_tol;
259 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
260 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const;
266 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
267 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const {
298 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B)
const;
303 int normalize ( MV &X, Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B )
const {
367 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
368 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
369 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const;
381 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
392 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
398 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
407 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
408 orthogError(
const MV &X1, Teuchos::RCP<const MV> MX1,
const MV &X2)
const;
421 const std::string&
getLabel()
const {
return label_; }
453 MagnitudeType blk_tol_;
455 MagnitudeType dep_tol_;
457 MagnitudeType sing_tol_;
461#ifdef BELOS_TEUCHOS_TIME_MONITOR
462 Teuchos::RCP<Teuchos::Time> timerOrtho_, timerUpdate_, timerNorm_, timerInnerProd_;
466 mutable Teuchos::RCP<Teuchos::ParameterList> defaultParams_;
469 int findBasis(MV &X, Teuchos::RCP<MV> MX,
470 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > C,
471 bool completeBasis,
int howMany = -1 )
const;
474 bool blkOrtho1 ( MV &X, Teuchos::RCP<MV> MX,
475 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
476 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const;
479 bool blkOrtho ( MV &X, Teuchos::RCP<MV> MX,
480 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
481 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const;
496 int blkOrthoSing ( MV &X, Teuchos::RCP<MV> MX,
497 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
498 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
499 Teuchos::ArrayView<Teuchos::RCP<const MV> > QQ)
const;
503 template<
class ScalarType,
class MV,
class OP>
506 template<
class ScalarType,
class MV,
class OP>
507 const typename DGKSOrthoManager<ScalarType,MV,OP>::MagnitudeType
509 = 10*Teuchos::ScalarTraits<typename DGKSOrthoManager<ScalarType,MV,OP>::MagnitudeType>::squareroot(
510 Teuchos::ScalarTraits<
typename DGKSOrthoManager<ScalarType,MV,OP>::MagnitudeType>::eps() );
512 template<
class ScalarType,
class MV,
class OP>
513 const typename DGKSOrthoManager<ScalarType,MV,OP>::MagnitudeType
515 = Teuchos::ScalarTraits<typename DGKSOrthoManager<ScalarType,MV,OP>::MagnitudeType>::one()
516 / Teuchos::ScalarTraits<typename DGKSOrthoManager<ScalarType,MV,OP>::MagnitudeType>::squareroot(
517 2*Teuchos::ScalarTraits<
typename DGKSOrthoManager<ScalarType,MV,OP>::MagnitudeType>::one() );
519 template<
class ScalarType,
class MV,
class OP>
520 const typename DGKSOrthoManager<ScalarType,MV,OP>::MagnitudeType
522 = 10*Teuchos::ScalarTraits<typename DGKSOrthoManager<ScalarType,MV,OP>::MagnitudeType>::eps();
524 template<
class ScalarType,
class MV,
class OP>
527 template<
class ScalarType,
class MV,
class OP>
528 const typename DGKSOrthoManager<ScalarType,MV,OP>::MagnitudeType
530 = Teuchos::ScalarTraits<typename DGKSOrthoManager<ScalarType,MV,OP>::MagnitudeType>::zero();
532 template<
class ScalarType,
class MV,
class OP>
533 const typename DGKSOrthoManager<ScalarType,MV,OP>::MagnitudeType
535 = Teuchos::ScalarTraits<typename DGKSOrthoManager<ScalarType,MV,OP>::MagnitudeType>::zero();
537 template<
class ScalarType,
class MV,
class OP>
538 const typename DGKSOrthoManager<ScalarType,MV,OP>::MagnitudeType
540 = Teuchos::ScalarTraits<typename DGKSOrthoManager<ScalarType,MV,OP>::MagnitudeType>::zero();
544 template<
class ScalarType,
class MV,
class OP>
547 if (label != label_) {
549#ifdef BELOS_TEUCHOS_TIME_MONITOR
550 std::stringstream ss;
551 ss << label_ +
": DGKS[" << max_blk_ortho_ <<
"]";
553 std::string orthoLabel = ss.str() +
": Orthogonalization";
554 timerOrtho_ = Teuchos::TimeMonitor::getNewCounter(orthoLabel);
556 std::string updateLabel = ss.str() +
": Ortho (Update)";
557 timerUpdate_ = Teuchos::TimeMonitor::getNewCounter(updateLabel);
559 std::string normLabel = ss.str() +
": Ortho (Norm)";
560 timerNorm_ = Teuchos::TimeMonitor::getNewCounter(normLabel);
562 std::string ipLabel = ss.str() +
": Ortho (Inner Product)";
563 timerInnerProd_ = Teuchos::TimeMonitor::getNewCounter(ipLabel);
570 template<
class ScalarType,
class MV,
class OP>
571 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
573 const ScalarType ONE = SCT::one();
575 Teuchos::SerialDenseMatrix<int,ScalarType> xTx(rank,rank);
577#ifdef BELOS_TEUCHOS_TIME_MONITOR
578 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
582 for (
int i=0; i<rank; i++) {
585 return xTx.normFrobenius();
590 template<
class ScalarType,
class MV,
class OP>
591 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
595 Teuchos::SerialDenseMatrix<int,ScalarType> xTx(r2,r1);
597#ifdef BELOS_TEUCHOS_TIME_MONITOR
598 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
602 return xTx.normFrobenius();
607 template<
class ScalarType,
class MV,
class OP>
612 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
613 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
614 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const
616 using Teuchos::Array;
618 using Teuchos::is_null;
621 using Teuchos::SerialDenseMatrix;
622 typedef SerialDenseMatrix< int, ScalarType > serial_dense_matrix_type;
623 typedef typename Array< RCP< const MV > >::size_type size_type;
625#ifdef BELOS_TEUCHOS_TIME_MONITOR
626 Teuchos::TimeMonitor orthotimer(*timerOrtho_);
629 ScalarType ONE = SCT::one();
630 const MagnitudeType ZERO = SCT::magnitude(SCT::zero());
641 B = rcp (
new serial_dense_matrix_type (xc, xc));
651 for (size_type k = 0; k < nq; ++k)
654 const int numCols = xc;
657 C[k] = rcp (
new serial_dense_matrix_type (numRows, numCols));
658 else if (C[k]->numRows() != numRows || C[k]->numCols() != numCols)
660 int err = C[k]->reshape (numRows, numCols);
661 TEUCHOS_TEST_FOR_EXCEPTION(err != 0, std::runtime_error,
662 "DGKS orthogonalization: failed to reshape "
663 "C[" << k <<
"] (the array of block "
664 "coefficients resulting from projecting X "
665 "against Q[1:" << nq <<
"]).");
671 if (MX == Teuchos::null) {
679 MX = Teuchos::rcp( &X,
false );
686 TEUCHOS_TEST_FOR_EXCEPTION( xc == 0 || xr == 0, std::invalid_argument,
"Belos::DGKSOrthoManager::projectAndNormalize(): X must be non-empty" );
689 for (
int i=0; i<nq; i++) {
694 TEUCHOS_TEST_FOR_EXCEPTION( B->numRows() != xc || B->numCols() != xc, std::invalid_argument,
695 "Belos::DGKSOrthoManager::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::DGKSOrthoManager::projectAndNormalize(): MVT returned negative dimensions for X,MX" );
700 TEUCHOS_TEST_FOR_EXCEPTION( xc!=mxc || xr!=mxr, std::invalid_argument,
701 "Belos::DGKSOrthoManager::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 ) {
717 B = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(xc,xc) );
719 std::vector<ScalarType> diag(1);
721#ifdef BELOS_TEUCHOS_TIME_MONITOR
722 Teuchos::TimeMonitor normTimer( *timerNorm_ );
726 (*B)(0,0) = SCT::squareroot(SCT::magnitude(diag[0]));
728 if (SCT::magnitude((*B)(0,0)) > ZERO) {
740 Teuchos::RCP<MV> tmpX, tmpMX;
747 dep_flg = blkOrtho( X, MX, C, Q );
752 rank = blkOrthoSing( *tmpX, tmpMX, C, B, Q );
762 rank = findBasis( X, MX, B,
false );
766 rank = blkOrthoSing( *tmpX, tmpMX, C, B, Q );
778 TEUCHOS_TEST_FOR_EXCEPTION( rank > xc || rank < 0, std::logic_error,
779 "Belos::DGKSOrthoManager::projectAndNormalize(): Debug error in rank variable." );
789 template<
class ScalarType,
class MV,
class OP>
791 MV &X, Teuchos::RCP<MV> MX,
792 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B )
const {
794#ifdef BELOS_TEUCHOS_TIME_MONITOR
795 Teuchos::TimeMonitor orthotimer(*timerOrtho_);
799 return findBasis(X, MX, B,
true);
806 template<
class ScalarType,
class MV,
class OP>
808 MV &X, Teuchos::RCP<MV> MX,
809 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
810 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const {
826#ifdef BELOS_TEUCHOS_TIME_MONITOR
827 Teuchos::TimeMonitor orthotimer(*timerOrtho_);
833 std::vector<int> qcs(nq);
835 if (nq == 0 || xc == 0 || xr == 0) {
847 if (MX == Teuchos::null) {
855 MX = Teuchos::rcp( &X,
false );
861 TEUCHOS_TEST_FOR_EXCEPTION( xc<0 || xr<0 || mxc<0 || mxr<0, std::invalid_argument,
862 "Belos::DGKSOrthoManager::project(): MVT returned negative dimensions for X,MX" );
864 TEUCHOS_TEST_FOR_EXCEPTION( xc!=mxc || xr!=mxr || xr!=qr, std::invalid_argument,
865 "Belos::DGKSOrthoManager::project(): Size of X not consistant with MX,Q" );
868 for (
int i=0; i<nq; i++) {
870 "Belos::DGKSOrthoManager::project(): Q lengths not mutually consistant" );
872 TEUCHOS_TEST_FOR_EXCEPTION( qr < qcs[i], std::invalid_argument,
873 "Belos::DGKSOrthoManager::project(): Q has less rows than columns" );
876 if ( C[i] == Teuchos::null ) {
877 C[i] = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(qcs[i],xc) );
880 TEUCHOS_TEST_FOR_EXCEPTION( C[i]->numRows() != qcs[i] || C[i]->numCols() != xc , std::invalid_argument,
881 "Belos::DGKSOrthoManager::project(): Size of Q not consistant with size of C" );
886 blkOrtho( X, MX, C, Q );
893 template<
class ScalarType,
class MV,
class OP>
894 int DGKSOrthoManager<ScalarType, MV, OP>::findBasis(
895 MV &X, Teuchos::RCP<MV> MX,
896 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
897 bool completeBasis,
int howMany )
const {
914 const ScalarType ONE = SCT::one();
915 const MagnitudeType ZERO = SCT::magnitude(SCT::zero());
917 int xc = MVT::GetNumberVecs( X );
918 ptrdiff_t xr = MVT::GetGlobalLength( X );
931 if (MX == Teuchos::null) {
933 MX = MVT::Clone(X,xc);
934 OPT::Apply(*(this->_Op),X,*MX);
941 if ( B == Teuchos::null ) {
942 B = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(xc,xc) );
945 int mxc = (this->_hasOp) ? MVT::GetNumberVecs( *MX ) : xc;
946 ptrdiff_t mxr = (this->_hasOp) ? MVT::GetGlobalLength( *MX ) : xr;
949 TEUCHOS_TEST_FOR_EXCEPTION( xc == 0 || xr == 0, std::invalid_argument,
950 "Belos::DGKSOrthoManager::findBasis(): X must be non-empty" );
951 TEUCHOS_TEST_FOR_EXCEPTION( B->numRows() != xc || B->numCols() != xc, std::invalid_argument,
952 "Belos::DGKSOrthoManager::findBasis(): Size of X not consistant with size of B" );
953 TEUCHOS_TEST_FOR_EXCEPTION( xc != mxc || xr != mxr, std::invalid_argument,
954 "Belos::DGKSOrthoManager::findBasis(): Size of X not consistant with size of MX" );
955 TEUCHOS_TEST_FOR_EXCEPTION(
static_cast<ptrdiff_t
>(xc) > xr, std::invalid_argument,
956 "Belos::DGKSOrthoManager::findBasis(): Size of X not feasible for normalization" );
957 TEUCHOS_TEST_FOR_EXCEPTION( howMany < 0 || howMany > xc, std::invalid_argument,
958 "Belos::DGKSOrthoManager::findBasis(): Invalid howMany parameter" );
963 int xstart = xc - howMany;
965 for (
int j = xstart; j < xc; j++) {
974 std::vector<int> index(1);
976 Teuchos::RCP<MV> Xj = MVT::CloneViewNonConst( X, index );
977 Teuchos::RCP<MV> MXj;
978 if ((this->_hasOp)) {
980 MXj = MVT::CloneViewNonConst( *MX, index );
988 std::vector<int> prev_idx( numX );
989 Teuchos::RCP<const MV> prevX, prevMX;
990 Teuchos::RCP<MV> oldMXj;
993 for (
int i=0; i<numX; i++) {
996 prevX = MVT::CloneView( X, prev_idx );
998 prevMX = MVT::CloneView( *MX, prev_idx );
1001 oldMXj = MVT::CloneCopy( *MXj );
1005 Teuchos::SerialDenseMatrix<int,ScalarType> product(numX, 1);
1006 std::vector<ScalarType> oldDot( 1 ), newDot( 1 );
1011#ifdef BELOS_TEUCHOS_TIME_MONITOR
1012 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1014 MVT::MvDot( *Xj, *MXj, oldDot );
1017 TEUCHOS_TEST_FOR_EXCEPTION( SCT::real(oldDot[0]) < ZERO,
OrthoError,
1018 "Belos::DGKSOrthoManager::findBasis(): Negative definiteness discovered in inner product" );
1025#ifdef BELOS_TEUCHOS_TIME_MONITOR
1026 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1033#ifdef BELOS_TEUCHOS_TIME_MONITOR
1034 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1036 MVT::MvTimesMatAddMv( -ONE, *prevX, product, ONE, *Xj );
1044#ifdef BELOS_TEUCHOS_TIME_MONITOR
1045 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1047 MVT::MvTimesMatAddMv( -ONE, *prevMX, product, ONE, *MXj );
1052#ifdef BELOS_TEUCHOS_TIME_MONITOR
1053 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1055 MVT::MvDot( *Xj, *MXj, newDot );
1059 if ( MGT::squareroot(SCT::magnitude(newDot[0])) < dep_tol_*MGT::squareroot(SCT::magnitude(oldDot[0])) ) {
1062 Teuchos::SerialDenseMatrix<int,ScalarType> P2(numX,1);
1064#ifdef BELOS_TEUCHOS_TIME_MONITOR
1065 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1072#ifdef BELOS_TEUCHOS_TIME_MONITOR
1073 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1075 MVT::MvTimesMatAddMv( -ONE, *prevX, P2, ONE, *Xj );
1077 if ((this->_hasOp)) {
1078#ifdef BELOS_TEUCHOS_TIME_MONITOR
1079 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1081 MVT::MvTimesMatAddMv( -ONE, *prevMX, P2, ONE, *MXj );
1089#ifdef BELOS_TEUCHOS_TIME_MONITOR
1090 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1092 MVT::MvDot( *Xj, *oldMXj, newDot );
1095 newDot[0] = oldDot[0];
1099 if (completeBasis) {
1103 if ( SCT::magnitude(newDot[0]) < SCT::magnitude(sing_tol_*oldDot[0]) ) {
1108 std::cout <<
"Belos::DGKSOrthoManager::findBasis() --> Random for column " << numX << std::endl;
1111 Teuchos::RCP<MV> tempXj = MVT::Clone( X, 1 );
1112 Teuchos::RCP<MV> tempMXj;
1113 MVT::MvRandom( *tempXj );
1115 tempMXj = MVT::Clone( X, 1 );
1116 OPT::Apply( *(this->_Op), *tempXj, *tempMXj );
1122#ifdef BELOS_TEUCHOS_TIME_MONITOR
1123 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1125 MVT::MvDot( *tempXj, *tempMXj, oldDot );
1128 for (
int num_orth=0; num_orth<max_blk_ortho_; num_orth++){
1130#ifdef BELOS_TEUCHOS_TIME_MONITOR
1131 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1136#ifdef BELOS_TEUCHOS_TIME_MONITOR
1137 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1139 MVT::MvTimesMatAddMv( -ONE, *prevX, product, ONE, *tempXj );
1142#ifdef BELOS_TEUCHOS_TIME_MONITOR
1143 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1145 MVT::MvTimesMatAddMv( -ONE, *prevMX, product, ONE, *tempMXj );
1150#ifdef BELOS_TEUCHOS_TIME_MONITOR
1151 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1153 MVT::MvDot( *tempXj, *tempMXj, newDot );
1156 if ( SCT::magnitude(newDot[0]) >= SCT::magnitude(oldDot[0]*sing_tol_) ) {
1158 MVT::Assign( *tempXj, *Xj );
1160 MVT::Assign( *tempMXj, *MXj );
1172 if ( SCT::magnitude(newDot[0]) < SCT::magnitude(oldDot[0]*blk_tol_) ) {
1180 ScalarType diag = SCT::squareroot(SCT::magnitude(newDot[0]));
1182 if (SCT::magnitude(diag) > ZERO) {
1183 MVT::MvScale( *Xj, ONE/diag );
1186 MVT::MvScale( *MXj, ONE/diag );
1200 for (
int i=0; i<numX; i++) {
1201 (*B)(i,j) = product(i,0);
1212 template<
class ScalarType,
class MV,
class OP>
1214 DGKSOrthoManager<ScalarType, MV, OP>::blkOrtho1 ( MV &X, Teuchos::RCP<MV> MX,
1215 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
1216 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const
1219 int xc = MVT::GetNumberVecs( X );
1220 const ScalarType ONE = SCT::one();
1222 std::vector<int> qcs( nq );
1223 for (
int i=0; i<nq; i++) {
1224 qcs[i] = MVT::GetNumberVecs( *Q[i] );
1228 std::vector<ScalarType> oldDot( 1 ), newDot( 1 );
1230#ifdef BELOS_TEUCHOS_TIME_MONITOR
1231 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1233 MVT::MvDot( X, *MX, oldDot );
1236 Teuchos::Array<Teuchos::RCP<MV> > MQ(nq);
1238 for (
int i=0; i<nq; i++) {
1241#ifdef BELOS_TEUCHOS_TIME_MONITOR
1242 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1248#ifdef BELOS_TEUCHOS_TIME_MONITOR
1249 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1251 MVT::MvTimesMatAddMv( -ONE, *Q[i], *C[i], ONE, X );
1257 OPT::Apply( *(this->_Op), X, *MX);
1261 MQ[i] = MVT::Clone( *Q[i], qcs[i] );
1262 OPT::Apply( *(this->_Op), *Q[i], *MQ[i] );
1264#ifdef BELOS_TEUCHOS_TIME_MONITOR
1265 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1267 MVT::MvTimesMatAddMv( -ONE, *MQ[i], *C[i], ONE, *MX );
1274#ifdef BELOS_TEUCHOS_TIME_MONITOR
1275 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1277 MVT::MvDot( X, *MX, newDot );
1291 if ( MGT::squareroot(SCT::magnitude(newDot[0])) < dep_tol_*MGT::squareroot(SCT::magnitude(oldDot[0])) ) {
1294 for (
int i=0; i<nq; i++) {
1295 Teuchos::SerialDenseMatrix<int,ScalarType> C2(C[i]->numRows(), C[i]->numCols());
1299#ifdef BELOS_TEUCHOS_TIME_MONITOR
1300 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1307#ifdef BELOS_TEUCHOS_TIME_MONITOR
1308 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1310 MVT::MvTimesMatAddMv( -ONE, *Q[i], C2, ONE, X );
1316#ifdef BELOS_TEUCHOS_TIME_MONITOR
1317 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1320 MVT::MvTimesMatAddMv( -ONE, *MQ[i], C2, ONE, *MX );
1322 else if (xc <= qcs[i]) {
1324 OPT::Apply( *(this->_Op), X, *MX);
1335 template<
class ScalarType,
class MV,
class OP>
1337 DGKSOrthoManager<ScalarType, MV, OP>::blkOrtho ( MV &X, Teuchos::RCP<MV> MX,
1338 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
1339 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const
1342 int xc = MVT::GetNumberVecs( X );
1343 bool dep_flg =
false;
1344 const ScalarType ONE = SCT::one();
1346 std::vector<int> qcs( nq );
1347 for (
int i=0; i<nq; i++) {
1348 qcs[i] = MVT::GetNumberVecs( *Q[i] );
1354 std::vector<ScalarType> oldDot( xc );
1356#ifdef BELOS_TEUCHOS_TIME_MONITOR
1357 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1359 MVT::MvDot( X, *MX, oldDot );
1362 Teuchos::Array<Teuchos::RCP<MV> > MQ(nq);
1364 for (
int i=0; i<nq; i++) {
1367#ifdef BELOS_TEUCHOS_TIME_MONITOR
1368 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1374#ifdef BELOS_TEUCHOS_TIME_MONITOR
1375 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1377 MVT::MvTimesMatAddMv( -ONE, *Q[i], *C[i], ONE, X );
1383 OPT::Apply( *(this->_Op), X, *MX);
1387 MQ[i] = MVT::Clone( *Q[i], qcs[i] );
1388 OPT::Apply( *(this->_Op), *Q[i], *MQ[i] );
1390#ifdef BELOS_TEUCHOS_TIME_MONITOR
1391 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1393 MVT::MvTimesMatAddMv( -ONE, *MQ[i], *C[i], ONE, *MX );
1400 for (
int j = 1; j < max_blk_ortho_; ++j) {
1402 for (
int i=0; i<nq; i++) {
1403 Teuchos::SerialDenseMatrix<int,ScalarType> C2(C[i]->numRows(), C[i]->numCols());
1407#ifdef BELOS_TEUCHOS_TIME_MONITOR
1408 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1415#ifdef BELOS_TEUCHOS_TIME_MONITOR
1416 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1418 MVT::MvTimesMatAddMv( -ONE, *Q[i], C2, ONE, X );
1424#ifdef BELOS_TEUCHOS_TIME_MONITOR
1425 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1428 MVT::MvTimesMatAddMv( -ONE, *MQ[i], C2, ONE, *MX );
1430 else if (xc <= qcs[i]) {
1432 OPT::Apply( *(this->_Op), X, *MX);
1439 std::vector<ScalarType> newDot(xc);
1441#ifdef BELOS_TEUCHOS_TIME_MONITOR
1442 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1444 MVT::MvDot( X, *MX, newDot );
1448 for (
int i=0; i<xc; i++){
1449 if (SCT::magnitude(newDot[i]) < SCT::magnitude(oldDot[i] * blk_tol_)) {
1459 template<
class ScalarType,
class MV,
class OP>
1461 DGKSOrthoManager<ScalarType, MV, OP>::blkOrthoSing ( MV &X, Teuchos::RCP<MV> MX,
1462 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
1463 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
1464 Teuchos::ArrayView<Teuchos::RCP<const MV> > QQ)
const
1466 Teuchos::Array<Teuchos::RCP<const MV> > Q (QQ);
1468 const ScalarType ONE = SCT::one();
1469 const ScalarType ZERO = SCT::zero();
1472 int xc = MVT::GetNumberVecs( X );
1473 std::vector<int> indX( 1 );
1474 std::vector<ScalarType> oldDot( 1 ), newDot( 1 );
1476 std::vector<int> qcs( nq );
1477 for (
int i=0; i<nq; i++) {
1478 qcs[i] = MVT::GetNumberVecs( *Q[i] );
1482 Teuchos::RCP<const MV> lastQ;
1483 Teuchos::RCP<MV> Xj, MXj;
1484 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > lastC;
1487 for (
int j=0; j<xc; j++) {
1489 bool dep_flg =
false;
1493 std::vector<int> index( j );
1494 for (
int ind=0; ind<j; ind++) {
1497 lastQ = MVT::CloneView( X, index );
1500 Q.push_back( lastQ );
1502 qcs.push_back( MVT::GetNumberVecs( *lastQ ) );
1507 Xj = MVT::CloneViewNonConst( X, indX );
1509 MXj = MVT::CloneViewNonConst( *MX, indX );
1517#ifdef BELOS_TEUCHOS_TIME_MONITOR
1518 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1520 MVT::MvDot( *Xj, *MXj, oldDot );
1523 Teuchos::Array<Teuchos::RCP<MV> > MQ(Q.size());
1525 for (
int i=0; i<Q.size(); i++) {
1528 Teuchos::SerialDenseMatrix<int,ScalarType> tempC( Teuchos::View, *C[i], qcs[i], 1, 0, j );
1532#ifdef BELOS_TEUCHOS_TIME_MONITOR
1533 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1539#ifdef BELOS_TEUCHOS_TIME_MONITOR
1540 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1542 MVT::MvTimesMatAddMv( -ONE, *Q[i], tempC, ONE, *Xj );
1548 OPT::Apply( *(this->_Op), *Xj, *MXj);
1552 MQ[i] = MVT::Clone( *Q[i], qcs[i] );
1553 OPT::Apply( *(this->_Op), *Q[i], *MQ[i] );
1555#ifdef BELOS_TEUCHOS_TIME_MONITOR
1556 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1558 MVT::MvTimesMatAddMv( -ONE, *MQ[i], tempC, ONE, *MXj );
1566#ifdef BELOS_TEUCHOS_TIME_MONITOR
1567 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1569 MVT::MvDot( *Xj, *MXj, newDot );
1575 if ( SCT::magnitude(newDot[0]) < SCT::magnitude(oldDot[0]*dep_tol_) ) {
1577 for (
int i=0; i<Q.size(); i++) {
1578 Teuchos::SerialDenseMatrix<int,ScalarType> tempC( Teuchos::View, *C[i], qcs[i], 1, 0, j );
1579 Teuchos::SerialDenseMatrix<int,ScalarType> C2( qcs[i], 1 );
1583#ifdef BELOS_TEUCHOS_TIME_MONITOR
1584 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1590#ifdef BELOS_TEUCHOS_TIME_MONITOR
1591 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1593 MVT::MvTimesMatAddMv( -ONE, *Q[i], C2, ONE, *Xj );
1599#ifdef BELOS_TEUCHOS_TIME_MONITOR
1600 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1603 MVT::MvTimesMatAddMv( -ONE, *MQ[i], C2, ONE, *MXj );
1605 else if (xc <= qcs[i]) {
1607 OPT::Apply( *(this->_Op), *Xj, *MXj);
1614#ifdef BELOS_TEUCHOS_TIME_MONITOR
1615 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1617 MVT::MvDot( *Xj, *MXj, newDot );
1622 if (SCT::magnitude(newDot[0]) < SCT::magnitude(oldDot[0]*sing_tol_)) {
1628 ScalarType diag = SCT::squareroot(SCT::magnitude(newDot[0]));
1630 MVT::MvScale( *Xj, ONE/diag );
1633 MVT::MvScale( *MXj, ONE/diag );
1641 Teuchos::RCP<MV> tempXj = MVT::Clone( X, 1 );
1642 Teuchos::RCP<MV> tempMXj;
1643 MVT::MvRandom( *tempXj );
1645 tempMXj = MVT::Clone( X, 1 );
1646 OPT::Apply( *(this->_Op), *tempXj, *tempMXj );
1652#ifdef BELOS_TEUCHOS_TIME_MONITOR
1653 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1655 MVT::MvDot( *tempXj, *tempMXj, oldDot );
1658 for (
int num_orth=0; num_orth<max_blk_ortho_; num_orth++) {
1660 for (
int i=0; i<Q.size(); i++) {
1661 Teuchos::SerialDenseMatrix<int,ScalarType> product( qcs[i], 1 );
1665#ifdef BELOS_TEUCHOS_TIME_MONITOR
1666 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1671#ifdef BELOS_TEUCHOS_TIME_MONITOR
1672 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1674 MVT::MvTimesMatAddMv( -ONE, *Q[i], product, ONE, *tempXj );
1680#ifdef BELOS_TEUCHOS_TIME_MONITOR
1681 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1684 MVT::MvTimesMatAddMv( -ONE, *MQ[i], product, ONE, *tempMXj );
1686 else if (xc <= qcs[i]) {
1688 OPT::Apply( *(this->_Op), *tempXj, *tempMXj);
1697#ifdef BELOS_TEUCHOS_TIME_MONITOR
1698 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1700 MVT::MvDot( *tempXj, *tempMXj, newDot );
1704 if ( SCT::magnitude(newDot[0]) >= SCT::magnitude(oldDot[0]*sing_tol_) ) {
1705 ScalarType diag = SCT::squareroot(SCT::magnitude(newDot[0]));
1711 MVT::MvAddMv( ONE/diag, *tempXj, ZERO, *tempXj, *Xj );
1713 MVT::MvAddMv( ONE/diag, *tempMXj, ZERO, *tempMXj, *MXj );
1733 template<
class ScalarType,
class MV,
class OP>
1736 using Teuchos::ParameterList;
1737 using Teuchos::parameterList;
1740 RCP<ParameterList> params = parameterList (
"DGKS");
1745 "Maximum number of orthogonalization passes (includes the "
1746 "first). Default is 2, since \"twice is enough\" for Krylov "
1749 "Block reorthogonalization threshold.");
1751 "(Non-block) reorthogonalization threshold.");
1753 "Singular block detection threshold.");
1758 template<
class ScalarType,
class MV,
class OP>
1761 using Teuchos::ParameterList;
1766 params->set (
"maxNumOrthogPasses",
1768 params->set (
"blkTol",
1770 params->set (
"depTol",
1772 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.
DGKSOrthoManager(const std::string &label="Belos", Teuchos::RCP< const OP > Op=Teuchos::null, const int max_blk_ortho=max_blk_ortho_default_, const MagnitudeType blk_tol=blk_tol_default_, const MagnitudeType dep_tol=dep_tol_default_, const MagnitudeType sing_tol=sing_tol_default_)
Constructor specifying re-orthogonalization tolerance.
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_blk_ortho_default_
~DGKSOrthoManager()
Destructor.
static const MagnitudeType blk_tol_fast_
MagnitudeType getSingTol() const
Return parameter for singular block detection.
Teuchos::ScalarTraits< ScalarType >::magnitudeType orthonormError(const MV &X, Teuchos::RCP< const MV > MX) const
This method computes the error in orthonormality of a multivector. The method has the option of explo...
DGKSOrthoManager(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.
static const MagnitudeType dep_tol_default_
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.
static const int max_blk_ortho_fast_
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &plist)
const std::string & getLabel() const
This method returns the label being used by the timers in the orthogonalization manager.
Teuchos::ScalarTraits< ScalarType >::magnitudeType orthonormError(const MV &X) const
This method computes the error in orthonormality of a multivector.
Teuchos::ScalarTraits< ScalarType >::magnitudeType orthogError(const MV &X1, Teuchos::RCP< const MV > MX1, const MV &X2) const
This method computes the error in orthogonality of two multivectors, measured as the Frobenius norm o...
void setDepTol(const MagnitudeType dep_tol)
Set parameter for re-orthogonalization threshhold.
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
static const MagnitudeType dep_tol_fast_
void setBlkTol(const MagnitudeType blk_tol)
Set parameter for block re-orthogonalization threshhold.
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 .
MagnitudeType getDepTol() const
Return parameter for re-orthogonalization threshhold.
static const MagnitudeType sing_tol_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.
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.
static const MagnitudeType blk_tol_default_
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 ,...
static const MagnitudeType sing_tol_default_
void setSingTol(const MagnitudeType sing_tol)
Set parameter for singular block detection.
MagnitudeType getBlkTol() const
Return parameter for block re-orthogonalization threshhold.
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 > getDGKSDefaultParameters()
"Default" parameters for robustness and accuracy.
Teuchos::RCP< Teuchos::ParameterList > getDGKSFastParameters()
"Fast" but possibly unsafe or less accurate parameters.