65 #ifndef ANASAZI_LOBPCG_HPP
66 #define ANASAZI_LOBPCG_HPP
113 template <
class ScalarType,
class MultiVector>
153 V(Teuchos::null),
KV(Teuchos::null),
MV(Teuchos::null),
154 X(Teuchos::null),
KX(Teuchos::null),
MX(Teuchos::null),
155 P(Teuchos::null),
KP(Teuchos::null),
MP(Teuchos::null),
156 H(Teuchos::null),
KH(Teuchos::null),
MH(Teuchos::null),
157 R(Teuchos::null),
T(Teuchos::null) {};
221 template <
class ScalarType,
class MV,
class OP>
386 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
getResNorms();
394 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
getRes2Norms();
404 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
getRitzRes2Norms();
509 const MagnitudeType ONE;
510 const MagnitudeType ZERO;
511 const MagnitudeType NANVAL;
516 bool checkX, checkMX, checkKX;
517 bool checkH, checkMH;
518 bool checkP, checkMP, checkKP;
520 CheckList() : checkX(false),checkMX(false),checkKX(false),
521 checkH(false),checkMH(false),
522 checkP(false),checkMP(false),checkKP(false),
523 checkR(false),checkQ(false) {};
528 std::string accuracyCheck(
const CheckList &chk,
const std::string &where)
const;
549 timerLocalProj_, timerDS_,
550 timerLocalUpdate_, timerCompRes_,
551 timerOrtho_, timerInit_;
556 int count_ApplyOp_, count_ApplyM_, count_ApplyPrec_;
611 std::vector<MagnitudeType> theta_, Rnorms_, R2norms_;
614 bool Rnorms_current_, R2norms_current_;
623 template <
class ScalarType,
class MV,
class OP>
632 ONE(Teuchos::ScalarTraits<MagnitudeType>::one()),
633 ZERO(Teuchos::ScalarTraits<MagnitudeType>::zero()),
634 NANVAL(Teuchos::ScalarTraits<MagnitudeType>::nan()),
642 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
643 timerOp_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: LOBPCG::Operation Op*x")),
644 timerMOp_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: LOBPCG::Operation M*x")),
645 timerPrec_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: LOBPCG::Operation Prec*x")),
646 timerSort_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: LOBPCG::Sorting eigenvalues")),
647 timerLocalProj_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: LOBPCG::Local projection")),
648 timerDS_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: LOBPCG::Direct solve")),
649 timerLocalUpdate_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: LOBPCG::Local update")),
650 timerCompRes_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: LOBPCG::Computing residuals")),
651 timerOrtho_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: LOBPCG::Orthogonalization")),
652 timerInit_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: LOBPCG::Initialization")),
659 fullOrtho_(params.get(
"Full Ortho", true)),
663 auxVecs_( Teuchos::Array<Teuchos::RCP<const MV> >(0) ),
666 Rnorms_current_(false),
667 R2norms_current_(false)
670 "Anasazi::LOBPCG::constructor: user passed null problem pointer.");
672 "Anasazi::LOBPCG::constructor: user passed null sort manager pointer.");
674 "Anasazi::LOBPCG::constructor: user passed null output manager pointer.");
676 "Anasazi::LOBPCG::constructor: user passed null status test pointer.");
678 "Anasazi::LOBPCG::constructor: user passed null orthogonalization manager pointer.");
680 "Anasazi::LOBPCG::constructor: problem is not set.");
682 "Anasazi::LOBPCG::constructor: problem is not Hermitian; LOBPCG requires Hermitian problem.");
685 Op_ = problem_->getOperator();
687 "Anasazi::LOBPCG::constructor: problem provides no operator.");
688 MOp_ = problem_->getM();
689 Prec_ = problem_->getPrec();
690 hasM_ = (MOp_ != Teuchos::null);
693 int bs = params.
get(
"Block Size", problem_->getNEV());
700 template <
class ScalarType,
class MV,
class OP>
704 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
718 if (blockSize_ > 0) {
722 tmp = problem_->getInitVec();
724 "Anasazi::LOBPCG::setBlockSize(): eigenproblem did not specify initial vectors to clone from.");
728 std::invalid_argument,
"Anasazi::LOBPCG::setBlockSize(): block size must be strictly positive.");
729 if (newBS == blockSize_) {
733 else if (newBS < blockSize_ && initialized_) {
749 std::vector<int> newind(newBS), oldind(newBS);
750 for (
int i=0; i<newBS; i++) {
758 newR = MVT::Clone(*tmp,newBS);
759 newV = MVT::Clone(*tmp,newBS*3);
760 newKV = MVT::Clone(*tmp,newBS*3);
762 newMV = MVT::Clone(*tmp,newBS*3);
782 theta_.resize(3*newBS);
783 Rnorms_.resize(newBS);
784 R2norms_.resize(newBS);
787 src = MVT::CloneView(*R_,newind);
788 MVT::SetBlock(*src,newind,*newR);
794 src = MVT::CloneView(*V_,oldind);
795 MVT::SetBlock(*src,newind,*newV);
796 src = MVT::CloneView(*KV_,oldind);
797 MVT::SetBlock(*src,newind,*newKV);
799 src = MVT::CloneView(*MV_,oldind);
800 MVT::SetBlock(*src,newind,*newMV);
803 for (
int i=0; i<newBS; i++) {
804 newind[i] += 2*newBS;
805 oldind[i] += 2*blockSize_;
807 src = MVT::CloneView(*V_,oldind);
808 MVT::SetBlock(*src,newind,*newV);
809 src = MVT::CloneView(*KV_,oldind);
810 MVT::SetBlock(*src,newind,*newKV);
812 src = MVT::CloneView(*MV_,oldind);
813 MVT::SetBlock(*src,newind,*newMV);
832 initialized_ =
false;
851 theta_.resize(3*newBS,NANVAL);
852 Rnorms_.resize(newBS,NANVAL);
853 R2norms_.resize(newBS,NANVAL);
856 R_ = MVT::Clone(*tmp,newBS);
857 V_ = MVT::Clone(*tmp,newBS*3);
858 KV_ = MVT::Clone(*tmp,newBS*3);
860 MV_ = MVT::Clone(*tmp,newBS*3);
868 tmpmvec_ = Teuchos::null;
870 tmpmvec_ = MVT::Clone(*tmp,newBS);
883 template <
class ScalarType,
class MV,
class OP>
886 std::vector<int> ind(blockSize_);
888 for (
int i=0; i<blockSize_; i++) {
891 X_ = MVT::CloneViewNonConst(*V_,ind);
892 KX_ = MVT::CloneViewNonConst(*KV_,ind);
894 MX_ = MVT::CloneViewNonConst(*MV_,ind);
900 for (
int i=0; i<blockSize_; i++) {
901 ind[i] += blockSize_;
903 H_ = MVT::CloneViewNonConst(*V_,ind);
904 KH_ = MVT::CloneViewNonConst(*KV_,ind);
906 MH_ = MVT::CloneViewNonConst(*MV_,ind);
912 for (
int i=0; i<blockSize_; i++) {
913 ind[i] += blockSize_;
915 P_ = MVT::CloneViewNonConst(*V_,ind);
916 KP_ = MVT::CloneViewNonConst(*KV_,ind);
918 MP_ = MVT::CloneViewNonConst(*MV_,ind);
928 template <
class ScalarType,
class MV,
class OP>
936 for (tarcpmv i=auxVecs_.begin(); i != auxVecs_.end(); i++) {
937 numAuxVecs_ += MVT::GetNumberVecs(**i);
941 if (numAuxVecs_ > 0 && initialized_) {
942 initialized_ =
false;
946 if (om_->isVerbosity(
Debug ) ) {
950 om_->print(
Debug, accuracyCheck(chk,
": in setAuxVecs()") );
973 template <
class ScalarType,
class MV,
class OP>
979 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
983 std::vector<int> bsind(blockSize_);
984 for (
int i=0; i<blockSize_; i++) bsind[i] = i;
1008 if (newstate.
X != Teuchos::null) {
1010 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): vector length of newstate.X not correct." );
1013 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): newstate.X must have at least block size vectors.");
1016 MVT::SetBlock(*newstate.
X,bsind,*X_);
1020 if (newstate.
MX != Teuchos::null) {
1022 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): vector length of newstate.MX not correct." );
1025 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): newstate.MX must have at least block size vectors.");
1026 MVT::SetBlock(*newstate.
MX,bsind,*MX_);
1031 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1034 OPT::Apply(*MOp_,*X_,*MX_);
1035 count_ApplyM_ += blockSize_;
1038 newstate.
R = Teuchos::null;
1043 if (newstate.
KX != Teuchos::null) {
1045 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): vector length of newstate.KX not correct." );
1048 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): newstate.KX must have at least block size vectors.");
1049 MVT::SetBlock(*newstate.
KX,bsind,*KX_);
1054 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1057 OPT::Apply(*Op_,*X_,*KX_);
1058 count_ApplyOp_ += blockSize_;
1061 newstate.
R = Teuchos::null;
1069 newstate.
P = Teuchos::null;
1070 newstate.
KP = Teuchos::null;
1071 newstate.
MP = Teuchos::null;
1072 newstate.
R = Teuchos::null;
1073 newstate.
T = Teuchos::null;
1078 "Anasazi::LOBPCG::initialize(): Eigenproblem did not specify initial vectors to clone from.");
1080 int initSize = MVT::GetNumberVecs(*ivec);
1081 if (initSize > blockSize_) {
1083 initSize = blockSize_;
1084 std::vector<int> ind(blockSize_);
1085 for (
int i=0; i<blockSize_; i++) ind[i] = i;
1086 ivec = MVT::CloneView(*ivec,ind);
1091 std::vector<int> ind(initSize);
1092 for (
int i=0; i<initSize; i++) ind[i] = i;
1093 MVT::SetBlock(*ivec,ind,*X_);
1096 if (blockSize_ > initSize) {
1097 std::vector<int> ind(blockSize_ - initSize);
1098 for (
int i=0; i<blockSize_ - initSize; i++) ind[i] = initSize + i;
1106 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1109 OPT::Apply(*MOp_,*X_,*MX_);
1110 count_ApplyM_ += blockSize_;
1114 if (numAuxVecs_ > 0) {
1115 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1119 int rank = orthman_->projectAndNormalizeMat(*X_,auxVecs_,dummy,Teuchos::null,MX_);
1121 "Anasazi::LOBPCG::initialize(): Couldn't generate initial basis of full rank.");
1124 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1127 int rank = orthman_->normalizeMat(*X_,Teuchos::null,MX_);
1129 "Anasazi::LOBPCG::initialize(): Couldn't generate initial basis of full rank.");
1134 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1137 OPT::Apply(*Op_,*X_,*KX_);
1138 count_ApplyOp_ += blockSize_;
1146 theta_.resize(3*blockSize_,NANVAL);
1147 if (newstate.
T != Teuchos::null) {
1149 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): newstate.T must contain at least block size Ritz values.");
1150 for (
int i=0; i<blockSize_; i++) {
1151 theta_[i] = (*newstate.
T)[i];
1153 nevLocal_ = blockSize_;
1158 MM(blockSize_,blockSize_),
1159 S(blockSize_,blockSize_);
1161 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1165 MVT::MvTransMv(ONE,*X_,*KX_,KK);
1167 MVT::MvTransMv(ONE,*X_,*MX_,MM);
1168 nevLocal_ = blockSize_;
1173 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1176 Utils::directSolver(blockSize_, KK, Teuchos::rcpFromRef(MM), S, theta_, nevLocal_, 1);
1178 "Anasazi::LOBPCG::initialize(): Initial Ritz analysis did not produce enough Ritz pairs to initialize algorithm.");
1184 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1188 std::vector<int> order(blockSize_);
1191 sm_->sort(theta_, Teuchos::rcpFromRef(order), blockSize_);
1194 Utils::permuteVectors(order,S);
1199 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1203 MVT::MvAddMv( ONE, *X_, ZERO, *X_, *R_ );
1204 MVT::MvTimesMatAddMv( ONE, *R_, S, ZERO, *X_ );
1206 MVT::MvAddMv( ONE, *KX_, ZERO, *KX_, *R_ );
1207 MVT::MvTimesMatAddMv( ONE, *R_, S, ZERO, *KX_ );
1210 MVT::MvAddMv( ONE, *MX_, ZERO, *MX_, *R_ );
1211 MVT::MvTimesMatAddMv( ONE, *R_, S, ZERO, *MX_ );
1219 if (newstate.
R != Teuchos::null) {
1221 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): vector length of newstate.R not correct." );
1223 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): newstate.R must have blockSize number of vectors." );
1224 MVT::SetBlock(*newstate.
R,bsind,*R_);
1227 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1231 MVT::MvAddMv(ZERO,*KX_,ONE,*KX_,*R_);
1233 for (
int i=0; i<blockSize_; i++) T(i,i) = theta_[i];
1234 MVT::MvTimesMatAddMv(-ONE,*MX_,T,ONE,*R_);
1238 Rnorms_current_ =
false;
1239 R2norms_current_ =
false;
1242 if (newstate.
P != Teuchos::null) {
1244 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): newstate.P must have blockSize number of vectors." );
1246 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): vector length of newstate.P not correct." );
1250 MVT::SetBlock(*newstate.
P,bsind,*P_);
1253 if (newstate.
KP != Teuchos::null) {
1255 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): newstate.KP must have blockSize number of vectors." );
1257 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): vector length of newstate.KP not correct." );
1258 MVT::SetBlock(*newstate.
KP,bsind,*KP_);
1261 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1264 OPT::Apply(*Op_,*P_,*KP_);
1265 count_ApplyOp_ += blockSize_;
1270 if (newstate.
MP != Teuchos::null) {
1272 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): newstate.MP must have blockSize number of vectors." );
1274 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): vector length of newstate.MP not correct." );
1275 MVT::SetBlock(*newstate.
MP,bsind,*MP_);
1278 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1281 OPT::Apply(*MOp_,*P_,*MP_);
1282 count_ApplyM_ += blockSize_;
1291 initialized_ =
true;
1293 if (om_->isVerbosity(
Debug ) ) {
1304 om_->print(
Debug, accuracyCheck(chk,
": after initialize()") );
1309 template <
class ScalarType,
class MV,
class OP>
1319 template <
class ScalarType,
class MV,
class OP>
1322 if ( fullOrtho_ ==
true || initialized_ ==
false || fullOrtho == fullOrtho_ ) {
1324 fullOrtho_ = fullOrtho;
1336 if (fullOrtho_ && tmpmvec_ == Teuchos::null) {
1338 tmpmvec_ = MVT::Clone(*X_,blockSize_);
1340 else if (fullOrtho_==
false) {
1342 tmpmvec_ = Teuchos::null;
1349 template <
class ScalarType,
class MV,
class OP>
1355 if (initialized_ ==
false) {
1361 const int oneBlock = blockSize_;
1362 const int twoBlocks = 2*blockSize_;
1363 const int threeBlocks = 3*blockSize_;
1365 std::vector<int> indblock1(blockSize_), indblock2(blockSize_), indblock3(blockSize_);
1366 for (
int i=0; i<blockSize_; i++) {
1368 indblock2[i] = i + blockSize_;
1369 indblock3[i] = i + 2*blockSize_;
1378 MM( threeBlocks, threeBlocks ),
1379 S( threeBlocks, threeBlocks );
1381 while (tester_->checkStatus(
this) !=
Passed) {
1384 if (om_->isVerbosity(
Debug)) {
1385 currentStatus( om_->stream(
Debug) );
1395 if (Prec_ != Teuchos::null) {
1396 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1399 OPT::Apply( *Prec_, *R_, *H_ );
1400 count_ApplyPrec_ += blockSize_;
1403 MVT::MvAddMv(ONE,*R_,ZERO,*R_,*H_);
1408 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1411 OPT::Apply( *MOp_, *H_, *MH_);
1412 count_ApplyM_ += blockSize_;
1428 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1432 Teuchos::tuple<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > >(Teuchos::null);
1433 int rank = orthman_->projectAndNormalizeMat(*H_,Q,dummyC,Teuchos::null,MH_);
1436 "Anasazi::LOBPCG::iterate(): unable to compute orthonormal basis for H.");
1439 if (om_->isVerbosity(
Debug ) ) {
1443 om_->print(
Debug, accuracyCheck(chk,
": after ortho H") );
1449 om_->print(
OrthoDetails, accuracyCheck(chk,
": after ortho H") );
1454 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1457 OPT::Apply( *Op_, *H_, *KH_);
1458 count_ApplyOp_ += blockSize_;
1462 nevLocal_ = threeBlocks;
1465 nevLocal_ = twoBlocks;
1487 KX_ = Teuchos::null;
1488 MX_ = Teuchos::null;
1490 KH_ = Teuchos::null;
1491 MH_ = Teuchos::null;
1493 KP_ = Teuchos::null;
1494 MP_ = Teuchos::null;
1495 Teuchos::RCP<const MV> cX, cH, cXHP, cHP, cK_XHP, cK_HP, cM_XHP, cM_HP, cP, cK_P, cM_P;
1497 cX = MVT::CloneView(*Teuchos::rcp_implicit_cast<const MV>(V_),indblock1);
1498 cH = MVT::CloneView(*Teuchos::rcp_implicit_cast<const MV>(V_),indblock2);
1500 std::vector<int> indXHP(nevLocal_);
1501 for (
int i=0; i<nevLocal_; i++) {
1504 cXHP = MVT::CloneView(*Teuchos::rcp_implicit_cast<const MV>(V_),indXHP);
1505 cK_XHP = MVT::CloneView(*Teuchos::rcp_implicit_cast<const MV>(KV_),indXHP);
1507 cM_XHP = MVT::CloneView(*Teuchos::rcp_implicit_cast<const MV>(MV_),indXHP);
1513 std::vector<int> indHP(nevLocal_-blockSize_);
1514 for (
int i=blockSize_; i<nevLocal_; i++) {
1515 indHP[i-blockSize_] = i;
1517 cHP = MVT::CloneView(*Teuchos::rcp_implicit_cast<const MV>(V_),indHP);
1518 cK_HP = MVT::CloneView(*Teuchos::rcp_implicit_cast<const MV>(KV_),indHP);
1520 cM_HP = MVT::CloneView(*Teuchos::rcp_implicit_cast<const MV>(MV_),indHP);
1526 if (nevLocal_ == threeBlocks) {
1527 cP = MVT::CloneView(*Teuchos::rcp_implicit_cast<const MV>(V_),indblock3);
1528 cK_P = MVT::CloneView(*Teuchos::rcp_implicit_cast<const MV>(KV_),indblock3);
1530 cM_P = MVT::CloneView(*Teuchos::rcp_implicit_cast<const MV>(MV_),indblock3);
1553 K1(
Teuchos::View,KK,blockSize_,nevLocal_ ,0*blockSize_,0*blockSize_),
1554 K2(
Teuchos::View,KK,blockSize_,nevLocal_-1*blockSize_,1*blockSize_,1*blockSize_),
1555 K3(
Teuchos::View,KK,blockSize_,nevLocal_-2*blockSize_,2*blockSize_,2*blockSize_),
1556 M1(
Teuchos::View,MM,blockSize_,nevLocal_ ,0*blockSize_,0*blockSize_),
1557 M2(
Teuchos::View,MM,blockSize_,nevLocal_-1*blockSize_,1*blockSize_,1*blockSize_),
1558 M3(
Teuchos::View,MM,blockSize_,nevLocal_-2*blockSize_,2*blockSize_,2*blockSize_);
1560 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1563 MVT::MvTransMv( ONE, *cX, *cK_XHP, K1 );
1564 MVT::MvTransMv( ONE, *cX, *cM_XHP, M1 );
1565 MVT::MvTransMv( ONE, *cH, *cK_HP , K2 );
1566 MVT::MvTransMv( ONE, *cH, *cM_HP , M2 );
1567 if (nevLocal_ == threeBlocks) {
1568 MVT::MvTransMv( ONE, *cP, *cK_P, K3 );
1569 MVT::MvTransMv( ONE, *cP, *cM_P, M3 );
1579 cK_P = Teuchos::null;
1580 cM_P = Teuchos::null;
1581 if (fullOrtho_ ==
true) {
1582 cHP = Teuchos::null;
1583 cK_HP = Teuchos::null;
1584 cM_HP = Teuchos::null;
1597 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1600 int localSize = nevLocal_;
1601 Utils::directSolver(localSize, lclKK, Teuchos::rcpFromRef(lclMM), lclS, theta_, nevLocal_, 0);
1610 if (nevLocal_ != localSize) {
1613 cXHP = Teuchos::null;
1614 cK_XHP = Teuchos::null;
1615 cM_XHP = Teuchos::null;
1616 cHP = Teuchos::null;
1617 cK_HP = Teuchos::null;
1618 cM_HP = Teuchos::null;
1622 "Anasazi::LOBPCG::iterate(): indefiniteness detected in projected mass matrix." );
1632 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1636 std::vector<int> order(nevLocal_);
1639 sm_->sort(theta_, Teuchos::rcpFromRef(order), nevLocal_);
1642 Utils::permuteVectors(order,lclS);
1666 MMC(nevLocal_,twoBlocks),
1667 CMMC(twoBlocks ,twoBlocks);
1670 for (
int j=0; j<oneBlock; j++) {
1671 for (
int i=0; i<oneBlock; i++) {
1675 C(i,j+oneBlock) = ZERO;
1679 for (
int j=0; j<oneBlock; j++) {
1680 for (
int i=oneBlock; i<twoBlocks; i++) {
1684 C(i,j+oneBlock) = lclS(i,j);
1688 if (nevLocal_ == threeBlocks) {
1689 for (
int j=0; j<oneBlock; j++) {
1690 for (
int i=twoBlocks; i<threeBlocks; i++) {
1694 C(i,j+oneBlock) = lclS(i,j);
1704 "Anasazi::LOBPCG::iterate(): Logic error calling SerialDenseMatrix::multiply");
1708 "Anasazi::LOBPCG::iterate(): Logic error calling SerialDenseMatrix::multiply");
1721 MagnitudeType symNorm = K22_trans.
normOne();
1722 MagnitudeType tol = SCT::magnitude(SCT::squareroot(SCT::eps()));
1724 cXHP = Teuchos::null;
1725 cHP = Teuchos::null;
1726 cK_XHP = Teuchos::null;
1727 cK_HP = Teuchos::null;
1728 cM_XHP = Teuchos::null;
1729 cM_HP = Teuchos::null;
1732 std::string errMsg =
"Anasazi::LOBPCG::iterate(): Cholesky factorization failed during full orthogonalization.";
1733 if ( symNorm < tol )
1739 errMsg +=
" Check the operator A (or K), it may not be Hermitian!";
1746 nevLocal_,twoBlocks,ONE,CMMC.
values(),CMMC.
stride(),C.values(),C.stride());
1753 if (om_->isVerbosity(
Debug ) ) {
1755 tmp2(oneBlock,oneBlock);
1758 std::stringstream os;
1760 os.setf(std::ios::scientific, std::ios::floatfield);
1762 os <<
" Checking Full Ortho: iteration " << iter_ << std::endl;
1768 "Anasazi::LOBPCG::iterate(): Logic error calling SerialDenseMatrix::multiply");
1772 "Anasazi::LOBPCG::iterate(): Logic error calling SerialDenseMatrix::multiply");
1774 for (
int i=0; i<oneBlock; i++) tmp2(i,i) -= ONE;
1776 os <<
" >> Error in CX^H MM CX == I : " << tmp << std::endl;
1782 "Anasazi::LOBPCG::iterate(): Logic error calling SerialDenseMatrix::multiply");
1786 "Anasazi::LOBPCG::iterate(): Logic error calling SerialDenseMatrix::multiply");
1788 for (
int i=0; i<oneBlock; i++) tmp2(i,i) -= ONE;
1790 os <<
" >> Error in CP^H MM CP == I : " << tmp << std::endl;
1795 TEUCHOS_TEST_FOR_EXCEPTION(teuchosret != 0,std::logic_error,
"Anasazi::LOBPCG::iterate(): Logic error calling SerialDenseMatrix::multiply");
1798 TEUCHOS_TEST_FOR_EXCEPTION(teuchosret != 0,std::logic_error,
"Anasazi::LOBPCG::iterate(): Logic error calling SerialDenseMatrix::multiply");
1801 os <<
" >> Error in CX^H MM CP == 0 : " << tmp << std::endl;
1804 om_->print(
Debug,os.str());
1829 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1858 MVT::MvTimesMatAddMv(ONE,*cXHP,*CX,ZERO,*tmpmvec_);
1859 MVT::MvTimesMatAddMv(ONE,*cXHP,*CP,ZERO,*R_);
1860 cXHP = Teuchos::null;
1861 MVT::SetBlock(*tmpmvec_,indblock1,*V_);
1862 MVT::SetBlock(*R_ ,indblock3,*V_);
1864 MVT::MvTimesMatAddMv(ONE,*cK_XHP,*CX,ZERO,*tmpmvec_);
1865 MVT::MvTimesMatAddMv(ONE,*cK_XHP,*CP,ZERO,*R_);
1866 cK_XHP = Teuchos::null;
1867 MVT::SetBlock(*tmpmvec_,indblock1,*KV_);
1868 MVT::SetBlock(*R_ ,indblock3,*KV_);
1871 MVT::MvTimesMatAddMv(ONE,*cM_XHP,*CX,ZERO,*tmpmvec_);
1872 MVT::MvTimesMatAddMv(ONE,*cM_XHP,*CP,ZERO,*R_);
1873 cM_XHP = Teuchos::null;
1874 MVT::SetBlock(*tmpmvec_,indblock1,*MV_);
1875 MVT::SetBlock(*R_ ,indblock3,*MV_);
1878 cM_XHP = Teuchos::null;
1883 MVT::MvTimesMatAddMv(ONE,*cXHP,*CX,ZERO,*R_);
1884 cXHP = Teuchos::null;
1885 MVT::SetBlock(*R_,indblock1,*V_);
1886 MVT::MvTimesMatAddMv(ONE,*cHP,*CP,ZERO,*R_);
1887 cHP = Teuchos::null;
1888 MVT::SetBlock(*R_,indblock3,*V_);
1890 MVT::MvTimesMatAddMv(ONE,*cK_XHP,*CX,ZERO,*R_);
1891 cK_XHP = Teuchos::null;
1892 MVT::SetBlock(*R_,indblock1,*KV_);
1893 MVT::MvTimesMatAddMv(ONE,*cK_HP,*CP,ZERO,*R_);
1894 cK_HP = Teuchos::null;
1895 MVT::SetBlock(*R_,indblock3,*KV_);
1898 MVT::MvTimesMatAddMv(ONE,*cM_XHP,*CX,ZERO,*R_);
1899 cM_XHP = Teuchos::null;
1900 MVT::SetBlock(*R_,indblock1,*MV_);
1901 MVT::MvTimesMatAddMv(ONE,*cM_HP,*CP,ZERO,*R_);
1902 cM_HP = Teuchos::null;
1903 MVT::SetBlock(*R_,indblock3,*MV_);
1906 cM_XHP = Teuchos::null;
1907 cM_HP = Teuchos::null;
1922 || cHP != Teuchos::null || cK_HP != Teuchos::null || cM_HP != Teuchos::null
1923 || cP != Teuchos::null || cK_P != Teuchos::null || cM_P != Teuchos::null,
1925 "Anasazi::BlockKrylovSchur::iterate(): const views were not all cleared! Something went wrong!" );
1934 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1937 MVT::MvAddMv( ONE, *KX_, ZERO, *KX_, *R_ );
1939 for (
int i = 0; i < blockSize_; i++) {
1942 MVT::MvTimesMatAddMv( -ONE, *MX_, T, ONE, *R_ );
1946 Rnorms_current_ =
false;
1947 R2norms_current_ =
false;
1950 if (om_->isVerbosity(
Debug ) ) {
1960 om_->print(
Debug, accuracyCheck(chk,
": after local update") );
1967 om_->print(
OrthoDetails, accuracyCheck(chk,
": after local update") );
1975 template <
class ScalarType,
class MV,
class OP>
1976 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
1978 if (Rnorms_current_ ==
false) {
1980 orthman_->norm(*R_,Rnorms_);
1981 Rnorms_current_ =
true;
1989 template <
class ScalarType,
class MV,
class OP>
1990 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
1992 if (R2norms_current_ ==
false) {
1994 MVT::MvNorm(*R_,R2norms_);
1995 R2norms_current_ =
true;
2030 template <
class ScalarType,
class MV,
class OP>
2035 std::stringstream os;
2037 os.setf(std::ios::scientific, std::ios::floatfield);
2040 os <<
" Debugging checks: iteration " << iter_ << where << endl;
2043 if (chk.checkX && initialized_) {
2044 tmp = orthman_->orthonormError(*X_);
2045 os <<
" >> Error in X^H M X == I : " << tmp << endl;
2046 for (Array_size_type i=0; i<auxVecs_.size(); i++) {
2047 tmp = orthman_->orthogError(*X_,*auxVecs_[i]);
2048 os <<
" >> Error in X^H M Q[" << i <<
"] == 0 : " << tmp << endl;
2051 if (chk.checkMX && hasM_ && initialized_) {
2052 tmp = Utils::errorEquality(*X_, *MX_, MOp_);
2053 os <<
" >> Error in MX == M*X : " << tmp << endl;
2055 if (chk.checkKX && initialized_) {
2056 tmp = Utils::errorEquality(*X_, *KX_, Op_);
2057 os <<
" >> Error in KX == K*X : " << tmp << endl;
2061 if (chk.checkP && hasP_ && initialized_) {
2063 tmp = orthman_->orthonormError(*P_);
2064 os <<
" >> Error in P^H M P == I : " << tmp << endl;
2065 tmp = orthman_->orthogError(*P_,*X_);
2066 os <<
" >> Error in P^H M X == 0 : " << tmp << endl;
2068 for (Array_size_type i=0; i<auxVecs_.size(); i++) {
2069 tmp = orthman_->orthogError(*P_,*auxVecs_[i]);
2070 os <<
" >> Error in P^H M Q[" << i <<
"] == 0 : " << tmp << endl;
2073 if (chk.checkMP && hasM_ && hasP_ && initialized_) {
2074 tmp = Utils::errorEquality(*P_, *MP_, MOp_);
2075 os <<
" >> Error in MP == M*P : " << tmp << endl;
2077 if (chk.checkKP && hasP_ && initialized_) {
2078 tmp = Utils::errorEquality(*P_, *KP_, Op_);
2079 os <<
" >> Error in KP == K*P : " << tmp << endl;
2083 if (chk.checkH && initialized_) {
2085 tmp = orthman_->orthonormError(*H_);
2086 os <<
" >> Error in H^H M H == I : " << tmp << endl;
2087 tmp = orthman_->orthogError(*H_,*X_);
2088 os <<
" >> Error in H^H M X == 0 : " << tmp << endl;
2090 tmp = orthman_->orthogError(*H_,*P_);
2091 os <<
" >> Error in H^H M P == 0 : " << tmp << endl;
2094 for (Array_size_type i=0; i<auxVecs_.size(); i++) {
2095 tmp = orthman_->orthogError(*H_,*auxVecs_[i]);
2096 os <<
" >> Error in H^H M Q[" << i <<
"] == 0 : " << tmp << endl;
2099 if (chk.checkMH && hasM_ && initialized_) {
2100 tmp = Utils::errorEquality(*H_, *MH_, MOp_);
2101 os <<
" >> Error in MH == M*H : " << tmp << endl;
2105 if (chk.checkR && initialized_) {
2107 MVT::MvTransMv(ONE,*X_,*R_,xTx);
2108 tmp = xTx.normFrobenius();
2109 MVT::MvTransMv(ONE,*R_,*R_,xTx);
2110 double normR = xTx.normFrobenius();
2111 os <<
" >> RelError in X^H R == 0: " << tmp/normR << endl;
2116 for (Array_size_type i=0; i<auxVecs_.size(); i++) {
2117 tmp = orthman_->orthonormError(*auxVecs_[i]);
2118 os <<
" >> Error in Q[" << i <<
"]^H M Q[" << i <<
"] == I : " << tmp << endl;
2119 for (Array_size_type j=i+1; j<auxVecs_.size(); j++) {
2120 tmp = orthman_->orthogError(*auxVecs_[i],*auxVecs_[j]);
2121 os <<
" >> Error in Q[" << i <<
"]^H M Q[" << j <<
"] == 0 : " << tmp << endl;
2134 template <
class ScalarType,
class MV,
class OP>
2140 os.setf(std::ios::scientific, std::ios::floatfield);
2143 os <<
"================================================================================" << endl;
2145 os <<
" LOBPCG Solver Status" << endl;
2147 os <<
"The solver is "<<(initialized_ ?
"initialized." :
"not initialized.") << endl;
2148 os <<
"The number of iterations performed is " << iter_ << endl;
2149 os <<
"The current block size is " << blockSize_ << endl;
2150 os <<
"The number of auxiliary vectors is " << numAuxVecs_ << endl;
2151 os <<
"The number of operations Op*x is " << count_ApplyOp_ << endl;
2152 os <<
"The number of operations M*x is " << count_ApplyM_ << endl;
2153 os <<
"The number of operations Prec*x is " << count_ApplyPrec_ << endl;
2155 os.setf(std::ios_base::right, std::ios_base::adjustfield);
2159 os <<
"CURRENT EIGENVALUE ESTIMATES "<<endl;
2160 os << std::setw(20) <<
"Eigenvalue"
2161 << std::setw(20) <<
"Residual(M)"
2162 << std::setw(20) <<
"Residual(2)"
2164 os <<
"--------------------------------------------------------------------------------"<<endl;
2165 for (
int i=0; i<blockSize_; i++) {
2166 os << std::setw(20) << theta_[i];
2167 if (Rnorms_current_) os << std::setw(20) << Rnorms_[i];
2168 else os << std::setw(20) <<
"not current";
2169 if (R2norms_current_) os << std::setw(20) << R2norms_[i];
2170 else os << std::setw(20) <<
"not current";
2174 os <<
"================================================================================" << endl;
2180 template <
class ScalarType,
class MV,
class OP>
2182 return initialized_;
2188 template <
class ScalarType,
class MV,
class OP>
2195 template <
class ScalarType,
class MV,
class OP>
2203 template <
class ScalarType,
class MV,
class OP>
2210 template <
class ScalarType,
class MV,
class OP>
2217 template <
class ScalarType,
class MV,
class OP>
2225 template <
class ScalarType,
class MV,
class OP>
2227 return 3*blockSize_;
2232 template <
class ScalarType,
class MV,
class OP>
2234 if (!initialized_)
return 0;
2241 template <
class ScalarType,
class MV,
class OP>
2242 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
2245 return this->getRes2Norms();
2251 template <
class ScalarType,
class MV,
class OP>
2253 std::vector<int> ret(nevLocal_,0);
2260 template <
class ScalarType,
class MV,
class OP>
2262 std::vector<Value<ScalarType> > ret(nevLocal_);
2263 for (
int i=0; i<nevLocal_; i++) {
2264 ret[i].realpart = theta_[i];
2265 ret[i].imagpart = ZERO;
2272 template <
class ScalarType,
class MV,
class OP>
2275 "Anasazi::LOBPCG::setStatusTest() was passed a null StatusTest.");
2281 template <
class ScalarType,
class MV,
class OP>
2288 template <
class ScalarType,
class MV,
class OP>
2296 template <
class ScalarType,
class MV,
class OP>
2304 template <
class ScalarType,
class MV,
class OP>
2312 template <
class ScalarType,
class MV,
class OP>
2324 state.
T =
Teuchos::rcp(
new std::vector<MagnitudeType>(theta_));
2332 state.
MX = Teuchos::null;
2333 state.
MP = Teuchos::null;
2334 state.
MH = Teuchos::null;
2341 #endif // ANASAZI_LOBPCG_HPP
ScalarTraits< ScalarType >::magnitudeType normOne() const
ScalarType * values() const
void TRSM(ESide side, EUplo uplo, ETransp transa, EDiag diag, const OrdinalType &m, const OrdinalType &n, const alpha_type alpha, const A_type *A, const OrdinalType &lda, ScalarType *B, const OrdinalType &ldb) const
Templated virtual class for providing orthogonalization/orthonormalization methods with matrix-based ...
Teuchos::Array< Teuchos::RCP< const MV > > getAuxVecs() const
Get the current auxiliary vectors.
LOBPCG(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)
LOBPCG constructor with eigenproblem, solver utilities, and parameter list of solver options...
This class defines the interface required by an eigensolver and status test class to compute solution...
int getBlockSize() const
Get the blocksize to be used by the iterative solver in solving this eigenproblem.
void setStatusTest(Teuchos::RCP< StatusTest< ScalarType, MV, OP > > test)
Set a new StatusTest for the solver.
Declaration of basic traits for the multivector type.
T & get(const std::string &name, T def_value)
int multiply(ETransp transa, ETransp transb, ScalarType alpha, const SerialDenseMatrix< OrdinalType, ScalarType > &A, const SerialDenseMatrix< OrdinalType, ScalarType > &B, ScalarType beta)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
This class provides the Locally Optimal Block Preconditioned Conjugate Gradient (LOBPCG) iteration...
Teuchos::RCP< const MultiVector > V
The current test basis.
virtual ~LOBPCG()
LOBPCG destructor
Virtual base class which defines basic traits for the operator type.
Teuchos::RCP< const MultiVector > H
The current preconditioned residual vectors.
Teuchos::RCP< const MultiVector > P
The current search direction.
An exception class parent to all Anasazi exceptions.
Teuchos::RCP< const MultiVector > MV
The image of the current test basis under M, or Teuchos::null if M was not specified.
ScalarTraits< ScalarType >::magnitudeType normFrobenius() const
Pure virtual base class which describes the basic interface to the iterative eigensolver.
Teuchos::RCP< const MultiVector > R
The current residual vectors.
void initialize()
Initialize the solver with the initial vectors from the eigenproblem or random data.
Teuchos::RCP< const std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > > T
The current Ritz values.
bool isInitialized() const
Indicates whether the solver has been initialized or not.
Anasazi's templated, static class providing utilities for the solvers.
const Eigenproblem< ScalarType, MV, OP > & getProblem() const
Get a constant reference to the eigenvalue problem.
Anasazi's templated virtual class for providing routines for orthogonalization and orthonormalization...
void setBlockSize(int blockSize)
Set the blocksize to be used by the iterative solver in solving this eigenproblem.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Output managers remove the need for the eigensolver to know any information about the required output...
void POTRF(const char &UPLO, const OrdinalType &n, ScalarType *A, const OrdinalType &lda, OrdinalType *info) const
Traits class which defines basic operations on multivectors.
int getNumIters() const
Get the current iteration count.
Virtual base class which defines basic traits for the operator type.
std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > getRes2Norms()
Get the current residual 2-norms.
Teuchos::RCP< const MultiVector > MX
The image of the current eigenvectors under M, or Teuchos::null if M was not specified.
Teuchos::RCP< const MultiVector > KX
The image of the current eigenvectors under K.
bool getFullOrtho() const
Determine if the LOBPCG iteration is using full orthogonality.
Teuchos::RCP< const MultiVector > KH
The image of the current preconditioned residual vectors under K.
std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > getResNorms()
Get the current residual norms.
std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > getRitzRes2Norms()
Get the 2-norms of the residuals.
std::vector< int > getRitzIndex()
Get the index used for extracting Ritz vectors from getRitzVectors().
int getMaxSubspaceDim() const
Get the maximum dimension allocated for the search subspace. For LOBPCG, this always returns 3*getBlo...
Teuchos::RCP< const MultiVector > MH
The image of the current preconditioned residual vectors under M, or Teuchos::null if M was not speci...
Teuchos::RCP< const MultiVector > KP
The image of the current search direction under K.
Teuchos::RCP< StatusTest< ScalarType, MV, OP > > getStatusTest() const
Get the current StatusTest used by the solver.
void push_back(const value_type &x)
void currentStatus(std::ostream &os)
This method requests that the solver print out its current status to screen.
void iterate()
This method performs LOBPCG iterations until the status test indicates the need to stop or an error o...
LOBPCGRitzFailure is thrown when the LOBPCG solver is unable to continue a call to LOBPCG::iterate() ...
std::vector< Value< ScalarType > > getRitzValues()
Get the Ritz values from the previous iteration.
Teuchos::RCP< const MultiVector > KV
The image of the current test basis under K.
void setAuxVecs(const Teuchos::Array< Teuchos::RCP< const MV > > &auxvecs)
Set the auxiliary vectors for the solver.
Types and exceptions used within Anasazi solvers and interfaces.
void resetNumIters()
Reset the iteration count.
Teuchos::RCP< const MultiVector > MP
The image of the current search direction under M, or Teuchos::null if M was not specified.
Anasazi's templated pure virtual class for managing the sorting of approximate eigenvalues computed b...
Common interface of stopping criteria for Anasazi's solvers.
LOBPCGOrthoFailure is thrown when an orthogonalization attempt fails.
LOBPCGInitFailure is thrown when the LOBPCG solver is unable to generate an initial iterate in the LO...
LOBPCGState< ScalarType, MV > getState() const
Get the current state of the eigensolver.
The Eigensolver is a templated virtual base class that defines the basic interface that any eigensolv...
void setFullOrtho(bool fullOrtho)
Instruct the LOBPCG iteration to use full orthogonality.
Structure to contain pointers to Anasazi state variables.
Teuchos::RCP< const MultiVector > X
The current eigenvectors.
OrdinalType stride() const
Teuchos::RCP< const MV > getRitzVectors()
Get the Ritz vectors from the previous iteration.
bool hasP()
Indicates whether the search direction given by getState() is valid.
int getCurSubspaceDim() const
Get the dimension of the search subspace used to generate the current eigenvectors and eigenvalues...
Class which provides internal utilities for the Anasazi solvers.