33 #ifndef ANASAZI_LOBPCG_HPP
34 #define ANASAZI_LOBPCG_HPP
81 template <
class ScalarType,
class MultiVector>
121 V(Teuchos::null),
KV(Teuchos::null),
MV(Teuchos::null),
122 X(Teuchos::null),
KX(Teuchos::null),
MX(Teuchos::null),
123 P(Teuchos::null),
KP(Teuchos::null),
MP(Teuchos::null),
124 H(Teuchos::null),
KH(Teuchos::null),
MH(Teuchos::null),
125 R(Teuchos::null),
T(Teuchos::null) {};
189 template <
class ScalarType,
class MV,
class OP>
354 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
getResNorms();
362 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
getRes2Norms();
372 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
getRitzRes2Norms();
477 const MagnitudeType ONE;
478 const MagnitudeType ZERO;
479 const MagnitudeType NANVAL;
484 bool checkX, checkMX, checkKX;
485 bool checkH, checkMH;
486 bool checkP, checkMP, checkKP;
488 CheckList() : checkX(false),checkMX(false),checkKX(false),
489 checkH(false),checkMH(false),
490 checkP(false),checkMP(false),checkKP(false),
491 checkR(false),checkQ(false) {};
496 std::string accuracyCheck(
const CheckList &chk,
const std::string &where)
const;
517 timerLocalProj_, timerDS_,
518 timerLocalUpdate_, timerCompRes_,
519 timerOrtho_, timerInit_;
524 int count_ApplyOp_, count_ApplyM_, count_ApplyPrec_;
579 std::vector<MagnitudeType> theta_, Rnorms_, R2norms_;
582 bool Rnorms_current_, R2norms_current_;
591 template <
class ScalarType,
class MV,
class OP>
600 ONE(Teuchos::ScalarTraits<MagnitudeType>::one()),
601 ZERO(Teuchos::ScalarTraits<MagnitudeType>::zero()),
602 NANVAL(Teuchos::ScalarTraits<MagnitudeType>::nan()),
610 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
611 timerOp_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: LOBPCG::Operation Op*x")),
612 timerMOp_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: LOBPCG::Operation M*x")),
613 timerPrec_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: LOBPCG::Operation Prec*x")),
614 timerSort_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: LOBPCG::Sorting eigenvalues")),
615 timerLocalProj_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: LOBPCG::Local projection")),
616 timerDS_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: LOBPCG::Direct solve")),
617 timerLocalUpdate_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: LOBPCG::Local update")),
618 timerCompRes_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: LOBPCG::Computing residuals")),
619 timerOrtho_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: LOBPCG::Orthogonalization")),
620 timerInit_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: LOBPCG::Initialization")),
627 fullOrtho_(params.get(
"Full Ortho", true)),
631 auxVecs_( Teuchos::Array<Teuchos::RCP<const MV> >(0) ),
634 Rnorms_current_(false),
635 R2norms_current_(false)
638 "Anasazi::LOBPCG::constructor: user passed null problem pointer.");
640 "Anasazi::LOBPCG::constructor: user passed null sort manager pointer.");
642 "Anasazi::LOBPCG::constructor: user passed null output manager pointer.");
644 "Anasazi::LOBPCG::constructor: user passed null status test pointer.");
646 "Anasazi::LOBPCG::constructor: user passed null orthogonalization manager pointer.");
648 "Anasazi::LOBPCG::constructor: problem is not set.");
650 "Anasazi::LOBPCG::constructor: problem is not Hermitian; LOBPCG requires Hermitian problem.");
653 Op_ = problem_->getOperator();
655 "Anasazi::LOBPCG::constructor: problem provides no operator.");
656 MOp_ = problem_->getM();
657 Prec_ = problem_->getPrec();
658 hasM_ = (MOp_ != Teuchos::null);
661 int bs = params.
get(
"Block Size", problem_->getNEV());
668 template <
class ScalarType,
class MV,
class OP>
672 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
686 if (blockSize_ > 0) {
690 tmp = problem_->getInitVec();
692 "Anasazi::LOBPCG::setBlockSize(): eigenproblem did not specify initial vectors to clone from.");
696 std::invalid_argument,
"Anasazi::LOBPCG::setBlockSize(): block size must be strictly positive.");
697 if (newBS == blockSize_) {
701 else if (newBS < blockSize_ && initialized_) {
717 std::vector<int> newind(newBS), oldind(newBS);
718 for (
int i=0; i<newBS; i++) {
726 newR = MVT::Clone(*tmp,newBS);
727 newV = MVT::Clone(*tmp,newBS*3);
728 newKV = MVT::Clone(*tmp,newBS*3);
730 newMV = MVT::Clone(*tmp,newBS*3);
750 theta_.resize(3*newBS);
751 Rnorms_.resize(newBS);
752 R2norms_.resize(newBS);
755 src = MVT::CloneView(*R_,newind);
756 MVT::SetBlock(*src,newind,*newR);
762 src = MVT::CloneView(*V_,oldind);
763 MVT::SetBlock(*src,newind,*newV);
764 src = MVT::CloneView(*KV_,oldind);
765 MVT::SetBlock(*src,newind,*newKV);
767 src = MVT::CloneView(*MV_,oldind);
768 MVT::SetBlock(*src,newind,*newMV);
771 for (
int i=0; i<newBS; i++) {
772 newind[i] += 2*newBS;
773 oldind[i] += 2*blockSize_;
775 src = MVT::CloneView(*V_,oldind);
776 MVT::SetBlock(*src,newind,*newV);
777 src = MVT::CloneView(*KV_,oldind);
778 MVT::SetBlock(*src,newind,*newKV);
780 src = MVT::CloneView(*MV_,oldind);
781 MVT::SetBlock(*src,newind,*newMV);
800 initialized_ =
false;
819 theta_.resize(3*newBS,NANVAL);
820 Rnorms_.resize(newBS,NANVAL);
821 R2norms_.resize(newBS,NANVAL);
824 R_ = MVT::Clone(*tmp,newBS);
825 V_ = MVT::Clone(*tmp,newBS*3);
826 KV_ = MVT::Clone(*tmp,newBS*3);
828 MV_ = MVT::Clone(*tmp,newBS*3);
836 tmpmvec_ = Teuchos::null;
838 tmpmvec_ = MVT::Clone(*tmp,newBS);
851 template <
class ScalarType,
class MV,
class OP>
854 std::vector<int> ind(blockSize_);
856 for (
int i=0; i<blockSize_; i++) {
859 X_ = MVT::CloneViewNonConst(*V_,ind);
860 KX_ = MVT::CloneViewNonConst(*KV_,ind);
862 MX_ = MVT::CloneViewNonConst(*MV_,ind);
868 for (
int i=0; i<blockSize_; i++) {
869 ind[i] += blockSize_;
871 H_ = MVT::CloneViewNonConst(*V_,ind);
872 KH_ = MVT::CloneViewNonConst(*KV_,ind);
874 MH_ = MVT::CloneViewNonConst(*MV_,ind);
880 for (
int i=0; i<blockSize_; i++) {
881 ind[i] += blockSize_;
883 P_ = MVT::CloneViewNonConst(*V_,ind);
884 KP_ = MVT::CloneViewNonConst(*KV_,ind);
886 MP_ = MVT::CloneViewNonConst(*MV_,ind);
896 template <
class ScalarType,
class MV,
class OP>
904 for (tarcpmv i=auxVecs_.begin(); i != auxVecs_.end(); i++) {
905 numAuxVecs_ += MVT::GetNumberVecs(**i);
909 if (numAuxVecs_ > 0 && initialized_) {
910 initialized_ =
false;
914 if (om_->isVerbosity(
Debug ) ) {
918 om_->print(
Debug, accuracyCheck(chk,
": in setAuxVecs()") );
941 template <
class ScalarType,
class MV,
class OP>
947 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
951 std::vector<int> bsind(blockSize_);
952 for (
int i=0; i<blockSize_; i++) bsind[i] = i;
976 if (newstate.
X != Teuchos::null) {
978 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): vector length of newstate.X not correct." );
981 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): newstate.X must have at least block size vectors.");
984 MVT::SetBlock(*newstate.
X,bsind,*X_);
988 if (newstate.
MX != Teuchos::null) {
990 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): vector length of newstate.MX not correct." );
993 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): newstate.MX must have at least block size vectors.");
994 MVT::SetBlock(*newstate.
MX,bsind,*MX_);
999 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1002 OPT::Apply(*MOp_,*X_,*MX_);
1003 count_ApplyM_ += blockSize_;
1006 newstate.
R = Teuchos::null;
1011 if (newstate.
KX != Teuchos::null) {
1013 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): vector length of newstate.KX not correct." );
1016 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): newstate.KX must have at least block size vectors.");
1017 MVT::SetBlock(*newstate.
KX,bsind,*KX_);
1022 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1025 OPT::Apply(*Op_,*X_,*KX_);
1026 count_ApplyOp_ += blockSize_;
1029 newstate.
R = Teuchos::null;
1037 newstate.
P = Teuchos::null;
1038 newstate.
KP = Teuchos::null;
1039 newstate.
MP = Teuchos::null;
1040 newstate.
R = Teuchos::null;
1041 newstate.
T = Teuchos::null;
1046 "Anasazi::LOBPCG::initialize(): Eigenproblem did not specify initial vectors to clone from.");
1048 int initSize = MVT::GetNumberVecs(*ivec);
1049 if (initSize > blockSize_) {
1051 initSize = blockSize_;
1052 std::vector<int> ind(blockSize_);
1053 for (
int i=0; i<blockSize_; i++) ind[i] = i;
1054 ivec = MVT::CloneView(*ivec,ind);
1059 std::vector<int> ind(initSize);
1060 for (
int i=0; i<initSize; i++) ind[i] = i;
1061 MVT::SetBlock(*ivec,ind,*X_);
1064 if (blockSize_ > initSize) {
1065 std::vector<int> ind(blockSize_ - initSize);
1066 for (
int i=0; i<blockSize_ - initSize; i++) ind[i] = initSize + i;
1074 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1077 OPT::Apply(*MOp_,*X_,*MX_);
1078 count_ApplyM_ += blockSize_;
1082 if (numAuxVecs_ > 0) {
1083 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1087 int rank = orthman_->projectAndNormalizeMat(*X_,auxVecs_,dummy,Teuchos::null,MX_);
1089 "Anasazi::LOBPCG::initialize(): Couldn't generate initial basis of full rank.");
1092 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1095 int rank = orthman_->normalizeMat(*X_,Teuchos::null,MX_);
1097 "Anasazi::LOBPCG::initialize(): Couldn't generate initial basis of full rank.");
1102 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1105 OPT::Apply(*Op_,*X_,*KX_);
1106 count_ApplyOp_ += blockSize_;
1114 theta_.resize(3*blockSize_,NANVAL);
1115 if (newstate.
T != Teuchos::null) {
1117 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): newstate.T must contain at least block size Ritz values.");
1118 for (
int i=0; i<blockSize_; i++) {
1119 theta_[i] = (*newstate.
T)[i];
1121 nevLocal_ = blockSize_;
1126 MM(blockSize_,blockSize_),
1127 S(blockSize_,blockSize_);
1129 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1133 MVT::MvTransMv(ONE,*X_,*KX_,KK);
1135 MVT::MvTransMv(ONE,*X_,*MX_,MM);
1136 nevLocal_ = blockSize_;
1141 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1144 Utils::directSolver(blockSize_, KK, Teuchos::rcpFromRef(MM), S, theta_, nevLocal_, 1);
1146 "Anasazi::LOBPCG::initialize(): Initial Ritz analysis did not produce enough Ritz pairs to initialize algorithm.");
1152 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1156 std::vector<int> order(blockSize_);
1159 sm_->sort(theta_, Teuchos::rcpFromRef(order), blockSize_);
1162 Utils::permuteVectors(order,S);
1167 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1171 MVT::MvAddMv( ONE, *X_, ZERO, *X_, *R_ );
1172 MVT::MvTimesMatAddMv( ONE, *R_, S, ZERO, *X_ );
1174 MVT::MvAddMv( ONE, *KX_, ZERO, *KX_, *R_ );
1175 MVT::MvTimesMatAddMv( ONE, *R_, S, ZERO, *KX_ );
1178 MVT::MvAddMv( ONE, *MX_, ZERO, *MX_, *R_ );
1179 MVT::MvTimesMatAddMv( ONE, *R_, S, ZERO, *MX_ );
1187 if (newstate.
R != Teuchos::null) {
1189 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): vector length of newstate.R not correct." );
1191 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): newstate.R must have blockSize number of vectors." );
1192 MVT::SetBlock(*newstate.
R,bsind,*R_);
1195 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1199 MVT::MvAddMv(ZERO,*KX_,ONE,*KX_,*R_);
1201 for (
int i=0; i<blockSize_; i++) T(i,i) = theta_[i];
1202 MVT::MvTimesMatAddMv(-ONE,*MX_,T,ONE,*R_);
1206 Rnorms_current_ =
false;
1207 R2norms_current_ =
false;
1210 if (newstate.
P != Teuchos::null) {
1212 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): newstate.P must have blockSize number of vectors." );
1214 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): vector length of newstate.P not correct." );
1218 MVT::SetBlock(*newstate.
P,bsind,*P_);
1221 if (newstate.
KP != Teuchos::null) {
1223 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): newstate.KP must have blockSize number of vectors." );
1225 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): vector length of newstate.KP not correct." );
1226 MVT::SetBlock(*newstate.
KP,bsind,*KP_);
1229 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1232 OPT::Apply(*Op_,*P_,*KP_);
1233 count_ApplyOp_ += blockSize_;
1238 if (newstate.
MP != Teuchos::null) {
1240 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): newstate.MP must have blockSize number of vectors." );
1242 std::invalid_argument,
"Anasazi::LOBPCG::initialize(newstate): vector length of newstate.MP not correct." );
1243 MVT::SetBlock(*newstate.
MP,bsind,*MP_);
1246 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1249 OPT::Apply(*MOp_,*P_,*MP_);
1250 count_ApplyM_ += blockSize_;
1259 initialized_ =
true;
1261 if (om_->isVerbosity(
Debug ) ) {
1272 om_->print(
Debug, accuracyCheck(chk,
": after initialize()") );
1277 template <
class ScalarType,
class MV,
class OP>
1287 template <
class ScalarType,
class MV,
class OP>
1290 if ( fullOrtho_ ==
true || initialized_ ==
false || fullOrtho == fullOrtho_ ) {
1292 fullOrtho_ = fullOrtho;
1304 if (fullOrtho_ && tmpmvec_ == Teuchos::null) {
1306 tmpmvec_ = MVT::Clone(*X_,blockSize_);
1308 else if (fullOrtho_==
false) {
1310 tmpmvec_ = Teuchos::null;
1317 template <
class ScalarType,
class MV,
class OP>
1323 if (initialized_ ==
false) {
1329 const int oneBlock = blockSize_;
1330 const int twoBlocks = 2*blockSize_;
1331 const int threeBlocks = 3*blockSize_;
1333 std::vector<int> indblock1(blockSize_), indblock2(blockSize_), indblock3(blockSize_);
1334 for (
int i=0; i<blockSize_; i++) {
1336 indblock2[i] = i + blockSize_;
1337 indblock3[i] = i + 2*blockSize_;
1346 MM( threeBlocks, threeBlocks ),
1347 S( threeBlocks, threeBlocks );
1349 while (tester_->checkStatus(
this) !=
Passed) {
1352 if (om_->isVerbosity(
Debug)) {
1353 currentStatus( om_->stream(
Debug) );
1363 if (Prec_ != Teuchos::null) {
1364 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1367 OPT::Apply( *Prec_, *R_, *H_ );
1368 count_ApplyPrec_ += blockSize_;
1371 MVT::MvAddMv(ONE,*R_,ZERO,*R_,*H_);
1376 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1379 OPT::Apply( *MOp_, *H_, *MH_);
1380 count_ApplyM_ += blockSize_;
1396 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1400 Teuchos::tuple<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > >(Teuchos::null);
1401 int rank = orthman_->projectAndNormalizeMat(*H_,Q,dummyC,Teuchos::null,MH_);
1404 "Anasazi::LOBPCG::iterate(): unable to compute orthonormal basis for H.");
1407 if (om_->isVerbosity(
Debug ) ) {
1411 om_->print(
Debug, accuracyCheck(chk,
": after ortho H") );
1417 om_->print(
OrthoDetails, accuracyCheck(chk,
": after ortho H") );
1422 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1425 OPT::Apply( *Op_, *H_, *KH_);
1426 count_ApplyOp_ += blockSize_;
1430 nevLocal_ = threeBlocks;
1433 nevLocal_ = twoBlocks;
1455 KX_ = Teuchos::null;
1456 MX_ = Teuchos::null;
1458 KH_ = Teuchos::null;
1459 MH_ = Teuchos::null;
1461 KP_ = Teuchos::null;
1462 MP_ = Teuchos::null;
1463 Teuchos::RCP<const MV> cX, cH, cXHP, cHP, cK_XHP, cK_HP, cM_XHP, cM_HP, cP, cK_P, cM_P;
1465 cX = MVT::CloneView(*Teuchos::rcp_implicit_cast<const MV>(V_),indblock1);
1466 cH = MVT::CloneView(*Teuchos::rcp_implicit_cast<const MV>(V_),indblock2);
1468 std::vector<int> indXHP(nevLocal_);
1469 for (
int i=0; i<nevLocal_; i++) {
1472 cXHP = MVT::CloneView(*Teuchos::rcp_implicit_cast<const MV>(V_),indXHP);
1473 cK_XHP = MVT::CloneView(*Teuchos::rcp_implicit_cast<const MV>(KV_),indXHP);
1475 cM_XHP = MVT::CloneView(*Teuchos::rcp_implicit_cast<const MV>(MV_),indXHP);
1481 std::vector<int> indHP(nevLocal_-blockSize_);
1482 for (
int i=blockSize_; i<nevLocal_; i++) {
1483 indHP[i-blockSize_] = i;
1485 cHP = MVT::CloneView(*Teuchos::rcp_implicit_cast<const MV>(V_),indHP);
1486 cK_HP = MVT::CloneView(*Teuchos::rcp_implicit_cast<const MV>(KV_),indHP);
1488 cM_HP = MVT::CloneView(*Teuchos::rcp_implicit_cast<const MV>(MV_),indHP);
1494 if (nevLocal_ == threeBlocks) {
1495 cP = MVT::CloneView(*Teuchos::rcp_implicit_cast<const MV>(V_),indblock3);
1496 cK_P = MVT::CloneView(*Teuchos::rcp_implicit_cast<const MV>(KV_),indblock3);
1498 cM_P = MVT::CloneView(*Teuchos::rcp_implicit_cast<const MV>(MV_),indblock3);
1521 K1(
Teuchos::View,KK,blockSize_,nevLocal_ ,0*blockSize_,0*blockSize_),
1522 K2(
Teuchos::View,KK,blockSize_,nevLocal_-1*blockSize_,1*blockSize_,1*blockSize_),
1523 K3(
Teuchos::View,KK,blockSize_,nevLocal_-2*blockSize_,2*blockSize_,2*blockSize_),
1524 M1(
Teuchos::View,MM,blockSize_,nevLocal_ ,0*blockSize_,0*blockSize_),
1525 M2(
Teuchos::View,MM,blockSize_,nevLocal_-1*blockSize_,1*blockSize_,1*blockSize_),
1526 M3(
Teuchos::View,MM,blockSize_,nevLocal_-2*blockSize_,2*blockSize_,2*blockSize_);
1528 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1531 MVT::MvTransMv( ONE, *cX, *cK_XHP, K1 );
1532 MVT::MvTransMv( ONE, *cX, *cM_XHP, M1 );
1533 MVT::MvTransMv( ONE, *cH, *cK_HP , K2 );
1534 MVT::MvTransMv( ONE, *cH, *cM_HP , M2 );
1535 if (nevLocal_ == threeBlocks) {
1536 MVT::MvTransMv( ONE, *cP, *cK_P, K3 );
1537 MVT::MvTransMv( ONE, *cP, *cM_P, M3 );
1547 cK_P = Teuchos::null;
1548 cM_P = Teuchos::null;
1549 if (fullOrtho_ ==
true) {
1550 cHP = Teuchos::null;
1551 cK_HP = Teuchos::null;
1552 cM_HP = Teuchos::null;
1565 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1568 int localSize = nevLocal_;
1569 Utils::directSolver(localSize, lclKK, Teuchos::rcpFromRef(lclMM), lclS, theta_, nevLocal_, 0);
1578 if (nevLocal_ != localSize) {
1581 cXHP = Teuchos::null;
1582 cK_XHP = Teuchos::null;
1583 cM_XHP = Teuchos::null;
1584 cHP = Teuchos::null;
1585 cK_HP = Teuchos::null;
1586 cM_HP = Teuchos::null;
1590 "Anasazi::LOBPCG::iterate(): indefiniteness detected in projected mass matrix." );
1600 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1604 std::vector<int> order(nevLocal_);
1607 sm_->sort(theta_, Teuchos::rcpFromRef(order), nevLocal_);
1610 Utils::permuteVectors(order,lclS);
1634 MMC(nevLocal_,twoBlocks),
1635 CMMC(twoBlocks ,twoBlocks);
1638 for (
int j=0; j<oneBlock; j++) {
1639 for (
int i=0; i<oneBlock; i++) {
1643 C(i,j+oneBlock) = ZERO;
1647 for (
int j=0; j<oneBlock; j++) {
1648 for (
int i=oneBlock; i<twoBlocks; i++) {
1652 C(i,j+oneBlock) = lclS(i,j);
1656 if (nevLocal_ == threeBlocks) {
1657 for (
int j=0; j<oneBlock; j++) {
1658 for (
int i=twoBlocks; i<threeBlocks; i++) {
1662 C(i,j+oneBlock) = lclS(i,j);
1672 "Anasazi::LOBPCG::iterate(): Logic error calling SerialDenseMatrix::multiply");
1676 "Anasazi::LOBPCG::iterate(): Logic error calling SerialDenseMatrix::multiply");
1689 MagnitudeType symNorm = K22_trans.
normOne();
1690 MagnitudeType tol = SCT::magnitude(SCT::squareroot(SCT::eps()));
1692 cXHP = Teuchos::null;
1693 cHP = Teuchos::null;
1694 cK_XHP = Teuchos::null;
1695 cK_HP = Teuchos::null;
1696 cM_XHP = Teuchos::null;
1697 cM_HP = Teuchos::null;
1700 std::string errMsg =
"Anasazi::LOBPCG::iterate(): Cholesky factorization failed during full orthogonalization.";
1701 if ( symNorm < tol )
1707 errMsg +=
" Check the operator A (or K), it may not be Hermitian!";
1714 nevLocal_,twoBlocks,ONE,CMMC.
values(),CMMC.
stride(),C.values(),C.stride());
1721 if (om_->isVerbosity(
Debug ) ) {
1723 tmp2(oneBlock,oneBlock);
1726 std::stringstream os;
1728 os.setf(std::ios::scientific, std::ios::floatfield);
1730 os <<
" Checking Full Ortho: iteration " << iter_ << std::endl;
1736 "Anasazi::LOBPCG::iterate(): Logic error calling SerialDenseMatrix::multiply");
1740 "Anasazi::LOBPCG::iterate(): Logic error calling SerialDenseMatrix::multiply");
1742 for (
int i=0; i<oneBlock; i++) tmp2(i,i) -= ONE;
1744 os <<
" >> Error in CX^H MM CX == I : " << tmp << std::endl;
1750 "Anasazi::LOBPCG::iterate(): Logic error calling SerialDenseMatrix::multiply");
1754 "Anasazi::LOBPCG::iterate(): Logic error calling SerialDenseMatrix::multiply");
1756 for (
int i=0; i<oneBlock; i++) tmp2(i,i) -= ONE;
1758 os <<
" >> Error in CP^H MM CP == I : " << tmp << std::endl;
1763 TEUCHOS_TEST_FOR_EXCEPTION(teuchosret != 0,std::logic_error,
"Anasazi::LOBPCG::iterate(): Logic error calling SerialDenseMatrix::multiply");
1766 TEUCHOS_TEST_FOR_EXCEPTION(teuchosret != 0,std::logic_error,
"Anasazi::LOBPCG::iterate(): Logic error calling SerialDenseMatrix::multiply");
1769 os <<
" >> Error in CX^H MM CP == 0 : " << tmp << std::endl;
1772 om_->print(
Debug,os.str());
1797 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1826 MVT::MvTimesMatAddMv(ONE,*cXHP,*CX,ZERO,*tmpmvec_);
1827 MVT::MvTimesMatAddMv(ONE,*cXHP,*CP,ZERO,*R_);
1828 cXHP = Teuchos::null;
1829 MVT::SetBlock(*tmpmvec_,indblock1,*V_);
1830 MVT::SetBlock(*R_ ,indblock3,*V_);
1832 MVT::MvTimesMatAddMv(ONE,*cK_XHP,*CX,ZERO,*tmpmvec_);
1833 MVT::MvTimesMatAddMv(ONE,*cK_XHP,*CP,ZERO,*R_);
1834 cK_XHP = Teuchos::null;
1835 MVT::SetBlock(*tmpmvec_,indblock1,*KV_);
1836 MVT::SetBlock(*R_ ,indblock3,*KV_);
1839 MVT::MvTimesMatAddMv(ONE,*cM_XHP,*CX,ZERO,*tmpmvec_);
1840 MVT::MvTimesMatAddMv(ONE,*cM_XHP,*CP,ZERO,*R_);
1841 cM_XHP = Teuchos::null;
1842 MVT::SetBlock(*tmpmvec_,indblock1,*MV_);
1843 MVT::SetBlock(*R_ ,indblock3,*MV_);
1846 cM_XHP = Teuchos::null;
1851 MVT::MvTimesMatAddMv(ONE,*cXHP,*CX,ZERO,*R_);
1852 cXHP = Teuchos::null;
1853 MVT::SetBlock(*R_,indblock1,*V_);
1854 MVT::MvTimesMatAddMv(ONE,*cHP,*CP,ZERO,*R_);
1855 cHP = Teuchos::null;
1856 MVT::SetBlock(*R_,indblock3,*V_);
1858 MVT::MvTimesMatAddMv(ONE,*cK_XHP,*CX,ZERO,*R_);
1859 cK_XHP = Teuchos::null;
1860 MVT::SetBlock(*R_,indblock1,*KV_);
1861 MVT::MvTimesMatAddMv(ONE,*cK_HP,*CP,ZERO,*R_);
1862 cK_HP = Teuchos::null;
1863 MVT::SetBlock(*R_,indblock3,*KV_);
1866 MVT::MvTimesMatAddMv(ONE,*cM_XHP,*CX,ZERO,*R_);
1867 cM_XHP = Teuchos::null;
1868 MVT::SetBlock(*R_,indblock1,*MV_);
1869 MVT::MvTimesMatAddMv(ONE,*cM_HP,*CP,ZERO,*R_);
1870 cM_HP = Teuchos::null;
1871 MVT::SetBlock(*R_,indblock3,*MV_);
1874 cM_XHP = Teuchos::null;
1875 cM_HP = Teuchos::null;
1890 || cHP != Teuchos::null || cK_HP != Teuchos::null || cM_HP != Teuchos::null
1891 || cP != Teuchos::null || cK_P != Teuchos::null || cM_P != Teuchos::null,
1893 "Anasazi::BlockKrylovSchur::iterate(): const views were not all cleared! Something went wrong!" );
1902 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1905 MVT::MvAddMv( ONE, *KX_, ZERO, *KX_, *R_ );
1907 for (
int i = 0; i < blockSize_; i++) {
1910 MVT::MvTimesMatAddMv( -ONE, *MX_, T, ONE, *R_ );
1914 Rnorms_current_ =
false;
1915 R2norms_current_ =
false;
1918 if (om_->isVerbosity(
Debug ) ) {
1928 om_->print(
Debug, accuracyCheck(chk,
": after local update") );
1935 om_->print(
OrthoDetails, accuracyCheck(chk,
": after local update") );
1943 template <
class ScalarType,
class MV,
class OP>
1944 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
1946 if (Rnorms_current_ ==
false) {
1948 orthman_->norm(*R_,Rnorms_);
1949 Rnorms_current_ =
true;
1957 template <
class ScalarType,
class MV,
class OP>
1958 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
1960 if (R2norms_current_ ==
false) {
1962 MVT::MvNorm(*R_,R2norms_);
1963 R2norms_current_ =
true;
1998 template <
class ScalarType,
class MV,
class OP>
2003 std::stringstream os;
2005 os.setf(std::ios::scientific, std::ios::floatfield);
2008 os <<
" Debugging checks: iteration " << iter_ << where << endl;
2011 if (chk.checkX && initialized_) {
2012 tmp = orthman_->orthonormError(*X_);
2013 os <<
" >> Error in X^H M X == I : " << tmp << endl;
2014 for (Array_size_type i=0; i<auxVecs_.size(); i++) {
2015 tmp = orthman_->orthogError(*X_,*auxVecs_[i]);
2016 os <<
" >> Error in X^H M Q[" << i <<
"] == 0 : " << tmp << endl;
2019 if (chk.checkMX && hasM_ && initialized_) {
2020 tmp = Utils::errorEquality(*X_, *MX_, MOp_);
2021 os <<
" >> Error in MX == M*X : " << tmp << endl;
2023 if (chk.checkKX && initialized_) {
2024 tmp = Utils::errorEquality(*X_, *KX_, Op_);
2025 os <<
" >> Error in KX == K*X : " << tmp << endl;
2029 if (chk.checkP && hasP_ && initialized_) {
2031 tmp = orthman_->orthonormError(*P_);
2032 os <<
" >> Error in P^H M P == I : " << tmp << endl;
2033 tmp = orthman_->orthogError(*P_,*X_);
2034 os <<
" >> Error in P^H M X == 0 : " << tmp << endl;
2036 for (Array_size_type i=0; i<auxVecs_.size(); i++) {
2037 tmp = orthman_->orthogError(*P_,*auxVecs_[i]);
2038 os <<
" >> Error in P^H M Q[" << i <<
"] == 0 : " << tmp << endl;
2041 if (chk.checkMP && hasM_ && hasP_ && initialized_) {
2042 tmp = Utils::errorEquality(*P_, *MP_, MOp_);
2043 os <<
" >> Error in MP == M*P : " << tmp << endl;
2045 if (chk.checkKP && hasP_ && initialized_) {
2046 tmp = Utils::errorEquality(*P_, *KP_, Op_);
2047 os <<
" >> Error in KP == K*P : " << tmp << endl;
2051 if (chk.checkH && initialized_) {
2053 tmp = orthman_->orthonormError(*H_);
2054 os <<
" >> Error in H^H M H == I : " << tmp << endl;
2055 tmp = orthman_->orthogError(*H_,*X_);
2056 os <<
" >> Error in H^H M X == 0 : " << tmp << endl;
2058 tmp = orthman_->orthogError(*H_,*P_);
2059 os <<
" >> Error in H^H M P == 0 : " << tmp << endl;
2062 for (Array_size_type i=0; i<auxVecs_.size(); i++) {
2063 tmp = orthman_->orthogError(*H_,*auxVecs_[i]);
2064 os <<
" >> Error in H^H M Q[" << i <<
"] == 0 : " << tmp << endl;
2067 if (chk.checkMH && hasM_ && initialized_) {
2068 tmp = Utils::errorEquality(*H_, *MH_, MOp_);
2069 os <<
" >> Error in MH == M*H : " << tmp << endl;
2073 if (chk.checkR && initialized_) {
2075 MVT::MvTransMv(ONE,*X_,*R_,xTx);
2076 tmp = xTx.normFrobenius();
2077 MVT::MvTransMv(ONE,*R_,*R_,xTx);
2078 double normR = xTx.normFrobenius();
2079 os <<
" >> RelError in X^H R == 0: " << tmp/normR << endl;
2084 for (Array_size_type i=0; i<auxVecs_.size(); i++) {
2085 tmp = orthman_->orthonormError(*auxVecs_[i]);
2086 os <<
" >> Error in Q[" << i <<
"]^H M Q[" << i <<
"] == I : " << tmp << endl;
2087 for (Array_size_type j=i+1; j<auxVecs_.size(); j++) {
2088 tmp = orthman_->orthogError(*auxVecs_[i],*auxVecs_[j]);
2089 os <<
" >> Error in Q[" << i <<
"]^H M Q[" << j <<
"] == 0 : " << tmp << endl;
2102 template <
class ScalarType,
class MV,
class OP>
2108 os.setf(std::ios::scientific, std::ios::floatfield);
2111 os <<
"================================================================================" << endl;
2113 os <<
" LOBPCG Solver Status" << endl;
2115 os <<
"The solver is "<<(initialized_ ?
"initialized." :
"not initialized.") << endl;
2116 os <<
"The number of iterations performed is " << iter_ << endl;
2117 os <<
"The current block size is " << blockSize_ << endl;
2118 os <<
"The number of auxiliary vectors is " << numAuxVecs_ << endl;
2119 os <<
"The number of operations Op*x is " << count_ApplyOp_ << endl;
2120 os <<
"The number of operations M*x is " << count_ApplyM_ << endl;
2121 os <<
"The number of operations Prec*x is " << count_ApplyPrec_ << endl;
2123 os.setf(std::ios_base::right, std::ios_base::adjustfield);
2127 os <<
"CURRENT EIGENVALUE ESTIMATES "<<endl;
2128 os << std::setw(20) <<
"Eigenvalue"
2129 << std::setw(20) <<
"Residual(M)"
2130 << std::setw(20) <<
"Residual(2)"
2132 os <<
"--------------------------------------------------------------------------------"<<endl;
2133 for (
int i=0; i<blockSize_; i++) {
2134 os << std::setw(20) << theta_[i];
2135 if (Rnorms_current_) os << std::setw(20) << Rnorms_[i];
2136 else os << std::setw(20) <<
"not current";
2137 if (R2norms_current_) os << std::setw(20) << R2norms_[i];
2138 else os << std::setw(20) <<
"not current";
2142 os <<
"================================================================================" << endl;
2148 template <
class ScalarType,
class MV,
class OP>
2150 return initialized_;
2156 template <
class ScalarType,
class MV,
class OP>
2163 template <
class ScalarType,
class MV,
class OP>
2171 template <
class ScalarType,
class MV,
class OP>
2178 template <
class ScalarType,
class MV,
class OP>
2185 template <
class ScalarType,
class MV,
class OP>
2193 template <
class ScalarType,
class MV,
class OP>
2195 return 3*blockSize_;
2200 template <
class ScalarType,
class MV,
class OP>
2202 if (!initialized_)
return 0;
2209 template <
class ScalarType,
class MV,
class OP>
2210 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
2213 return this->getRes2Norms();
2219 template <
class ScalarType,
class MV,
class OP>
2221 std::vector<int> ret(nevLocal_,0);
2228 template <
class ScalarType,
class MV,
class OP>
2230 std::vector<Value<ScalarType> > ret(nevLocal_);
2231 for (
int i=0; i<nevLocal_; i++) {
2232 ret[i].realpart = theta_[i];
2233 ret[i].imagpart = ZERO;
2240 template <
class ScalarType,
class MV,
class OP>
2243 "Anasazi::LOBPCG::setStatusTest() was passed a null StatusTest.");
2249 template <
class ScalarType,
class MV,
class OP>
2256 template <
class ScalarType,
class MV,
class OP>
2264 template <
class ScalarType,
class MV,
class OP>
2272 template <
class ScalarType,
class MV,
class OP>
2280 template <
class ScalarType,
class MV,
class OP>
2292 state.
T =
Teuchos::rcp(
new std::vector<MagnitudeType>(theta_));
2300 state.
MX = Teuchos::null;
2301 state.
MP = Teuchos::null;
2302 state.
MH = Teuchos::null;
2309 #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.