12#ifndef ANASAZI_SIRTR_HPP
13#define ANASAZI_SIRTR_HPP
21#include "Teuchos_ScalarTraits.hpp"
23#include "Teuchos_LAPACK.hpp"
24#include "Teuchos_BLAS.hpp"
25#include "Teuchos_SerialDenseMatrix.hpp"
26#include "Teuchos_ParameterList.hpp"
27#include "Teuchos_TimeMonitor.hpp"
53 template <
class ScalarType,
class MV,
class OP>
72 const Teuchos::RCP<
SortManager<
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > &
sorter,
76 Teuchos::ParameterList &
params
107 typedef Teuchos::ScalarTraits<ScalarType> SCT;
108 typedef typename SCT::magnitudeType MagnitudeType;
109 typedef Teuchos::ScalarTraits<MagnitudeType> MAT;
119 std::vector<std::string> stopReasons_;
123 const MagnitudeType ZERO;
124 const MagnitudeType ONE;
129 void solveTRSubproblem();
132 MagnitudeType rho_prime_;
135 MagnitudeType normgradf0_;
138 trRetType innerStop_;
141 int innerIters_, totalInnerIters_;
149 template <
class ScalarType,
class MV,
class OP>
152 const Teuchos::RCP<
SortManager<
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > &
sorter,
156 Teuchos::ParameterList &
params
158 RTRBase<ScalarType,MV,
OP>(
problem,
sorter,
printer,
tester,
ortho,
params,
"SIRTR",
true),
164 stopReasons_.push_back(
"n/a");
165 stopReasons_.push_back(
"maximum iterations");
166 stopReasons_.push_back(
"negative curvature");
167 stopReasons_.push_back(
"exceeded TR");
168 stopReasons_.push_back(
"kappa convergence");
169 stopReasons_.push_back(
"theta convergence");
171 rho_prime_ =
params.get(
"Rho Prime",0.5);
173 "Anasazi::SIRTR::constructor: rho_prime must be in (0,1).");
186 template <
class ScalarType,
class MV,
class OP>
197 using Teuchos::tuple;
199#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
200 using Teuchos::TimeMonitor;
203 typedef Teuchos::RCP<const MV>
PCMV;
204 typedef Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> >
PSDM;
206 innerStop_ = MAXIMUM_ITERATIONS;
208 const int n = MVT::GetGlobalLength(*this->eta_);
209 const int p = this->blockSize_;
210 const int d =
n*
p - (
p*
p+
p)/2;
224 const double D2 = ONE/rho_prime_ - ONE;
230 MVT::MvInit(*this->eta_ ,0.0);
245#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
248 this->orthman_->projectGen(
253 if (this->leftMost_) {
254 MVT::MvScale(*this->R_,2.0);
257 MVT::MvScale(*this->R_,-2.0);
261 r0_norm = MAT::squareroot( RTRBase<ScalarType,MV,OP>::ginner(*this->R_) );
269 MagnitudeType
tconv = MAT::pow(
r0_norm,this->conv_theta_+ONE);
270 if (this->om_->isVerbosity(
Debug)) {
271 this->om_->stream(
Debug)
282 if (this->hasPrec_ && this->olsenPrec_)
284 std::vector<int>
ind(this->blockSize_);
285 for (
int i=0;
i<this->blockSize_; ++
i)
ind[
i] = this->numAuxVecs_+
i;
286 Teuchos::RCP<MV>
PBX = MVT::CloneViewNonConst(*this->PBV_,
ind);
288#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
291 OPT::Apply(*this->Prec_,*this->BX_,*
PBX);
292 this->counterPrec_ += this->blockSize_;
303#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
306 OPT::Apply(*this->Prec_,*this->R_,*this->Z_);
307 this->counterPrec_ += this->blockSize_;
309 if (this->olsenPrec_) {
310#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
313 this->orthman_->projectGen(
320#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
323 this->orthman_->projectGen(
329 RTRBase<ScalarType,MV,OP>::ginnersep(*this->R_,*this->Z_,
z_r);
333 MVT::MvAddMv(ONE,*this->R_,ZERO,*this->R_,*this->Z_);
334 RTRBase<ScalarType,MV,OP>::ginnersep(*this->R_,
z_r);
337 if (this->om_->isVerbosity(
Debug )) {
339 typename RTRBase<ScalarType,MV,OP>::CheckList
chk;
341 if (this->hasPrec_)
chk.checkZ =
true;
342 this->om_->print(
Debug, this->accuracyCheck(
chk,
"after computing gradient") );
346 typename RTRBase<ScalarType,MV,OP>::CheckList
chk;
348 if (this->hasPrec_)
chk.checkZ =
true;
349 this->om_->print(
OrthoDetails, this->accuracyCheck(
chk,
"after computing gradient") );
353 MVT::MvAddMv(-ONE,*this->Z_,ZERO,*this->Z_,*this->delta_);
355 if (this->om_->isVerbosity(
Debug)) {
360 std::vector<MagnitudeType>
eAx(this->blockSize_),
361 d_eAe(this->blockSize_),
362 d_eBe(this->blockSize_),
363 d_mxe(this->blockSize_);
366#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
369 OPT::Apply(*this->AOp_,*this->X_,*this->Z_);
370 this->counterAOp_ += this->blockSize_;
372 RTRBase<ScalarType,MV,OP>::ginnersep(*this->eta_,*this->Z_,
eAx);
375#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
378 OPT::Apply(*this->AOp_,*this->eta_,*this->Z_);
379 this->counterAOp_ += this->blockSize_;
381 RTRBase<ScalarType,MV,OP>::ginnersep(*this->eta_,*this->Z_,
d_eAe);
384#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
387 OPT::Apply(*this->BOp_,*this->eta_,*this->Z_);
388 this->counterBOp_ += this->blockSize_;
391 MVT::MvAddMv(ONE,*this->eta_,ZERO,*this->eta_,*this->Z_);
393 RTRBase<ScalarType,MV,OP>::ginnersep(*this->eta_,*this->Z_,
d_eBe);
396 if (this->leftMost_) {
397 for (
int j=0;
j<this->blockSize_; ++
j) {
402 for (
int j=0;
j<this->blockSize_; ++
j) {
406 this->om_->stream(
Debug)
407 <<
" Debugging checks: SIRTR inner iteration " << innerIters_ <<
endl
408 <<
" >> m_X(eta) : " << std::accumulate(
d_mxe.begin(),
d_mxe.end(),0.0) <<
endl;
409 for (
int j=0;
j<this->blockSize_; ++
j) {
410 this->om_->stream(
Debug)
411 <<
" >> m_X(eta_" <<
j <<
") : " <<
d_mxe[
j] <<
endl;
418 for (innerIters_=1; innerIters_<=
d; ++innerIters_) {
426#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
429 OPT::Apply(*this->AOp_,*this->delta_,*this->Z_);
430 this->counterAOp_ += this->blockSize_;
433#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
436 OPT::Apply(*this->BOp_,*this->delta_,*this->Hdelta_);
437 this->counterBOp_ += this->blockSize_;
440 MVT::MvAddMv(ONE,*this->delta_,ZERO,*this->delta_,*this->Hdelta_);
444 RTRBase<ScalarType,MV,OP>::ginnersep(*this->eta_ ,*this->Hdelta_,
eBd);
445 RTRBase<ScalarType,MV,OP>::ginnersep(*this->delta_,*this->Hdelta_,
dBd);
448 std::vector<ScalarType>
theta_comp(this->theta_.begin(),
this->theta_.end());
451 if (this->leftMost_) {
452 MVT::MvAddMv( 2.0,*this->Z_,-2.0,*this->Hdelta_,*this->Hdelta_);
455 MVT::MvAddMv(-2.0,*this->Z_, 2.0,*this->Hdelta_,*this->Hdelta_);
459#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
462 this->orthman_->projectGen(
468 RTRBase<ScalarType,MV,OP>::ginnersep(*this->delta_,*this->Hdelta_,
d_Hd);
472 for (
unsigned int j=0;
j<
alpha.size(); ++
j)
478 for (
unsigned int j=0;
j<
alpha.size(); ++
j)
483 if (this->om_->isVerbosity(
Debug)) {
484 for (
unsigned int j=0;
j<
alpha.size();
j++) {
485 this->om_->stream(
Debug)
486 <<
" >> z_r[" <<
j <<
"] : " <<
z_r[
j]
488 <<
" >> eBe[" <<
j <<
"] : " <<
eBe[
j]
490 <<
" >> eBd[" <<
j <<
"] : " <<
eBd[
j]
491 <<
" dBd[" <<
j <<
"] : " <<
dBd[
j] <<
endl;
501 for (
unsigned int j=0;
j<
d_Hd.size(); ++
j) {
514 if (this->om_->isVerbosity(
Debug)) {
516 this->om_->stream(
Debug)
524 if (this->om_->isVerbosity(
Debug)) {
526 this->om_->stream(
Debug)
531 innerStop_ = NEGATIVE_CURVATURE;
534 innerStop_ = EXCEEDED_TR;
547 MVT::MvAddMv(ONE,*this->delta_ ,ONE,*this->eta_ ,*this->eta_);
554 if (this->om_->isVerbosity(
Debug)) {
559 std::vector<MagnitudeType>
eAx(this->blockSize_),
560 d_eAe(this->blockSize_),
561 d_eBe(this->blockSize_),
562 d_mxe(this->blockSize_);
565#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
568 OPT::Apply(*this->AOp_,*this->X_,*this->Z_);
569 this->counterAOp_ += this->blockSize_;
571 RTRBase<ScalarType,MV,OP>::ginnersep(*this->eta_,*this->Z_,
eAx);
574#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
577 OPT::Apply(*this->AOp_,*this->eta_,*this->Z_);
578 this->counterAOp_ += this->blockSize_;
580 RTRBase<ScalarType,MV,OP>::ginnersep(*this->eta_,*this->Z_,
d_eAe);
583#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
586 OPT::Apply(*this->BOp_,*this->eta_,*this->Z_);
587 this->counterBOp_ += this->blockSize_;
590 MVT::MvAddMv(ONE,*this->eta_,ZERO,*this->eta_,*this->Z_);
592 RTRBase<ScalarType,MV,OP>::ginnersep(*this->eta_,*this->Z_,
d_eBe);
595 if (this->leftMost_) {
596 for (
int j=0;
j<this->blockSize_; ++
j) {
601 for (
int j=0;
j<this->blockSize_; ++
j) {
605 this->om_->stream(
Debug)
606 <<
" Debugging checks: SIRTR inner iteration " << innerIters_ <<
endl
607 <<
" >> m_X(eta) : " << std::accumulate(
d_mxe.begin(),
d_mxe.end(),0.0) <<
endl;
608 for (
int j=0;
j<this->blockSize_; ++
j) {
609 this->om_->stream(
Debug)
610 <<
" >> m_X(eta_" <<
j <<
") : " <<
d_mxe[
j] <<
endl;
624 MVT::MvAddMv(ONE,*this->Hdelta_,ONE,*this->R_,*this->R_);
627#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
630 this->orthman_->projectGen(
639 MagnitudeType
r_norm = MAT::squareroot(RTRBase<ScalarType,MV,OP>::ginner(*this->R_,*this->R_));
647 if (this->om_->isVerbosity(
Debug)) {
648 this->om_->stream(
Debug)
649 <<
" >> |r" << innerIters_ <<
"| : " <<
r_norm <<
endl;
653 innerStop_ = THETA_CONVERGENCE;
656 innerStop_ = KAPPA_CONVERGENCE;
668#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
671 OPT::Apply(*this->Prec_,*this->R_,*this->Z_);
672 this->counterPrec_ += this->blockSize_;
674 if (this->olsenPrec_) {
675#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
678 this->orthman_->projectGen(
685#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
688 this->orthman_->projectGen(
694 RTRBase<ScalarType,MV,OP>::ginnersep(*this->R_,*this->Z_,
z_r);
698 MVT::MvAddMv(ONE,*this->R_,ZERO,*this->R_,*this->Z_);
699 RTRBase<ScalarType,MV,OP>::ginnersep(*this->R_,
z_r);
715 for (
unsigned int j=0;
j<
beta.size(); ++
j) {
722 MVT::MvAddMv(-ONE,*this->Z_,ONE,*this->delta_,*this->delta_);
728 if (innerIters_ >
d) innerIters_ =
d;
730 this->om_->stream(
Debug)
731 <<
" >> stop reason is " << stopReasons_[innerStop_] <<
endl
737#define SIRTR_GET_TEMP_MV(mv,workspace) \
739 TEUCHOS_TEST_FOR_EXCEPTION(workspace.size() == 0,std::logic_error,"SIRTR: Request for workspace could not be honored."); \
740 mv = workspace.back(); \
741 workspace.pop_back(); \
744#define SIRTR_RELEASE_TEMP_MV(mv,workspace) \
746 workspace.push_back(mv); \
747 mv = Teuchos::null; \
753 template <
class ScalarType,
class MV,
class OP>
758 using Teuchos::tuple;
759 using Teuchos::TimeMonitor;
767 if (this->initialized_ ==
false) {
771 Teuchos::SerialDenseMatrix<int,ScalarType>
AA(this->blockSize_,this->blockSize_),
772 BB(this->blockSize_,this->blockSize_),
773 S(this->blockSize_,this->blockSize_);
787 innerStop_ = UNINITIALIZED;
790 while (this->tester_->checkStatus(
this) !=
Passed) {
793 if (this->om_->isVerbosity(
Debug)) {
794 this->currentStatus( this->om_->stream(
Debug) );
805 totalInnerIters_ += innerIters_;
808 if (this->om_->isVerbosity(
Debug ) ) {
813 this->om_->print(
Debug, this->accuracyCheck(
chk,
"in iterate() after solveTRSubproblem()") );
827 SIRTR_RELEASE_TEMP_MV(this->delta_ ,
workspace);
828 SIRTR_RELEASE_TEMP_MV(this->Hdelta_,
workspace);
829 SIRTR_RELEASE_TEMP_MV(this->R_ ,
workspace);
830 SIRTR_RELEASE_TEMP_MV(this->Z_ ,
workspace);
838#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
841 MVT::MvAddMv(ONE,*this->X_,ONE,*this->eta_,*
XpEta);
848 MagnitudeType
oldfx = this->fx_;
850 rank = this->blockSize_;
856#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
860 this->counterAOp_ += this->blockSize_;
864#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
875#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
879 this->counterBOp_ += this->blockSize_;
883#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
891#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
896 this->om_->stream(
Debug) <<
"AA: " << std::endl <<
printMat(
AA) << std::endl;;
897 this->om_->stream(
Debug) <<
"BB: " << std::endl <<
printMat(
BB) << std::endl;;
900 std::vector<MagnitudeType>
oldtheta(this->theta_);
902#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
905 ret = Utils::directSolver(this->blockSize_,
AA,Teuchos::rcpFromRef(
BB),S,this->theta_,
rank,1);
907 this->om_->stream(
Debug) <<
"S: " << std::endl <<
printMat(S) << std::endl;;
915#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
918 std::vector<int>
order(this->blockSize_);
920 this->sm_->sort(this->theta_, Teuchos::rcpFromRef(
order), this->blockSize_);
922 Utils::permuteVectors(
order,S);
926 this->fx_ = std::accumulate(this->theta_.begin(),
this->theta_.end(),ZERO);
932 if (this->om_->isVerbosity(
Debug ) ) {
954#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
957 OPT::Apply(*this->AOp_,*this->eta_,*AX);
958 this->counterAOp_ += this->blockSize_;
964#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
967 OPT::Apply(*this->BOp_,*this->eta_,*AX);
968 this->counterBOp_ += this->blockSize_;
972 MVT::MvAddMv(ONE,*this->eta_,ZERO,*this->eta_,*AX);
975 std::vector<MagnitudeType>
eBe(this->blockSize_);
985#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
988 OPT::Apply(*this->AOp_,*this->X_,*AX);
989 this->counterAOp_ += this->blockSize_;
996 this->om_->stream(
Debug)
998 <<
" >> new f(x) is : " << this->fx_ <<
endl
1002 <<
" >> rho is : " << this->rho_ <<
endl;
1004 for (
int j=0;
j<this->blockSize_; ++
j) {
1005 this->om_->stream(
Debug)
1006 <<
" >> rho[" <<
j <<
"] : " << 1.0/(1.0+
eBe[
j]) <<
endl;
1013 this->X_ = Teuchos::null;
1014 this->BX_ = Teuchos::null;
1016 std::vector<int>
ind(this->blockSize_);
1017 for (
int i=0;
i<this->blockSize_; ++
i)
ind[
i] = this->numAuxVecs_+
i;
1018 Teuchos::RCP<MV> X, BX;
1019 X = MVT::CloneViewNonConst(*this->V_,
ind);
1020 if (this->hasBOp_) {
1021 BX = MVT::CloneViewNonConst(*this->BV_,
ind);
1025#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1028 MVT::MvTimesMatAddMv(ONE,*
XpEta,S,ZERO,*X);
1029 MVT::MvTimesMatAddMv(ONE,*
AXpEta,S,ZERO,*AX);
1030 if (this->hasBOp_) {
1031 MVT::MvTimesMatAddMv(ONE,*
BXpEta,S,ZERO,*BX);
1037 this->X_ = MVT::CloneView(
static_cast<const MV&
>(*this->V_ ),
ind);
1038 this->BX_ = MVT::CloneView(
static_cast<const MV&
>(*this->BV_),
ind);
1044 if (this->hasBOp_) {
1055#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1058 MVT::MvAddMv( ONE, *this->BX_, ZERO, *this->BX_, *this->R_ );
1060 std::vector<ScalarType>
theta_comp(this->theta_.begin(),
this->theta_.end());
1063 MVT::MvAddMv( ONE, *AX, -ONE, *this->R_, *this->R_ );
1067 this->Rnorms_current_ =
false;
1068 this->R2norms_current_ =
false;
1075 SIRTR_GET_TEMP_MV(this->delta_,
workspace);
1076 SIRTR_GET_TEMP_MV(this->Hdelta_,
workspace);
1081 if (this->om_->isVerbosity(
Debug ) ) {
1087 this->om_->print(
Debug, this->accuracyCheck(
chk,
"after local update") );
1093 this->om_->print(
OrthoDetails, this->accuracyCheck(
chk,
"after local update") );
1103 template <
class ScalarType,
class MV,
class OP>
1108 os.setf(std::ios::scientific, std::ios::floatfield);
1111 os <<
"================================================================================" <<
endl;
1113 os <<
" SIRTR Solver Status" <<
endl;
1115 os <<
"The solver is "<<(this->initialized_ ?
"initialized." :
"not initialized.") <<
endl;
1116 os <<
"The number of iterations performed is " << this->iter_ <<
endl;
1117 os <<
"The current block size is " << this->blockSize_ <<
endl;
1118 os <<
"The number of auxiliary vectors is " << this->numAuxVecs_ <<
endl;
1119 os <<
"The number of operations A*x is " << this->counterAOp_ <<
endl;
1120 os <<
"The number of operations B*x is " << this->counterBOp_ <<
endl;
1121 os <<
"The number of operations B*x by the orthomanager is " << this->orthman_->getOpCounter() <<
endl;
1122 os <<
"The number of operations Prec*x is " << this->counterPrec_ <<
endl;
1123 os <<
"Parameter rho_prime is " << rho_prime_ <<
endl;
1124 os <<
"Inner stopping condition was " << stopReasons_[innerStop_] <<
endl;
1125 os <<
"Number of inner iterations was " << innerIters_ <<
endl;
1126 os <<
"Total number of inner iterations is " << totalInnerIters_ <<
endl;
1127 os <<
"f(x) is " << this->fx_ <<
endl;
1129 os.setf(std::ios_base::right, std::ios_base::adjustfield);
1131 if (this->initialized_) {
1133 os <<
"CURRENT EIGENVALUE ESTIMATES "<<
endl;
1134 os << std::setw(20) <<
"Eigenvalue"
1135 << std::setw(20) <<
"Residual(B)"
1136 << std::setw(20) <<
"Residual(2)"
1138 os <<
"--------------------------------------------------------------------------------"<<
endl;
1139 for (
int i=0;
i<this->blockSize_;
i++) {
1140 os << std::setw(20) << this->theta_[
i];
1141 if (this->Rnorms_current_)
os << std::setw(20) << this->Rnorms_[
i];
1142 else os << std::setw(20) <<
"not current";
1143 if (this->R2norms_current_)
os << std::setw(20) << this->R2norms_[
i];
1144 else os << std::setw(20) <<
"not current";
1148 os <<
"================================================================================" <<
endl;
Pure virtual base class which describes the basic interface to the iterative eigensolver.
Declaration of basic traits for the multivector type.
Virtual base class which defines basic traits for the operator type.
Base class for Implicit Riemannian Trust-Region solvers.
Types and exceptions used within Anasazi solvers and interfaces.
Anasazi's templated virtual class for constructing an operator that can interface with the OperatorTr...
Operator()
Default constructor.
This class is an abstract base class for Implicit Riemannian Trust-Region based eigensolvers....
RTRRitzFailure is thrown when the RTR solver is unable to continue a call to RTRBase::iterate() due t...
virtual ~SIRTR()
SIRTR destructor
void currentStatus(std::ostream &os)
Impemements Eigensolver. This method requests that the solver print out its current status to screen.
void iterate()
Impemements Eigensolver. The outer IRTR iteration. See RTRBase::iterate().
SIRTR(const Teuchos::RCP< Eigenproblem< ScalarType, MV, OP > > &problem, const Teuchos::RCP< SortManager< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > > &sorter, const Teuchos::RCP< OutputManager< ScalarType > > &printer, const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > &tester, const Teuchos::RCP< GenOrthoManager< ScalarType, MV, OP > > &ortho, Teuchos::ParameterList ¶ms)
SIRTR constructor with eigenproblem, solver utilities, and parameter list of solver options.
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.