33#ifndef ANASAZI_LOBPCG_HPP
34#define ANASAZI_LOBPCG_HPP
41#include "Teuchos_ScalarTraits.hpp"
46#include "Teuchos_LAPACK.hpp"
47#include "Teuchos_BLAS.hpp"
48#include "Teuchos_SerialDenseMatrix.hpp"
49#include "Teuchos_ParameterList.hpp"
50#include "Teuchos_TimeMonitor.hpp"
81 template <
class ScalarType,
class MultiVector>
84 Teuchos::RCP<const MultiVector>
V;
86 Teuchos::RCP<const MultiVector>
KV;
88 Teuchos::RCP<const MultiVector>
MV;
91 Teuchos::RCP<const MultiVector>
X;
93 Teuchos::RCP<const MultiVector>
KX;
95 Teuchos::RCP<const MultiVector>
MX;
98 Teuchos::RCP<const MultiVector>
P;
100 Teuchos::RCP<const MultiVector>
KP;
102 Teuchos::RCP<const MultiVector>
MP;
108 Teuchos::RCP<const MultiVector>
H;
110 Teuchos::RCP<const MultiVector>
KH;
112 Teuchos::RCP<const MultiVector>
MH;
115 Teuchos::RCP<const MultiVector>
R;
118 Teuchos::RCP<const std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> >
T;
189 template <
class ScalarType,
class MV,
class OP>
204 const Teuchos::RCP<
SortManager<
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > &
sorter,
208 Teuchos::ParameterList &
params
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();
399 Teuchos::RCP<StatusTest<ScalarType,MV,OP> >
getStatusTest()
const;
434 Teuchos::Array<Teuchos::RCP<const MV> >
getAuxVecs()
const;
475 typedef Teuchos::ScalarTraits<ScalarType> SCT;
476 typedef typename SCT::magnitudeType MagnitudeType;
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;
496 std::string accuracyCheck(
const CheckList &chk,
const std::string &where)
const;
500 const Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > problem_;
501 const Teuchos::RCP<SortManager<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > sm_;
502 const Teuchos::RCP<OutputManager<ScalarType> > om_;
503 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > tester_;
504 const Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > orthman_;
508 Teuchos::RCP<const OP> Op_;
509 Teuchos::RCP<const OP> MOp_;
510 Teuchos::RCP<const OP> Prec_;
515 Teuchos::RCP<Teuchos::Time> timerOp_, timerMOp_, timerPrec_,
517 timerLocalProj_, timerDS_,
518 timerLocalUpdate_, timerCompRes_,
519 timerOrtho_, timerInit_;
524 int count_ApplyOp_, count_ApplyM_, count_ApplyPrec_;
553 Teuchos::RCP<MV> V_, KV_, MV_, R_;
555 Teuchos::RCP<MV> X_, KX_, MX_,
569 Teuchos::RCP<MV> tmpmvec_;
572 Teuchos::Array<Teuchos::RCP<const MV> > auxVecs_;
579 std::vector<MagnitudeType> theta_, Rnorms_, R2norms_;
582 bool Rnorms_current_, R2norms_current_;
591 template <
class ScalarType,
class MV,
class OP>
594 const Teuchos::RCP<
SortManager<
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > &
sorter,
598 Teuchos::ParameterList &
params
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
673 Teuchos::TimeMonitor
lcltimer( *timerInit_ );
680 Teuchos::RCP<const MV>
tmp;
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_) {
724 Teuchos::RCP<const MV>
src;
750 theta_.resize(3*
newBS);
751 Rnorms_.resize(
newBS);
752 R2norms_.resize(
newBS);
800 initialized_ =
false;
819 theta_.resize(3*
newBS,NANVAL);
820 Rnorms_.resize(
newBS,NANVAL);
821 R2norms_.resize(
newBS,NANVAL);
836 tmpmvec_ = Teuchos::null;
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
948 Teuchos::TimeMonitor
inittimer( *timerInit_ );
951 std::vector<int>
bsind(blockSize_);
952 for (
int i=0;
i<blockSize_;
i++)
bsind[
i] =
i;
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.");
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.");
999#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1000 Teuchos::TimeMonitor
lcltimer( *timerMOp_ );
1002 OPT::Apply(*MOp_,*X_,*MX_);
1003 count_ApplyM_ += blockSize_;
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.");
1022#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1023 Teuchos::TimeMonitor
lcltimer( *timerOp_ );
1025 OPT::Apply(*Op_,*X_,*KX_);
1026 count_ApplyOp_ += blockSize_;
1044 Teuchos::RCP<const MV>
ivec = problem_->getInitVec();
1046 "Anasazi::LOBPCG::initialize(): Eigenproblem did not specify initial vectors to clone from.");
1052 std::vector<int>
ind(blockSize_);
1053 for (
int i=0;
i<blockSize_;
i++)
ind[
i] =
i;
1067 Teuchos::RCP<MV>
rX = MVT::CloneViewNonConst(*X_,
ind);
1074#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1075 Teuchos::TimeMonitor
lcltimer( *timerMOp_ );
1077 OPT::Apply(*MOp_,*X_,*MX_);
1078 count_ApplyM_ += blockSize_;
1082 if (numAuxVecs_ > 0) {
1083#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1084 Teuchos::TimeMonitor
lcltimer( *timerOrtho_ );
1086 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > >
dummy;
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
1093 Teuchos::TimeMonitor
lcltimer( *timerOrtho_ );
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
1103 Teuchos::TimeMonitor
lcltimer( *timerOp_ );
1105 OPT::Apply(*Op_,*X_,*KX_);
1106 count_ApplyOp_ += blockSize_;
1114 theta_.resize(3*blockSize_,NANVAL);
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++) {
1121 nevLocal_ = blockSize_;
1125 Teuchos::SerialDenseMatrix<int,ScalarType> KK(blockSize_,blockSize_),
1126 MM(blockSize_,blockSize_),
1127 S(blockSize_,blockSize_);
1129#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1130 Teuchos::TimeMonitor
lcltimer( *timerLocalProj_ );
1133 MVT::MvTransMv(ONE,*X_,*KX_,KK);
1135 MVT::MvTransMv(ONE,*X_,*MX_,
MM);
1136 nevLocal_ = blockSize_;
1141#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1142 Teuchos::TimeMonitor
lcltimer( *timerDS_ );
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
1153 Teuchos::TimeMonitor
lcltimer( *timerSort_ );
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
1168 Teuchos::TimeMonitor
lcltimer( *timerLocalUpdate_ );
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_ );
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." );
1195#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1196 Teuchos::TimeMonitor
lcltimer( *timerCompRes_ );
1199 MVT::MvAddMv(ZERO,*KX_,ONE,*KX_,*R_);
1200 Teuchos::SerialDenseMatrix<int,ScalarType> T(blockSize_,blockSize_);
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;
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." );
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." );
1229#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1230 Teuchos::TimeMonitor
lcltimer( *timerOp_ );
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." );
1246#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1247 Teuchos::TimeMonitor
lcltimer( *timerMOp_ );
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_ ) {
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) {
1334 for (
int i=0;
i<blockSize_;
i++) {
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
1365 Teuchos::TimeMonitor
lcltimer( *timerPrec_ );
1367 OPT::Apply( *Prec_, *R_, *H_ );
1368 count_ApplyPrec_ += blockSize_;
1371 MVT::MvAddMv(ONE,*R_,ZERO,*R_,*H_);
1376#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1377 Teuchos::TimeMonitor
lcltimer( *timerMOp_ );
1379 OPT::Apply( *MOp_, *H_, *MH_);
1380 count_ApplyM_ += blockSize_;
1385 Teuchos::Array<Teuchos::RCP<const MV> > Q;
1396#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1397 Teuchos::TimeMonitor
lcltimer( *timerOrtho_ );
1399 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > >
dummyC =
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") );
1422#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1423 Teuchos::TimeMonitor
lcltimer( *timerOp_ );
1425 OPT::Apply( *Op_, *H_, *KH_);
1426 count_ApplyOp_ += blockSize_;
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++) {
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);
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);
1520 Teuchos::SerialDenseMatrix<int,ScalarType>
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
1529 Teuchos::TimeMonitor
lcltimer( *timerLocalProj_ );
1533 MVT::MvTransMv( ONE, *
cH, *
cK_HP ,
K2 );
1534 MVT::MvTransMv( ONE, *
cH, *
cM_HP ,
M2 );
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;
1561 Teuchos::SerialDenseMatrix<int,ScalarType>
lclKK(Teuchos::View,KK,nevLocal_,nevLocal_),
1562 lclMM(Teuchos::View,
MM,nevLocal_,nevLocal_),
1563 lclS(Teuchos::View, S,nevLocal_,nevLocal_);
1565#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1566 Teuchos::TimeMonitor
lcltimer( *timerDS_ );
1581 cXHP = 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." );
1597 Teuchos::LAPACK<int,ScalarType>
lapack;
1598 Teuchos::BLAS<int,ScalarType>
blas;
1600#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1601 Teuchos::TimeMonitor
lcltimer( *timerSort_ );
1604 std::vector<int>
order(nevLocal_);
1607 sm_->sort(theta_, Teuchos::rcpFromRef(
order), nevLocal_);
1622 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> >
CX,
CP;
1633 Teuchos::SerialDenseMatrix<int,ScalarType>
C(nevLocal_,
twoBlocks),
1672 "Anasazi::LOBPCG::iterate(): Logic error calling SerialDenseMatrix::multiply");
1676 "Anasazi::LOBPCG::iterate(): Logic error calling SerialDenseMatrix::multiply");
1686 Teuchos::SerialDenseMatrix<int,ScalarType>
K22(Teuchos::View,KK,blockSize_,blockSize_,1*blockSize_,1*blockSize_);
1687 Teuchos::SerialDenseMatrix<int,ScalarType>
K22_trans(
K22, Teuchos::CONJ_TRANS );
1690 MagnitudeType
tol = SCT::magnitude(SCT::squareroot(SCT::eps()));
1692 cXHP = Teuchos::null;
1693 cHP = Teuchos::null;
1695 cK_HP = Teuchos::null;
1697 cM_HP = Teuchos::null;
1700 std::string
errMsg =
"Anasazi::LOBPCG::iterate(): Cholesky factorization failed during full orthogonalization.";
1707 errMsg +=
" Check the operator A (or K), it may not be Hermitian!";
1713 blas.TRSM(Teuchos::RIGHT_SIDE,Teuchos::UPPER_TRI,Teuchos::NO_TRANS,Teuchos::NON_UNIT_DIAG,
1716 CX = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::Copy,
C,nevLocal_,
oneBlock,0,0) );
1718 CP = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::Copy,
C,nevLocal_,
oneBlock,0,
oneBlock) );
1721 if (om_->isVerbosity(
Debug ) ) {
1722 Teuchos::SerialDenseMatrix<int,ScalarType>
tmp1(nevLocal_,
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");
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");
1758 os <<
" >> Error in CP^H MM CP == I : " <<
tmp << std::endl;
1769 os <<
" >> Error in CX^H MM CP == 0 : " <<
tmp << std::endl;
1787 CX = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::Copy,
lclS,nevLocal_ ,
oneBlock,0 ,0) );
1797#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1798 Teuchos::TimeMonitor
lcltimer( *timerLocalUpdate_ );
1826 MVT::MvTimesMatAddMv(ONE,*
cXHP,*
CX,ZERO,*tmpmvec_);
1827 MVT::MvTimesMatAddMv(ONE,*
cXHP,*
CP,ZERO,*R_);
1828 cXHP = Teuchos::null;
1832 MVT::MvTimesMatAddMv(ONE,*
cK_XHP,*
CX,ZERO,*tmpmvec_);
1833 MVT::MvTimesMatAddMv(ONE,*
cK_XHP,*
CP,ZERO,*R_);
1835 MVT::SetBlock(*tmpmvec_,
indblock1,*KV_);
1839 MVT::MvTimesMatAddMv(ONE,*
cM_XHP,*
CX,ZERO,*tmpmvec_);
1840 MVT::MvTimesMatAddMv(ONE,*
cM_XHP,*
CP,ZERO,*R_);
1842 MVT::SetBlock(*tmpmvec_,
indblock1,*MV_);
1851 MVT::MvTimesMatAddMv(ONE,*
cXHP,*
CX,ZERO,*R_);
1852 cXHP = Teuchos::null;
1854 MVT::MvTimesMatAddMv(ONE,*
cHP,*
CP,ZERO,*R_);
1855 cHP = Teuchos::null;
1858 MVT::MvTimesMatAddMv(ONE,*
cK_XHP,*
CX,ZERO,*R_);
1861 MVT::MvTimesMatAddMv(ONE,*
cK_HP,*
CP,ZERO,*R_);
1862 cK_HP = Teuchos::null;
1866 MVT::MvTimesMatAddMv(ONE,*
cM_XHP,*
CX,ZERO,*R_);
1869 MVT::MvTimesMatAddMv(ONE,*
cM_HP,*
CP,ZERO,*R_);
1870 cM_HP = 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
1903 Teuchos::TimeMonitor
lcltimer( *timerCompRes_ );
1905 MVT::MvAddMv( ONE, *KX_, ZERO, *KX_, *R_ );
1906 Teuchos::SerialDenseMatrix<int,ScalarType> T( blockSize_, blockSize_ );
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;
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_) {
2074 Teuchos::SerialDenseMatrix<int,ScalarType>
xTx(blockSize_,blockSize_);
2075 MVT::MvTransMv(ONE,*X_,*R_,
xTx);
2076 tmp =
xTx.normFrobenius();
2077 MVT::MvTransMv(ONE,*R_,*R_,
xTx);
2078 double normR =
xTx.normFrobenius();
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;
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.
The Eigensolver is a templated virtual base class that defines the basic interface that any eigensolv...
LOBPCGInitFailure is thrown when the LOBPCG solver is unable to generate an initial iterate in the LO...
LOBPCGOrthoFailure is thrown when an orthogonalization attempt fails.
LOBPCGRitzFailure is thrown when the LOBPCG solver is unable to continue a call to LOBPCG::iterate() ...
This class provides the Locally Optimal Block Preconditioned Conjugate Gradient (LOBPCG) iteration,...
void iterate()
This method performs LOBPCG iterations until the status test indicates the need to stop or an error o...
std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > getRitzRes2Norms()
Get the 2-norms of the residuals.
void setStatusTest(Teuchos::RCP< StatusTest< ScalarType, MV, OP > > test)
Set a new StatusTest for the solver.
virtual ~LOBPCG()
LOBPCG destructor
void resetNumIters()
Reset the iteration count.
void setBlockSize(int blockSize)
Set the blocksize to be used by the iterative solver in solving this eigenproblem.
std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > getResNorms()
Get the current residual norms.
Teuchos::RCP< const MV > getRitzVectors()
Get the Ritz vectors from the previous iteration.
void initialize()
Initialize the solver with the initial vectors from the eigenproblem or random data.
void setFullOrtho(bool fullOrtho)
Instruct the LOBPCG iteration to use full orthogonality.
const Eigenproblem< ScalarType, MV, OP > & getProblem() const
Get a constant reference to the eigenvalue problem.
void currentStatus(std::ostream &os)
This method requests that the solver print out its current status to screen.
std::vector< int > getRitzIndex()
Get the index used for extracting Ritz vectors from getRitzVectors().
Teuchos::RCP< StatusTest< ScalarType, MV, OP > > getStatusTest() const
Get the current StatusTest used by the solver.
int getCurSubspaceDim() const
Get the dimension of the search subspace used to generate the current eigenvectors and eigenvalues.
std::vector< Value< ScalarType > > getRitzValues()
Get the Ritz values from the previous iteration.
std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > getRes2Norms()
Get the current residual 2-norms.
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.
void setAuxVecs(const Teuchos::Array< Teuchos::RCP< const MV > > &auxvecs)
Set the auxiliary vectors for the solver.
int getBlockSize() const
Get the blocksize to be used by the iterative solver in solving this eigenproblem.
int getNumIters() const
Get the current iteration count.
int getMaxSubspaceDim() const
Get the maximum dimension allocated for the search subspace. For LOBPCG, this always returns 3*getBlo...
bool getFullOrtho() const
Determine if the LOBPCG iteration is using full orthogonality.
LOBPCGState< ScalarType, MV > getState() const
Get the current state of the eigensolver.
bool isInitialized() const
Indicates whether the solver has been initialized or not.
Teuchos::Array< Teuchos::RCP< const MV > > getAuxVecs() const
Get the current auxiliary vectors.
bool hasP()
Indicates whether the search direction given by getState() is valid.
Anasazi's templated virtual class for constructing an operator that can interface with the OperatorTr...
Operator()
Default constructor.
Anasazi's templated pure virtual class for managing the sorting of approximate eigenvalues computed b...
Namespace Anasazi contains the classes, structs, enums and utilities used by the Anasazi package.
Structure to contain pointers to Anasazi state variables.
Teuchos::RCP< const MultiVector > KH
The image of the current preconditioned residual vectors under K.
Teuchos::RCP< const MultiVector > X
The current eigenvectors.
Teuchos::RCP< const MultiVector > KV
The image of the current test basis under K.
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 > V
The current test basis.
Teuchos::RCP< const MultiVector > KX
The image of the current eigenvectors under K.
Teuchos::RCP< const MultiVector > R
The current residual vectors.
Teuchos::RCP< const MultiVector > MP
The image of the current search direction under M, or Teuchos::null if M was not specified.
Teuchos::RCP< const std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > > T
The current Ritz values.
Teuchos::RCP< const MultiVector > MV
The image of the current test basis under M, or Teuchos::null if M was not specified.
Teuchos::RCP< const MultiVector > H
The current preconditioned residual vectors.
Teuchos::RCP< const MultiVector > P
The current search direction.
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.