14#ifndef ANASAZI_BLOCK_KRYLOV_SCHUR_HPP
15#define ANASAZI_BLOCK_KRYLOV_SCHUR_HPP
22#include "Teuchos_ScalarTraits.hpp"
23#include "AnasaziHelperTraits.hpp"
27#include "Teuchos_LAPACK.hpp"
28#include "Teuchos_BLAS.hpp"
29#include "Teuchos_SerialDenseMatrix.hpp"
30#include "Teuchos_ParameterList.hpp"
31#include "Teuchos_TimeMonitor.hpp"
56 template <
class ScalarType,
class MulVec>
64 Teuchos::RCP<const MulVec>
V;
70 Teuchos::RCP<const Teuchos::SerialDenseMatrix<int,ScalarType> >
H;
72 Teuchos::RCP<const Teuchos::SerialDenseMatrix<int,ScalarType> >
S;
74 Teuchos::RCP<const Teuchos::SerialDenseMatrix<int,ScalarType> >
Q;
114 template <
class ScalarType,
class MV,
class OP>
132 const Teuchos::RCP<
SortManager<
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > &
sorter,
136 Teuchos::ParameterList &
params
217 state.curDim = curDim_;
254 std::vector<Value<ScalarType> >
ret = ritzValues_;
255 ret.resize(ritzIndex_.size());
270 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
getResNorms() {
271 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
ret(0);
279 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
getRes2Norms() {
280 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
ret(0);
288 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
getRitzRes2Norms() {
289 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
ret = ritzResiduals_;
290 ret.resize(ritzIndex_.size());
303 Teuchos::RCP<StatusTest<ScalarType,MV,OP> >
getStatusTest()
const;
340 if (!initialized_)
return 0;
345 int getMaxSubspaceDim()
const {
return (problem_->isHermitian()?blockSize_*numBlocks_:blockSize_*numBlocks_+1); }
363 Teuchos::Array<Teuchos::RCP<const MV> >
getAuxVecs()
const {
return auxVecs_;}
409 typedef Teuchos::ScalarTraits<ScalarType> SCT;
410 typedef typename SCT::magnitudeType MagnitudeType;
411 typedef typename std::vector<ScalarType>::iterator STiter;
412 typedef typename std::vector<MagnitudeType>::iterator MTiter;
413 const MagnitudeType MT_ONE;
414 const MagnitudeType MT_ZERO;
415 const MagnitudeType NANVAL;
416 const ScalarType ST_ONE;
417 const ScalarType ST_ZERO;
430 std::string accuracyCheck(
const CheckList &chk,
const std::string &where)
const;
431 void sortSchurForm( Teuchos::SerialDenseMatrix<int,ScalarType>& H,
432 Teuchos::SerialDenseMatrix<int,ScalarType>& Q,
433 std::vector<int>& order );
437 const Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > problem_;
438 const Teuchos::RCP<SortManager<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > sm_;
439 const Teuchos::RCP<OutputManager<ScalarType> > om_;
440 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > tester_;
441 const Teuchos::RCP<OrthoManager<ScalarType,MV> > orthman_;
445 Teuchos::RCP<const OP> Op_;
449 Teuchos::RCP<Teuchos::Time> timerOp_, timerSortRitzVal_,
450 timerCompSF_, timerSortSF_,
451 timerCompRitzVec_, timerOrtho_;
485 Teuchos::RCP<MV> ritzVectors_, V_;
491 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > H_;
496 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > schurH_;
497 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > Q_;
500 Teuchos::Array<Teuchos::RCP<const MV> > auxVecs_;
507 bool ritzVecsCurrent_, ritzValsCurrent_, schurCurrent_;
510 std::vector<Value<ScalarType> > ritzValues_;
511 std::vector<MagnitudeType> ritzResiduals_;
514 std::vector<int> ritzIndex_;
515 std::vector<int> ritzOrder_;
524 template <
class ScalarType,
class MV,
class OP>
527 const Teuchos::RCP<
SortManager<
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > &
sorter,
531 Teuchos::ParameterList &
params
550 timerCompRitzVec_(Teuchos::
TimeMonitor::
getNewTimer(
"Anasazi: BlockKrylovSchur::Computing Ritz vectors")),
561 auxVecs_( Teuchos::
Array<Teuchos::RCP<
const MV> >(0) ),
564 ritzVecsCurrent_(
false),
565 ritzValsCurrent_(
false),
566 schurCurrent_(
false),
570 "Anasazi::BlockKrylovSchur::constructor: user specified null problem pointer.");
572 "Anasazi::BlockKrylovSchur::constructor: user passed null sort manager pointer.");
574 "Anasazi::BlockKrylovSchur::constructor: user passed null output manager pointer.");
576 "Anasazi::BlockKrylovSchur::constructor: user passed null status test pointer.");
578 "Anasazi::BlockKrylovSchur::constructor: user passed null orthogonalization manager pointer.");
580 "Anasazi::BlockKrylovSchur::constructor: user specified problem is not set.");
582 "Anasazi::BlockKrylovSchur::constructor: user specified null sort manager pointer.");
584 "Anasazi::BlockKrylovSchur::constructor: user specified null output manager pointer.");
586 "Anasazi::BlockKrylovSchur::constructor: user specified null status test pointer.");
588 "Anasazi::BlockKrylovSchur::constructor: user specified null ortho manager pointer.");
591 Op_ = problem_->getOperator();
595 "Anasazi::BlockKrylovSchur::constructor: mandatory parameter 'Step Size' is not specified.");
596 int ss =
params.get(
"Step Size",numBlocks_);
600 int bs =
params.get(
"Block Size", 1);
601 int nb =
params.get(
"Num Blocks", 3*problem_->getNEV());
610 numRitzPrint_ =
params.get(
"Print Number of Ritz Values",
bs);
617 template <
class ScalarType,
class MV,
class OP>
626 template <
class ScalarType,
class MV,
class OP>
635 template <
class ScalarType,
class MV,
class OP>
646 ritzVectors_ = Teuchos::null;
649 ritzVectors_ = Teuchos::null;
652 ritzVecsCurrent_ =
false;
658 template <
class ScalarType,
class MV,
class OP>
674 Teuchos::RCP<const MV>
tmp;
680 if (problem_->getInitVec() != Teuchos::null) {
681 tmp = problem_->getInitVec();
686 "Anasazi::BlockKrylovSchur::setSize(): eigenproblem did not specify initial vectors to clone from.");
694 if (problem_->isHermitian()) {
695 newsd = blockSize_*numBlocks_;
697 newsd = blockSize_*numBlocks_+1;
701 "Anasazi::BlockKrylovSchur::setSize(): maximum basis size is larger than problem dimension.");
703 ritzValues_.resize(
newsd);
704 ritzResiduals_.resize(
newsd,MT_ONE);
705 ritzOrder_.resize(
newsd);
707 V_ = MVT::Clone(*
tmp,
newsd+blockSize_);
708 H_ = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(
newsd+blockSize_,
newsd) );
709 Q_ = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(
newsd,
newsd) );
711 initialized_ =
false;
718 template <
class ScalarType,
class MV,
class OP>
725 if (om_->isVerbosity(
Debug ) ) {
729 om_->print(
Debug, accuracyCheck(
chk,
": in setAuxVecs()") );
733 for (
tarcpmv i=auxVecs_.begin();
i != auxVecs_.end();
i++) {
734 numAuxVecs_ += MVT::GetNumberVecs(**
i);
738 if (numAuxVecs_ > 0 && initialized_) {
739 initialized_ =
false;
752 template <
class ScalarType,
class MV,
class OP>
757 std::vector<int>
bsind(blockSize_);
758 for (
int i=0;
i<blockSize_;
i++)
bsind[
i] =
i;
766 std::string
errstr(
"Anasazi::BlockKrylovSchur::initialize(): specified multivectors must have a consistent length and width.");
775 std::invalid_argument,
errstr );
778 std::invalid_argument,
errstr );
780 std::invalid_argument,
errstr );
783 std::invalid_argument,
errstr );
791 if (curDim_ == 0 &&
lclDim > blockSize_) {
792 om_->stream(
Warnings) <<
"Anasazi::BlockKrylovSchur::initialize(): the solver was initialized with a kernel of " <<
lclDim << std::endl
793 <<
"The block size however is only " << blockSize_ << std::endl
794 <<
"The last " <<
lclDim - blockSize_ <<
" vectors of the kernel will be overwritten on the first call to iterate()." << std::endl;
807 H_->putScalar( ST_ZERO );
808 Teuchos::SerialDenseMatrix<int,ScalarType>
newH(Teuchos::View,*
newstate.H,curDim_+blockSize_,curDim_);
809 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> >
lclH;
810 lclH = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::View,*H_,curDim_+blockSize_,curDim_) );
814 lclH = Teuchos::null;
821 Teuchos::RCP<const MV>
ivec = problem_->getInitVec();
823 "Anasazi::BlockKrylovSchur::initialize(): eigenproblem did not specify initial vectors to clone from.");
827 if (
lclDim < blockSize_) {
839 Teuchos::RCP<MV>
newV1 = MVT::CloneViewNonConst(*V_,
dimind2);
849 Teuchos::RCP<MV>
newV2 = MVT::CloneViewNonConst(*V_,
dimind2);
850 MVT::MvRandom(*
newV2);
854 Teuchos::RCP<MV>
newV1 = MVT::CloneViewNonConst(*V_,
bsind);
864 Teuchos::RCP<MV>
newV = MVT::CloneViewNonConst(*V_,
bsind);
867 if (auxVecs_.size() > 0) {
868#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
869 Teuchos::TimeMonitor
lcltimer( *timerOrtho_ );
872 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > >
dummy;
873 int rank = orthman_->projectAndNormalize(*
newV,auxVecs_);
875 "Anasazi::BlockKrylovSchur::initialize(): couldn't generate initial basis of full rank." );
878#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
879 Teuchos::TimeMonitor
lcltimer( *timerOrtho_ );
882 int rank = orthman_->normalize(*
newV);
884 "Anasazi::BlockKrylovSchur::initialize(): couldn't generate initial basis of full rank." );
891 newV = Teuchos::null;
895 ritzVecsCurrent_ =
false;
896 ritzValsCurrent_ =
false;
897 schurCurrent_ =
false;
902 if (om_->isVerbosity(
Debug ) ) {
908 om_->print(
Debug, accuracyCheck(
chk,
": after initialize()") );
912 if (om_->isVerbosity(
Debug)) {
913 currentStatus( om_->stream(
Debug) );
923 template <
class ScalarType,
class MV,
class OP>
933 template <
class ScalarType,
class MV,
class OP>
939 if (initialized_ ==
false) {
946 if (problem_->isHermitian() ==
false) {
955 while (tester_->checkStatus(
this) !=
Passed && curDim_+blockSize_ <=
searchDim) {
960 int lclDim = curDim_ + blockSize_;
963 std::vector<int>
curind(blockSize_);
965 Teuchos::RCP<MV>
Vnext = MVT::CloneViewNonConst(*V_,
curind);
969 for (
int i=0;
i<blockSize_;
i++) {
curind[
i] = curDim_ +
i; }
970 Teuchos::RCP<const MV>
Vprev = MVT::CloneView(*V_,
curind);
976#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
977 Teuchos::TimeMonitor
lcltimer( *timerOp_ );
980 count_ApplyOp_ += blockSize_;
984 Vprev = Teuchos::null;
988#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
989 Teuchos::TimeMonitor
lcltimer( *timerOrtho_ );
996 Teuchos::Array<Teuchos::RCP<const MV> >
AVprev(1,
Vprev);
999 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> >
1000 subH = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>
1001 ( Teuchos::View,*H_,
lclDim,blockSize_,0,curDim_ ) );
1002 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > >
AsubH;
1006 if (auxVecs_.size() > 0) {
1009 AsubH.append( Teuchos::null );
1016 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> >
1017 subR = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>
1018 ( Teuchos::View,*H_,blockSize_,blockSize_,
lclDim,curDim_ ) );
1026 "Anasazi::BlockKrylovSchur::iterate(): couldn't generate basis of full rank.");
1032 Vnext = Teuchos::null;
1033 curDim_ += blockSize_;
1035 ritzVecsCurrent_ =
false;
1036 ritzValsCurrent_ =
false;
1037 schurCurrent_ =
false;
1040 if (!(iter_%stepSize_)) {
1041 computeRitzValues();
1045 if (om_->isVerbosity(
Debug ) ) {
1049 chk.checkArn =
true;
1050 om_->print(
Debug, accuracyCheck(
chk,
": after local update") );
1055 om_->print(
OrthoDetails, accuracyCheck(
chk,
": after local update") );
1059 if (om_->isVerbosity(
Debug)) {
1060 currentStatus( om_->stream(
Debug) );
1084 template <
class ScalarType,
class MV,
class OP>
1087 std::stringstream
os;
1089 os.setf(std::ios::scientific, std::ios::floatfield);
1092 os <<
" Debugging checks: iteration " << iter_ <<
where << std::endl;
1095 std::vector<int>
lclind(curDim_);
1097 std::vector<int>
bsind(blockSize_);
1098 for (
int i=0;
i<blockSize_;
i++) {
bsind[
i] = curDim_ +
i; }
1101 Teuchos::RCP<MV>
lclAV;
1108 tmp = orthman_->orthonormError(*
lclV);
1109 os <<
" >> Error in V^H M V == I : " <<
tmp << std::endl;
1111 tmp = orthman_->orthonormError(*
lclF);
1112 os <<
" >> Error in F^H M F == I : " <<
tmp << std::endl;
1115 os <<
" >> Error in V^H M F == 0 : " <<
tmp << std::endl;
1117 for (Array_size_type
i=0;
i<auxVecs_.size();
i++) {
1119 tmp = orthman_->orthogError(*
lclV,*auxVecs_[
i]);
1120 os <<
" >> Error in V^H M Aux[" <<
i <<
"] == 0 : " <<
tmp << std::endl;
1122 tmp = orthman_->orthogError(*
lclF,*auxVecs_[
i]);
1123 os <<
" >> Error in F^H M Aux[" <<
i <<
"] == 0 : " <<
tmp << std::endl;
1131 lclAV = MVT::Clone(*V_,curDim_);
1133#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1134 Teuchos::TimeMonitor
lcltimer( *timerOp_ );
1140 Teuchos::SerialDenseMatrix<int,ScalarType>
subH(Teuchos::View,*H_,curDim_,curDim_);
1141 MVT::MvTimesMatAddMv( -ST_ONE, *
lclV,
subH, ST_ONE, *
lclAV );
1144 Teuchos::SerialDenseMatrix<int,ScalarType>
curB(Teuchos::View,*H_,
1145 blockSize_,curDim_, curDim_ );
1146 MVT::MvTimesMatAddMv( -ST_ONE, *
lclF,
curB, ST_ONE, *
lclAV );
1149 std::vector<MagnitudeType>
arnNorms( curDim_ );
1152 for (
int i=0;
i<curDim_;
i++) {
1153 os <<
" >> Error in Krylov-Schur factorization (R = AV-VS-FB^H), ||R[" <<
i <<
"]|| : " <<
arnNorms[
i] << std::endl;
1159 for (Array_size_type
i=0;
i<auxVecs_.size();
i++) {
1160 tmp = orthman_->orthonormError(*auxVecs_[
i]);
1161 os <<
" >> Error in Aux[" <<
i <<
"]^H M Aux[" <<
i <<
"] == I : " <<
tmp << std::endl;
1162 for (Array_size_type
j=
i+1;
j<auxVecs_.size();
j++) {
1163 tmp = orthman_->orthogError(*auxVecs_[
i],*auxVecs_[
j]);
1164 os <<
" >> Error in Aux[" <<
i <<
"]^H M Aux[" <<
j <<
"] == 0 : " <<
tmp << std::endl;
1185 template <
class ScalarType,
class MV,
class OP>
1193 if (!ritzValsCurrent_) {
1196 computeSchurForm(
false );
1213 template <
class ScalarType,
class MV,
class OP>
1216#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1217 Teuchos::TimeMonitor
LocalTimer(*timerCompRitzVec_);
1221 "Anasazi::BlockKrylovSchur::computeRitzVectors(): no Ritz vectors were required from this solver.");
1224 "Anasazi::BlockKrylovSchur::computeRitzVectors(): the current subspace is not large enough to compute the number of requested Ritz vectors.");
1228 if (curDim_ && initialized_) {
1231 if (!ritzVecsCurrent_) {
1234 if (!schurCurrent_) {
1237 computeSchurForm(
true );
1243 "Anasazi::BlockKrylovSchur::computeRitzVectors(): the number of required Ritz vectors splits a complex conjugate pair.");
1245 Teuchos::LAPACK<int,ScalarType>
lapack;
1246 Teuchos::LAPACK<int,MagnitudeType>
lapack_mag;
1256 std::vector<int>
curind( curDim_ );
1258 Teuchos::RCP<const MV>
Vtemp = MVT::CloneView( *V_,
curind );
1259 if (problem_->isHermitian()) {
1261 Teuchos::SerialDenseMatrix<int,ScalarType>
subQ( Teuchos::View, *Q_, curDim_, numRitzVecs_ );
1264 MVT::MvTimesMatAddMv( ST_ONE, *
Vtemp,
subQ, ST_ZERO, *ritzVectors_ );
1268 for (
int i=0;
i<numRitzVecs_;
i++) {
1269 if (ritzIndex_[
i] != 0) {
1275 om_->stream(
Warnings) <<
" Eigenproblem is Hermitian and complex eigenvalues have converged, corresponding eigenvectors will be incorrect!!!"
1280 Teuchos::SerialDenseMatrix<int,ScalarType>
subQ( Teuchos::View, *Q_, curDim_, curDim_ );
1294 int lwork = 3*curDim_;
1296 std::vector<MagnitudeType>
rwork( curDim_ );
1301 Teuchos::SerialDenseMatrix<int,ScalarType>
copyQ( Teuchos::Copy, *Q_, curDim_, curDim_ );
1302 lapack.TREVC(
side, curDim_, schurH_->values(), schurH_->stride(),
vl,
ldvl,
1305 "Anasazi::BlockKrylovSchur::computeRitzVectors(): TREVC(n==" << curDim_ <<
") returned info " <<
info <<
" != 0.");
1308 Teuchos::SerialDenseMatrix<int,ScalarType>
subCopyQ( Teuchos::View,
copyQ, curDim_, numRitzVecs_ );
1311 curind.resize( numRitzVecs_ );
1316 std::vector<MagnitudeType>
ritzNrm( numRitzVecs_ );
1325 for (
int i=0;
i<numRitzVecs_;
i++) {
1328 if (ritzIndex_[
i] == 1 ) {
1330 std::vector<int>
newind(2);
1341 std::vector<int>
newind(1);
1352 ritzVecsCurrent_ =
true;
1361 template <
class ScalarType,
class MV,
class OP>
1364 "Anasazi::BlockKrylovSchur::setStatusTest() was passed a null StatusTest.");
1370 template <
class ScalarType,
class MV,
class OP>
1388 template <
class ScalarType,
class MV,
class OP>
1392#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1393 Teuchos::TimeMonitor
LocalTimer(*timerCompSF_);
1400 if (!schurCurrent_) {
1404 if (!ritzValsCurrent_) {
1405 Teuchos::LAPACK<int,ScalarType>
lapack;
1406 Teuchos::LAPACK<int,MagnitudeType>
lapack_mag;
1407 Teuchos::BLAS<int,ScalarType>
blas;
1408 Teuchos::BLAS<int,MagnitudeType>
blas_mag;
1411 Teuchos::SerialDenseMatrix<int,ScalarType>
subQ( Teuchos::View, *Q_, curDim_, curDim_ );
1414 schurH_ = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::Copy, *H_, curDim_, curDim_ ) );
1428 int lwork = 3*curDim_;
1430 std::vector<MagnitudeType>
rwork( curDim_ );
1433 std::vector<int>
bwork( curDim_ );
1441 "Anasazi::BlockKrylovSchur::computeSchurForm(): GEES(n==" << curDim_ <<
") returned info " <<
info <<
" != 0.");
1448 if (problem_->isHermitian()) {
1449 for (
int i=0;
i<curDim_;
i++)
1459 om_->stream(
Warnings) <<
" Eigenproblem is Hermitian and complex eigenvalues have been detected!!!" << std::endl;
1461 Teuchos::SerialDenseMatrix<int,ScalarType>
localH( Teuchos::View, *H_, curDim_, curDim_ );
1462 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> >
tLocalH;
1463 if (Teuchos::ScalarTraits<ScalarType>::isComplex)
1464 tLocalH = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(
localH, Teuchos::CONJ_TRANS ) );
1466 tLocalH = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(
localH, Teuchos::TRANS ) );
1470 om_->stream(
Warnings) <<
" Symmetry error in projected eigenproblem: || S - S' ||_F = " <<
normF
1471 <<
", || S - S' ||_1 = " <<
norm1 << std::endl;
1489 Teuchos::SerialDenseMatrix<int,ScalarType>
curB(Teuchos::View, *H_,
1490 blockSize_, curDim_, curDim_ );
1493 Teuchos::SerialDenseMatrix<int,ScalarType>
subB( blockSize_, curDim_ );
1494 blas.GEMM( Teuchos::NO_TRANS, Teuchos::NO_TRANS, blockSize_, curDim_, curDim_, ST_ONE,
1496 ST_ZERO,
subB.values(),
subB.stride() );
1505 for (
int i=0;
i<curDim_ ;
i++) {
1506 ritzResiduals_[
i] =
blas.NRM2(blockSize_,
b_ptr +
i*blockSize_, 1);
1516 Teuchos::SerialDenseMatrix<int,ScalarType> S( curDim_, curDim_ );
1517 lapack.TREVC(
side, curDim_, schurH_->values(), schurH_->stride(),
vl,
ldvl,
1521 "Anasazi::BlockKrylovSchur::computeSchurForm(): TREVC(n==" << curDim_ <<
") returned info " <<
info <<
" != 0.");
1529 Teuchos::SerialDenseMatrix<int,ScalarType>
ritzRes( blockSize_, curDim_ );
1530 blas.GEMM( Teuchos::NO_TRANS, Teuchos::NO_TRANS, blockSize_, curDim_, curDim_, ST_ONE,
1531 subB.values(),
subB.stride(), S.values(), S.stride(),
1566#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1567 Teuchos::TimeMonitor
LocalTimer2(*timerSortRitzVal_);
1575 while (
i < curDim_ ) {
1578 ritzIndex_.push_back(0);
1590 std::vector<MagnitudeType>
ritz2( curDim_ );
1591 for (
i=0;
i<curDim_;
i++) {
ritz2[
i] = ritzResiduals_[ ritzOrder_[
i] ]; }
1592 blas_mag.COPY( curDim_, &
ritz2[0], 1, &ritzResiduals_[0], 1 );
1595 ritzValsCurrent_ =
true;
1611 sortSchurForm( *schurH_, *Q_, ritzOrder_ );
1614 schurCurrent_ =
true;
1625 template <
class ScalarType,
class MV,
class OP>
1627 Teuchos::SerialDenseMatrix<int,ScalarType>& Q,
1628 std::vector<int>&
order )
1631#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1632 Teuchos::TimeMonitor
LocalTimer(*timerSortSF_);
1645 std::vector<int>
offset2( curDim_ );
1646 std::vector<int>
order2( curDim_ );
1649 Teuchos::LAPACK<int,ScalarType>
lapack;
1650 int lwork = 3*curDim_;
1653 while (
i < curDim_) {
1654 if ( ritzIndex_[
i] != 0 ) {
1656 for (
int j=
i;
j<curDim_;
j++) {
1663 for (
int j=
i;
j<curDim_;
j++) {
1671 ScalarType *
ptr_h = H.values();
1672 ScalarType *
ptr_q = Q.values();
1673 int ldh = H.stride(),
ldq = Q.stride();
1681 "Anasazi::BlockKrylovSchur::computeSchurForm(): TREXC(n==" << curDim_ <<
") returned info " <<
info <<
" != 0.");
1687 template <
class ScalarType,
class MV,
class OP>
1692 os.setf(std::ios::scientific, std::ios::floatfield);
1694 os <<
"================================================================================" <<
endl;
1696 os <<
" BlockKrylovSchur Solver Status" <<
endl;
1698 os <<
"The solver is "<<(initialized_ ?
"initialized." :
"not initialized.") <<
endl;
1699 os <<
"The number of iterations performed is " <<iter_<<
endl;
1700 os <<
"The block size is " << blockSize_<<
endl;
1701 os <<
"The number of blocks is " << numBlocks_<<
endl;
1702 os <<
"The current basis size is " << curDim_<<
endl;
1703 os <<
"The number of auxiliary vectors is " << numAuxVecs_ <<
endl;
1704 os <<
"The number of operations Op*x is "<<count_ApplyOp_<<
endl;
1706 os.setf(std::ios_base::right, std::ios_base::adjustfield);
1710 os <<
"CURRENT RITZ VALUES "<<
endl;
1711 if (ritzIndex_.size() != 0) {
1712 int numPrint = (curDim_ < numRitzPrint_? curDim_: numRitzPrint_);
1713 if (problem_->isHermitian()) {
1714 os << std::setw(20) <<
"Ritz Value"
1715 << std::setw(20) <<
"Ritz Residual"
1717 os <<
"--------------------------------------------------------------------------------"<<
endl;
1719 os << std::setw(20) << ritzValues_[
i].realpart
1720 << std::setw(20) << ritzResiduals_[
i]
1724 os << std::setw(24) <<
"Ritz Value"
1725 << std::setw(30) <<
"Ritz Residual"
1727 os <<
"--------------------------------------------------------------------------------"<<
endl;
1730 os << std::setw(15) << ritzValues_[
i].realpart;
1731 if (ritzValues_[
i].imagpart < MT_ZERO) {
1732 os <<
" - i" << std::setw(15) << Teuchos::ScalarTraits<MagnitudeType>::magnitude(ritzValues_[
i].imagpart);
1734 os <<
" + i" << std::setw(15) << ritzValues_[
i].imagpart;
1736 os << std::setw(20) << ritzResiduals_[
i] <<
endl;
1740 os << std::setw(20) <<
"[ NONE COMPUTED ]" <<
endl;
1744 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.
Templated virtual class for providing orthogonalization/orthonormalization methods.
Types and exceptions used within Anasazi solvers and interfaces.
An exception class parent to all Anasazi exceptions.
BlockKrylovSchurInitFailure is thrown when the BlockKrylovSchur solver is unable to generate an initi...
BlockKrylovSchurOrthoFailure is thrown when the orthogonalization manager is unable to generate ortho...
This class implements the block Krylov-Schur iteration, for solving linear eigenvalue problems.
void resetNumIters()
Reset the iteration count.
const Eigenproblem< ScalarType, MV, OP > & getProblem() const
Get a constant reference to the eigenvalue problem.
void computeSchurForm(const bool sort=true)
Compute the Schur form of the projected eigenproblem from the current Krylov factorization.
void setNumRitzVectors(int numRitzVecs)
Set the number of Ritz vectors to compute.
BlockKrylovSchur(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< OrthoManager< ScalarType, MV > > &ortho, Teuchos::ParameterList ¶ms)
BlockKrylovSchur constructor with eigenproblem, solver utilities, and parameter list of solver option...
BlockKrylovSchurState< ScalarType, MV > getState() const
Get the current state of the eigensolver.
void setAuxVecs(const Teuchos::Array< Teuchos::RCP< const MV > > &auxvecs)
Set the auxiliary vectors for the solver.
bool isInitialized() const
Indicates whether the solver has been initialized or not.
Teuchos::RCP< const MV > getRitzVectors()
Get the Ritz vectors.
void setStepSize(int stepSize)
Set the step size.
int getMaxSubspaceDim() const
Get the maximum dimension allocated for the search subspace.
bool isSchurCurrent() const
Get the status of the Schur form currently stored in the eigensolver.
void iterate()
This method performs Block Krylov-Schur iterations until the status test indicates the need to stop o...
void computeRitzValues()
Compute the Ritz values using the current Krylov factorization.
Teuchos::Array< Teuchos::RCP< const MV > > getAuxVecs() const
Get the auxiliary vectors for the solver.
void setStatusTest(Teuchos::RCP< StatusTest< ScalarType, MV, OP > > test)
Set a new StatusTest for the solver.
void setSize(int blockSize, int numBlocks)
Set the blocksize and number of blocks to be used by the iterative solver in solving this eigenproble...
void initialize()
Initialize the solver with the initial vectors from the eigenproblem or random data.
int getCurSubspaceDim() const
Get the dimension of the search subspace used to generate the current eigenvectors and eigenvalues.
void setBlockSize(int blockSize)
Set the blocksize.
Teuchos::RCP< StatusTest< ScalarType, MV, OP > > getStatusTest() const
Get the current StatusTest used by the solver.
bool isRitzVecsCurrent() const
Get the status of the Ritz vectors currently stored in the eigensolver.
std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > getRes2Norms()
Get the current residual 2-norms.
bool isRitzValsCurrent() const
Get the status of the Ritz values currently stored in the eigensolver.
int getNumIters() const
Get the current iteration count.
std::vector< int > getRitzIndex()
Get the Ritz index vector.
std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > getRitzRes2Norms()
Get the current Ritz residual 2-norms.
int getStepSize() const
Get the step size.
std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > getResNorms()
Get the current residual norms.
std::vector< Value< ScalarType > > getRitzValues()
Get the Ritz values.
void computeRitzVectors()
Compute the Ritz vectors using the current Krylov factorization.
int getNumRitzVectors() const
Get the number of Ritz vectors to compute.
void currentStatus(std::ostream &os)
This method requests that the solver print out its current status to screen.
int getBlockSize() const
Get the blocksize to be used by the iterative solver in solving this eigenproblem.
virtual ~BlockKrylovSchur()
BlockKrylovSchur destructor.
The Eigensolver is a templated virtual base class that defines the basic interface that any eigensolv...
static void computeRitzResiduals(const std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > &iRV, const Teuchos::SerialDenseMatrix< int, ScalarType > &S, std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > *RR)
Helper function for correctly computing the Ritz residuals of the projected eigenproblem.
static void scaleRitzVectors(const std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > &iRV, Teuchos::SerialDenseMatrix< int, ScalarType > *S)
Helper function for correctly scaling the eigenvectors of the projected eigenproblem.
static void sortRitzValues(const std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > &rRV, const std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > &iRV, std::vector< Value< ScalarType > > *RV, std::vector< int > *RO, std::vector< int > *RI)
Helper function for correctly storing the Ritz values when the eigenproblem is non-Hermitian.
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 BlockKrylovSchur state variables.
Teuchos::RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > S
The current Schur form reduction of the valid part of H.
int curDim
The current dimension of the reduction.
Teuchos::RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > Q
The current Schur vectors of the valid part of H.
Teuchos::RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > H
The current Hessenberg matrix.
Teuchos::RCP< const MulVec > V
The current Krylov basis.