14#ifndef ANASAZI_RTRBASE_HPP
15#define ANASAZI_RTRBASE_HPP
22#include "Teuchos_ScalarTraits.hpp"
27#include "Teuchos_LAPACK.hpp"
28#include "Teuchos_BLAS.hpp"
29#include "Teuchos_SerialDenseMatrix.hpp"
30#include "Teuchos_ParameterList.hpp"
31#include "Teuchos_TimeMonitor.hpp"
91 template <
class ScalarType,
class MV>
94 Teuchos::RCP<const MV>
X;
96 Teuchos::RCP<const MV>
AX;
98 Teuchos::RCP<const MV>
BX;
100 Teuchos::RCP<const MV>
R;
102 Teuchos::RCP<const std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> >
T;
106 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
rho;
107 RTRState() :
X(Teuchos::null),
AX(Teuchos::null),
BX(Teuchos::null),
108 R(Teuchos::null),
T(Teuchos::null),
rho(0) {};
169 template <
class ScalarType,
class MV,
class OP>
182 const Teuchos::RCP<
SortManager<
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > &sorter,
186 Teuchos::ParameterList ¶ms,
187 const std::string &solverLabel,
bool skinnySolver
316 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
getResNorms();
324 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
getRes2Norms();
331 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
getRitzRes2Norms();
357 Teuchos::RCP<StatusTest<ScalarType,MV,OP> >
getStatusTest()
const;
398 void setAuxVecs(
const Teuchos::Array<Teuchos::RCP<const MV> > &auxvecs);
401 Teuchos::Array<Teuchos::RCP<const MV> >
getAuxVecs()
const;
420 typedef Teuchos::ScalarTraits<ScalarType> SCT;
421 typedef typename SCT::magnitudeType MagnitudeType;
422 typedef Teuchos::ScalarTraits<MagnitudeType> MAT;
423 const MagnitudeType ONE;
424 const MagnitudeType ZERO;
425 const MagnitudeType NANVAL;
426 typedef typename std::vector<MagnitudeType>::iterator vecMTiter;
427 typedef typename std::vector<ScalarType>::iterator vecSTiter;
432 bool checkX, checkAX, checkBX;
433 bool checkEta, checkAEta, checkBEta;
434 bool checkR, checkQ, checkBR;
435 bool checkZ, checkPBX;
436 CheckList() : checkX(false),checkAX(false),checkBX(false),
437 checkEta(false),checkAEta(false),checkBEta(false),
438 checkR(false),checkQ(false),checkBR(false),
439 checkZ(false), checkPBX(false) {};
444 std::string accuracyCheck(
const CheckList &chk,
const std::string &where)
const;
446 virtual void solveTRSubproblem() = 0;
448 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType ginner(
const MV &xi)
const;
449 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType ginner(
const MV &xi,
const MV &zeta)
const;
450 void ginnersep(
const MV &xi, std::vector<
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType > &d)
const;
451 void ginnersep(
const MV &xi,
const MV &zeta, std::vector<
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType > &d)
const;
455 const Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > problem_;
456 const Teuchos::RCP<SortManager<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > sm_;
457 const Teuchos::RCP<OutputManager<ScalarType> > om_;
458 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > tester_;
459 const Teuchos::RCP<GenOrthoManager<ScalarType,MV,OP> > orthman_;
463 Teuchos::RCP<const OP> AOp_;
464 Teuchos::RCP<const OP> BOp_;
465 Teuchos::RCP<const OP> Prec_;
466 bool hasBOp_, hasPrec_, olsenPrec_;
470 Teuchos::RCP<Teuchos::Time> timerAOp_, timerBOp_, timerPrec_,
472 timerLocalProj_, timerDS_,
473 timerLocalUpdate_, timerCompRes_,
474 timerOrtho_, timerInit_;
479 int counterAOp_, counterBOp_, counterPrec_;
542 Teuchos::RCP<MV> V_, BV_, PBV_,
545 delta_, Adelta_, Bdelta_, Hdelta_,
547 Teuchos::RCP<const MV> X_, BX_;
550 Teuchos::Array<Teuchos::RCP<const MV> > auxVecs_;
557 std::vector<MagnitudeType> theta_, Rnorms_, R2norms_, ritz2norms_;
560 bool Rnorms_current_, R2norms_current_;
563 MagnitudeType conv_kappa_, conv_theta_;
575 template <
class ScalarType,
class MV,
class OP>
578 const Teuchos::RCP<
SortManager<
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > &sorter,
582 Teuchos::ParameterList ¶ms,
583 const std::string &solverLabel,
bool skinnySolver
585 ONE(Teuchos::ScalarTraits<MagnitudeType>::one()),
586 ZERO(Teuchos::ScalarTraits<MagnitudeType>::zero()),
587 NANVAL(Teuchos::ScalarTraits<MagnitudeType>::nan()),
594#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
595 timerAOp_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: "+solverLabel+
"::Operation A*x")),
596 timerBOp_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: "+solverLabel+
"::Operation B*x")),
597 timerPrec_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: "+solverLabel+
"::Operation Prec*x")),
598 timerSort_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: "+solverLabel+
"::Sorting eigenvalues")),
599 timerLocalProj_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: "+solverLabel+
"::Local projection")),
600 timerDS_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: "+solverLabel+
"::Direct solve")),
601 timerLocalUpdate_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: "+solverLabel+
"::Local update")),
602 timerCompRes_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: "+solverLabel+
"::Computing residuals")),
603 timerOrtho_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: "+solverLabel+
"::Orthogonalization")),
604 timerInit_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: "+solverLabel+
"::Initialization")),
613 isSkinny_(skinnySolver),
615 auxVecs_( Teuchos::Array<Teuchos::RCP<const MV> >(0) ),
618 Rnorms_current_(false),
619 R2norms_current_(false),
625 TEUCHOS_TEST_FOR_EXCEPTION(problem_ == Teuchos::null,std::invalid_argument,
626 "Anasazi::RTRBase::constructor: user passed null problem pointer.");
627 TEUCHOS_TEST_FOR_EXCEPTION(sm_ == Teuchos::null,std::invalid_argument,
628 "Anasazi::RTRBase::constructor: user passed null sort manager pointer.");
629 TEUCHOS_TEST_FOR_EXCEPTION(om_ == Teuchos::null,std::invalid_argument,
630 "Anasazi::RTRBase::constructor: user passed null output manager pointer.");
631 TEUCHOS_TEST_FOR_EXCEPTION(tester_ == Teuchos::null,std::invalid_argument,
632 "Anasazi::RTRBase::constructor: user passed null status test pointer.");
633 TEUCHOS_TEST_FOR_EXCEPTION(orthman_ == Teuchos::null,std::invalid_argument,
634 "Anasazi::RTRBase::constructor: user passed null orthogonalization manager pointer.");
635 TEUCHOS_TEST_FOR_EXCEPTION(problem_->isProblemSet() ==
false, std::invalid_argument,
636 "Anasazi::RTRBase::constructor: problem is not set.");
637 TEUCHOS_TEST_FOR_EXCEPTION(problem_->isHermitian() ==
false, std::invalid_argument,
638 "Anasazi::RTRBase::constructor: problem is not Hermitian.");
641 AOp_ = problem_->getOperator();
642 TEUCHOS_TEST_FOR_EXCEPTION(AOp_ == Teuchos::null, std::invalid_argument,
643 "Anasazi::RTRBase::constructor: problem provides no A matrix.");
644 BOp_ = problem_->getM();
645 Prec_ = problem_->getPrec();
646 hasBOp_ = (BOp_ != Teuchos::null);
647 hasPrec_ = (Prec_ != Teuchos::null);
648 olsenPrec_ = params.get<
bool>(
"Olsen Prec",
true);
650 TEUCHOS_TEST_FOR_EXCEPTION(orthman_->getOp() != BOp_,std::invalid_argument,
651 "Anasazi::RTRBase::constructor: orthogonalization manager must use mass matrix for inner product.");
654 int bs = params.get(
"Block Size", problem_->getNEV());
658 leftMost_ = params.get(
"Leftmost",leftMost_);
660 conv_kappa_ = params.get(
"Kappa Convergence",conv_kappa_);
661 TEUCHOS_TEST_FOR_EXCEPTION(conv_kappa_ <= 0 || conv_kappa_ >= 1,std::invalid_argument,
662 "Anasazi::RTRBase::constructor: kappa must be in (0,1).");
663 conv_theta_ = params.get(
"Theta Convergence",conv_theta_);
664 TEUCHOS_TEST_FOR_EXCEPTION(conv_theta_ <= 0,std::invalid_argument,
665 "Anasazi::RTRBase::constructor: theta must be strictly postitive.");
671 template <
class ScalarType,
class MV,
class OP>
675#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
676 Teuchos::TimeMonitor lcltimer( *timerInit_ );
683 Teuchos::RCP<const MV> tmp;
689 if (blockSize_ > 0) {
693 tmp = problem_->getInitVec();
694 TEUCHOS_TEST_FOR_EXCEPTION(tmp == Teuchos::null,std::logic_error,
695 "Anasazi::RTRBase::setBlockSize(): Eigenproblem did not specify initial vectors to clone from");
698 TEUCHOS_TEST_FOR_EXCEPTION(blockSize <= 0 || blockSize > MVT::GetGlobalLength(*tmp), std::invalid_argument,
699 "Anasazi::RTRBase::setBlockSize was passed a non-positive block size");
702 if (blockSize == blockSize_) {
721 if (blockSize > blockSize_)
725 Teuchos::RCP<const MV> Q;
726 std::vector<int> indQ(numAuxVecs_);
727 for (
int i=0; i<numAuxVecs_; i++) indQ[i] = i;
729 TEUCHOS_TEST_FOR_EXCEPTION(numAuxVecs_ > 0 && blockSize_ == 0, std::logic_error,
730 "Anasazi::RTRBase::setSize(): logic error. Please contact Anasazi team.");
732 if (numAuxVecs_ > 0) Q = MVT::CloneView(*V_,indQ);
733 V_ = MVT::Clone(*tmp,numAuxVecs_ + blockSize);
734 if (numAuxVecs_ > 0) MVT::SetBlock(*Q,indQ,*V_);
737 if (numAuxVecs_ > 0) Q = MVT::CloneView(*BV_,indQ);
738 BV_ = MVT::Clone(*tmp,numAuxVecs_ + blockSize);
739 if (numAuxVecs_ > 0) MVT::SetBlock(*Q,indQ,*BV_);
745 if (hasPrec_ && olsenPrec_) {
746 if (numAuxVecs_ > 0) Q = MVT::CloneView(*PBV_,indQ);
747 PBV_ = MVT::Clone(*tmp,numAuxVecs_ + blockSize);
748 if (numAuxVecs_ > 0) MVT::SetBlock(*Q,indQ,*PBV_);
754 std::vector<int> indV(numAuxVecs_+blockSize);
755 for (
int i=0; i<numAuxVecs_+blockSize; i++) indV[i] = i;
757 V_ = MVT::CloneCopy(*V_,indV);
760 BV_ = MVT::CloneCopy(*BV_,indV);
766 if (hasPrec_ && olsenPrec_) {
767 PBV_ = MVT::CloneCopy(*PBV_,indV);
771 if (blockSize < blockSize_) {
773 blockSize_ = blockSize;
775 theta_.resize(blockSize_);
776 ritz2norms_.resize(blockSize_);
777 Rnorms_.resize(blockSize_);
778 R2norms_.resize(blockSize_);
782 std::vector<int> ind(blockSize_);
783 for (
int i=0; i<blockSize_; i++) ind[i] = i;
791 R_ = MVT::CloneCopy(*R_ ,ind);
792 eta_ = MVT::CloneCopy(*eta_ ,ind);
793 delta_ = MVT::CloneCopy(*delta_ ,ind);
794 Hdelta_ = MVT::CloneCopy(*Hdelta_,ind);
796 AX_ = MVT::CloneCopy(*AX_ ,ind);
797 Aeta_ = MVT::CloneCopy(*Aeta_ ,ind);
798 Adelta_ = MVT::CloneCopy(*Adelta_,ind);
802 Aeta_ = Teuchos::null;
803 Adelta_ = Teuchos::null;
808 Beta_ = MVT::CloneCopy(*Beta_,ind);
809 Bdelta_ = MVT::CloneCopy(*Bdelta_,ind);
812 Beta_ = Teuchos::null;
813 Bdelta_ = Teuchos::null;
823 if (hasPrec_ || isSkinny_) {
824 Z_ = MVT::Clone(*V_,blockSize_);
836 eta_ = Teuchos::null;
837 Aeta_ = Teuchos::null;
838 delta_ = Teuchos::null;
839 Adelta_ = Teuchos::null;
840 Hdelta_ = Teuchos::null;
841 Beta_ = Teuchos::null;
842 Bdelta_ = Teuchos::null;
845 R_ = MVT::Clone(*tmp,blockSize_);
846 eta_ = MVT::Clone(*tmp,blockSize_);
847 delta_ = MVT::Clone(*tmp,blockSize_);
848 Hdelta_ = MVT::Clone(*tmp,blockSize_);
850 AX_ = MVT::Clone(*tmp,blockSize_);
851 Aeta_ = MVT::Clone(*tmp,blockSize_);
852 Adelta_ = MVT::Clone(*tmp,blockSize_);
857 Beta_ = MVT::Clone(*tmp,blockSize_);
858 Bdelta_ = MVT::Clone(*tmp,blockSize_);
868 if (hasPrec_ || isSkinny_) {
869 Z_ = MVT::Clone(*tmp,blockSize_);
878 initialized_ =
false;
881 theta_.resize(blockSize,NANVAL);
882 ritz2norms_.resize(blockSize,NANVAL);
883 Rnorms_.resize(blockSize,NANVAL);
884 R2norms_.resize(blockSize,NANVAL);
889 eta_ = Teuchos::null;
890 Aeta_ = Teuchos::null;
891 delta_ = Teuchos::null;
892 Adelta_ = Teuchos::null;
893 Hdelta_ = Teuchos::null;
894 Beta_ = Teuchos::null;
895 Bdelta_ = Teuchos::null;
899 R_ = MVT::Clone(*tmp,blockSize);
900 eta_ = MVT::Clone(*tmp,blockSize);
901 delta_ = MVT::Clone(*tmp,blockSize);
902 Hdelta_ = MVT::Clone(*tmp,blockSize);
904 AX_ = MVT::Clone(*tmp,blockSize);
905 Aeta_ = MVT::Clone(*tmp,blockSize);
906 Adelta_ = MVT::Clone(*tmp,blockSize);
911 Beta_ = MVT::Clone(*tmp,blockSize);
912 Bdelta_ = MVT::Clone(*tmp,blockSize);
919 if (hasPrec_ || isSkinny_) {
920 Z_ = MVT::Clone(*tmp,blockSize);
925 blockSize_ = blockSize;
931 std::vector<int> indX(blockSize_);
932 for (
int i=0; i<blockSize_; i++) indX[i] = numAuxVecs_+i;
933 X_ = MVT::CloneView(*V_,indX);
935 BX_ = MVT::CloneView(*BV_,indX);
946 template <
class ScalarType,
class MV,
class OP>
948 TEUCHOS_TEST_FOR_EXCEPTION(test == Teuchos::null,std::invalid_argument,
949 "Anasazi::RTRBase::setStatusTest() was passed a null StatusTest.");
956 template <
class ScalarType,
class MV,
class OP>
964 template <
class ScalarType,
class MV,
class OP>
966 typedef typename Teuchos::Array<Teuchos::RCP<const MV> >::const_iterator tarcpmv;
970 auxVecs_.reserve(auxvecs.size());
973 for (tarcpmv v=auxvecs.begin(); v != auxvecs.end(); ++v) {
974 numAuxVecs_ += MVT::GetNumberVecs(**v);
978 if (numAuxVecs_ > 0 && initialized_) {
979 initialized_ =
false;
988 PBV_ = Teuchos::null;
991 if (numAuxVecs_ > 0) {
992 V_ = MVT::Clone(*R_,numAuxVecs_ + blockSize_);
994 for (tarcpmv v=auxvecs.begin(); v != auxvecs.end(); ++v) {
995 std::vector<int> ind(MVT::GetNumberVecs(**v));
996 for (
size_t j=0; j<ind.size(); j++) ind[j] = numsofar++;
997 MVT::SetBlock(**v,ind,*V_);
998 auxVecs_.push_back(MVT::CloneView(*Teuchos::rcp_static_cast<const MV>(V_),ind));
1000 TEUCHOS_TEST_FOR_EXCEPTION(numsofar != numAuxVecs_, std::logic_error,
1001 "Anasazi::RTRBase::setAuxVecs(): Logic error. Please contact Anasazi team.");
1004 BV_ = MVT::Clone(*R_,numAuxVecs_ + blockSize_);
1005 OPT::Apply(*BOp_,*V_,*BV_);
1010 if (hasPrec_ && olsenPrec_) {
1011 PBV_ = MVT::Clone(*R_,numAuxVecs_ + blockSize_);
1012 OPT::Apply(*Prec_,*BV_,*V_);
1017 if (om_->isVerbosity(
Debug ) ) {
1021 om_->print(
Debug, accuracyCheck(chk,
"in setAuxVecs()") );
1038 template <
class ScalarType,
class MV,
class OP>
1047 BX_ = Teuchos::null;
1048 Teuchos::RCP<MV> X, BX;
1050 std::vector<int> ind(blockSize_);
1051 for (
int i=0; i<blockSize_; ++i) ind[i] = numAuxVecs_+i;
1052 X = MVT::CloneViewNonConst(*V_,ind);
1054 BX = MVT::CloneViewNonConst(*BV_,ind);
1061#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1062 Teuchos::TimeMonitor inittimer( *timerInit_ );
1065 std::vector<int> bsind(blockSize_);
1066 for (
int i=0; i<blockSize_; i++) bsind[i] = i;
1085 if (newstate.
X != Teuchos::null) {
1086 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*newstate.
X) != MVT::GetGlobalLength(*X),
1087 std::invalid_argument,
"Anasazi::RTRBase::initialize(newstate): vector length of newstate.X not correct." );
1089 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetNumberVecs(*newstate.
X) < blockSize_,
1090 std::invalid_argument,
"Anasazi::RTRBase::initialize(newstate): newstate.X must have at least block size vectors.");
1093 MVT::SetBlock(*newstate.
X,bsind,*X);
1102 if (newstate.
AX != Teuchos::null) {
1103 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*newstate.
AX) != MVT::GetGlobalLength(*X),
1104 std::invalid_argument,
"Anasazi::RTRBase::initialize(newstate): vector length of newstate.AX not correct." );
1106 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetNumberVecs(*newstate.
AX) < blockSize_,
1107 std::invalid_argument,
"Anasazi::RTRBase::initialize(newstate): newstate.AX must have at least block size vectors.");
1108 MVT::SetBlock(*newstate.
AX,bsind,*AX_);
1112#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1113 Teuchos::TimeMonitor lcltimer( *timerAOp_ );
1115 OPT::Apply(*AOp_,*X,*AX_);
1116 counterAOp_ += blockSize_;
1119 newstate.
R = Teuchos::null;
1125 if (newstate.
BX != Teuchos::null) {
1126 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*newstate.
BX) != MVT::GetGlobalLength(*X),
1127 std::invalid_argument,
"Anasazi::RTRBase::initialize(newstate): vector length of newstate.BX not correct." );
1129 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetNumberVecs(*newstate.
BX) < blockSize_,
1130 std::invalid_argument,
"Anasazi::RTRBase::initialize(newstate): newstate.BX must have at least block size vectors.");
1131 MVT::SetBlock(*newstate.
BX,bsind,*BX);
1135#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1136 Teuchos::TimeMonitor lcltimer( *timerBOp_ );
1138 OPT::Apply(*BOp_,*X,*BX);
1139 counterBOp_ += blockSize_;
1142 newstate.
R = Teuchos::null;
1147 TEUCHOS_TEST_FOR_EXCEPTION(BX != X, std::logic_error,
"Anasazi::RTRBase::initialize(): solver invariant not satisfied (BX==X).");
1155 newstate.
R = Teuchos::null;
1156 newstate.
T = Teuchos::null;
1159 Teuchos::RCP<const MV> ivec = problem_->getInitVec();
1160 TEUCHOS_TEST_FOR_EXCEPTION(ivec == Teuchos::null,std::logic_error,
1161 "Anasazi::RTRBase::initialize(): Eigenproblem did not specify initial vectors to clone from.");
1163 int initSize = MVT::GetNumberVecs(*ivec);
1164 if (initSize > blockSize_) {
1166 initSize = blockSize_;
1167 std::vector<int> ind(blockSize_);
1168 for (
int i=0; i<blockSize_; i++) ind[i] = i;
1169 ivec = MVT::CloneView(*ivec,ind);
1174 std::vector<int> ind(initSize);
1175 for (
int i=0; i<initSize; i++) ind[i] = i;
1176 MVT::SetBlock(*ivec,ind,*X);
1179 if (blockSize_ > initSize) {
1180 std::vector<int> ind(blockSize_ - initSize);
1181 for (
int i=0; i<blockSize_ - initSize; i++) ind[i] = initSize + i;
1182 Teuchos::RCP<MV> rX = MVT::CloneViewNonConst(*X,ind);
1189#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1190 Teuchos::TimeMonitor lcltimer( *timerBOp_ );
1192 OPT::Apply(*BOp_,*X,*BX);
1193 counterBOp_ += blockSize_;
1197 TEUCHOS_TEST_FOR_EXCEPTION(BX != X, std::logic_error,
"Anasazi::RTRBase::initialize(): solver invariant not satisfied (BX==X).");
1201 if (numAuxVecs_ > 0) {
1202#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1203 Teuchos::TimeMonitor lcltimer( *timerOrtho_ );
1205 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > dummyC;
1206 int rank = orthman_->projectAndNormalizeMat(*X,auxVecs_,dummyC,Teuchos::null,BX);
1208 "Anasazi::RTRBase::initialize(): Couldn't generate initial basis of full rank.");
1211#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1212 Teuchos::TimeMonitor lcltimer( *timerOrtho_ );
1214 int rank = orthman_->normalizeMat(*X,Teuchos::null,BX);
1216 "Anasazi::RTRBase::initialize(): Couldn't generate initial basis of full rank.");
1224#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1225 Teuchos::TimeMonitor lcltimer( *timerAOp_ );
1227 OPT::Apply(*AOp_,*X,*AX_);
1228 counterAOp_ += blockSize_;
1235 if (newstate.
T != Teuchos::null) {
1236 TEUCHOS_TEST_FOR_EXCEPTION( (
signed int)(newstate.
T->size()) < blockSize_,
1237 std::invalid_argument,
"Anasazi::RTRBase::initialize(newstate): newstate.T must contain at least block size Ritz values.");
1238 for (
int i=0; i<blockSize_; i++) {
1239 theta_[i] = (*newstate.
T)[i];
1244 Teuchos::SerialDenseMatrix<int,ScalarType> AA(blockSize_,blockSize_),
1245 BB(blockSize_,blockSize_),
1246 S(blockSize_,blockSize_);
1249#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1250 Teuchos::TimeMonitor lcltimer( *timerLocalProj_ );
1252 MVT::MvTransMv(ONE,*X,*AX_,AA);
1254 MVT::MvTransMv(ONE,*X,*BX,BB);
1257 nevLocal_ = blockSize_;
1263#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1264 Teuchos::TimeMonitor lcltimer( *timerDS_ );
1266 ret = Utils::directSolver(blockSize_,AA,Teuchos::rcpFromRef(BB),S,theta_,nevLocal_,1);
1269#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1270 Teuchos::TimeMonitor lcltimer( *timerDS_ );
1272 ret = Utils::directSolver(blockSize_,AA,Teuchos::null,S,theta_,nevLocal_,10);
1275 "Anasazi::RTRBase::initialize(): failure solving projected eigenproblem after retraction. LAPACK returns " << ret);
1276 TEUCHOS_TEST_FOR_EXCEPTION(nevLocal_ != blockSize_,
RTRInitFailure,
"Anasazi::RTRBase::initialize(): retracted iterate failed in Ritz analysis.");
1281#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1282 Teuchos::TimeMonitor lcltimer( *timerSort_ );
1285 std::vector<int> order(blockSize_);
1288 sm_->sort(theta_, Teuchos::rcpFromRef(order), blockSize_);
1291 Utils::permuteVectors(order,S);
1296 Teuchos::BLAS<int,ScalarType> blas;
1297 Teuchos::SerialDenseMatrix<int,ScalarType> RR(blockSize_,blockSize_);
1301 info = RR.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,ONE,BB,S,ZERO);
1302 TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::logic_error,
"Anasazi::RTRBase::initialize(): Logic error calling SerialDenseMatrix::multiply.");
1307 for (
int i=0; i<blockSize_; i++) {
1308 blas.SCAL(blockSize_,theta_[i],RR[i],1);
1310 info = RR.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,ONE,AA,S,-ONE);
1311 TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::logic_error,
"Anasazi::RTRBase::initialize(): Logic error calling SerialDenseMatrix::multiply.");
1312 for (
int i=0; i<blockSize_; i++) {
1313 ritz2norms_[i] = blas.NRM2(blockSize_,RR[i],1);
1321#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1322 Teuchos::TimeMonitor lcltimer( *timerLocalUpdate_ );
1325 MVT::MvAddMv( ONE, *X, ZERO, *X, *R_ );
1326 MVT::MvTimesMatAddMv( ONE, *R_, S, ZERO, *X );
1328 MVT::MvAddMv( ONE, *AX_, ZERO, *AX_, *R_ );
1329 MVT::MvTimesMatAddMv( ONE, *R_, S, ZERO, *AX_ );
1332 MVT::MvAddMv( ONE, *BX, ZERO, *BX, *R_ );
1333 MVT::MvTimesMatAddMv( ONE, *R_, S, ZERO, *BX );
1342 std::vector<int> ind(blockSize_);
1343 for (
int i=0; i<blockSize_; ++i) ind[i] = numAuxVecs_+i;
1344 this->X_ = MVT::CloneView(
static_cast<const MV&
>(*V_),ind);
1346 this->BX_ = MVT::CloneView(
static_cast<const MV&
>(*BV_),ind);
1349 this->BX_ = this->X_;
1355 fx_ = std::accumulate(theta_.begin(),theta_.end(),ZERO);
1358 if (newstate.
R != Teuchos::null) {
1359 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetNumberVecs(*newstate.
R) < blockSize_,
1360 std::invalid_argument,
"Anasazi::RTRBase::initialize(newstate): newstate.R must have blockSize number of vectors." );
1361 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*newstate.
R) != MVT::GetGlobalLength(*R_),
1362 std::invalid_argument,
"Anasazi::RTRBase::initialize(newstate): vector length of newstate.R not correct." );
1363 MVT::SetBlock(*newstate.
R,bsind,*R_);
1366#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1367 Teuchos::TimeMonitor lcltimer( *timerCompRes_ );
1370 MVT::MvAddMv(ZERO,*AX_,ONE,*AX_,*R_);
1371 Teuchos::SerialDenseMatrix<int,ScalarType> T(blockSize_,blockSize_);
1373 for (
int i=0; i<blockSize_; i++) T(i,i) = theta_[i];
1374 MVT::MvTimesMatAddMv(-ONE,*BX_,T,ONE,*R_);
1378 Rnorms_current_ =
false;
1379 R2norms_current_ =
false;
1384 AX_ = Teuchos::null;
1388 initialized_ =
true;
1390 if (om_->isVerbosity(
Debug ) ) {
1398 om_->print(
Debug, accuracyCheck(chk,
"after initialize()") );
1402 template <
class ScalarType,
class MV,
class OP>
1414 template <
class ScalarType,
class MV,
class OP>
1415 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
1417 if (Rnorms_current_ ==
false) {
1419 orthman_->norm(*R_,Rnorms_);
1420 Rnorms_current_ =
true;
1428 template <
class ScalarType,
class MV,
class OP>
1429 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
1431 if (R2norms_current_ ==
false) {
1433 MVT::MvNorm(*R_,R2norms_);
1434 R2norms_current_ =
true;
1466 template <
class ScalarType,
class MV,
class OP>
1469 using std::setprecision;
1470 using std::scientific;
1473 std::stringstream os;
1476 os <<
" Debugging checks: " << where << endl;
1479 if (chk.checkX && initialized_) {
1480 tmp = orthman_->orthonormError(*X_);
1481 os <<
" >> Error in X^H B X == I : " << scientific << setprecision(10) << tmp << endl;
1482 for (Array_size_type i=0; i<auxVecs_.size(); i++) {
1483 tmp = orthman_->orthogError(*X_,*auxVecs_[i]);
1484 os <<
" >> Error in X^H B Q[" << i <<
"] == 0 : " << scientific << setprecision(10) << tmp << endl;
1487 if (chk.checkAX && !isSkinny_ && initialized_) {
1488 tmp = Utils::errorEquality(*X_, *AX_, AOp_);
1489 os <<
" >> Error in AX == A*X : " << scientific << setprecision(10) << tmp << endl;
1491 if (chk.checkBX && hasBOp_ && initialized_) {
1492 Teuchos::RCP<MV> BX = MVT::Clone(*this->X_,this->blockSize_);
1493 OPT::Apply(*BOp_,*this->X_,*BX);
1494 tmp = Utils::errorEquality(*BX, *BX_);
1495 os <<
" >> Error in BX == B*X : " << scientific << setprecision(10) << tmp << endl;
1499 if (chk.checkEta && initialized_) {
1500 tmp = orthman_->orthogError(*X_,*eta_);
1501 os <<
" >> Error in X^H B Eta == 0 : " << scientific << setprecision(10) << tmp << endl;
1502 for (Array_size_type i=0; i<auxVecs_.size(); i++) {
1503 tmp = orthman_->orthogError(*eta_,*auxVecs_[i]);
1504 os <<
" >> Error in Eta^H B Q[" << i <<
"]==0 : " << scientific << setprecision(10) << tmp << endl;
1507 if (chk.checkAEta && !isSkinny_ && initialized_) {
1508 tmp = Utils::errorEquality(*eta_, *Aeta_, AOp_);
1509 os <<
" >> Error in AEta == A*Eta : " << scientific << setprecision(10) << tmp << endl;
1511 if (chk.checkBEta && !isSkinny_ && hasBOp_ && initialized_) {
1512 tmp = Utils::errorEquality(*eta_, *Beta_, BOp_);
1513 os <<
" >> Error in BEta == B*Eta : " << scientific << setprecision(10) << tmp << endl;
1517 if (chk.checkR && initialized_) {
1518 Teuchos::SerialDenseMatrix<int,ScalarType> xTx(blockSize_,blockSize_);
1519 MVT::MvTransMv(ONE,*X_,*R_,xTx);
1520 tmp = xTx.normFrobenius();
1521 os <<
" >> Error in X^H R == 0 : " << scientific << setprecision(10) << tmp << endl;
1526 if (chk.checkBR && hasBOp_ && initialized_) {
1527 Teuchos::SerialDenseMatrix<int,ScalarType> xTx(blockSize_,blockSize_);
1528 MVT::MvTransMv(ONE,*BX_,*R_,xTx);
1529 tmp = xTx.normFrobenius();
1530 os <<
" >> Error in X^H B R == 0 : " << scientific << setprecision(10) << tmp << endl;
1534 if (chk.checkZ && initialized_) {
1535 Teuchos::SerialDenseMatrix<int,ScalarType> xTx(blockSize_,blockSize_);
1536 MVT::MvTransMv(ONE,*BX_,*Z_,xTx);
1537 tmp = xTx.normFrobenius();
1538 os <<
" >> Error in X^H B Z == 0 : " << scientific << setprecision(10) << tmp << endl;
1543 for (Array_size_type i=0; i<auxVecs_.size(); i++) {
1544 tmp = orthman_->orthonormError(*auxVecs_[i]);
1545 os <<
" >> Error in Q[" << i <<
"]^H B Q[" << i <<
"]==I: " << scientific << setprecision(10) << tmp << endl;
1546 for (Array_size_type j=i+1; j<auxVecs_.size(); j++) {
1547 tmp = orthman_->orthogError(*auxVecs_[i],*auxVecs_[j]);
1548 os <<
" >> Error in Q[" << i <<
"]^H B Q[" << j <<
"]==0: " << scientific << setprecision(10) << tmp << endl;
1559 template <
class ScalarType,
class MV,
class OP>
1563 using std::setprecision;
1564 using std::scientific;
1569 os <<
"================================================================================" << endl;
1571 os <<
" RTRBase Solver Status" << endl;
1573 os <<
"The solver is "<<(initialized_ ?
"initialized." :
"not initialized.") << endl;
1574 os <<
"The number of iterations performed is " << iter_ << endl;
1575 os <<
"The current block size is " << blockSize_ << endl;
1576 os <<
"The number of auxiliary vectors is " << numAuxVecs_ << endl;
1577 os <<
"The number of operations A*x is " << counterAOp_ << endl;
1578 os <<
"The number of operations B*x is " << counterBOp_ << endl;
1579 os <<
"The number of operations Prec*x is " << counterPrec_ << endl;
1580 os <<
"The most recent rho was " << scientific << setprecision(10) << rho_ << endl;
1581 os <<
"The current value of f(x) is " << scientific << setprecision(10) << fx_ << endl;
1585 os <<
"CURRENT EIGENVALUE ESTIMATES "<<endl;
1586 os << setw(20) <<
"Eigenvalue"
1587 << setw(20) <<
"Residual(B)"
1588 << setw(20) <<
"Residual(2)"
1590 os <<
"--------------------------------------------------------------------------------"<<endl;
1591 for (
int i=0; i<blockSize_; i++) {
1592 os << scientific << setprecision(10) << setw(20) << theta_[i];
1593 if (Rnorms_current_) os << scientific << setprecision(10) << setw(20) << Rnorms_[i];
1594 else os << scientific << setprecision(10) << setw(20) <<
"not current";
1595 if (R2norms_current_) os << scientific << setprecision(10) << setw(20) << R2norms_[i];
1596 else os << scientific << setprecision(10) << setw(20) <<
"not current";
1600 os <<
"================================================================================" << endl;
1607 template <
class ScalarType,
class MV,
class OP>
1608 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
1611 std::vector<MagnitudeType> d(MVT::GetNumberVecs(xi));
1613 MagnitudeType ret = 0;
1614 for (vecMTiter i=d.begin(); i != d.end(); ++i) {
1623 template <
class ScalarType,
class MV,
class OP>
1624 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
1625 RTRBase<ScalarType,MV,OP>::ginner(
const MV &xi,
const MV &zeta)
const
1627 std::vector<ScalarType> d(MVT::GetNumberVecs(xi));
1628 MVT::MvDot(xi,zeta,d);
1629 return SCT::real(std::accumulate(d.begin(),d.end(),SCT::zero()));
1635 template <
class ScalarType,
class MV,
class OP>
1636 void RTRBase<ScalarType,MV,OP>::ginnersep(
1638 std::vector<
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &d)
const
1641 for (vecMTiter i=d.begin(); i != d.end(); ++i) {
1649 template <
class ScalarType,
class MV,
class OP>
1650 void RTRBase<ScalarType,MV,OP>::ginnersep(
1651 const MV &xi,
const MV &zeta,
1652 std::vector<
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &d)
const
1654 std::vector<ScalarType> dC(MVT::GetNumberVecs(xi));
1655 MVT::MvDot(xi,zeta,dC);
1656 vecMTiter iR=d.begin();
1657 vecSTiter iS=dC.begin();
1658 for (; iR != d.end(); iR++, iS++) {
1659 (*iR) = SCT::real(*iS);
1663 template <
class ScalarType,
class MV,
class OP>
1668 template <
class ScalarType,
class MV,
class OP>
1673 template <
class ScalarType,
class MV,
class OP>
1678 template <
class ScalarType,
class MV,
class OP>
1683 template <
class ScalarType,
class MV,
class OP>
1686 if (!initialized_)
return 0;
1690 template <
class ScalarType,
class MV,
class OP>
1691 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
1694 std::vector<MagnitudeType> ret = ritz2norms_;
1695 ret.resize(nevLocal_);
1699 template <
class ScalarType,
class MV,
class OP>
1700 std::vector<Value<ScalarType> >
1703 std::vector<Value<ScalarType> > ret(nevLocal_);
1704 for (
int i=0; i<nevLocal_; i++) {
1705 ret[i].realpart = theta_[i];
1706 ret[i].imagpart = ZERO;
1711 template <
class ScalarType,
class MV,
class OP>
1712 Teuchos::RCP<const MV>
1718 template <
class ScalarType,
class MV,
class OP>
1724 template <
class ScalarType,
class MV,
class OP>
1730 template <
class ScalarType,
class MV,
class OP>
1740 state.
BX = Teuchos::null;
1744 state.
T = Teuchos::rcp(
new std::vector<MagnitudeType>(theta_));
1748 template <
class ScalarType,
class MV,
class OP>
1751 return initialized_;
1754 template <
class ScalarType,
class MV,
class OP>
1757 std::vector<int> ret(nevLocal_,0);
Pure virtual base class which describes the basic interface to the iterative eigensolver.
Templated virtual class for providing orthogonalization/orthonormalization methods with matrix-based ...
Declaration of basic traits for the multivector type.
Virtual base class which defines basic traits for the operator type.
Class which provides internal utilities for the Anasazi solvers.
Types and exceptions used within Anasazi solvers and interfaces.
An exception class parent to all Anasazi exceptions.
This class defines the interface required by an eigensolver and status test class to compute solution...
The Eigensolver is a templated virtual base class that defines the basic interface that any eigensolv...
Traits class which defines basic operations on multivectors.
Virtual base class which defines basic traits for the operator type.
Output managers remove the need for the eigensolver to know any information about the required output...
This class is an abstract base class for Implicit Riemannian Trust-Region based eigensolvers....
virtual void iterate()=0
This method performs RTR iterations until the status test indicates the need to stop or an error occu...
void setAuxVecs(const Teuchos::Array< Teuchos::RCP< const MV > > &auxvecs)
Set the auxiliary vectors for the solver.
int getMaxSubspaceDim() const
Get the maximum dimension allocated for the search subspace. For RTR, this always returns getBlockSiz...
Teuchos::RCP< const MV > getRitzVectors()
Get the Ritz vectors from the previous iteration.
Teuchos::Array< Teuchos::RCP< const MV > > getAuxVecs() const
Get the current auxiliary vectors.
Teuchos::RCP< StatusTest< ScalarType, MV, OP > > getStatusTest() const
Get the current StatusTest used by the solver.
void resetNumIters()
Reset the iteration count.
void setBlockSize(int blockSize)
Set the blocksize to be used by the iterative solver in solving this eigenproblem.
const Eigenproblem< ScalarType, MV, OP > & getProblem() const
Get a constant reference to the eigenvalue problem.
std::vector< Value< ScalarType > > getRitzValues()
Get the Ritz values from the previous iteration.
virtual void currentStatus(std::ostream &os)
This method requests that the solver print out its current status to screen.
int getNumIters() const
Get the current iteration count.
void initialize()
Initialize the solver with the initial vectors from the eigenproblem or random data.
virtual ~RTRBase()
RTRBase destructor
std::vector< int > getRitzIndex()
Get the index used for extracting Ritz vectors from getRitzVectors().
std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > getRitzRes2Norms()
Get the 2-norms of the Ritz residuals.
int getCurSubspaceDim() const
Get the dimension of the search subspace used to generate the current eigenvectors and eigenvalues.
int getBlockSize() const
Get the blocksize to be used by the iterative solver in solving this eigenproblem.
std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > getRes2Norms()
Get the current residual 2-norms.
RTRBase(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< GenOrthoManager< ScalarType, MV, OP > > &ortho, Teuchos::ParameterList ¶ms, const std::string &solverLabel, bool skinnySolver)
RTRBase constructor with eigenproblem, solver utilities, and parameter list of solver options.
bool isInitialized() const
Indicates whether the solver has been initialized or not.
std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > getResNorms()
Get the current residual norms.
void setStatusTest(Teuchos::RCP< StatusTest< ScalarType, MV, OP > > test)
Set a new StatusTest for the solver.
RTRState< ScalarType, MV > getState() const
Get the current state of the eigensolver.
RTRInitFailure is thrown when the RTR solver is unable to generate an initial iterate in the RTRBase:...
RTROrthoFailure is thrown when an orthogonalization attempt fails.
RTRRitzFailure is thrown when the RTR solver is unable to continue a call to RTRBase::iterate() due t...
Anasazi's templated, static class providing utilities for the solvers.
Anasazi's templated pure virtual class for managing the sorting of approximate eigenvalues computed b...
Common interface of stopping criteria for Anasazi's solvers.
Namespace Anasazi contains the classes, structs, enums and utilities used by the Anasazi package.
Structure to contain pointers to RTR state variables.
Teuchos::RCP< const std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > > T
The current Ritz values.
Teuchos::RCP< const MV > BX
The image of the current eigenvectors under B, or Teuchos::null if B was not specified.
Teuchos::ScalarTraits< ScalarType >::magnitudeType rho
The current rho value. This is only valid if the debugging level of verbosity is enabled.
Teuchos::RCP< const MV > R
The current residual vectors.
Teuchos::RCP< const MV > X
The current eigenvectors.
Teuchos::RCP< const MV > AX
The image of the current eigenvectors under A, or Teuchos::null is we implement a skinny solver.