14 #ifndef ANASAZI_BLOCK_KRYLOV_SCHUR_HPP
15 #define ANASAZI_BLOCK_KRYLOV_SCHUR_HPP
23 #include "AnasaziHelperTraits.hpp"
56 template <
class ScalarType,
class MulVec>
76 H(Teuchos::null),
S(Teuchos::null),
114 template <
class ScalarType,
class MV,
class OP>
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());
314 void setSize(
int blockSize,
int numBlocks);
340 if (!initialized_)
return 0;
345 int getMaxSubspaceDim()
const {
return (problem_->isHermitian()?blockSize_*numBlocks_:blockSize_*numBlocks_+1); }
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;
425 CheckList() : checkV(false), checkArn(false), checkAux(false) {};
430 std::string accuracyCheck(
const CheckList &chk,
const std::string &where)
const;
433 std::vector<int>& order );
450 timerCompSF_, timerSortSF_,
451 timerCompRitzVec_, timerOrtho_;
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>
533 MT_ONE(Teuchos::ScalarTraits<MagnitudeType>::one()),
534 MT_ZERO(Teuchos::ScalarTraits<MagnitudeType>::zero()),
535 NANVAL(Teuchos::ScalarTraits<MagnitudeType>::nan()),
536 ST_ONE(Teuchos::ScalarTraits<ScalarType>::one()),
537 ST_ZERO(Teuchos::ScalarTraits<ScalarType>::zero()),
545 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
546 timerOp_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: BlockKrylovSchur::Operation Op*x")),
547 timerSortRitzVal_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: BlockKrylovSchur::Sorting Ritz values")),
548 timerCompSF_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: BlockKrylovSchur::Computing Schur form")),
549 timerSortSF_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: BlockKrylovSchur::Sorting Schur form")),
550 timerCompRitzVec_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: BlockKrylovSchur::Computing Ritz vectors")),
551 timerOrtho_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: BlockKrylovSchur::Orthogonalization")),
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.");
583 TEUCHOS_TEST_FOR_EXCEPTION(printer == Teuchos::null,std::invalid_argument,
584 "Anasazi::BlockKrylovSchur::constructor: user specified null output manager pointer.");
585 TEUCHOS_TEST_FOR_EXCEPTION(tester == Teuchos::null,std::invalid_argument,
586 "Anasazi::BlockKrylovSchur::constructor: user specified null status test pointer.");
587 TEUCHOS_TEST_FOR_EXCEPTION(ortho == Teuchos::null,std::invalid_argument,
588 "Anasazi::BlockKrylovSchur::constructor: user specified null ortho manager pointer.");
591 Op_ = problem_->getOperator();
594 TEUCHOS_TEST_FOR_EXCEPTION(!params.
isParameter(
"Step Size"), std::invalid_argument,
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());
606 int numRitzVecs = params.
get(
"Number of Ritz Vectors", 0);
610 numRitzPrint_ = params.
get(
"Print Number of Ritz Values", bs);
617 template <
class ScalarType,
class MV,
class OP>
620 setSize(blockSize,numBlocks_);
626 template <
class ScalarType,
class MV,
class OP>
629 TEUCHOS_TEST_FOR_EXCEPTION(stepSize <= 0, std::invalid_argument,
"Anasazi::BlockKrylovSchur::setStepSize(): new step size must be positive and non-zero.");
630 stepSize_ = stepSize;
635 template <
class ScalarType,
class MV,
class OP>
641 TEUCHOS_TEST_FOR_EXCEPTION(numRitzVecs < 0, std::invalid_argument,
"Anasazi::BlockKrylovSchur::setNumRitzVectors(): number of Ritz vectors to compute must be positive.");
644 if (numRitzVecs != numRitzVecs_) {
646 ritzVectors_ = Teuchos::null;
647 ritzVectors_ = MVT::Clone(*V_, numRitzVecs);
649 ritzVectors_ = Teuchos::null;
651 numRitzVecs_ = numRitzVecs;
652 ritzVecsCurrent_ =
false;
658 template <
class ScalarType,
class MV,
class OP>
664 TEUCHOS_TEST_FOR_EXCEPTION(numBlocks <= 0 || blockSize <= 0, std::invalid_argument,
"Anasazi::BlockKrylovSchur::setSize was passed a non-positive argument.");
665 TEUCHOS_TEST_FOR_EXCEPTION(numBlocks < 3, std::invalid_argument,
"Anasazi::BlockKrylovSchur::setSize(): numBlocks must be at least three.");
666 if (blockSize == blockSize_ && numBlocks == numBlocks_) {
671 blockSize_ = blockSize;
672 numBlocks_ = numBlocks;
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_);
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.");
770 if (newstate.
V != Teuchos::null && newstate.
H != Teuchos::null) {
775 std::invalid_argument, errstr );
776 if (newstate.
V != V_) {
778 std::invalid_argument, errstr );
780 std::invalid_argument, errstr );
783 std::invalid_argument, errstr );
785 curDim_ = newstate.
curDim;
786 int lclDim = MVT::GetNumberVecs(*newstate.
V);
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;
799 if (newstate.
V != V_) {
800 std::vector<int> nevind(lclDim);
801 for (
int i=0; i<lclDim; i++) nevind[i] = i;
802 MVT::SetBlock(*newstate.
V,nevind,*V_);
806 if (newstate.
H != H_) {
807 H_->putScalar( ST_ZERO );
814 lclH = Teuchos::null;
823 "Anasazi::BlockKrylovSchur::initialize(): eigenproblem did not specify initial vectors to clone from.");
825 int lclDim = MVT::GetNumberVecs(*ivec);
826 bool userand =
false;
827 if (lclDim < blockSize_) {
835 std::vector<int> dimind2(lclDim);
836 for (
int i=0; i<lclDim; i++) { dimind2[i] = i; }
842 MVT::SetBlock(*ivec,dimind2,*newV1);
845 dimind2.resize(blockSize_-lclDim);
846 for (
int i=0; i<blockSize_-lclDim; i++) { dimind2[i] = lclDim + i; }
850 MVT::MvRandom(*newV2);
860 MVT::SetBlock(*ivecV,bsind,*newV1);
867 if (auxVecs_.size() > 0) {
868 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
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
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) {
945 int searchDim = blockSize_*numBlocks_;
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_);
964 for (
int i=0; i<blockSize_; i++) { curind[i] = lclDim + i; }
969 for (
int i=0; i<blockSize_; i++) { curind[i] = curDim_ + i; }
976 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
979 OPT::Apply(*Op_,*Vprev,*Vnext);
980 count_ApplyOp_ += blockSize_;
984 Vprev = Teuchos::null;
988 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
993 std::vector<int> prevind(lclDim);
994 for (
int i=0; i<lclDim; i++) { prevind[i] = i; }
995 Vprev = MVT::CloneView(*V_,prevind);
1006 if (auxVecs_.size() > 0) {
1007 for (Array_size_type i=0; i<auxVecs_.size(); i++) {
1008 AVprev.
append( auxVecs_[i] );
1009 AsubH.
append( Teuchos::null );
1018 (
Teuchos::View,*H_,blockSize_,blockSize_,lclDim,curDim_ ) );
1019 int rank = orthman_->projectAndNormalize(*Vnext,AVprev,AsubH,subR);
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_);
1096 for (
int i=0; i<curDim_; i++) lclind[i] = i;
1097 std::vector<int> bsind(blockSize_);
1098 for (
int i=0; i<blockSize_; i++) { bsind[i] = curDim_ + i; }
1103 lclV = MVT::CloneView(*V_,lclind);
1104 lclF = MVT::CloneView(*V_,bsind);
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;
1114 tmp = orthman_->orthogError(*lclV,*lclF);
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
1136 OPT::Apply(*Op_,*lclV,*lclAV);
1141 MVT::MvTimesMatAddMv( -ST_ONE, *lclV, subH, ST_ONE, *lclAV );
1145 blockSize_,curDim_, curDim_ );
1146 MVT::MvTimesMatAddMv( -ST_ONE, *lclF, curB, ST_ONE, *lclAV );
1149 std::vector<MagnitudeType> arnNorms( curDim_ );
1150 orthman_->norm( *lclAV, arnNorms );
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
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.");
1256 std::vector<int> curind( curDim_ );
1257 for (
int i=0; i<curDim_; i++) { curind[i] = i; }
1259 if (problem_->isHermitian()) {
1264 MVT::MvTimesMatAddMv( ST_ONE, *Vtemp, subQ, ST_ZERO, *ritzVectors_ );
1267 bool complexRitzVals =
false;
1268 for (
int i=0; i<numRitzVecs_; i++) {
1269 if (ritzIndex_[i] != 0) {
1270 complexRitzVals =
true;
1274 if (complexRitzVals)
1275 om_->stream(
Warnings) <<
" Eigenproblem is Hermitian and complex eigenvalues have converged, corresponding eigenvectors will be incorrect!!!"
1286 MVT::MvTimesMatAddMv( ST_ONE, *Vtemp, subQ, ST_ZERO, *tmpritzVectors_ );
1294 int lwork = 3*curDim_;
1295 std::vector<ScalarType> work( lwork );
1296 std::vector<MagnitudeType> rwork( curDim_ );
1300 ScalarType vl[ ldvl ];
1302 lapack.
TREVC( side, curDim_, schurH_->values(), schurH_->stride(), vl, ldvl,
1303 copyQ.
values(), copyQ.
stride(), curDim_, &mm, &work[0], &rwork[0], &info );
1305 "Anasazi::BlockKrylovSchur::computeRitzVectors(): TREVC(n==" << curDim_ <<
") returned info " << info <<
" != 0.");
1311 curind.resize( numRitzVecs_ );
1312 Teuchos::RCP<MV> view_ritzVectors = MVT::CloneViewNonConst( *ritzVectors_, curind );
1313 MVT::MvTimesMatAddMv( ST_ONE, *tmpritzVectors_, subCopyQ, ST_ZERO, *view_ritzVectors );
1316 std::vector<MagnitudeType> ritzNrm( numRitzVecs_ );
1317 MVT::MvNorm( *view_ritzVectors, ritzNrm );
1320 tmpritzVectors_ = Teuchos::null;
1321 view_ritzVectors = Teuchos::null;
1324 ScalarType ritzScale = ST_ONE;
1325 for (
int i=0; i<numRitzVecs_; i++) {
1328 if (ritzIndex_[i] == 1 ) {
1329 ritzScale = ST_ONE/lapack_mag.
LAPY2(ritzNrm[i],ritzNrm[i+1]);
1330 std::vector<int> newind(2);
1331 newind[0] = i; newind[1] = i+1;
1332 tmpritzVectors_ = MVT::CloneCopy( *ritzVectors_, newind );
1333 view_ritzVectors = MVT::CloneViewNonConst( *ritzVectors_, newind );
1334 MVT::MvAddMv( ritzScale, *tmpritzVectors_, ST_ZERO, *tmpritzVectors_, *view_ritzVectors );
1341 std::vector<int> newind(1);
1343 tmpritzVectors_ = MVT::CloneCopy( *ritzVectors_, newind );
1344 view_ritzVectors = MVT::CloneViewNonConst( *ritzVectors_, newind );
1345 MVT::MvAddMv( ST_ONE/ritzNrm[i], *tmpritzVectors_, ST_ZERO, *tmpritzVectors_, *view_ritzVectors );
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
1400 if (!schurCurrent_) {
1404 if (!ritzValsCurrent_) {
1428 int lwork = 3*curDim_;
1429 std::vector<ScalarType> work( lwork );
1430 std::vector<MagnitudeType> rwork( curDim_ );
1431 std::vector<MagnitudeType> tmp_rRitzValues( curDim_ );
1432 std::vector<MagnitudeType> tmp_iRitzValues( curDim_ );
1433 std::vector<int> bwork( curDim_ );
1434 int info = 0, sdim = 0;
1436 lapack.
GEES( jobvs,curDim_, schurH_->values(), schurH_->stride(), &sdim, &tmp_rRitzValues[0],
1437 &tmp_iRitzValues[0], subQ.
values(), subQ.
stride(), &work[0], lwork,
1438 &rwork[0], &bwork[0], &info );
1441 "Anasazi::BlockKrylovSchur::computeSchurForm(): GEES(n==" << curDim_ <<
") returned info " << info <<
" != 0.");
1447 bool hermImagDetected =
false;
1448 if (problem_->isHermitian()) {
1449 for (
int i=0; i<curDim_; i++)
1451 if (tmp_iRitzValues[i] != MT_ZERO)
1453 hermImagDetected =
true;
1457 if (hermImagDetected) {
1459 om_->stream(
Warnings) <<
" Eigenproblem is Hermitian and complex eigenvalues have been detected!!!" << std::endl;
1467 (*tLocalH) -= localH;
1468 MagnitudeType normF = tLocalH->normFrobenius();
1469 MagnitudeType norm1 = tLocalH->normOne();
1470 om_->stream(
Warnings) <<
" Symmetry error in projected eigenproblem: || S - S' ||_F = " << normF
1471 <<
", || S - S' ||_1 = " << norm1 << std::endl;
1490 blockSize_, curDim_, curDim_ );
1500 ScalarType* b_ptr = subB.
values();
1501 if (problem_->isHermitian() && !hermImagDetected) {
1505 for (
int i=0; i<curDim_ ; i++) {
1506 ritzResiduals_[i] = blas.
NRM2(blockSize_, b_ptr + i*blockSize_, 1);
1515 ScalarType vl[ ldvl ];
1517 lapack.
TREVC( side, curDim_, schurH_->values(), schurH_->stride(), vl, ldvl,
1518 S.
values(), S.
stride(), curDim_, &mm, &work[0], &rwork[0], &info );
1521 "Anasazi::BlockKrylovSchur::computeSchurForm(): TREVC(n==" << curDim_ <<
") returned info " << info <<
" != 0.");
1566 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1570 if (problem_->isHermitian() && !hermImagDetected) {
1573 sm_->sort(tmp_rRitzValues, Teuchos::rcpFromRef(ritzOrder_), curDim_);
1575 while ( i < curDim_ ) {
1577 ritzValues_[i].set(tmp_rRitzValues[i], MT_ZERO);
1578 ritzIndex_.push_back(0);
1585 sm_->sort(tmp_rRitzValues, tmp_iRitzValues, Teuchos::rcpFromRef(ritzOrder_) , curDim_);
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>
1628 std::vector<int>& order )
1631 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1643 int i = 0, nevtemp = 0;
1645 std::vector<int> offset2( curDim_ );
1646 std::vector<int> order2( curDim_ );
1650 int lwork = 3*curDim_;
1651 std::vector<ScalarType> work( lwork );
1653 while (i < curDim_) {
1654 if ( ritzIndex_[i] != 0 ) {
1655 offset2[nevtemp] = 0;
1656 for (
int j=i; j<curDim_; j++) {
1657 if (order[j] > order[i]) { offset2[nevtemp]++; }
1659 order2[nevtemp] = order[i];
1662 offset2[nevtemp] = 0;
1663 for (
int j=i; j<curDim_; j++) {
1664 if (order[j] > order[i]) { offset2[nevtemp]++; }
1666 order2[nevtemp] = order[i];
1671 ScalarType *ptr_h = H.
values();
1672 ScalarType *ptr_q = Q.
values();
1675 for (i=nevtemp-1; i>=0; i--) {
1676 int ifst = order2[i]+1+offset2[i];
1678 lapack.
TREXC( compq, curDim_, ptr_h, ldh, ptr_q, ldq, &ifst,
1679 &ilst, &work[0], &info );
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;
1718 for (
int i=0; i<numPrint; i++) {
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;
1728 for (
int i=0; i<numPrint; i++) {
1730 os << std::setw(15) << ritzValues_[i].realpart;
1731 if (ritzValues_[i].imagpart < MT_ZERO) {
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;
ScalarType * values() const
void computeRitzValues()
Compute the Ritz values using the current Krylov factorization.
BlockKrylovSchurOrthoFailure is thrown when the orthogonalization manager is unable to generate ortho...
Teuchos::Array< Teuchos::RCP< const MV > > getAuxVecs() const
Get the auxiliary vectors for the solver.
Teuchos::RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > H
The current Hessenberg matrix.
BlockKrylovSchurState< ScalarType, MV > getState() const
Get the current state of the eigensolver.
void setStepSize(int stepSize)
Set the step size.
bool isRitzValsCurrent() const
Get the status of the Ritz values currently stored in the eigensolver.
const Eigenproblem< ScalarType, MV, OP > & getProblem() const
Get a constant reference to the eigenvalue problem.
std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > getRitzRes2Norms()
Get the current Ritz residual 2-norms.
Array< T > & append(const T &x)
Teuchos::RCP< const MV > getRitzVectors()
Get the Ritz vectors.
This class defines the interface required by an eigensolver and status test class to compute solution...
virtual ~BlockKrylovSchur()
BlockKrylovSchur destructor.
int getBlockSize() const
Get the blocksize to be used by the iterative solver in solving this eigenproblem.
Declaration of basic traits for the multivector type.
bool isInitialized() const
Indicates whether the solver has been initialized or not.
T & get(const std::string &name, T def_value)
std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > getResNorms()
Get the current residual norms.
void setAuxVecs(const Teuchos::Array< Teuchos::RCP< const MV > > &auxvecs)
Set the auxiliary vectors for the solver.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void iterate()
This method performs Block Krylov-Schur iterations until the status test indicates the need to stop o...
Virtual base class which defines basic traits for the operator type.
ScalarTraits< ScalarType >::magnitudeType NRM2(const OrdinalType &n, const ScalarType *x, const OrdinalType &incx) const
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.
Structure to contain pointers to BlockKrylovSchur state variables.
void GEMM(ETransp transa, ETransp transb, const OrdinalType &m, const OrdinalType &n, const OrdinalType &k, const alpha_type alpha, const A_type *A, const OrdinalType &lda, const B_type *B, const OrdinalType &ldb, const beta_type beta, ScalarType *C, const OrdinalType &ldc) const
An exception class parent to all Anasazi exceptions.
void setStatusTest(Teuchos::RCP< StatusTest< ScalarType, MV, OP > > test)
Set a new StatusTest for the solver.
int getCurSubspaceDim() const
Get the dimension of the search subspace used to generate the current eigenvectors and eigenvalues...
void TREVC(const char &SIDE, const char &HOWMNY, OrdinalType *select, const OrdinalType &n, const ScalarType *T, const OrdinalType &ldt, ScalarType *VL, const OrdinalType &ldvl, ScalarType *VR, const OrdinalType &ldvr, const OrdinalType &mm, OrdinalType *m, ScalarType *WORK, OrdinalType *info) const
int getNumIters() const
Get the current iteration count.
Pure virtual base class which describes the basic interface to the iterative eigensolver.
bool isRitzVecsCurrent() const
Get the status of the Ritz vectors currently stored in the eigensolver.
void initialize()
Initialize the solver with the initial vectors from the eigenproblem or random data.
void computeRitzVectors()
Compute the Ritz vectors using the current Krylov factorization.
int getStepSize() const
Get the step size.
bool isParameter(const std::string &name) const
void setNumRitzVectors(int numRitzVecs)
Set the number of Ritz vectors to compute.
void COPY(const OrdinalType &n, const ScalarType *x, const OrdinalType &incx, ScalarType *y, const OrdinalType &incy) const
Teuchos::RCP< StatusTest< ScalarType, MV, OP > > getStatusTest() const
Get the current StatusTest used by the solver.
void computeSchurForm(const bool sort=true)
Compute the Schur form of the projected eigenproblem from the current Krylov factorization.
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.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
bool isSchurCurrent() const
Get the status of the Schur form currently stored in the eigensolver.
void GEES(const char &JOBVS, const char &SORT, OrdinalType &(*ptr2func)(ScalarType *, ScalarType *), const OrdinalType &n, ScalarType *A, const OrdinalType &lda, OrdinalType *sdim, ScalarType *WR, ScalarType *WI, ScalarType *VS, const OrdinalType &ldvs, ScalarType *WORK, const OrdinalType &lwork, OrdinalType *BWORK, OrdinalType *info) const
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...
Output managers remove the need for the eigensolver to know any information about the required output...
void resetNumIters()
Reset the iteration count.
Templated virtual class for providing orthogonalization/orthonormalization methods.
Traits class which defines basic operations on multivectors.
Virtual base class which defines basic traits for the operator type.
void TREXC(const char &COMPQ, const OrdinalType &n, ScalarType *T, const OrdinalType &ldt, ScalarType *Q, const OrdinalType &ldq, OrdinalType *ifst, OrdinalType *ilst, ScalarType *WORK, OrdinalType *info) const
int getMaxSubspaceDim() const
Get the maximum dimension allocated for the search subspace.
int getNumRitzVectors() const
Get the number of Ritz vectors to compute.
ScalarType LAPY2(const ScalarType &x, const ScalarType &y) const
std::vector< Value< ScalarType > > getRitzValues()
Get the Ritz values.
std::vector< int > getRitzIndex()
Get the Ritz index vector.
static magnitudeType magnitude(T a)
std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > getRes2Norms()
Get the current residual 2-norms.
Teuchos::RCP< const MulVec > V
The current Krylov basis.
BlockKrylovSchurInitFailure is thrown when the BlockKrylovSchur solver is unable to generate an initi...
Types and exceptions used within Anasazi solvers and interfaces.
void currentStatus(std::ostream &os)
This method requests that the solver print out its current status to screen.
Anasazi's templated virtual class for providing routines for orthogonalization and orthonormalization...
Teuchos::RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > Q
The current Schur vectors of the valid part of H.
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.
void setBlockSize(int blockSize)
Set the blocksize.
This class implements the block Krylov-Schur iteration, for solving linear eigenvalue problems...
Anasazi's templated pure virtual class for managing the sorting of approximate eigenvalues computed b...
void setSize(int blockSize, int numBlocks)
Set the blocksize and number of blocks to be used by the iterative solver in solving this eigenproble...
int curDim
The current dimension of the reduction.
Common interface of stopping criteria for Anasazi's solvers.
The Eigensolver is a templated virtual base class that defines the basic interface that any eigensolv...
Teuchos::RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > S
The current Schur form reduction of the valid part of H.
OrdinalType stride() const