14#ifndef ANASAZI_BLOCK_DAVIDSON_HPP
15#define ANASAZI_BLOCK_DAVIDSON_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"
57 template <
class ScalarType,
class MV>
68 Teuchos::RCP<const MV>
V;
70 Teuchos::RCP<const MV>
X;
72 Teuchos::RCP<const MV>
KX;
74 Teuchos::RCP<const MV>
MX;
76 Teuchos::RCP<const MV>
R;
81 Teuchos::RCP<const MV>
H;
83 Teuchos::RCP<const std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> >
T;
89 Teuchos::RCP<const Teuchos::SerialDenseMatrix<int,ScalarType> >
KK;
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>
145 const Teuchos::RCP<
SortManager<
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > &sorter,
149 Teuchos::ParameterList ¶ms
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();
340 Teuchos::RCP<StatusTest<ScalarType,MV,OP> >
getStatusTest()
const;
371 void setAuxVecs(
const Teuchos::Array<Teuchos::RCP<const MV> > &auxvecs);
374 Teuchos::Array<Teuchos::RCP<const MV> >
getAuxVecs()
const;
390 void setSize(
int blockSize,
int numBlocks);
409 typedef Teuchos::ScalarTraits<ScalarType> SCT;
410 typedef typename SCT::magnitudeType MagnitudeType;
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;
435 const Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > problem_;
436 const Teuchos::RCP<SortManager<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > sm_;
437 const Teuchos::RCP<OutputManager<ScalarType> > om_;
438 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > tester_;
439 const Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > orthman_;
443 Teuchos::RCP<const OP> Op_;
444 Teuchos::RCP<const OP> MOp_;
445 Teuchos::RCP<const OP> Prec_;
450 Teuchos::RCP<Teuchos::Time> timerOp_, timerMOp_, timerPrec_,
451 timerSortEval_, timerDS_,
452 timerLocal_, timerCompRes_,
453 timerOrtho_, timerInit_;
457 int count_ApplyOp_, count_ApplyM_, count_ApplyPrec_;
486 Teuchos::RCP<MV> X_, KX_, MX_, R_,
492 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > KK_;
495 Teuchos::Array<Teuchos::RCP<const MV> > auxVecs_;
502 std::vector<MagnitudeType> theta_, Rnorms_, R2norms_;
505 bool Rnorms_current_, R2norms_current_;
520 template <
class ScalarType,
class MV,
class OP>
523 const Teuchos::RCP<
SortManager<
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > &sorter,
527 Teuchos::ParameterList ¶ms
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)
564 TEUCHOS_TEST_FOR_EXCEPTION(problem_ == Teuchos::null,std::invalid_argument,
565 "Anasazi::BlockDavidson::constructor: user passed null problem pointer.");
566 TEUCHOS_TEST_FOR_EXCEPTION(sm_ == Teuchos::null,std::invalid_argument,
567 "Anasazi::BlockDavidson::constructor: user passed null sort manager pointer.");
568 TEUCHOS_TEST_FOR_EXCEPTION(om_ == Teuchos::null,std::invalid_argument,
569 "Anasazi::BlockDavidson::constructor: user passed null output manager pointer.");
570 TEUCHOS_TEST_FOR_EXCEPTION(tester_ == Teuchos::null,std::invalid_argument,
571 "Anasazi::BlockDavidson::constructor: user passed null status test pointer.");
572 TEUCHOS_TEST_FOR_EXCEPTION(orthman_ == Teuchos::null,std::invalid_argument,
573 "Anasazi::BlockDavidson::constructor: user passed null orthogonalization manager pointer.");
574 TEUCHOS_TEST_FOR_EXCEPTION(problem_->isProblemSet() ==
false, std::invalid_argument,
575 "Anasazi::BlockDavidson::constructor: problem is not set.");
576 TEUCHOS_TEST_FOR_EXCEPTION(problem_->isHermitian() ==
false, std::invalid_argument,
577 "Anasazi::BlockDavidson::constructor: problem is not hermitian.");
580 Op_ = problem_->getOperator();
581 TEUCHOS_TEST_FOR_EXCEPTION(Op_ == Teuchos::null, std::invalid_argument,
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_) );
727 state.
T = Teuchos::rcp(
new std::vector<MagnitudeType>(0));
735 template <
class ScalarType,
class MV,
class OP>
741 template <
class ScalarType,
class MV,
class OP>
745#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
746 Teuchos::TimeMonitor initimer( *timerInit_ );
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;
762 Teuchos::RCP<const MV> tmp;
767 if (X_ != Teuchos::null) {
771 tmp = problem_->getInitVec();
772 TEUCHOS_TEST_FOR_EXCEPTION(tmp == Teuchos::null,std::invalid_argument,
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);
817 KK_ = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(newsd,newsd) );
819 om_->print(
Debug,
" >> done allocating.\n");
821 initialized_ =
false;
828 template <
class ScalarType,
class MV,
class OP>
830 typedef typename Teuchos::Array<Teuchos::RCP<const MV> >::iterator tarcpmv;
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
872 Teuchos::TimeMonitor inittimer( *timerInit_ );
875 std::vector<int> bsind(blockSize_);
876 for (
int i=0; i<blockSize_; ++i) bsind[i] = i;
878 Teuchos::BLAS<int,ScalarType> blas;
902 Teuchos::RCP<MV> lclV;
903 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > lclKK;
905 if (newstate.
V != Teuchos::null && newstate.
KK != Teuchos::null) {
906 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*newstate.
V) != MVT::GetGlobalLength(*V_), std::invalid_argument,
907 "Anasazi::BlockDavidson::initialize(newstate): Vector length of V not correct." );
908 TEUCHOS_TEST_FOR_EXCEPTION( newstate.
curDim < blockSize_, std::invalid_argument,
909 "Anasazi::BlockDavidson::initialize(newstate): Rank of new state must be at least blockSize().");
910 TEUCHOS_TEST_FOR_EXCEPTION( newstate.
curDim > blockSize_*numBlocks_, std::invalid_argument,
911 "Anasazi::BlockDavidson::initialize(newstate): Rank of new state must be less than getMaxSubspaceDim().");
912 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetNumberVecs(*newstate.
V) < newstate.
curDim, std::invalid_argument,
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_;
919 TEUCHOS_TEST_FOR_EXCEPTION( curDim_ != newstate.
curDim, std::invalid_argument,
920 "Anasazi::BlockDavidson::initialize(newstate): Rank of new state must be a multiple of getBlockSize().");
923 TEUCHOS_TEST_FOR_EXCEPTION( newstate.
KK->numRows() < curDim_ || newstate.
KK->numCols() < curDim_, std::invalid_argument,
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);
938 lclKK = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::View,*KK_,curDim_,curDim_) );
939 if (newstate.
KK != KK_) {
940 if (newstate.
KK->numRows() > curDim_ || newstate.
KK->numCols() > curDim_) {
941 newstate.
KK = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::View,*newstate.
KK,curDim_,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));
956 Teuchos::RCP<const MV> ivec = problem_->getInitVec();
957 TEUCHOS_TEST_FOR_EXCEPTION(ivec == Teuchos::null,std::invalid_argument,
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);
1007 Teuchos::RCP<MV> tmpVecs;
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
1022 Teuchos::TimeMonitor lcltimer( *timerMOp_ );
1024 OPT::Apply(*MOp_,*lclV,*tmpVecs);
1025 count_ApplyM_ += curDim_;
1029 if (auxVecs_.size() > 0) {
1030#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1031 Teuchos::TimeMonitor lcltimer( *timerOrtho_ );
1034 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > dummyC;
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
1041 Teuchos::TimeMonitor lcltimer( *timerOrtho_ );
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
1052 Teuchos::TimeMonitor lcltimer( *timerOp_ );
1054 OPT::Apply(*Op_,*lclV,*tmpVecs);
1055 count_ApplyOp_ += curDim_;
1059 lclKK = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::View,*KK_,curDim_,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.");
1070 TEUCHOS_TEST_FOR_EXCEPTION((
signed int)(newstate.
T->size()) != curDim_,
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());
1081 Teuchos::SerialDenseMatrix<int,ScalarType> S(curDim_,curDim_);
1083#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1084 Teuchos::TimeMonitor lcltimer( *timerDS_ );
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
1095 Teuchos::TimeMonitor lcltimer( *timerSortEval_ );
1098 std::vector<int> order(curDim_);
1101 sm_->sort(theta_, Teuchos::rcpFromRef(order), curDim_);
1104 Utils::permuteVectors(order,S);
1108 Teuchos::SerialDenseMatrix<int,ScalarType> S1(Teuchos::View,S,curDim_,blockSize_);
1110#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1111 Teuchos::TimeMonitor lcltimer( *timerLocal_ );
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 ) {
1128 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*newstate.
KX) != blockSize_,
1129 std::invalid_argument,
"Anasazi::BlockDavidson::initialize(newstate): vector length of newstate.KX not correct." );
1130 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetGlobalLength(*newstate.
KX) != MVT::GetGlobalLength(*X_),
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
1140 Teuchos::TimeMonitor lcltimer( *timerOp_ );
1142 OPT::Apply(*Op_,*X_,*KX_);
1143 count_ApplyOp_ += blockSize_;
1146 newstate.
R = Teuchos::null;
1151 if ( newstate.
MX != Teuchos::null ) {
1152 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*newstate.
MX) != blockSize_,
1153 std::invalid_argument,
"Anasazi::BlockDavidson::initialize(newstate): vector length of newstate.MX not correct." );
1154 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetGlobalLength(*newstate.
MX) != MVT::GetGlobalLength(*X_),
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
1164 Teuchos::TimeMonitor lcltimer( *timerOp_ );
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) {
1180 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*newstate.
R) != blockSize_,
1181 std::invalid_argument,
"Anasazi::BlockDavidson::initialize(newstate): vector length of newstate.R not correct." );
1182 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetGlobalLength(*newstate.
R) != MVT::GetGlobalLength(*X_),
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
1190 Teuchos::TimeMonitor lcltimer( *timerCompRes_ );
1194 MVT::MvAddMv(ZERO,*KX_,ONE,*KX_,*R_);
1195 Teuchos::SerialDenseMatrix<int,ScalarType> T(blockSize_,blockSize_);
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_;
1257 Teuchos::BLAS<int,ScalarType> blas;
1262 Teuchos::SerialDenseMatrix<int,ScalarType> S( searchDim, searchDim );
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
1289 Teuchos::TimeMonitor lcltimer( *timerPrec_ );
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
1305 Teuchos::TimeMonitor lcltimer( *timerMOp_ );
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;
1318 Teuchos::RCP<const MV> Vprev = MVT::CloneView(*V_,prevind);
1322#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1323 Teuchos::TimeMonitor lcltimer( *timerOrtho_ );
1326 Teuchos::Array<Teuchos::RCP<const MV> > against = auxVecs_;
1327 against.push_back(Vprev);
1328 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > dummyC;
1329 int rank = orthman_->projectAndNormalizeMat(*H_,against,
1333 "Anasazi::BlockDavidson::iterate(): unable to compute orthonormal basis for H.");
1340#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1341 Teuchos::TimeMonitor lcltimer( *timerOp_ );
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") );
1364 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > nextKK;
1366 nextKK = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::View,*KK_,curDim_,blockSize_,0,curDim_) );
1367 MVT::MvTransMv(ONE,*Vprev,*KH_,*nextKK);
1369 nextKK = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::View,*KK_,blockSize_,blockSize_,curDim_,curDim_) );
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;
1394 Teuchos::RCP<const MV> curV = MVT::CloneView(*V_,curind);
1398#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1399 Teuchos::TimeMonitor lcltimer(*timerDS_);
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
1411 Teuchos::TimeMonitor lcltimer( *timerSortEval_ );
1414 std::vector<int> order(curDim_);
1417 sm_->sort(theta_, Teuchos::rcp(&order,
false), curDim_);
1420 Teuchos::SerialDenseMatrix<int,ScalarType> curS(Teuchos::View,S,curDim_,curDim_);
1421 Utils::permuteVectors(order,curS);
1425 Teuchos::SerialDenseMatrix<int,ScalarType> S1( Teuchos::View, S, curDim_, blockSize_ );
1429#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1430 Teuchos::TimeMonitor lcltimer( *timerLocal_ );
1432 MVT::MvTimesMatAddMv(ONE,*curV,S1,ZERO,*X_);
1437#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1438 Teuchos::TimeMonitor lcltimer( *timerOp_ );
1440 OPT::Apply( *Op_, *X_, *KX_);
1441 count_ApplyOp_ += blockSize_;
1445#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1446 Teuchos::TimeMonitor lcltimer( *timerMOp_ );
1448 OPT::Apply(*MOp_,*X_,*MX_);
1449 count_ApplyM_ += blockSize_;
1458#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1459 Teuchos::TimeMonitor lcltimer( *timerCompRes_ );
1462 MVT::MvAddMv( ONE, *KX_, ZERO, *KX_, *R_ );
1463 Teuchos::SerialDenseMatrix<int,ScalarType> T( blockSize_, blockSize_ );
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>
1531 TEUCHOS_TEST_FOR_EXCEPTION(test == Teuchos::null,std::invalid_argument,
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;
1584 Teuchos::RCP<const MV> lclV;
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;
1595 Teuchos::SerialDenseMatrix<int,ScalarType> curKK(curDim_,curDim_);
1596 Teuchos::RCP<MV> lclKV = MVT::Clone(*V_,curDim_);
1597 OPT::Apply(*Op_,*lclV,*lclKV);
1598 MVT::MvTransMv(ONE,*lclV,*lclKV,curKK);
1599 Teuchos::SerialDenseMatrix<int,ScalarType> subKK(Teuchos::View,*KK_,curDim_,curDim_);
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_) {
1652 Teuchos::SerialDenseMatrix<int,ScalarType> xTx(blockSize_,blockSize_);
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_) {
1660 Teuchos::SerialDenseMatrix<int,ScalarType> SDMerr(curDim_,curDim_), lclKK(Teuchos::View,*KK_,curDim_,curDim_);
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;
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.
BlockDavidsonInitFailure is thrown when the BlockDavidson solver is unable to generate an initial ite...
BlockDavidsonOrthoFailure is thrown when the orthogonalization manager is unable to orthogonalize the...
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.
void resetNumIters()
Reset the iteration count.
std::vector< int > getRitzIndex()
Get the index used for extracting individual Ritz vectors from getRitzVectors().
int getCurSubspaceDim() const
Get the dimension of the search subspace used to generate the current eigenvectors and eigenvalues.
void setBlockSize(int blockSize)
Set the blocksize.
Teuchos::RCP< StatusTest< ScalarType, MV, OP > > getStatusTest() const
Get the current StatusTest used by the solver.
std::vector< Value< ScalarType > > getRitzValues()
Get the Ritz values for the previous iteration.
void setStatusTest(Teuchos::RCP< StatusTest< ScalarType, MV, OP > > test)
Set a new StatusTest for the solver.
std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > getRitzRes2Norms()
Get the 2-norms of the residuals.
const Eigenproblem< ScalarType, MV, OP > & getProblem() const
Get a constant reference to the eigenvalue problem.
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...
void setAuxVecs(const Teuchos::Array< Teuchos::RCP< const MV > > &auxvecs)
Set the auxiliary vectors for the solver.
void initialize()
Initialize the solver with the initial vectors from the eigenproblem or random data.
BlockDavidsonState< ScalarType, MV > getState() const
Get access to the current state of the eigensolver.
void currentStatus(std::ostream &os)
This method requests that the solver print out its current status to the given output stream.
int getNumIters() const
Get the current iteration count.
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.
void iterate()
This method performs BlockDavidson iterations until the status test indicates the need to stop or an ...
void setSize(int blockSize, int numBlocks)
Set the blocksize and number of blocks to be used by the iterative solver in solving this eigenproble...
virtual ~BlockDavidson()
Anasazi::BlockDavidson destructor.
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, 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.
int getBlockSize() const
Get the blocksize used by the iterative solver.
int getMaxSubspaceDim() const
Get the maximum dimension allocated for the search subspace. For BlockDavidson, this always returns n...
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...
Anasazi's templated virtual class for providing routines for orthogonalization and orthonormalization...
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...
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 BlockDavidson state variables.
int curDim
The current dimension of the solver.
Teuchos::RCP< const MV > V
The basis for the Krylov space.
Teuchos::RCP< const MV > H
The current preconditioned residual vectors.
Teuchos::RCP< const MV > X
The current eigenvectors.
Teuchos::RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > KK
The current projected K matrix.
Teuchos::RCP< const MV > R
The current residual vectors.
Teuchos::RCP< const std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > > T
The current Ritz values. This vector is a copy of the internal data.
Teuchos::RCP< const MV > KX
The image of the current eigenvectors under K.
Teuchos::RCP< const MV > MX
The image of the current eigenvectors under M, or Teuchos::null if M was not specified.