14 #ifndef ANASAZI_BLOCK_DAVIDSON_HPP
15 #define ANASAZI_BLOCK_DAVIDSON_HPP
57 template <
class ScalarType,
class MV>
91 X(Teuchos::null),
KX(Teuchos::null),
MX(Teuchos::null),
92 R(Teuchos::null),
H(Teuchos::null),
93 T(Teuchos::null),
KK(Teuchos::null) {}
131 template <
class ScalarType,
class MV,
class OP>
300 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
getResNorms();
308 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
getRes2Norms();
318 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
getRitzRes2Norms();
390 void setSize(
int blockSize,
int numBlocks);
411 const MagnitudeType ONE;
412 const MagnitudeType ZERO;
413 const MagnitudeType NANVAL;
419 bool checkX, checkMX, checkKX;
420 bool checkH, checkMH, checkKH;
423 CheckList() : checkV(
false),
424 checkX(
false),checkMX(
false),checkKX(
false),
425 checkH(
false),checkMH(
false),checkKH(
false),
426 checkR(
false),checkQ(
false),checkKK(
false) {};
431 std::string accuracyCheck(
const CheckList &chk,
const std::string &where)
const;
451 timerSortEval_, timerDS_,
452 timerLocal_, timerCompRes_,
453 timerOrtho_, timerInit_;
457 int count_ApplyOp_, count_ApplyM_, count_ApplyPrec_;
502 std::vector<MagnitudeType> theta_, Rnorms_, R2norms_;
505 bool Rnorms_current_, R2norms_current_;
520 template <
class ScalarType,
class MV,
class OP>
529 ONE(Teuchos::ScalarTraits<MagnitudeType>::one()),
530 ZERO(Teuchos::ScalarTraits<MagnitudeType>::zero()),
531 NANVAL(Teuchos::ScalarTraits<MagnitudeType>::nan()),
539 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
540 timerOp_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: BlockDavidson::Operation Op*x")),
541 timerMOp_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: BlockDavidson::Operation M*x")),
542 timerPrec_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: BlockDavidson::Operation Prec*x")),
543 timerSortEval_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: BlockDavidson::Sorting eigenvalues")),
544 timerDS_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: BlockDavidson::Direct solve")),
545 timerLocal_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: BlockDavidson::Local update")),
546 timerCompRes_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: BlockDavidson::Computing residuals")),
547 timerOrtho_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: BlockDavidson::Orthogonalization")),
548 timerInit_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: BlockDavidson::Initialization")),
558 auxVecs_( Teuchos::Array<Teuchos::RCP<const MV> >(0) ),
561 Rnorms_current_(false),
562 R2norms_current_(false)
565 "Anasazi::BlockDavidson::constructor: user passed null problem pointer.");
567 "Anasazi::BlockDavidson::constructor: user passed null sort manager pointer.");
569 "Anasazi::BlockDavidson::constructor: user passed null output manager pointer.");
571 "Anasazi::BlockDavidson::constructor: user passed null status test pointer.");
573 "Anasazi::BlockDavidson::constructor: user passed null orthogonalization manager pointer.");
575 "Anasazi::BlockDavidson::constructor: problem is not set.");
577 "Anasazi::BlockDavidson::constructor: problem is not hermitian.");
580 Op_ = problem_->getOperator();
582 "Anasazi::BlockDavidson::constructor: problem provides no operator.");
583 MOp_ = problem_->getM();
584 Prec_ = problem_->getPrec();
585 hasM_ = (MOp_ != Teuchos::null);
588 int bs = params.
get(
"Block Size", problem_->getNEV());
589 int nb = params.
get(
"Num Blocks", 2);
596 template <
class ScalarType,
class MV,
class OP>
603 template <
class ScalarType,
class MV,
class OP>
606 setSize(blockSize,numBlocks_);
612 template <
class ScalarType,
class MV,
class OP>
621 template <
class ScalarType,
class MV,
class OP>
629 template <
class ScalarType,
class MV,
class OP>
637 template <
class ScalarType,
class MV,
class OP>
639 return blockSize_*numBlocks_;
644 template <
class ScalarType,
class MV,
class OP>
646 if (!initialized_)
return 0;
653 template <
class ScalarType,
class MV,
class OP>
654 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
656 return this->getRes2Norms();
662 template <
class ScalarType,
class MV,
class OP>
664 std::vector<int> ret(curDim_,0);
671 template <
class ScalarType,
class MV,
class OP>
673 std::vector<Value<ScalarType> > ret(curDim_);
674 for (
int i=0; i<curDim_; ++i) {
675 ret[i].realpart = theta_[i];
676 ret[i].imagpart = ZERO;
684 template <
class ScalarType,
class MV,
class OP>
692 template <
class ScalarType,
class MV,
class OP>
700 template <
class ScalarType,
class MV,
class OP>
708 template <
class ScalarType,
class MV,
class OP>
719 state.
MX = Teuchos::null;
725 state.
T =
Teuchos::rcp(
new std::vector<MagnitudeType>(theta_.begin(),theta_.begin()+curDim_) );
735 template <
class ScalarType,
class MV,
class OP>
741 template <
class ScalarType,
class MV,
class OP>
745 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
752 TEUCHOS_TEST_FOR_EXCEPTION(blockSize < 1, std::invalid_argument,
"Anasazi::BlockDavidson::setSize(blocksize,numblocks): blocksize must be strictly positive.");
753 TEUCHOS_TEST_FOR_EXCEPTION(numBlocks < 2, std::invalid_argument,
"Anasazi::BlockDavidson::setSize(blocksize,numblocks): numblocks must be greater than one.");
754 if (blockSize == blockSize_ && numBlocks == numBlocks_) {
759 blockSize_ = blockSize;
760 numBlocks_ = numBlocks;
767 if (X_ != Teuchos::null) {
771 tmp = problem_->getInitVec();
773 "Anasazi::BlockDavidson::setSize(): eigenproblem did not specify initial vectors to clone from.");
776 TEUCHOS_TEST_FOR_EXCEPTION(numAuxVecs_+blockSize*static_cast<ptrdiff_t>(numBlocks) > MVT::GetGlobalLength(*tmp),std::invalid_argument,
777 "Anasazi::BlockDavidson::setSize(): max subspace dimension and auxilliary subspace too large.");
784 Rnorms_.resize(blockSize_,NANVAL);
785 R2norms_.resize(blockSize_,NANVAL);
796 om_->print(
Debug,
" >> Allocating X_\n");
797 X_ = MVT::Clone(*tmp,blockSize_);
798 om_->print(
Debug,
" >> Allocating KX_\n");
799 KX_ = MVT::Clone(*tmp,blockSize_);
801 om_->print(
Debug,
" >> Allocating MX_\n");
802 MX_ = MVT::Clone(*tmp,blockSize_);
807 om_->print(
Debug,
" >> Allocating R_\n");
808 R_ = MVT::Clone(*tmp,blockSize_);
813 int newsd = blockSize_*numBlocks_;
814 theta_.resize(blockSize_*numBlocks_,NANVAL);
815 om_->print(
Debug,
" >> Allocating V_\n");
816 V_ = MVT::Clone(*tmp,newsd);
819 om_->print(
Debug,
" >> done allocating.\n");
821 initialized_ =
false;
828 template <
class ScalarType,
class MV,
class OP>
835 for (tarcpmv i=auxVecs_.begin(); i != auxVecs_.end(); ++i) {
836 numAuxVecs_ += MVT::GetNumberVecs(**i);
840 if (numAuxVecs_ > 0 && initialized_) {
841 initialized_ =
false;
844 if (om_->isVerbosity(
Debug ) ) {
847 om_->print(
Debug, accuracyCheck(chk,
": in setAuxVecs()") );
865 template <
class ScalarType,
class MV,
class OP>
871 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
875 std::vector<int> bsind(blockSize_);
876 for (
int i=0; i<blockSize_; ++i) bsind[i] = i;
905 if (newstate.
V != Teuchos::null && newstate.
KK != Teuchos::null) {
907 "Anasazi::BlockDavidson::initialize(newstate): Vector length of V not correct." );
909 "Anasazi::BlockDavidson::initialize(newstate): Rank of new state must be at least blockSize().");
911 "Anasazi::BlockDavidson::initialize(newstate): Rank of new state must be less than getMaxSubspaceDim().");
913 "Anasazi::BlockDavidson::initialize(newstate): Multivector for basis in new state must be as large as specified state rank.");
915 curDim_ = newstate.
curDim;
917 curDim_ = (int)(curDim_ / blockSize_)*blockSize_;
920 "Anasazi::BlockDavidson::initialize(newstate): Rank of new state must be a multiple of getBlockSize().");
924 "Anasazi::BlockDavidson::initialize(newstate): Projected matrix in new state must be as large as specified state rank.");
927 std::vector<int> nevind(curDim_);
928 for (
int i=0; i<curDim_; ++i) nevind[i] = i;
929 if (newstate.
V != V_) {
930 if (curDim_ < MVT::GetNumberVecs(*newstate.
V)) {
931 newstate.
V = MVT::CloneView(*newstate.
V,nevind);
933 MVT::SetBlock(*newstate.
V,nevind,*V_);
935 lclV = MVT::CloneViewNonConst(*V_,nevind);
939 if (newstate.
KK != KK_) {
940 if (newstate.
KK->numRows() > curDim_ || newstate.
KK->numCols() > curDim_) {
943 lclKK->assign(*newstate.
KK);
947 for (
int j=0; j<curDim_-1; ++j) {
948 for (
int i=j+1; i<curDim_; ++i) {
949 (*lclKK)(i,j) = SCT::conjugate((*lclKK)(j,i));
958 "Anasazi::BlockDavdison::initialize(newstate): Eigenproblem did not specify initial vectors to clone from.");
960 newstate.
X = Teuchos::null;
961 newstate.
MX = Teuchos::null;
962 newstate.
KX = Teuchos::null;
963 newstate.
R = Teuchos::null;
964 newstate.
H = Teuchos::null;
965 newstate.
T = Teuchos::null;
966 newstate.
KK = Teuchos::null;
967 newstate.
V = Teuchos::null;
970 curDim_ = MVT::GetNumberVecs(*ivec);
972 curDim_ = (int)(curDim_ / blockSize_)*blockSize_;
973 if (curDim_ > blockSize_*numBlocks_) {
976 curDim_ = blockSize_*numBlocks_;
978 bool userand =
false;
983 curDim_ = blockSize_;
993 std::vector<int> dimind(curDim_);
994 for (
int i=0; i<curDim_; ++i) dimind[i] = i;
995 lclV = MVT::CloneViewNonConst(*V_,dimind);
998 MVT::MvRandom(*lclV);
1001 if (MVT::GetNumberVecs(*ivec) > curDim_) {
1002 ivec = MVT::CloneView(*ivec,dimind);
1005 MVT::SetBlock(*ivec,dimind,*lclV);
1008 if (curDim_*2 <= blockSize_*numBlocks_) {
1010 std::vector<int> block2(curDim_);
1011 for (
int i=0; i<curDim_; ++i) block2[i] = curDim_+i;
1012 tmpVecs = MVT::CloneViewNonConst(*V_,block2);
1016 tmpVecs = MVT::Clone(*V_,curDim_);
1021 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1024 OPT::Apply(*MOp_,*lclV,*tmpVecs);
1025 count_ApplyM_ += curDim_;
1029 if (auxVecs_.size() > 0) {
1030 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1035 int rank = orthman_->projectAndNormalizeMat(*lclV,auxVecs_,dummyC,Teuchos::null,tmpVecs);
1037 "Anasazi::BlockDavidson::initialize(): Couldn't generate initial basis of full rank.");
1040 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1044 int rank = orthman_->normalizeMat(*lclV,Teuchos::null,tmpVecs);
1046 "Anasazi::BlockDavidson::initialize(): Couldn't generate initial basis of full rank.");
1051 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1054 OPT::Apply(*Op_,*lclV,*tmpVecs);
1055 count_ApplyOp_ += curDim_;
1060 MVT::MvTransMv(ONE,*lclV,*tmpVecs,*lclKK);
1063 tmpVecs = Teuchos::null;
1067 if (newstate.
X != Teuchos::null && newstate.
T != Teuchos::null) {
1068 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*newstate.
X) != blockSize_ || MVT::GetGlobalLength(*newstate.
X) != MVT::GetGlobalLength(*X_),
1069 std::invalid_argument,
"Anasazi::BlockDavidson::initialize(newstate): Size of X must be consistent with block size and length of V.");
1071 std::invalid_argument,
"Anasazi::BlockDavidson::initialize(newstate): Size of T must be consistent with dimension of V.");
1073 if (newstate.
X != X_) {
1074 MVT::SetBlock(*newstate.
X,bsind,*X_);
1077 std::copy(newstate.
T->begin(),newstate.
T->end(),theta_.begin());
1083 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1087 Utils::directSolver(curDim_, *lclKK, Teuchos::null, S, theta_, rank, 10);
1090 "Anasazi::BlockDavidson::initialize(newstate): Not enough Ritz vectors to initialize algorithm.");
1094 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1098 std::vector<int> order(curDim_);
1101 sm_->sort(theta_, Teuchos::rcpFromRef(order), curDim_);
1104 Utils::permuteVectors(order,S);
1110 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1115 MVT::MvTimesMatAddMv( ONE, *lclV, S1, ZERO, *X_ );
1118 newstate.
KX = Teuchos::null;
1119 newstate.
MX = Teuchos::null;
1123 lclV = Teuchos::null;
1124 lclKK = Teuchos::null;
1127 if ( newstate.
KX != Teuchos::null ) {
1129 std::invalid_argument,
"Anasazi::BlockDavidson::initialize(newstate): vector length of newstate.KX not correct." );
1131 std::invalid_argument,
"Anasazi::BlockDavidson::initialize(newstate): newstate.KX must have at least block size vectors." );
1132 if (newstate.
KX != KX_) {
1133 MVT::SetBlock(*newstate.
KX,bsind,*KX_);
1139 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1142 OPT::Apply(*Op_,*X_,*KX_);
1143 count_ApplyOp_ += blockSize_;
1146 newstate.
R = Teuchos::null;
1151 if ( newstate.
MX != Teuchos::null ) {
1153 std::invalid_argument,
"Anasazi::BlockDavidson::initialize(newstate): vector length of newstate.MX not correct." );
1155 std::invalid_argument,
"Anasazi::BlockDavidson::initialize(newstate): newstate.MX must have at least block size vectors." );
1156 if (newstate.
MX != MX_) {
1157 MVT::SetBlock(*newstate.
MX,bsind,*MX_);
1163 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1166 OPT::Apply(*MOp_,*X_,*MX_);
1167 count_ApplyOp_ += blockSize_;
1170 newstate.
R = Teuchos::null;
1175 TEUCHOS_TEST_FOR_EXCEPTION(MX_ != X_, std::logic_error,
"Anasazi::BlockDavidson::initialize(): solver invariant not satisfied (MX==X).");
1179 if (newstate.
R != Teuchos::null) {
1181 std::invalid_argument,
"Anasazi::BlockDavidson::initialize(newstate): vector length of newstate.R not correct." );
1183 std::invalid_argument,
"Anasazi::BlockDavidson::initialize(newstate): newstate.R must have at least block size vectors." );
1184 if (newstate.
R != R_) {
1185 MVT::SetBlock(*newstate.
R,bsind,*R_);
1189 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1194 MVT::MvAddMv(ZERO,*KX_,ONE,*KX_,*R_);
1197 for (
int i=0; i<blockSize_; ++i) T(i,i) = theta_[i];
1198 MVT::MvTimesMatAddMv(-ONE,*MX_,T,ONE,*R_);
1203 Rnorms_current_ =
false;
1204 R2norms_current_ =
false;
1207 initialized_ =
true;
1209 if (om_->isVerbosity(
Debug ) ) {
1219 om_->print(
Debug, accuracyCheck(chk,
": after initialize()") );
1223 if (om_->isVerbosity(
Debug)) {
1224 currentStatus( om_->stream(
Debug) );
1234 template <
class ScalarType,
class MV,
class OP>
1244 template <
class ScalarType,
class MV,
class OP>
1249 if (initialized_ ==
false) {
1255 const int searchDim = blockSize_*numBlocks_;
1268 while (tester_->checkStatus(
this) !=
Passed && curDim_ < searchDim) {
1271 if (om_->isVerbosity(
Debug)) {
1272 currentStatus( om_->stream(
Debug) );
1281 std::vector<int> curind(blockSize_);
1282 for (
int i=0; i<blockSize_; ++i) curind[i] = curDim_ + i;
1283 H_ = MVT::CloneViewNonConst(*V_,curind);
1287 if (Prec_ != Teuchos::null) {
1288 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1291 OPT::Apply( *Prec_, *R_, *H_ );
1292 count_ApplyPrec_ += blockSize_;
1295 std::vector<int> bsind(blockSize_);
1296 for (
int i=0; i<blockSize_; ++i) { bsind[i] = i; }
1297 MVT::SetBlock(*R_,bsind,*H_);
1304 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1307 OPT::Apply( *MOp_, *H_, *MH_);
1308 count_ApplyM_ += blockSize_;
1316 std::vector<int> prevind(curDim_);
1317 for (
int i=0; i<curDim_; ++i) prevind[i] = i;
1322 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1329 int rank = orthman_->projectAndNormalizeMat(*H_,against,
1333 "Anasazi::BlockDavidson::iterate(): unable to compute orthonormal basis for H.");
1340 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1343 OPT::Apply( *Op_, *H_, *KH_);
1344 count_ApplyOp_ += blockSize_;
1347 if (om_->isVerbosity(
Debug ) ) {
1352 om_->print(
Debug, accuracyCheck(chk,
": after ortho H") );
1359 om_->print(
OrthoDetails, accuracyCheck(chk,
": after ortho H") );
1367 MVT::MvTransMv(ONE,*Vprev,*KH_,*nextKK);
1370 MVT::MvTransMv(ONE,*H_,*KH_,*nextKK);
1373 nextKK = Teuchos::null;
1374 for (
int i=curDim_; i<curDim_+blockSize_; ++i) {
1375 for (
int j=0; j<i; ++j) {
1376 (*KK_)(i,j) = SCT::conjugate((*KK_)(j,i));
1381 curDim_ += blockSize_;
1382 H_ = KH_ = MH_ = Teuchos::null;
1383 Vprev = Teuchos::null;
1385 if (om_->isVerbosity(
Debug ) ) {
1388 om_->print(
Debug, accuracyCheck(chk,
": after expanding KK") );
1392 curind.resize(curDim_);
1393 for (
int i=0; i<curDim_; ++i) curind[i] = i;
1398 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1401 int nevlocal = curDim_;
1402 int info = Utils::directSolver(curDim_,*KK_,Teuchos::null,S,theta_,nevlocal,10);
1403 TEUCHOS_TEST_FOR_EXCEPTION(info != 0,std::logic_error,
"Anasazi::BlockDavidson::iterate(): direct solve returned error code.");
1405 TEUCHOS_TEST_FOR_EXCEPTION(nevlocal != curDim_,std::logic_error,
"Anasazi::BlockDavidson::iterate(): direct solve did not compute all eigenvectors.");
1410 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1414 std::vector<int> order(curDim_);
1417 sm_->sort(theta_,
Teuchos::rcp(&order,
false), curDim_);
1421 Utils::permuteVectors(order,curS);
1429 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1432 MVT::MvTimesMatAddMv(ONE,*curV,S1,ZERO,*X_);
1437 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1440 OPT::Apply( *Op_, *X_, *KX_);
1441 count_ApplyOp_ += blockSize_;
1445 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1448 OPT::Apply(*MOp_,*X_,*MX_);
1449 count_ApplyM_ += blockSize_;
1458 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1462 MVT::MvAddMv( ONE, *KX_, ZERO, *KX_, *R_ );
1464 for (
int i = 0; i < blockSize_; ++i) {
1467 MVT::MvTimesMatAddMv( -ONE, *MX_, T, ONE, *R_ );
1471 Rnorms_current_ =
false;
1472 R2norms_current_ =
false;
1476 if (om_->isVerbosity(
Debug ) ) {
1484 om_->print(
Debug, accuracyCheck(chk,
": after local update") );
1492 om_->print(
OrthoDetails, accuracyCheck(chk,
": after local update") );
1502 template <
class ScalarType,
class MV,
class OP>
1503 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
1505 if (Rnorms_current_ ==
false) {
1507 orthman_->norm(*R_,Rnorms_);
1508 Rnorms_current_ =
true;
1516 template <
class ScalarType,
class MV,
class OP>
1517 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
1519 if (R2norms_current_ ==
false) {
1521 MVT::MvNorm(*R_,R2norms_);
1522 R2norms_current_ =
true;
1529 template <
class ScalarType,
class MV,
class OP>
1532 "Anasazi::BlockDavidson::setStatusTest() was passed a null StatusTest.");
1538 template <
class ScalarType,
class MV,
class OP>
1570 template <
class ScalarType,
class MV,
class OP>
1575 std::stringstream os;
1577 os.setf(std::ios::scientific, std::ios::floatfield);
1579 os <<
" Debugging checks: iteration " << iter_ << where << endl;
1582 std::vector<int> lclind(curDim_);
1583 for (
int i=0; i<curDim_; ++i) lclind[i] = i;
1586 lclV = MVT::CloneView(*V_,lclind);
1588 if (chk.checkV && initialized_) {
1589 MagnitudeType err = orthman_->orthonormError(*lclV);
1590 os <<
" >> Error in V^H M V == I : " << err << endl;
1591 for (Array_size_type i=0; i<auxVecs_.size(); ++i) {
1592 err = orthman_->orthogError(*lclV,*auxVecs_[i]);
1593 os <<
" >> Error in V^H M Q[" << i <<
"] == 0 : " << err << endl;
1597 OPT::Apply(*Op_,*lclV,*lclKV);
1598 MVT::MvTransMv(ONE,*lclV,*lclKV,curKK);
1602 for (
int j=0; j<curDim_; ++j) {
1603 for (
int i=j+1; i<curDim_; ++i) {
1604 curKK(i,j) = curKK(j,i);
1607 os <<
" >> Error in V^H K V == KK : " << curKK.normFrobenius() << endl;
1611 if (chk.checkX && initialized_) {
1612 MagnitudeType err = orthman_->orthonormError(*X_);
1613 os <<
" >> Error in X^H M X == I : " << err << endl;
1614 for (Array_size_type i=0; i<auxVecs_.size(); ++i) {
1615 err = orthman_->orthogError(*X_,*auxVecs_[i]);
1616 os <<
" >> Error in X^H M Q[" << i <<
"] == 0 : " << err << endl;
1619 if (chk.checkMX && hasM_ && initialized_) {
1620 MagnitudeType err = Utils::errorEquality(*X_, *MX_, MOp_);
1621 os <<
" >> Error in MX == M*X : " << err << endl;
1623 if (chk.checkKX && initialized_) {
1624 MagnitudeType err = Utils::errorEquality(*X_, *KX_, Op_);
1625 os <<
" >> Error in KX == K*X : " << err << endl;
1629 if (chk.checkH && initialized_) {
1630 MagnitudeType err = orthman_->orthonormError(*H_);
1631 os <<
" >> Error in H^H M H == I : " << err << endl;
1632 err = orthman_->orthogError(*H_,*lclV);
1633 os <<
" >> Error in H^H M V == 0 : " << err << endl;
1634 err = orthman_->orthogError(*H_,*X_);
1635 os <<
" >> Error in H^H M X == 0 : " << err << endl;
1636 for (Array_size_type i=0; i<auxVecs_.size(); ++i) {
1637 err = orthman_->orthogError(*H_,*auxVecs_[i]);
1638 os <<
" >> Error in H^H M Q[" << i <<
"] == 0 : " << err << endl;
1641 if (chk.checkKH && initialized_) {
1642 MagnitudeType err = Utils::errorEquality(*H_, *KH_, Op_);
1643 os <<
" >> Error in KH == K*H : " << err << endl;
1645 if (chk.checkMH && hasM_ && initialized_) {
1646 MagnitudeType err = Utils::errorEquality(*H_, *MH_, MOp_);
1647 os <<
" >> Error in MH == M*H : " << err << endl;
1651 if (chk.checkR && initialized_) {
1653 MVT::MvTransMv(ONE,*X_,*R_,xTx);
1654 MagnitudeType err = xTx.normFrobenius();
1655 os <<
" >> Error in X^H R == 0 : " << err << endl;
1659 if (chk.checkKK && initialized_) {
1661 for (
int j=0; j<curDim_; ++j) {
1662 for (
int i=0; i<curDim_; ++i) {
1663 SDMerr(i,j) = lclKK(i,j) - SCT::conjugate(lclKK(j,i));
1666 os <<
" >> Error in KK - KK^H == 0 : " << SDMerr.normFrobenius() << endl;
1671 for (Array_size_type i=0; i<auxVecs_.size(); ++i) {
1672 MagnitudeType err = orthman_->orthonormError(*auxVecs_[i]);
1673 os <<
" >> Error in Q[" << i <<
"]^H M Q[" << i <<
"] == I : " << err << endl;
1674 for (Array_size_type j=i+1; j<auxVecs_.size(); ++j) {
1675 err = orthman_->orthogError(*auxVecs_[i],*auxVecs_[j]);
1676 os <<
" >> Error in Q[" << i <<
"]^H M Q[" << j <<
"] == 0 : " << err << endl;
1689 template <
class ScalarType,
class MV,
class OP>
1695 os.setf(std::ios::scientific, std::ios::floatfield);
1698 os <<
"================================================================================" << endl;
1700 os <<
" BlockDavidson Solver Status" << endl;
1702 os <<
"The solver is "<<(initialized_ ?
"initialized." :
"not initialized.") << endl;
1703 os <<
"The number of iterations performed is " <<iter_<<endl;
1704 os <<
"The block size is " << blockSize_<<endl;
1705 os <<
"The number of blocks is " << numBlocks_<<endl;
1706 os <<
"The current basis size is " << curDim_<<endl;
1707 os <<
"The number of auxiliary vectors is "<< numAuxVecs_ << endl;
1708 os <<
"The number of operations Op*x is "<<count_ApplyOp_<<endl;
1709 os <<
"The number of operations M*x is "<<count_ApplyM_<<endl;
1710 os <<
"The number of operations Prec*x is "<<count_ApplyPrec_<<endl;
1712 os.setf(std::ios_base::right, std::ios_base::adjustfield);
1716 os <<
"CURRENT EIGENVALUE ESTIMATES "<<endl;
1717 os << std::setw(20) <<
"Eigenvalue"
1718 << std::setw(20) <<
"Residual(M)"
1719 << std::setw(20) <<
"Residual(2)"
1721 os <<
"--------------------------------------------------------------------------------"<<endl;
1722 for (
int i=0; i<blockSize_; ++i) {
1723 os << std::setw(20) << theta_[i];
1724 if (Rnorms_current_) os << std::setw(20) << Rnorms_[i];
1725 else os << std::setw(20) <<
"not current";
1726 if (R2norms_current_) os << std::setw(20) << R2norms_[i];
1727 else os << std::setw(20) <<
"not current";
1731 os <<
"================================================================================" << endl;
virtual ~BlockDavidson()
Anasazi::BlockDavidson destructor.
bool isInitialized() const
Indicates whether the solver has been initialized or not.
Teuchos::RCP< const MV > H
The current preconditioned residual vectors.
int getNumIters() const
Get the current iteration count.
std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > getRitzRes2Norms()
Get the 2-norms of the residuals.
Templated virtual class for providing orthogonalization/orthonormalization methods with matrix-based ...
void setSize(int blockSize, int numBlocks)
Set the blocksize and number of blocks to be used by the iterative solver in solving this eigenproble...
This class defines the interface required by an eigensolver and status test class to compute solution...
Teuchos::RCP< const MV > R
The current residual vectors.
Teuchos::RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > KK
The current projected K matrix.
Declaration of basic traits for the multivector type.
T & get(const std::string &name, T def_value)
BlockDavidsonOrthoFailure is thrown when the orthogonalization manager is unable to orthogonalize the...
void currentStatus(std::ostream &os)
This method requests that the solver print out its current status to the given output stream...
int getCurSubspaceDim() const
Get the dimension of the search subspace used to generate the current eigenvectors and eigenvalues...
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void setStatusTest(Teuchos::RCP< StatusTest< ScalarType, MV, OP > > test)
Set a new StatusTest for the solver.
Virtual base class which defines basic traits for the operator type.
Teuchos::RCP< const MV > KX
The image of the current eigenvectors under K.
BlockDavidsonInitFailure is thrown when the BlockDavidson solver is unable to generate an initial ite...
Teuchos::RCP< StatusTest< ScalarType, MV, OP > > getStatusTest() const
Get the current StatusTest used by the solver.
An exception class parent to all Anasazi exceptions.
std::vector< Value< ScalarType > > getRitzValues()
Get the Ritz values for the previous iteration.
This class implements a Block Davidson iteration, a preconditioned iteration for solving linear Hermi...
Teuchos::Array< Teuchos::RCP< const MV > > getAuxVecs() const
Get the auxiliary vectors for the solver.
Pure virtual base class which describes the basic interface to the iterative eigensolver.
Anasazi's templated, static class providing utilities for the solvers.
Anasazi's templated virtual class for providing routines for orthogonalization and orthonormalization...
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
int getMaxSubspaceDim() const
Get the maximum dimension allocated for the search subspace. For BlockDavidson, this always returns n...
Output managers remove the need for the eigensolver to know any information about the required output...
Teuchos::RCP< const MV > V
The basis for the Krylov space.
int putScalar(const ScalarType value=Teuchos::ScalarTraits< ScalarType >::zero())
Traits class which defines basic operations on multivectors.
Virtual base class which defines basic traits for the operator type.
int getBlockSize() const
Get the blocksize used by the iterative solver.
void setAuxVecs(const Teuchos::Array< Teuchos::RCP< const MV > > &auxvecs)
Set the auxiliary vectors for the solver.
const Eigenproblem< ScalarType, MV, OP > & getProblem() const
Get a constant reference to the eigenvalue problem.
int curDim
The current dimension of the solver.
void initialize()
Initialize the solver with the initial vectors from the eigenproblem or random data.
void push_back(const value_type &x)
Structure to contain pointers to BlockDavidson state variables.
Teuchos::RCP< const MV > X
The current eigenvectors.
Teuchos::RCP< const MV > MX
The image of the current eigenvectors under M, or Teuchos::null if M was not specified.
Types and exceptions used within Anasazi solvers and interfaces.
std::vector< int > getRitzIndex()
Get the index used for extracting individual Ritz vectors from getRitzVectors().
void iterate()
This method performs BlockDavidson iterations until the status test indicates the need to stop or an ...
BlockDavidsonState< ScalarType, MV > getState() const
Get access to the current state of the eigensolver.
Anasazi's templated pure virtual class for managing the sorting of approximate eigenvalues computed b...
Common interface of stopping criteria for Anasazi's solvers.
BlockDavidson(const Teuchos::RCP< Eigenproblem< ScalarType, MV, OP > > &problem, const Teuchos::RCP< SortManager< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > > &sorter, const Teuchos::RCP< OutputManager< ScalarType > > &printer, const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > &tester, const Teuchos::RCP< MatOrthoManager< ScalarType, MV, OP > > &ortho, Teuchos::ParameterList ¶ms)
BlockDavidson constructor with eigenproblem, solver utilities, and parameter list of solver options...
std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > getRes2Norms()
Get the current residual 2-norms, computing the norms if they are not up-to-date with the current res...
The Eigensolver is a templated virtual base class that defines the basic interface that any eigensolv...
void setBlockSize(int blockSize)
Set the blocksize.
Teuchos::RCP< const std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > > T
The current Ritz values. This vector is a copy of the internal data.
void resetNumIters()
Reset the iteration count.
Class which provides internal utilities for the Anasazi solvers.
std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > getResNorms()
Get the current residual norms, computing the norms if they are not up-to-date with the current resid...
Teuchos::RCP< const MV > getRitzVectors()
Get access to the current Ritz vectors.