16 #ifndef ANASAZI_TRACEMIN_BASE_HPP
17 #define ANASAZI_TRACEMIN_BASE_HPP
52 namespace Experimental {
61 template <
class ScalarType,
class MV>
101 X(Teuchos::null),
KX(Teuchos::null),
MX(Teuchos::null),
R(Teuchos::null),
102 T(Teuchos::null),
KK(Teuchos::null),
RV(Teuchos::null),
isOrtho(false),
149 template <
class ScalarType,
class MV,
class OP>
223 void harmonicIterate();
328 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
getResNorms();
336 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
getRes2Norms();
346 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
getRitzRes2Norms();
420 void setSize(
int blockSize,
int numBlocks);
439 typedef TraceMinRitzOp<ScalarType,MV,OP> tracemin_ritz_op_type;
440 typedef SaddleContainer<ScalarType,MV> saddle_container_type;
441 typedef SaddleOperator<ScalarType,MV,tracemin_ritz_op_type> saddle_op_type;
442 const MagnitudeType ONE;
443 const MagnitudeType ZERO;
444 const MagnitudeType NANVAL;
465 timerLocal_, timerCompRes_, timerOrtho_, timerInit_;
471 bool checkV, checkX, checkMX,
472 checkKX, checkQ, checkKK;
473 CheckList() : checkV(
false),checkX(
false),
474 checkMX(
false),checkKX(
false),
475 checkQ(
false),checkKK(
false) {};
480 std::string accuracyCheck(
const CheckList &chk,
const std::string &where)
const;
485 int count_ApplyOp_, count_ApplyM_;
512 RCP<MV> X_, KX_, MX_, KV_, MV_, R_, V_;
526 std::vector<MagnitudeType> theta_, Rnorms_, R2norms_;
529 bool Rnorms_current_, R2norms_current_;
533 enum SaddleSolType saddleSolType_;
534 bool previouslyLeveled_;
535 MagnitudeType previousTrace_;
536 bool posSafeToShift_, negSafeToShift_;
537 MagnitudeType largestSafeShift_;
539 std::vector<ScalarType> ritzShifts_;
545 enum WhenToShiftType whenToShift_;
546 enum HowToShiftType howToShift_;
547 bool useMultipleShifts_;
548 bool considerClusters_;
549 bool projectAllVecs_;
550 bool projectLockedVecs_;
554 MagnitudeType traceThresh_;
555 MagnitudeType alpha_;
559 std::string shiftNorm_;
560 MagnitudeType shiftThresh_;
561 bool useRelShiftThresh_;
565 ScalarType getTrace()
const;
571 std::vector<ScalarType> getClusterResids();
574 void computeRitzShifts(
const std::vector<ScalarType>& clusterResids);
577 std::vector<ScalarType> computeTol();
579 void solveSaddlePointProblem(
RCP<MV> Delta);
581 void solveSaddleProj(
RCP<MV> Delta)
const;
584 void solveSaddleProjPrec(
RCP<MV> Delta)
const;
586 void solveSaddleSchur (
RCP<MV> Delta)
const;
588 void solveSaddleBDPrec (
RCP<MV> Delta)
const;
590 void solveSaddleHSSPrec (
RCP<MV> Delta)
const;
594 void computeRitzPairs();
600 void updateResidual();
604 virtual void harmonicAddToBasis(
const RCP<const MV> Delta) =0;
620 template <
class ScalarType,
class MV,
class OP>
629 ONE(Teuchos::ScalarTraits<MagnitudeType>::one()),
630 ZERO(Teuchos::ScalarTraits<MagnitudeType>::zero()),
631 NANVAL(Teuchos::ScalarTraits<MagnitudeType>::nan()),
639 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
640 timerOp_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: TraceMinBase::Operation Op*x")),
641 timerMOp_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: TraceMinBase::Operation M*x")),
642 timerSaddle_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: TraceMinBase::Solving saddle point problem")),
643 timerSortEval_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: TraceMinBase::Sorting eigenvalues")),
644 timerDS_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: TraceMinBase::Direct solve")),
645 timerLocal_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: TraceMinBase::Local update")),
646 timerCompRes_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: TraceMinBase::Computing residuals")),
647 timerOrtho_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: TraceMinBase::Orthogonalization")),
648 timerInit_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: TraceMinBase::Initialization")),
657 auxVecs_( Teuchos::Array<
RCP<const MV> >(0) ),
658 MauxVecs_( Teuchos::Array<
RCP<const MV> >(0) ),
661 Rnorms_current_(false),
662 R2norms_current_(false),
664 previouslyLeveled_(false),
665 previousTrace_(ZERO),
666 posSafeToShift_(false),
667 negSafeToShift_(false),
668 largestSafeShift_(ZERO),
672 "Anasazi::TraceMinBase::constructor: user passed null problem pointer.");
674 "Anasazi::TraceMinBase::constructor: user passed null sort manager pointer.");
676 "Anasazi::TraceMinBase::constructor: user passed null output manager pointer.");
678 "Anasazi::TraceMinBase::constructor: user passed null status test pointer.");
680 "Anasazi::TraceMinBase::constructor: user passed null orthogonalization manager pointer.");
682 "Anasazi::TraceMinBase::constructor: problem is not hermitian.");
685 Op_ = problem_->getOperator();
686 MOp_ = problem_->getM();
687 Prec_ = problem_->getPrec();
688 hasM_ = (MOp_ != Teuchos::null);
691 saddleSolType_ = params.
get(
"Saddle Solver Type", PROJECTED_KRYLOV_SOLVER);
692 TEUCHOS_TEST_FOR_EXCEPTION(saddleSolType_ != PROJECTED_KRYLOV_SOLVER && saddleSolType_ != SCHUR_COMPLEMENT_SOLVER && saddleSolType_ != BD_PREC_MINRES && saddleSolType_ != HSS_PREC_GMRES, std::invalid_argument,
693 "Anasazi::TraceMin::constructor: Invalid value for \"Saddle Solver Type\"; valid options are PROJECTED_KRYLOV_SOLVER, SCHUR_COMPLEMENT_SOLVER, and BD_PREC_MINRES.");
696 whenToShift_ = params.
get(
"When To Shift", ALWAYS_SHIFT);
697 TEUCHOS_TEST_FOR_EXCEPTION(whenToShift_ != NEVER_SHIFT && whenToShift_ != SHIFT_WHEN_TRACE_LEVELS && whenToShift_ != SHIFT_WHEN_RESID_SMALL && whenToShift_ != ALWAYS_SHIFT, std::invalid_argument,
698 "Anasazi::TraceMin::constructor: Invalid value for \"When To Shift\"; valid options are \"NEVER_SHIFT\", \"SHIFT_WHEN_TRACE_LEVELS\", \"SHIFT_WHEN_RESID_SMALL\", and \"ALWAYS_SHIFT\".");
700 traceThresh_ = params.
get(
"Trace Threshold", 2e-2);
702 "Anasazi::TraceMin::constructor: Invalid value for \"Trace Threshold\"; Must be positive.");
704 howToShift_ = params.
get(
"How To Choose Shift", ADJUSTED_RITZ_SHIFT);
705 TEUCHOS_TEST_FOR_EXCEPTION(howToShift_ != LARGEST_CONVERGED_SHIFT && howToShift_ != ADJUSTED_RITZ_SHIFT && howToShift_ != RITZ_VALUES_SHIFT && howToShift_ != EXPERIMENTAL_SHIFT, std::invalid_argument,
706 "Anasazi::TraceMin::constructor: Invalid value for \"How To Choose Shift\"; valid options are \"LARGEST_CONVERGED_SHIFT\", \"ADJUSTED_RITZ_SHIFT\", \"RITZ_VALUES_SHIFT\".");
708 useMultipleShifts_ = params.
get(
"Use Multiple Shifts",
true);
710 shiftThresh_ = params.
get(
"Shift Threshold", 1e-2);
711 useRelShiftThresh_ = params.
get(
"Relative Shift Threshold",
true);
712 shiftNorm_ = params.
get(
"Shift Norm",
"2");
714 "Anasazi::TraceMin::constructor: Invalid value for \"Shift Norm\"; valid options are \"2\", \"M\".");
716 considerClusters_ = params.
get(
"Consider Clusters",
true);
718 projectAllVecs_ = params.
get(
"Project All Vectors",
true);
719 projectLockedVecs_ = params.
get(
"Project Locked Vectors",
true);
720 useRHSR_ = params.
get(
"Use Residual as RHS",
true);
721 useHarmonic_ = params.
get(
"Use Harmonic Ritz Values",
false);
722 computeAllRes_ = params.
get(
"Compute All Residuals",
true);
725 int bs = params.
get(
"Block Size", problem_->getNEV());
726 int nb = params.
get(
"Num Blocks", 1);
729 NEV_ = problem_->getNEV();
732 ritzOp_ =
rcp (
new tracemin_ritz_op_type (Op_, MOp_, Prec_));
735 const int innerMaxIts = params.
get (
"Maximum Krylov Iterations", 200);
736 ritzOp_->setMaxIts (innerMaxIts);
738 alpha_ = params.
get (
"HSS: alpha", ONE);
744 template <
class ScalarType,
class MV,
class OP>
751 template <
class ScalarType,
class MV,
class OP>
754 TEUCHOS_TEST_FOR_EXCEPTION(blockSize < 1, std::invalid_argument,
"Anasazi::TraceMinBase::setSize(blocksize,numblocks): blocksize must be strictly positive.");
755 setSize(blockSize,numBlocks_);
761 template <
class ScalarType,
class MV,
class OP>
769 template <
class ScalarType,
class MV,
class OP>
777 template <
class ScalarType,
class MV,
class OP>
785 template <
class ScalarType,
class MV,
class OP>
787 return blockSize_*numBlocks_;
792 template <
class ScalarType,
class MV,
class OP>
794 if (!initialized_)
return 0;
801 template <
class ScalarType,
class MV,
class OP>
802 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
804 return getRes2Norms();
810 template <
class ScalarType,
class MV,
class OP>
812 std::vector<int> ret(curDim_,0);
819 template <
class ScalarType,
class MV,
class OP>
821 std::vector<Value<ScalarType> > ret(curDim_);
822 for (
int i=0; i<curDim_; ++i) {
823 ret[i].realpart = theta_[i];
824 ret[i].imagpart = ZERO;
832 template <
class ScalarType,
class MV,
class OP>
840 template <
class ScalarType,
class MV,
class OP>
848 template <
class ScalarType,
class MV,
class OP>
856 template <
class ScalarType,
class MV,
class OP>
862 if (Op_ != Teuchos::null) {
867 state.
KV = Teuchos::null;
868 state.
KX = Teuchos::null;
875 state.
MopV = Teuchos::null;
876 state.
MX = Teuchos::null;
880 state.
RV = ritzVecs_;
882 state.
T =
rcp(
new std::vector<MagnitudeType>(theta_.begin(),theta_.begin()+curDim_) );
884 state.
T =
rcp(
new std::vector<MagnitudeType>(0));
886 state.
ritzShifts =
rcp(
new std::vector<MagnitudeType>(ritzShifts_.begin(),ritzShifts_.begin()+blockSize_) );
896 template <
class ScalarType,
class MV,
class OP>
907 if (initialized_ ==
false) {
913 const int searchDim = blockSize_*numBlocks_;
916 RCP<MV> Delta = MVT::Clone(*X_,blockSize_);
921 while (tester_->checkStatus(
this) !=
Passed && (numBlocks_ == 1 || curDim_ < searchDim)) {
924 if (om_->isVerbosity(
Debug)) {
925 currentStatus( om_->stream(
Debug) );
934 solveSaddlePointProblem(Delta);
939 if (om_->isVerbosity(
Debug ) ) {
943 om_->print(
Debug, accuracyCheck(chk,
": after addToBasis(Delta)") );
949 if (om_->isVerbosity(
Debug ) ) {
953 om_->print(
Debug, accuracyCheck(chk,
": after computeKK()") );
962 if (om_->isVerbosity(
Debug ) ) {
966 om_->print(
Debug, accuracyCheck(chk,
": after computeX()") );
972 if (om_->isVerbosity(
Debug ) ) {
977 om_->print(
Debug, accuracyCheck(chk,
": after updateKXMX()") );
990 template <
class ScalarType,
class MV,
class OP>
995 if (initialized_ ==
false) {
1001 const int searchDim = blockSize_*numBlocks_;
1004 RCP<MV> Delta = MVT::Clone(*X_,blockSize_);
1009 while (tester_->checkStatus(
this) !=
Passed && (numBlocks_ == 1 || curDim_ < searchDim)) {
1012 if (om_->isVerbosity(
Debug)) {
1013 currentStatus( om_->stream(
Debug) );
1022 solveSaddlePointProblem(Delta);
1025 harmonicAddToBasis(Delta);
1027 if (om_->isVerbosity(
Debug ) ) {
1031 om_->print(
Debug, accuracyCheck(chk,
": after addToBasis(Delta)") );
1037 if (om_->isVerbosity(
Debug ) ) {
1041 om_->print(
Debug, accuracyCheck(chk,
": after computeKK()") );
1056 std::vector<int> dimind(nvecs);
1057 for(
int i=0; i<nvecs; i++)
1059 RCP<MV> lclX = MVT::CloneViewNonConst(*X_,dimind);
1060 std::vector<ScalarType> normvec(nvecs);
1061 orthman_->normMat(*lclX,normvec);
1064 for(
int i=0; i<nvecs; i++)
1065 normvec[i] = ONE/normvec[i];
1066 MVT::MvScale(*lclX,normvec);
1069 for(
int i=0; i<nvecs; i++)
1071 theta_[i] = theta_[i] * normvec[i] * normvec[i];
1074 if (om_->isVerbosity(
Debug ) ) {
1078 om_->print(
Debug, accuracyCheck(chk,
": after computeX()") );
1085 if(Op_ != Teuchos::null)
1087 RCP<MV> lclKX = MVT::CloneViewNonConst(*KX_,dimind);
1088 MVT::MvScale(*lclKX,normvec);
1092 RCP<MV> lclMX = MVT::CloneViewNonConst(*MX_,dimind);
1093 MVT::MvScale(*lclMX,normvec);
1096 if (om_->isVerbosity(
Debug ) ) {
1101 om_->print(
Debug, accuracyCheck(chk,
": after updateKXMX()") );
1113 template <
class ScalarType,
class MV,
class OP>
1134 template <
class ScalarType,
class MV,
class OP>
1141 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1145 previouslyLeveled_ =
false;
1149 harmonicInitialize(newstate);
1153 std::vector<int> bsind(blockSize_);
1154 for (
int i=0; i<blockSize_; ++i) bsind[i] = i;
1182 if (newstate.
V != Teuchos::null) {
1183 om_->stream(
Debug) <<
"Copying V from the user\n";
1186 "Anasazi::TraceMinBase::initialize(newstate): Vector length of V not correct." );
1188 "Anasazi::TraceMinBase::initialize(newstate): Rank of new state must be at least blockSize().");
1190 "Anasazi::TraceMinBase::initialize(newstate): Rank of new state must be less than getMaxSubspaceDim().");
1193 "Anasazi::TraceMinBase::initialize(newstate): Multivector for basis in new state must be as large as specified state rank.");
1195 curDim_ = newstate.
curDim;
1197 curDim_ = (int)(curDim_ / blockSize_)*blockSize_;
1200 "Anasazi::TraceMinBase::initialize(newstate): Rank of new state must be a multiple of getBlockSize().");
1203 std::vector<int> nevind(curDim_);
1204 for (
int i=0; i<curDim_; ++i) nevind[i] = i;
1205 if (newstate.
V != V_) {
1206 if (curDim_ < MVT::GetNumberVecs(*newstate.
V)) {
1207 newstate.
V = MVT::CloneView(*newstate.
V,nevind);
1209 MVT::SetBlock(*newstate.
V,nevind,*V_);
1211 lclV = MVT::CloneViewNonConst(*V_,nevind);
1218 "Anasazi::TraceMinBase::initialize(newstate): Eigenproblem did not specify initial vectors to clone from.");
1220 newstate.
X = Teuchos::null;
1221 newstate.
MX = Teuchos::null;
1222 newstate.
KX = Teuchos::null;
1223 newstate.
R = Teuchos::null;
1224 newstate.
T = Teuchos::null;
1225 newstate.
RV = Teuchos::null;
1226 newstate.
KK = Teuchos::null;
1227 newstate.
KV = Teuchos::null;
1228 newstate.
MopV = Teuchos::null;
1233 curDim_ = newstate.
curDim;
1235 curDim_ = MVT::GetNumberVecs(*ivec);
1238 curDim_ = (int)(curDim_ / blockSize_)*blockSize_;
1239 if (curDim_ > blockSize_*numBlocks_) {
1242 curDim_ = blockSize_*numBlocks_;
1244 bool userand =
false;
1249 curDim_ = blockSize_;
1252 std::vector<int> nevind(curDim_);
1253 for (
int i=0; i<curDim_; ++i) nevind[i] = i;
1259 lclV = MVT::CloneViewNonConst(*V_,nevind);
1263 MVT::MvRandom(*lclV);
1269 if(MVT::GetNumberVecs(*newstate.
V) > curDim_) {
1271 MVT::SetBlock(*helperMV,nevind,*lclV);
1274 MVT::SetBlock(*newstate.
V,nevind,*lclV);
1278 if(MVT::GetNumberVecs(*ivec) > curDim_) {
1279 ivec = MVT::CloneView(*ivec,nevind);
1282 MVT::SetBlock(*ivec,nevind,*lclV);
1288 std::vector<int> dimind(curDim_);
1289 for (
int i=0; i<curDim_; ++i) dimind[i] = i;
1292 if(hasM_ && newstate.
MopV == Teuchos::null)
1294 om_->stream(
Debug) <<
"Computing MV\n";
1296 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1299 count_ApplyM_+= curDim_;
1303 lclMV = MVT::CloneViewNonConst(*MV_,dimind);
1304 OPT::Apply(*MOp_,*lclV,*lclMV);
1309 om_->stream(
Debug) <<
"Copying MV\n";
1312 "Anasazi::TraceMinBase::initialize(newstate): Vector length of MV not correct." );
1315 "Anasazi::TraceMinBase::initialize(newstate): Number of vectors in MV not correct.");
1317 if(newstate.
MopV != MV_) {
1318 if(curDim_ < MVT::GetNumberVecs(*newstate.
MopV)) {
1319 newstate.
MopV = MVT::CloneView(*newstate.
MopV,dimind);
1321 MVT::SetBlock(*newstate.
MopV,dimind,*MV_);
1323 lclMV = MVT::CloneViewNonConst(*MV_,dimind);
1328 om_->stream(
Debug) <<
"There is no MV\n";
1337 om_->stream(
Debug) <<
"Project and normalize\n";
1339 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1344 newstate.
X = Teuchos::null;
1345 newstate.
MX = Teuchos::null;
1346 newstate.
KX = Teuchos::null;
1347 newstate.
R = Teuchos::null;
1348 newstate.
T = Teuchos::null;
1349 newstate.
RV = Teuchos::null;
1350 newstate.
KK = Teuchos::null;
1351 newstate.
KV = Teuchos::null;
1354 if(auxVecs_.size() > 0)
1356 rank = orthman_->projectAndNormalizeMat(*lclV, auxVecs_,
1358 Teuchos::null, lclMV, MauxVecs_);
1362 rank = orthman_->normalizeMat(*lclV,Teuchos::null,lclMV);
1366 "Anasazi::TraceMinBase::initialize(): Couldn't generate initial basis of full rank.");
1370 if(Op_ != Teuchos::null && newstate.
KV == Teuchos::null)
1372 om_->stream(
Debug) <<
"Computing KV\n";
1374 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1377 count_ApplyOp_+= curDim_;
1380 newstate.
X = Teuchos::null;
1381 newstate.
MX = Teuchos::null;
1382 newstate.
KX = Teuchos::null;
1383 newstate.
R = Teuchos::null;
1384 newstate.
T = Teuchos::null;
1385 newstate.
RV = Teuchos::null;
1386 newstate.
KK = Teuchos::null;
1387 newstate.
KV = Teuchos::null;
1389 lclKV = MVT::CloneViewNonConst(*KV_,dimind);
1390 OPT::Apply(*Op_,*lclV,*lclKV);
1393 else if(Op_ != Teuchos::null)
1395 om_->stream(
Debug) <<
"Copying MV\n";
1398 "Anasazi::TraceMinBase::initialize(newstate): Vector length of MV not correct." );
1401 "Anasazi::TraceMinBase::initialize(newstate): Number of vectors in KV not correct.");
1403 if (newstate.
KV != KV_) {
1404 if (curDim_ < MVT::GetNumberVecs(*newstate.
KV)) {
1405 newstate.
KV = MVT::CloneView(*newstate.
KV,dimind);
1407 MVT::SetBlock(*newstate.
KV,dimind,*KV_);
1409 lclKV = MVT::CloneViewNonConst(*KV_,dimind);
1413 om_->stream(
Debug) <<
"There is no KV\n";
1420 if(newstate.
KK == Teuchos::null)
1422 om_->stream(
Debug) <<
"Computing KK\n";
1425 newstate.
X = Teuchos::null;
1426 newstate.
MX = Teuchos::null;
1427 newstate.
KX = Teuchos::null;
1428 newstate.
R = Teuchos::null;
1429 newstate.
T = Teuchos::null;
1430 newstate.
RV = Teuchos::null;
1439 MVT::MvTransMv(ONE,*lclV,*lclKV,*lclKK);
1444 om_->stream(
Debug) <<
"Copying KK\n";
1448 "Anasazi::TraceMinBase::initialize(newstate): Projected matrix in new state must be as large as specified state rank.");
1452 if (newstate.
KK != KK_) {
1453 if (newstate.
KK->numRows() > curDim_ || newstate.
KK->numCols() > curDim_) {
1456 lclKK->assign(*newstate.
KK);
1461 if(newstate.
T == Teuchos::null || newstate.
RV == Teuchos::null)
1463 om_->stream(
Debug) <<
"Computing Ritz pairs\n";
1466 newstate.
X = Teuchos::null;
1467 newstate.
MX = Teuchos::null;
1468 newstate.
KX = Teuchos::null;
1469 newstate.
R = Teuchos::null;
1470 newstate.
T = Teuchos::null;
1471 newstate.
RV = Teuchos::null;
1478 om_->stream(
Debug) <<
"Copying Ritz pairs\n";
1481 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of T must be consistent with dimension of V.");
1484 "Anasazi::TraceMinBase::initialize(newstate): Ritz vectors in new state must be as large as specified state rank.");
1486 std::copy(newstate.
T->begin(),newstate.
T->end(),theta_.begin());
1489 if (newstate.
RV != ritzVecs_) {
1490 if (newstate.
RV->numRows() > curDim_ || newstate.
RV->numCols() > curDim_) {
1493 lclRV->assign(*newstate.
RV);
1498 if(newstate.
X == Teuchos::null)
1500 om_->stream(
Debug) <<
"Computing X\n";
1503 newstate.
MX = Teuchos::null;
1504 newstate.
KX = Teuchos::null;
1505 newstate.
R = Teuchos::null;
1512 om_->stream(
Debug) <<
"Copying X\n";
1514 if(computeAllRes_ ==
false)
1516 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*newstate.
X) != blockSize_ || MVT::GetGlobalLength(*newstate.
X) != MVT::GetGlobalLength(*X_),
1517 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of X must be consistent with block size and length of V.");
1519 if(newstate.
X != X_) {
1520 MVT::SetBlock(*newstate.
X,bsind,*X_);
1525 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*newstate.
X) != curDim_ || MVT::GetGlobalLength(*newstate.
X) != MVT::GetGlobalLength(*X_),
1526 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of X must be consistent with current dimension and length of V.");
1528 if(newstate.
X != X_) {
1529 MVT::SetBlock(*newstate.
X,dimind,*X_);
1536 if((Op_ != Teuchos::null && newstate.
KX == Teuchos::null) || (hasM_ && newstate.
MX == Teuchos::null))
1538 om_->stream(
Debug) <<
"Computing KX and MX\n";
1541 newstate.
R = Teuchos::null;
1548 om_->stream(
Debug) <<
"Copying KX and MX\n";
1549 if(Op_ != Teuchos::null)
1551 if(computeAllRes_ ==
false)
1554 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of KX must be consistent with block size and length of V.");
1556 if(newstate.
KX != KX_) {
1557 MVT::SetBlock(*newstate.
KX,bsind,*KX_);
1563 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of KX must be consistent with current dimension and length of V.");
1565 if (newstate.
KX != KX_) {
1566 MVT::SetBlock(*newstate.
KX,dimind,*KX_);
1573 if(computeAllRes_ ==
false)
1576 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of MX must be consistent with block size and length of V.");
1578 if (newstate.
MX != MX_) {
1579 MVT::SetBlock(*newstate.
MX,bsind,*MX_);
1585 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of MX must be consistent with current dimension and length of V.");
1587 if (newstate.
MX != MX_) {
1588 MVT::SetBlock(*newstate.
MX,dimind,*MX_);
1595 if(newstate.
R == Teuchos::null)
1597 om_->stream(
Debug) <<
"Computing R\n";
1604 om_->stream(
Debug) <<
"Copying R\n";
1606 if(computeAllRes_ ==
false)
1609 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): vector length of newstate.R not correct." );
1611 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): newstate.R must have at least block size vectors." );
1612 if (newstate.
R != R_) {
1613 MVT::SetBlock(*newstate.
R,bsind,*R_);
1619 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): vector length of newstate.R not correct." );
1621 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): newstate.R must have at least curDim vectors." );
1622 if (newstate.
R != R_) {
1623 MVT::SetBlock(*newstate.
R,dimind,*R_);
1629 Rnorms_current_ =
false;
1630 R2norms_current_ =
false;
1638 om_->stream(
Debug) <<
"Copying Ritz shifts\n";
1643 om_->stream(
Debug) <<
"Setting Ritz shifts to 0\n";
1644 for(
size_t i=0; i<ritzShifts_.size(); i++)
1645 ritzShifts_[i] = ZERO;
1648 for(
size_t i=0; i<ritzShifts_.size(); i++)
1649 om_->stream(
Debug) <<
"Ritz shifts[" << i <<
"] = " << ritzShifts_[i] << std::endl;
1652 initialized_ =
true;
1654 if (om_->isVerbosity(
Debug ) ) {
1663 om_->print(
Debug, accuracyCheck(chk,
": after initialize()") );
1667 if (om_->isVerbosity(
Debug)) {
1668 currentStatus( om_->stream(
Debug) );
1690 template <
class ScalarType,
class MV,
class OP>
1697 std::vector<int> bsind(blockSize_);
1698 for (
int i=0; i<blockSize_; ++i) bsind[i] = i;
1726 if (newstate.
V != Teuchos::null) {
1727 om_->stream(
Debug) <<
"Copying V from the user\n";
1730 "Anasazi::TraceMinBase::initialize(newstate): Vector length of V not correct." );
1732 "Anasazi::TraceMinBase::initialize(newstate): Rank of new state must be at least blockSize().");
1734 "Anasazi::TraceMinBase::initialize(newstate): Rank of new state must be less than getMaxSubspaceDim().");
1737 "Anasazi::TraceMinBase::initialize(newstate): Multivector for basis in new state must be as large as specified state rank.");
1739 curDim_ = newstate.
curDim;
1741 curDim_ = (int)(curDim_ / blockSize_)*blockSize_;
1744 "Anasazi::TraceMinBase::initialize(newstate): Rank of new state must be a multiple of getBlockSize().");
1747 std::vector<int> nevind(curDim_);
1748 for (
int i=0; i<curDim_; ++i) nevind[i] = i;
1749 if (newstate.
V != V_) {
1750 if (curDim_ < MVT::GetNumberVecs(*newstate.
V)) {
1751 newstate.
V = MVT::CloneView(*newstate.
V,nevind);
1753 MVT::SetBlock(*newstate.
V,nevind,*V_);
1755 lclV = MVT::CloneViewNonConst(*V_,nevind);
1762 "Anasazi::TraceMinBase::initialize(newstate): Eigenproblem did not specify initial vectors to clone from.");
1764 newstate.
X = Teuchos::null;
1765 newstate.
MX = Teuchos::null;
1766 newstate.
KX = Teuchos::null;
1767 newstate.
R = Teuchos::null;
1768 newstate.
T = Teuchos::null;
1769 newstate.
RV = Teuchos::null;
1770 newstate.
KK = Teuchos::null;
1771 newstate.
KV = Teuchos::null;
1772 newstate.
MopV = Teuchos::null;
1777 curDim_ = newstate.
curDim;
1779 curDim_ = MVT::GetNumberVecs(*ivec);
1782 curDim_ = (int)(curDim_ / blockSize_)*blockSize_;
1783 if (curDim_ > blockSize_*numBlocks_) {
1786 curDim_ = blockSize_*numBlocks_;
1788 bool userand =
false;
1793 curDim_ = blockSize_;
1796 std::vector<int> nevind(curDim_);
1797 for (
int i=0; i<curDim_; ++i) nevind[i] = i;
1803 lclV = MVT::CloneViewNonConst(*V_,nevind);
1807 MVT::MvRandom(*lclV);
1813 if(MVT::GetNumberVecs(*newstate.
V) > curDim_) {
1815 MVT::SetBlock(*helperMV,nevind,*lclV);
1818 MVT::SetBlock(*newstate.
V,nevind,*lclV);
1822 if(MVT::GetNumberVecs(*ivec) > curDim_) {
1823 ivec = MVT::CloneView(*ivec,nevind);
1826 MVT::SetBlock(*ivec,nevind,*lclV);
1834 newstate.
X = Teuchos::null;
1835 newstate.
MX = Teuchos::null;
1836 newstate.
KX = Teuchos::null;
1837 newstate.
R = Teuchos::null;
1838 newstate.
T = Teuchos::null;
1839 newstate.
RV = Teuchos::null;
1840 newstate.
KK = Teuchos::null;
1841 newstate.
KV = Teuchos::null;
1842 newstate.
MopV = Teuchos::null;
1846 std::vector<int> dimind(curDim_);
1847 for (
int i=0; i<curDim_; ++i) dimind[i] = i;
1850 if(auxVecs_.size() > 0)
1851 orthman_->projectMat(*lclV,auxVecs_);
1854 if(Op_ != Teuchos::null && newstate.
KV == Teuchos::null)
1856 om_->stream(
Debug) <<
"Computing KV\n";
1858 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1861 count_ApplyOp_+= curDim_;
1864 newstate.
X = Teuchos::null;
1865 newstate.
MX = Teuchos::null;
1866 newstate.
KX = Teuchos::null;
1867 newstate.
R = Teuchos::null;
1868 newstate.
T = Teuchos::null;
1869 newstate.
RV = Teuchos::null;
1870 newstate.
KK = Teuchos::null;
1872 lclKV = MVT::CloneViewNonConst(*KV_,dimind);
1873 OPT::Apply(*Op_,*lclV,*lclKV);
1876 else if(Op_ != Teuchos::null)
1878 om_->stream(
Debug) <<
"Copying KV\n";
1881 "Anasazi::TraceMinBase::initialize(newstate): Vector length of KV not correct." );
1884 "Anasazi::TraceMinBase::initialize(newstate): Number of vectors in KV not correct.");
1886 if (newstate.
KV != KV_) {
1887 if (curDim_ < MVT::GetNumberVecs(*newstate.
KV)) {
1888 newstate.
KV = MVT::CloneView(*newstate.
KV,dimind);
1890 MVT::SetBlock(*newstate.
KV,dimind,*KV_);
1892 lclKV = MVT::CloneViewNonConst(*KV_,dimind);
1896 om_->stream(
Debug) <<
"There is no KV\n";
1907 om_->stream(
Debug) <<
"Project and normalize\n";
1909 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1914 newstate.
MopV = Teuchos::null;
1915 newstate.
X = Teuchos::null;
1916 newstate.
MX = Teuchos::null;
1917 newstate.
KX = Teuchos::null;
1918 newstate.
R = Teuchos::null;
1919 newstate.
T = Teuchos::null;
1920 newstate.
RV = Teuchos::null;
1921 newstate.
KK = Teuchos::null;
1925 int rank = orthman_->normalizeMat(*lclKV,gamma);
1931 RCP<MV> tempMV = MVT::CloneCopy(*lclV);
1932 MVT::MvTimesMatAddMv(ONE,*tempMV,*gamma,ZERO,*lclV);
1935 "Anasazi::TraceMinBase::initialize(): Couldn't generate initial basis of full rank.");
1939 if(hasM_ && newstate.
MopV == Teuchos::null)
1941 om_->stream(
Debug) <<
"Computing MV\n";
1943 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1946 count_ApplyM_+= curDim_;
1949 lclMV = MVT::CloneViewNonConst(*MV_,dimind);
1950 OPT::Apply(*MOp_,*lclV,*lclMV);
1955 om_->stream(
Debug) <<
"Copying MV\n";
1958 "Anasazi::TraceMinBase::initialize(newstate): Vector length of MV not correct." );
1961 "Anasazi::TraceMinBase::initialize(newstate): Number of vectors in MV not correct.");
1963 if(newstate.
MopV != MV_) {
1964 if(curDim_ < MVT::GetNumberVecs(*newstate.
MopV)) {
1965 newstate.
MopV = MVT::CloneView(*newstate.
MopV,dimind);
1967 MVT::SetBlock(*newstate.
MopV,dimind,*MV_);
1969 lclMV = MVT::CloneViewNonConst(*MV_,dimind);
1974 om_->stream(
Debug) <<
"There is no MV\n";
1981 if(newstate.
KK == Teuchos::null)
1983 om_->stream(
Debug) <<
"Computing KK\n";
1986 newstate.
X = Teuchos::null;
1987 newstate.
MX = Teuchos::null;
1988 newstate.
KX = Teuchos::null;
1989 newstate.
R = Teuchos::null;
1990 newstate.
T = Teuchos::null;
1991 newstate.
RV = Teuchos::null;
2000 MVT::MvTransMv(ONE,*lclV,*lclKV,*lclKK);
2005 om_->stream(
Debug) <<
"Copying KK\n";
2009 "Anasazi::TraceMinBase::initialize(newstate): Projected matrix in new state must be as large as specified state rank.");
2013 if (newstate.
KK != KK_) {
2014 if (newstate.
KK->numRows() > curDim_ || newstate.
KK->numCols() > curDim_) {
2017 lclKK->assign(*newstate.
KK);
2022 if(newstate.
T == Teuchos::null || newstate.
RV == Teuchos::null)
2024 om_->stream(
Debug) <<
"Computing Ritz pairs\n";
2027 newstate.
X = Teuchos::null;
2028 newstate.
MX = Teuchos::null;
2029 newstate.
KX = Teuchos::null;
2030 newstate.
R = Teuchos::null;
2031 newstate.
T = Teuchos::null;
2032 newstate.
RV = Teuchos::null;
2039 om_->stream(
Debug) <<
"Copying Ritz pairs\n";
2042 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of T must be consistent with dimension of V.");
2045 "Anasazi::TraceMinBase::initialize(newstate): Ritz vectors in new state must be as large as specified state rank.");
2047 std::copy(newstate.
T->begin(),newstate.
T->end(),theta_.begin());
2050 if (newstate.
RV != ritzVecs_) {
2051 if (newstate.
RV->numRows() > curDim_ || newstate.
RV->numCols() > curDim_) {
2054 lclRV->assign(*newstate.
RV);
2059 if(newstate.
X == Teuchos::null)
2061 om_->stream(
Debug) <<
"Computing X\n";
2064 newstate.
MX = Teuchos::null;
2065 newstate.
KX = Teuchos::null;
2066 newstate.
R = Teuchos::null;
2073 om_->stream(
Debug) <<
"Copying X\n";
2075 if(computeAllRes_ ==
false)
2077 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*newstate.
X) != blockSize_ || MVT::GetGlobalLength(*newstate.
X) != MVT::GetGlobalLength(*X_),
2078 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of X must be consistent with block size and length of V.");
2080 if(newstate.
X != X_) {
2081 MVT::SetBlock(*newstate.
X,bsind,*X_);
2086 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*newstate.
X) != curDim_ || MVT::GetGlobalLength(*newstate.
X) != MVT::GetGlobalLength(*X_),
2087 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of X must be consistent with current dimension and length of V.");
2089 if(newstate.
X != X_) {
2090 MVT::SetBlock(*newstate.
X,dimind,*X_);
2097 if((Op_ != Teuchos::null && newstate.
KX == Teuchos::null) || (hasM_ && newstate.
MX == Teuchos::null))
2099 om_->stream(
Debug) <<
"Computing KX and MX\n";
2102 newstate.
R = Teuchos::null;
2109 om_->stream(
Debug) <<
"Copying KX and MX\n";
2110 if(Op_ != Teuchos::null)
2112 if(computeAllRes_ ==
false)
2115 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of KX must be consistent with block size and length of V.");
2117 if(newstate.
KX != KX_) {
2118 MVT::SetBlock(*newstate.
KX,bsind,*KX_);
2124 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of KX must be consistent with current dimension and length of V.");
2126 if (newstate.
KX != KX_) {
2127 MVT::SetBlock(*newstate.
KX,dimind,*KX_);
2134 if(computeAllRes_ ==
false)
2137 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of MX must be consistent with block size and length of V.");
2139 if (newstate.
MX != MX_) {
2140 MVT::SetBlock(*newstate.
MX,bsind,*MX_);
2146 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of MX must be consistent with current dimension and length of V.");
2148 if (newstate.
MX != MX_) {
2149 MVT::SetBlock(*newstate.
MX,dimind,*MX_);
2158 const int nvecs = computeAllRes_ ? curDim_ : blockSize_;
2160 RCP<MV> lclX = MVT::CloneViewNonConst(*X_, dimind2);
2161 std::vector<ScalarType> normvec(nvecs);
2162 orthman_->normMat(*lclX,normvec);
2165 for (
int i = 0; i < nvecs; ++i) {
2166 normvec[i] = ONE / normvec[i];
2168 MVT::MvScale (*lclX, normvec);
2169 if (Op_ != Teuchos::null) {
2170 RCP<MV> lclKX = MVT::CloneViewNonConst (*KX_, dimind2);
2171 MVT::MvScale (*lclKX, normvec);
2174 RCP<MV> lclMX = MVT::CloneViewNonConst (*MX_, dimind2);
2175 MVT::MvScale (*lclMX, normvec);
2179 for (
int i = 0; i < nvecs; ++i) {
2180 theta_[i] = theta_[i] * normvec[i] * normvec[i];
2185 if(newstate.
R == Teuchos::null)
2187 om_->stream(
Debug) <<
"Computing R\n";
2194 om_->stream(
Debug) <<
"Copying R\n";
2196 if(computeAllRes_ ==
false)
2199 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): vector length of newstate.R not correct." );
2201 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): newstate.R must have at least block size vectors." );
2202 if (newstate.
R != R_) {
2203 MVT::SetBlock(*newstate.
R,bsind,*R_);
2209 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): vector length of newstate.R not correct." );
2211 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): newstate.R must have at least curDim vectors." );
2212 if (newstate.
R != R_) {
2213 MVT::SetBlock(*newstate.
R,dimind,*R_);
2219 Rnorms_current_ =
false;
2220 R2norms_current_ =
false;
2228 om_->stream(
Debug) <<
"Copying Ritz shifts\n";
2233 om_->stream(
Debug) <<
"Setting Ritz shifts to 0\n";
2234 for(
size_t i=0; i<ritzShifts_.size(); i++)
2235 ritzShifts_[i] = ZERO;
2238 for(
size_t i=0; i<ritzShifts_.size(); i++)
2239 om_->stream(
Debug) <<
"Ritz shifts[" << i <<
"] = " << ritzShifts_[i] << std::endl;
2242 initialized_ =
true;
2244 if (om_->isVerbosity(
Debug ) ) {
2253 om_->print(
Debug, accuracyCheck(chk,
": after initialize()") );
2257 if (om_->isVerbosity(
Debug)) {
2258 currentStatus( om_->stream(
Debug) );
2268 template <
class ScalarType,
class MV,
class OP>
2274 template <
class ScalarType,
class MV,
class OP>
2280 TEUCHOS_TEST_FOR_EXCEPTION(blockSize < 1, std::invalid_argument,
"Anasazi::TraceMinBase::setSize(blocksize,numblocks): blocksize must be strictly positive.");
2282 if (blockSize == blockSize_ && numBlocks == numBlocks_) {
2287 blockSize_ = blockSize;
2288 numBlocks_ = numBlocks;
2295 if (X_ != Teuchos::null) {
2299 tmp = problem_->getInitVec();
2301 "Anasazi::TraceMinBase::setSize(): eigenproblem did not specify initial vectors to clone from.");
2304 TEUCHOS_TEST_FOR_EXCEPTION(numAuxVecs_+blockSize*static_cast<ptrdiff_t>(numBlocks) > MVT::GetGlobalLength(*tmp),std::invalid_argument,
2305 "Anasazi::TraceMinBase::setSize(): max subspace dimension and auxilliary subspace too large. Potentially impossible orthogonality constraints.");
2308 int newsd = blockSize_*numBlocks_;
2313 ritzShifts_.resize(blockSize_,ZERO);
2314 if(computeAllRes_ ==
false)
2317 Rnorms_.resize(blockSize_,NANVAL);
2318 R2norms_.resize(blockSize_,NANVAL);
2324 KX_ = Teuchos::null;
2325 MX_ = Teuchos::null;
2328 KV_ = Teuchos::null;
2329 MV_ = Teuchos::null;
2331 om_->print(
Debug,
" >> Allocating X_\n");
2332 X_ = MVT::Clone(*tmp,blockSize_);
2333 if(Op_ != Teuchos::null) {
2334 om_->print(
Debug,
" >> Allocating KX_\n");
2335 KX_ = MVT::Clone(*tmp,blockSize_);
2341 om_->print(
Debug,
" >> Allocating MX_\n");
2342 MX_ = MVT::Clone(*tmp,blockSize_);
2347 om_->print(
Debug,
" >> Allocating R_\n");
2348 R_ = MVT::Clone(*tmp,blockSize_);
2353 Rnorms_.resize(newsd,NANVAL);
2354 R2norms_.resize(newsd,NANVAL);
2360 KX_ = Teuchos::null;
2361 MX_ = Teuchos::null;
2364 KV_ = Teuchos::null;
2365 MV_ = Teuchos::null;
2367 om_->print(
Debug,
" >> Allocating X_\n");
2368 X_ = MVT::Clone(*tmp,newsd);
2369 if(Op_ != Teuchos::null) {
2370 om_->print(
Debug,
" >> Allocating KX_\n");
2371 KX_ = MVT::Clone(*tmp,newsd);
2377 om_->print(
Debug,
" >> Allocating MX_\n");
2378 MX_ = MVT::Clone(*tmp,newsd);
2383 om_->print(
Debug,
" >> Allocating R_\n");
2384 R_ = MVT::Clone(*tmp,newsd);
2390 theta_.resize(newsd,NANVAL);
2391 om_->print(
Debug,
" >> Allocating V_\n");
2392 V_ = MVT::Clone(*tmp,newsd);
2396 if(Op_ != Teuchos::null) {
2397 om_->print(
Debug,
" >> Allocating KV_\n");
2398 KV_ = MVT::Clone(*tmp,newsd);
2404 om_->print(
Debug,
" >> Allocating MV_\n");
2405 MV_ = MVT::Clone(*tmp,newsd);
2411 om_->print(
Debug,
" >> done allocating.\n");
2413 initialized_ =
false;
2420 template <
class ScalarType,
class MV,
class OP>
2431 for (tarcpmv i=auxVecs_.begin(); i != auxVecs_.end(); ++i) {
2432 numAuxVecs_ += MVT::GetNumberVecs(**i);
2436 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
2439 count_ApplyM_+= MVT::GetNumberVecs(**i);
2441 RCP<MV> helperMV = MVT::Clone(**i,MVT::GetNumberVecs(**i));
2442 OPT::Apply(*MOp_,**i,*helperMV);
2443 MauxVecs_.push_back(helperMV);
2448 if (numAuxVecs_ > 0 && initialized_) {
2449 initialized_ =
false;
2452 if (om_->isVerbosity(
Debug ) ) {
2456 om_->print(
Debug, accuracyCheck(chk,
": after setAuxVecs()") );
2463 template <
class ScalarType,
class MV,
class OP>
2464 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
2466 if (Rnorms_current_ ==
false) {
2470 std::vector<int> curind(curDim_);
2471 for(
int i=0; i<curDim_; i++)
2475 std::vector<ScalarType> locNorms(curDim_);
2476 orthman_->norm(*locR,locNorms);
2478 for(
int i=0; i<curDim_; i++)
2479 Rnorms_[i] = locNorms[i];
2480 for(
int i=curDim_+1; i<blockSize_*numBlocks_; i++)
2481 Rnorms_[i] = NANVAL;
2483 Rnorms_current_ =
true;
2484 locNorms.resize(blockSize_);
2488 orthman_->norm(*R_,Rnorms_);
2489 Rnorms_current_ =
true;
2491 else if(computeAllRes_)
2493 std::vector<ScalarType> locNorms(blockSize_);
2494 for(
int i=0; i<blockSize_; i++)
2495 locNorms[i] = Rnorms_[i];
2505 template <
class ScalarType,
class MV,
class OP>
2506 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
2508 if (R2norms_current_ ==
false) {
2512 std::vector<int> curind(curDim_);
2513 for(
int i=0; i<curDim_; i++)
2517 std::vector<ScalarType> locNorms(curDim_);
2518 MVT::MvNorm(*locR,locNorms);
2520 for(
int i=0; i<curDim_; i++)
2522 R2norms_[i] = locNorms[i];
2524 for(
int i=curDim_+1; i<blockSize_*numBlocks_; i++)
2525 R2norms_[i] = NANVAL;
2527 R2norms_current_ =
true;
2528 locNorms.resize(blockSize_);
2532 MVT::MvNorm(*R_,R2norms_);
2533 R2norms_current_ =
true;
2535 else if(computeAllRes_)
2537 std::vector<ScalarType> locNorms(blockSize_);
2538 for(
int i=0; i<blockSize_; i++)
2539 locNorms[i] = R2norms_[i];
2548 template <
class ScalarType,
class MV,
class OP>
2551 "Anasazi::TraceMinBase::setStatusTest() was passed a null StatusTest.");
2557 template <
class ScalarType,
class MV,
class OP>
2564 template <
class ScalarType,
class MV,
class OP>
2570 os.setf(std::ios::scientific, std::ios::floatfield);
2573 os <<
"================================================================================" << endl;
2575 os <<
" TraceMinBase Solver Status" << endl;
2577 os <<
"The solver is "<<(initialized_ ?
"initialized." :
"not initialized.") << endl;
2578 os <<
"The number of iterations performed is " <<iter_<<endl;
2579 os <<
"The block size is " << blockSize_<<endl;
2580 os <<
"The number of blocks is " << numBlocks_<<endl;
2581 os <<
"The current basis size is " << curDim_<<endl;
2582 os <<
"The number of auxiliary vectors is "<< numAuxVecs_ << endl;
2583 os <<
"The number of operations Op*x is "<<count_ApplyOp_<<endl;
2584 os <<
"The number of operations M*x is "<<count_ApplyM_<<endl;
2586 os.setf(std::ios_base::right, std::ios_base::adjustfield);
2590 os <<
"CURRENT EIGENVALUE ESTIMATES "<<endl;
2591 os << std::setw(20) <<
"Eigenvalue"
2592 << std::setw(20) <<
"Residual(M)"
2593 << std::setw(20) <<
"Residual(2)"
2595 os <<
"--------------------------------------------------------------------------------"<<endl;
2596 for (
int i=0; i<blockSize_; ++i) {
2597 os << std::setw(20) << theta_[i];
2598 if (Rnorms_current_) os << std::setw(20) << Rnorms_[i];
2599 else os << std::setw(20) <<
"not current";
2600 if (R2norms_current_) os << std::setw(20) << R2norms_[i];
2601 else os << std::setw(20) <<
"not current";
2605 os <<
"================================================================================" << endl;
2610 template <
class ScalarType,
class MV,
class OP>
2613 ScalarType currentTrace = ZERO;
2615 for(
int i=0; i < blockSize_; i++)
2616 currentTrace += theta_[i];
2618 return currentTrace;
2622 template <
class ScalarType,
class MV,
class OP>
2623 bool TraceMinBase<ScalarType,MV,OP>::traceLeveled()
2625 ScalarType ratioOfChange = traceThresh_;
2627 if(previouslyLeveled_)
2629 om_->stream(
Debug) <<
"The trace already leveled, so we're not going to check it again\n";
2633 ScalarType currentTrace = getTrace();
2635 om_->stream(
Debug) <<
"The current trace is " << currentTrace << std::endl;
2640 if(previousTrace_ != ZERO)
2642 om_->stream(
Debug) <<
"The previous trace was " << previousTrace_ << std::endl;
2644 ratioOfChange = std::abs(previousTrace_-currentTrace)/std::abs(previousTrace_);
2645 om_->stream(
Debug) <<
"The ratio of change is " << ratioOfChange << std::endl;
2648 previousTrace_ = currentTrace;
2650 if(ratioOfChange < traceThresh_)
2652 previouslyLeveled_ =
true;
2661 template <
class ScalarType,
class MV,
class OP>
2662 std::vector<ScalarType> TraceMinBase<ScalarType,MV,OP>::getClusterResids()
2673 std::vector<ScalarType> clusterResids(nvecs);
2674 std::vector<int> clusterIndices;
2675 if(considerClusters_)
2677 for(
int i=0; i < nvecs; i++)
2680 if(clusterIndices.empty() || (theta_[i-1] + R2norms_[i-1] >= theta_[i] - R2norms_[i]))
2683 if(!clusterIndices.empty()) om_->stream(
Debug) << theta_[i-1] <<
" is in a cluster with " << theta_[i] <<
" because " << theta_[i-1] + R2norms_[i-1] <<
" >= " << theta_[i] - R2norms_[i] << std::endl;
2684 clusterIndices.push_back(i);
2689 om_->stream(
Debug) << theta_[i-1] <<
" is NOT in a cluster with " << theta_[i] <<
" because " << theta_[i-1] + R2norms_[i-1] <<
" < " << theta_[i] - R2norms_[i] << std::endl;
2690 ScalarType totalRes = ZERO;
2691 for(
size_t j=0; j < clusterIndices.size(); j++)
2692 totalRes += (R2norms_[clusterIndices[j]]*R2norms_[clusterIndices[j]]);
2697 if(theta_[clusterIndices[0]] < 0 && theta_[i] < 0)
2698 negSafeToShift_ =
true;
2699 else if(theta_[clusterIndices[0]] > 0 && theta_[i] > 0)
2700 posSafeToShift_ =
true;
2702 for(
size_t j=0; j < clusterIndices.size(); j++)
2703 clusterResids[clusterIndices[j]] = sqrt(totalRes);
2705 clusterIndices.clear();
2706 clusterIndices.push_back(i);
2711 ScalarType totalRes = ZERO;
2712 for(
size_t j=0; j < clusterIndices.size(); j++)
2713 totalRes += R2norms_[clusterIndices[j]];
2714 for(
size_t j=0; j < clusterIndices.size(); j++)
2715 clusterResids[clusterIndices[j]] = totalRes;
2719 for(
int j=0; j < nvecs; j++)
2720 clusterResids[j] = R2norms_[j];
2723 return clusterResids;
2732 template <
class ScalarType,
class MV,
class OP>
2733 void TraceMinBase<ScalarType,MV,OP>::computeRitzShifts(
const std::vector<ScalarType>& clusterResids)
2735 std::vector<ScalarType> thetaMag(theta_);
2736 bool traceHasLeveled = traceLeveled();
2739 for(
int i=0; i<blockSize_; i++)
2740 thetaMag[i] = std::abs(thetaMag[i]);
2748 if(whenToShift_ == ALWAYS_SHIFT || (whenToShift_ == SHIFT_WHEN_TRACE_LEVELS && traceHasLeveled))
2751 if(howToShift_ == LARGEST_CONVERGED_SHIFT)
2753 for(
int i=0; i<blockSize_; i++)
2754 ritzShifts_[i] = largestSafeShift_;
2757 else if(howToShift_ == RITZ_VALUES_SHIFT)
2759 ritzShifts_[0] = theta_[0];
2763 if(useMultipleShifts_)
2765 for(
int i=1; i<blockSize_; i++)
2766 ritzShifts_[i] = theta_[i];
2770 for(
int i=1; i<blockSize_; i++)
2771 ritzShifts_[i] = ritzShifts_[0];
2774 else if(howToShift_ == EXPERIMENTAL_SHIFT)
2776 ritzShifts_[0] = std::max(largestSafeShift_,theta_[0]-clusterResids[0]);
2777 for(
int i=1; i<blockSize_; i++)
2779 ritzShifts_[i] = std::max(ritzShifts_[i-1],theta_[i]-clusterResids[i]);
2783 else if(howToShift_ == ADJUSTED_RITZ_SHIFT)
2785 om_->stream(
Debug) <<
"\nSeeking a shift for theta[0]=" << thetaMag[0] << std::endl;
2789 if((theta_[0] > 0 && posSafeToShift_) || (theta_[0] < 0 && negSafeToShift_) || considerClusters_ ==
false)
2792 ritzShifts_[0] = std::max(largestSafeShift_,thetaMag[0]-clusterResids[0]);
2794 om_->stream(
Debug) <<
"Initializing with a conservative shift, either the most positive converged eigenvalue ("
2795 << largestSafeShift_ <<
") or the eigenvalue adjusted by the residual (" << thetaMag[0] <<
"-"
2796 << clusterResids[0] <<
").\n";
2799 if(R2norms_[0] == clusterResids[0])
2801 ritzShifts_[0] = thetaMag[0];
2802 om_->stream(
Debug) <<
"Since this eigenvalue is NOT in a cluster, we can use the eigenvalue itself as a shift: ritzShifts[0]=" << ritzShifts_[0] << std::endl;
2805 om_->stream(
Debug) <<
"This eigenvalue is in a cluster, so it would not be safe to use the eigenvalue itself as a shift\n";
2809 if(largestSafeShift_ > std::abs(ritzShifts_[0]))
2811 om_->stream(
Debug) <<
"Initializing with a conservative shift...the most positive converged eigenvalue: " << largestSafeShift_ << std::endl;
2812 ritzShifts_[0] = largestSafeShift_;
2815 om_->stream(
Debug) <<
"Using the previous value of ritzShifts[0]=" << ritzShifts_[0];
2819 om_->stream(
Debug) <<
"ritzShifts[0]=" << ritzShifts_[0] << std::endl;
2821 if(useMultipleShifts_)
2825 for(
int i=1; i < blockSize_; i++)
2827 om_->stream(
Debug) <<
"\nSeeking a shift for theta[" << i <<
"]=" << thetaMag[i] << std::endl;
2830 if(ritzShifts_[i-1] == thetaMag[i-1] && i < blockSize_-1 && thetaMag[i] < thetaMag[i+1] - clusterResids[i+1])
2832 ritzShifts_[i] = thetaMag[i];
2833 om_->stream(
Debug) <<
"Using an aggressive shift: ritzShifts_[" << i <<
"]=" << ritzShifts_[i] << std::endl;
2837 if(ritzShifts_[0] > std::abs(ritzShifts_[i]))
2839 om_->stream(
Debug) <<
"It was unsafe to use the aggressive shift. Choose the shift used by theta[0]="
2840 << thetaMag[0] <<
": ritzShifts[0]=" << ritzShifts_[0] << std::endl;
2843 ritzShifts_[i] = ritzShifts_[0];
2846 om_->stream(
Debug) <<
"It was unsafe to use the aggressive shift. We will use the shift from the previous iteration: " << ritzShifts_[i] << std::endl;
2848 om_->stream(
Debug) <<
"Check whether any less conservative shifts would work (such as the biggest eigenvalue outside of the cluster, namely theta[ell] < "
2849 << thetaMag[i] <<
"-" << clusterResids[i] <<
" (" << thetaMag[i] - clusterResids[i] <<
")\n";
2852 for(
int ell=0; ell < i; ell++)
2854 if(thetaMag[ell] < thetaMag[i] - clusterResids[i])
2856 ritzShifts_[i] = thetaMag[ell];
2857 om_->stream(
Debug) <<
"ritzShifts_[" << i <<
"]=" << ritzShifts_[i] <<
" is valid\n";
2864 om_->stream(
Debug) <<
"ritzShifts[" << i <<
"]=" << ritzShifts_[i] << std::endl;
2869 for(
int i=1; i<blockSize_; i++)
2870 ritzShifts_[i] = ritzShifts_[0];
2876 for(
int i=0; i<blockSize_; i++)
2879 ritzShifts_[i] = -abs(ritzShifts_[i]);
2881 ritzShifts_[i] = abs(ritzShifts_[i]);
2886 template <
class ScalarType,
class MV,
class OP>
2887 std::vector<ScalarType> TraceMinBase<ScalarType,MV,OP>::computeTol()
2890 std::vector<ScalarType> tolerances(blockSize_);
2892 for(
int i=0; i < blockSize_-1; i++)
2894 if(std::abs(theta_[blockSize_-1]) != std::abs(ritzShifts_[i]))
2895 temp1 = std::abs(theta_[i]-ritzShifts_[i])/std::abs(std::abs(theta_[blockSize_-1])-std::abs(ritzShifts_[i]));
2901 tolerances[i] = std::min(temp1*temp1,0.5);
2905 tolerances[blockSize_-1] = tolerances[blockSize_-2];
2911 template <
class ScalarType,
class MV,
class OP>
2912 void TraceMinBase<ScalarType,MV,OP>::solveSaddlePointProblem(
RCP<MV> Delta)
2914 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
2919 if(Op_ == Teuchos::null)
2930 std::vector<int> curind(blockSize_);
2931 for(
int i=0; i<blockSize_; i++)
2938 MVT::MvTransMv(ONE,*lclMX,*lclMX,*lclS);
2946 MVT::Assign(*lclX,*Delta);
2947 MVT::MvTimesMatAddMv( -ONE, *lclMX, *lclS, ONE, *Delta);
2952 MVT::MvTransMv(ONE,*MX_,*MX_,*lclS);
2959 MVT::Assign(*X_,*Delta);
2960 MVT::MvTimesMatAddMv( -ONE, *MX_, *lclS, ONE, *Delta);
2965 std::vector<int> order(curDim_);
2966 std::vector<ScalarType> tempvec(blockSize_);
2970 std::vector<ScalarType> clusterResids;
2983 clusterResids = getClusterResids();
2998 computeRitzShifts(clusterResids);
3001 std::vector<ScalarType> tolerances = computeTol();
3003 for(
int i=0; i<blockSize_; i++)
3005 om_->stream(
IterationDetails) <<
"Choosing Ritz shifts...theta[" << i <<
"]="
3006 << theta_[i] <<
", resids[" << i <<
"]=" << R2norms_[i] <<
", clusterResids[" << i <<
"]=" << clusterResids[i]
3007 <<
", ritzShifts[" << i <<
"]=" << ritzShifts_[i] <<
", and tol[" << i <<
"]=" << tolerances[i] << std::endl;
3011 ritzOp_->setRitzShifts(ritzShifts_);
3015 ritzOp_->setInnerTol(tolerances);
3018 if(saddleSolType_ == PROJECTED_KRYLOV_SOLVER)
3020 if(Prec_ != Teuchos::null)
3021 solveSaddleProjPrec(Delta);
3023 solveSaddleProj(Delta);
3025 else if(saddleSolType_ == SCHUR_COMPLEMENT_SOLVER)
3027 if(Z_ == Teuchos::null || MVT::GetNumberVecs(*Z_) != blockSize_)
3031 Z_ = MVT::Clone(*X_,blockSize_);
3034 solveSaddleSchur(Delta);
3036 else if(saddleSolType_ == BD_PREC_MINRES)
3038 solveSaddleBDPrec(Delta);
3041 else if(saddleSolType_ == HSS_PREC_GMRES)
3043 solveSaddleHSSPrec(Delta);
3046 std::cout <<
"Invalid saddle solver type\n";
3053 template <
class ScalarType,
class MV,
class OP>
3054 void TraceMinBase<ScalarType,MV,OP>::solveSaddleProj (
RCP<MV> Delta)
const
3061 std::vector<int> curind(blockSize_);
3062 for(
int i=0; i<blockSize_; i++)
3070 if(projectLockedVecs_ && numAuxVecs_ > 0)
3071 projOp =
rcp(
new TraceMinProjRitzOp<ScalarType,MV,OP>(ritzOp_,locMX,orthman_,auxVecs_) );
3073 projOp =
rcp(
new TraceMinProjRitzOp<ScalarType,MV,OP>(ritzOp_,locMX,orthman_) );
3076 projOp =
rcp(
new TraceMinProjRitzOp<ScalarType,MV,OP>(ritzOp_,locMX) );
3080 MVT::MvInit(*Delta);
3085 projOp->ApplyInverse(*locR, *Delta);
3090 projOp->ApplyInverse(*locKX, *Delta);
3098 if(projectLockedVecs_ && numAuxVecs_ > 0)
3099 projOp =
rcp(
new TraceMinProjRitzOp<ScalarType,MV,OP>(ritzOp_,MX_,orthman_,auxVecs_) );
3101 projOp =
rcp(
new TraceMinProjRitzOp<ScalarType,MV,OP>(ritzOp_,MX_,orthman_) );
3104 projOp =
rcp(
new TraceMinProjRitzOp<ScalarType,MV,OP>(ritzOp_,MX_) );
3108 MVT::MvInit(*Delta);
3111 projOp->ApplyInverse(*R_, *Delta);
3114 projOp->ApplyInverse(*KX_, *Delta);
3121 template <
class ScalarType,
class MV,
class OP>
3122 void TraceMinBase<ScalarType,MV,OP>::solveSaddleProjPrec (
RCP<MV> Delta)
const
3127 #ifdef HAVE_ANASAZI_BELOS
3134 dimension = curDim_;
3136 dimension = blockSize_;
3139 std::vector<int> curind(dimension);
3140 for(
int i=0; i<dimension; i++)
3148 if(projectLockedVecs_ && numAuxVecs_ > 0)
3149 projOp =
rcp(
new TraceMinProjRitzOpWithPrec<ScalarType,MV,OP>(ritzOp_,locMX,orthman_,auxVecs_) );
3151 projOp =
rcp(
new TraceMinProjRitzOpWithPrec<ScalarType,MV,OP>(ritzOp_,locMX,orthman_) );
3154 projOp =
rcp(
new TraceMinProjRitzOpWithPrec<ScalarType,MV,OP>(ritzOp_,locMX) );
3158 MVT::MvInit(*Delta);
3160 std::vector<int> dimind(blockSize_);
3161 for(
int i=0; i<blockSize_; i++)
3167 projOp->ApplyInverse(*locR, *Delta);
3168 MVT::MvScale(*Delta, -ONE);
3173 projOp->ApplyInverse(*locKX, *Delta);
3181 if(projectLockedVecs_ && numAuxVecs_ > 0)
3182 projOp =
rcp(
new TraceMinProjRitzOpWithPrec<ScalarType,MV,OP>(ritzOp_,MX_,orthman_,auxVecs_) );
3184 projOp =
rcp(
new TraceMinProjRitzOpWithPrec<ScalarType,MV,OP>(ritzOp_,MX_,orthman_) );
3187 projOp =
rcp(
new TraceMinProjRitzOpWithPrec<ScalarType,MV,OP>(ritzOp_,MX_) );
3191 MVT::MvInit(*Delta);
3195 projOp->ApplyInverse(*R_, *Delta);
3196 MVT::MvScale(*Delta,-ONE);
3199 projOp->ApplyInverse(*KX_, *Delta);
3207 template <
class ScalarType,
class MV,
class OP>
3208 void TraceMinBase<ScalarType,MV,OP>::solveSaddleSchur (
RCP<MV> Delta)
const
3219 std::vector<int> curind(blockSize_);
3220 for(
int i=0; i<blockSize_; i++)
3227 #ifdef USE_APPLY_INVERSE
3228 Op_->ApplyInverse(*lclMX,*Z_);
3230 ritzOp_->ApplyInverse(*lclMX,*Z_);
3234 MVT::MvTransMv(ONE,*Z_,*lclMX,*lclS);
3243 MVT::Assign(*lclX,*Delta);
3244 MVT::MvTimesMatAddMv( -ONE, *Z_, *lclL, ONE, *Delta);
3249 #ifdef USE_APPLY_INVERSE
3250 Op_->ApplyInverse(*MX_,*Z_);
3252 ritzOp_->ApplyInverse(*MX_,*Z_);
3256 MVT::MvTransMv(ONE,*Z_,*MX_,*lclS);
3264 MVT::Assign(*X_,*Delta);
3265 MVT::MvTimesMatAddMv( -ONE, *Z_, *lclL, ONE, *Delta);
3272 template <
class ScalarType,
class MV,
class OP>
3273 void TraceMinBase<ScalarType,MV,OP>::solveSaddleBDPrec (
RCP<MV> Delta)
const
3278 std::vector<int> curind(blockSize_);
3279 for(
int i=0; i<blockSize_; i++)
3281 locKX = MVT::CloneViewNonConst(*KX_, curind);
3282 locMX = MVT::CloneViewNonConst(*MX_, curind);
3301 MVT::MvInit(*Delta);
3306 if(Prec_ != Teuchos::null)
3309 sadSolver =
rcp(
new PseudoBlockMinres<ScalarType,saddle_container_type,saddle_op_type>(sadOp, sadPrec));
3312 sadSolver =
rcp(
new PseudoBlockMinres<ScalarType,saddle_container_type,saddle_op_type>(sadOp));
3316 std::vector<ScalarType> tol;
3317 ritzOp_->getInnerTol(tol);
3318 sadSolver->setTol(tol);
3321 sadSolver->setMaxIter(ritzOp_->getMaxIts());
3324 sadSolver->setSol(sadSol);
3327 sadSolver->setRHS(sadRHS);
3337 template <
class ScalarType,
class MV,
class OP>
3338 void TraceMinBase<ScalarType,MV,OP>::solveSaddleHSSPrec (
RCP<MV> Delta)
const
3340 #ifdef HAVE_ANASAZI_BELOS
3341 typedef Belos::LinearProblem<ScalarType,saddle_container_type,saddle_op_type> LP;
3342 typedef Belos::PseudoBlockGmresSolMgr<ScalarType,saddle_container_type,saddle_op_type> GmresSolMgr;
3347 std::vector<int> curind(blockSize_);
3348 for(
int i=0; i<blockSize_; i++)
3350 locKX = MVT::CloneViewNonConst(*KX_, curind);
3351 locMX = MVT::CloneViewNonConst(*MX_, curind);
3366 MVT::MvInit(*Delta);
3373 std::vector<ScalarType> tol;
3374 ritzOp_->getInnerTol(tol);
3375 pl->
set(
"Convergence Tolerance",tol[0]);
3379 pl->
set(
"Maximum Iterations", ritzOp_->getMaxIts());
3380 pl->
set(
"Num Blocks", ritzOp_->getMaxIts());
3385 pl->
set(
"Block Size", blockSize_);
3392 RCP<LP> problem =
rcp(
new LP(sadOp,sadSol,sadRHS));
3395 if(Prec_ != Teuchos::null)
3398 problem->setLeftPrec(sadPrec);
3402 problem->setProblem();
3410 std::cout <<
"No Belos. This is bad\n";
3419 template <
class ScalarType,
class MV,
class OP>
3420 void TraceMinBase<ScalarType,MV,OP>::computeKK()
3423 std::vector<int> curind(curDim_);
3424 for(
int i=0; i<curDim_; i++)
3431 curind.resize(blockSize_);
3432 for(
int i=0; i<blockSize_; i++)
3433 curind[i] = curDim_-blockSize_+i;
3441 MVT::MvTransMv(ONE,*lclV,*lclKV,*lclKK);
3444 for(
int r=0; r<curDim_; r++)
3446 for(
int c=0; c<r; c++)
3448 (*KK_)(r,c) = (*KK_)(c,r);
3455 template <
class ScalarType,
class MV,
class OP>
3456 void TraceMinBase<ScalarType,MV,OP>::computeRitzPairs()
3468 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
3472 Utils::directSolver(curDim_, *lclKK, Teuchos::null, *lclRV, theta_, rank, 10);
3476 "Anasazi::TraceMinBase::computeRitzPairs(): Failed to compute all eigenpairs of KK.");
3481 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
3485 std::vector<int> order(curDim_);
3491 sm.
sort(theta_, Teuchos::rcpFromRef(order), curDim_);
3495 sm_->sort(theta_, Teuchos::rcpFromRef(order), curDim_);
3499 Utils::permuteVectors(order,*lclRV);
3505 template <
class ScalarType,
class MV,
class OP>
3506 void TraceMinBase<ScalarType,MV,OP>::computeX()
3508 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
3513 std::vector<int> curind(curDim_);
3514 for(
int i=0; i<curDim_; i++)
3527 RCP<MV> lclX = MVT::CloneViewNonConst(*X_,curind);
3528 MVT::MvTimesMatAddMv( ONE, *lclV, *relevantEvecs, ZERO, *lclX );
3537 MVT::MvTimesMatAddMv( ONE, *lclV, *relevantEvecs, ZERO, *X_ );
3543 template <
class ScalarType,
class MV,
class OP>
3544 void TraceMinBase<ScalarType,MV,OP>::updateKXMX()
3546 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
3551 std::vector<int> curind(curDim_);
3552 for(
int i=0; i<curDim_; i++)
3566 RCP<MV> lclKX = MVT::CloneViewNonConst(*KX_,curind);
3567 MVT::MvTimesMatAddMv( ONE, *lclKV, *relevantEvecs, ZERO, *lclKX );
3571 RCP<MV> lclMX = MVT::CloneViewNonConst(*MX_,curind);
3572 MVT::MvTimesMatAddMv( ONE, *lclMV, *relevantEvecs, ZERO, *lclMX );
3582 MVT::MvTimesMatAddMv( ONE, *lclKV, *relevantEvecs, ZERO, *KX_ );
3586 MVT::MvTimesMatAddMv( ONE, *lclMV, *relevantEvecs, ZERO, *MX_ );
3593 template <
class ScalarType,
class MV,
class OP>
3594 void TraceMinBase<ScalarType,MV,OP>::updateResidual () {
3595 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
3602 std::vector<int> curind(curDim_);
3603 for(
int i=0; i<curDim_; i++)
3607 RCP<MV> MXT = MVT::CloneCopy(*MX_,curind);
3610 std::vector<ScalarType> locTheta(curDim_);
3611 for(
int i=0; i<curDim_; i++)
3612 locTheta[i] = theta_[i];
3615 MVT::MvScale(*MXT,locTheta);
3619 RCP<MV> locR = MVT::CloneViewNonConst(*R_,curind);
3620 MVT::MvAddMv(ONE,*locKX,-ONE,*MXT,*locR);
3625 RCP<MV> MXT = MVT::CloneCopy(*MX_);
3628 std::vector<ScalarType> locTheta(blockSize_);
3629 for(
int i=0; i<blockSize_; i++)
3630 locTheta[i] = theta_[i];
3633 MVT::MvScale(*MXT,locTheta);
3636 MVT::MvAddMv(ONE,*KX_,-ONE,*MXT,*R_);
3640 Rnorms_current_ =
false;
3641 R2norms_current_ =
false;
3671 template <
class ScalarType,
class MV,
class OP>
3672 std::string TraceMinBase<ScalarType,MV,OP>::accuracyCheck(
const CheckList &chk,
const std::string &where )
const
3676 std::stringstream os;
3678 os.setf(std::ios::scientific, std::ios::floatfield);
3680 os <<
" Debugging checks: iteration " << iter_ << where << endl;
3683 std::vector<int> lclind(curDim_);
3684 for (
int i=0; i<curDim_; ++i) lclind[i] = i;
3687 lclV = MVT::CloneView(*V_,lclind);
3689 if (chk.checkV && initialized_) {
3690 MagnitudeType err = orthman_->orthonormError(*lclV);
3691 os <<
" >> Error in V^H M V == I : " << err << endl;
3692 for (Array_size_type i=0; i<auxVecs_.size(); ++i) {
3693 err = orthman_->orthogError(*lclV,*auxVecs_[i]);
3694 os <<
" >> Error in V^H M Q[" << i <<
"] == 0 : " << err << endl;
3703 lclX = MVT::CloneView(*X_,lclind);
3708 if (chk.checkX && initialized_) {
3709 MagnitudeType err = orthman_->orthonormError(*lclX);
3710 os <<
" >> Error in X^H M X == I : " << err << endl;
3711 for (Array_size_type i=0; i<auxVecs_.size(); ++i) {
3712 err = orthman_->orthogError(*lclX,*auxVecs_[i]);
3713 os <<
" >> Error in X^H M Q[" << i <<
"] == 0 : " << err << endl;
3716 if (chk.checkMX && hasM_ && initialized_) {
3719 lclMX = MVT::CloneView(*MX_,lclind);
3723 MagnitudeType err = Utils::errorEquality(*lclX, *lclMX, MOp_);
3724 os <<
" >> Error in MX == M*X : " << err << endl;
3726 if (Op_ != Teuchos::null && chk.checkKX && initialized_) {
3729 lclKX = MVT::CloneView(*KX_,lclind);
3733 MagnitudeType err = Utils::errorEquality(*lclX, *lclKX, Op_);
3734 os <<
" >> Error in KX == K*X : " << err << endl;
3738 if (chk.checkKK && initialized_) {
3740 if(Op_ != Teuchos::null) {
3741 RCP<MV> lclKV = MVT::Clone(*V_,curDim_);
3742 OPT::Apply(*Op_,*lclV,*lclKV);
3743 MVT::MvTransMv(ONE,*lclV,*lclKV,curKK);
3746 MVT::MvTransMv(ONE,*lclV,*lclV,curKK);
3750 os <<
" >> Error in V^H K V == KK : " << curKK.normFrobenius() << endl;
3753 for (
int j=0; j<curDim_; ++j) {
3754 for (
int i=0; i<curDim_; ++i) {
3755 SDMerr(i,j) = subKK(i,j) - SCT::conjugate(subKK(j,i));
3758 os <<
" >> Error in KK - KK^H == 0 : " << SDMerr.normFrobenius() << endl;
3763 for (Array_size_type i=0; i<auxVecs_.size(); ++i) {
3764 MagnitudeType err = orthman_->orthonormError(*auxVecs_[i]);
3765 os <<
" >> Error in Q[" << i <<
"]^H M Q[" << i <<
"] == I : " << err << endl;
3766 for (Array_size_type j=i+1; j<auxVecs_.size(); ++j) {
3767 err = orthman_->orthogError(*auxVecs_[i],*auxVecs_[j]);
3768 os <<
" >> Error in Q[" << i <<
"]^H M Q[" << j <<
"] == 0 : " << err << endl;
RCP< const MV > getRitzVectors()
Get access to the current Ritz vectors.
int NEV
Number of unconverged eigenvalues.
Templated virtual class for providing orthogonalization/orthonormalization methods with matrix-based ...
RCP< const MV > X
The current eigenvectors.
This class defines the interface required by an eigensolver and status test class to compute solution...
Structure to contain pointers to TraceMinBase state variables.
An implementation of the Anasazi::SortManager that performs a collection of common sorting techniques...
void setBlockSize(int blockSize)
Set the blocksize.
RCP< const MV > V
The current basis.
Declaration of basic traits for the multivector type.
std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > getResNorms()
Get the current residual norms, computing the norms if they are not up-to-date with the current resid...
int getBlockSize() const
Get the blocksize used by the iterative solver.
T & get(const std::string &name, T def_value)
An operator of the form [A Y; Y' 0] where A is a sparse matrix and Y a multivector.
RCP< const MV > MopV
The image of V under M, or Teuchos::null if M was not specified.
TraceMinBaseState< ScalarType, MV > getState() const
Get access to the current state of the eigensolver.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
TraceMinBaseOrthoFailure is thrown when the orthogonalization manager is unable to orthogonalize the ...
Virtual base class which defines basic traits for the operator type.
std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > getRes2Norms()
Get the current residual 2-norms, computing the norms if they are not up-to-date with the current res...
int getMaxSubspaceDim() const
Get the maximum dimension allocated for the search subspace. For the trace minimization methods...
std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > getRitzRes2Norms()
Get the 2-norms of the residuals.
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
Basic implementation of the Anasazi::SortManager class.
TraceMinBaseInitFailure is thrown when the TraceMinBase solver is unable to generate an initial itera...
An exception class parent to all Anasazi exceptions.
std::vector< int > getRitzIndex()
Get the index used for extracting individual Ritz vectors from getRitzVectors().
void setStatusTest(RCP< StatusTest< ScalarType, MV, OP > > test)
Set a new StatusTest for the solver.
void initialize()
Initialize the solver with the initial vectors from the eigenproblem or random data.
void currentStatus(std::ostream &os)
This method requests that the solver print out its current status to the given output stream...
bool isOrtho
Whether V has been projected and orthonormalized already.
Pure virtual base class which describes the basic interface to the iterative eigensolver.
Anasazi's templated, static class providing utilities for the solvers.
bool isInitialized() const
Indicates whether the solver has been initialized or not.
Anasazi's templated virtual class for providing routines for orthogonalization and orthonormalization...
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
virtual ~TraceMinBase()
Anasazi::TraceMinBase destructor.
Output managers remove the need for the eigensolver to know any information about the required output...
Teuchos::Array< RCP< const MV > > getAuxVecs() const
Get the auxiliary vectors for the solver.
Traits class which defines basic operations on multivectors.
void iterate()
This method performs trace minimization iterations until the status test indicates the need to stop o...
Virtual base class which defines basic traits for the operator type.
int curDim
The current dimension of the solver.
RCP< const MV > KV
The image of V under K.
Anasazi header file which uses auto-configuration information to include necessary C++ headers...
void resize(size_type new_size, const value_type &x=value_type())
RCP< const MV > MX
The image of the current eigenvectors under M, or Teuchos::null if M was not specified.
RCP< StatusTest< ScalarType, MV, OP > > getStatusTest() const
Get the current StatusTest used by the solver.
RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > RV
The current Ritz vectors.
ScalarType largestSafeShift
Largest safe shift.
RCP< const std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > > T
The current Ritz values. This vector is a copy of the internal data.
std::vector< Value< ScalarType > > getRitzValues()
Get the Ritz values for the previous iteration.
RCP< const std::vector< ScalarType > > ritzShifts
Current Ritz shifts.
void sort(std::vector< MagnitudeType > &evals, Teuchos::RCP< std::vector< int > > perm=Teuchos::null, int n=-1) const
Sort real eigenvalues, optionally returning the permutation vector.
RCP< const MV > KX
The image of the current eigenvectors under K.
RCP< const MV > R
The current residual vectors.
RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > KK
The current projected K matrix.
Types and exceptions used within Anasazi solvers and interfaces.
const Eigenproblem< ScalarType, MV, OP > & getProblem() const
Get a constant reference to the eigenvalue problem.
void setSize(int blockSize, int numBlocks)
Set the blocksize and number of blocks to be used by the iterative solver in solving this eigenproble...
This is an abstract base class for the trace minimization eigensolvers.
int getNumIters() const
Get the current iteration count.
Anasazi's templated pure virtual class for managing the sorting of approximate eigenvalues computed b...
Stores a set of vectors of the form [V; L] where V is a distributed multivector and L is a serialdens...
Common interface of stopping criteria for Anasazi's solvers.
void setAuxVecs(const Teuchos::Array< RCP< const MV > > &auxvecs)
Set the auxiliary vectors for the solver.
int getCurSubspaceDim() const
Get the dimension of the search subspace used to generate the current eigenvectors and eigenvalues...
The Eigensolver is a templated virtual base class that defines the basic interface that any eigensolv...
void resetNumIters()
Reset the iteration count.
TraceMinBase(const RCP< Eigenproblem< ScalarType, MV, OP > > &problem, const RCP< SortManager< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > > &sorter, const RCP< OutputManager< ScalarType > > &printer, const RCP< StatusTest< ScalarType, MV, OP > > &tester, const RCP< MatOrthoManager< ScalarType, MV, OP > > &ortho, Teuchos::ParameterList ¶ms)
TraceMinBase constructor with eigenproblem, solver utilities, and parameter list of solver options...
int setMatrix(const RCP< SerialDenseMatrix< OrdinalType, ScalarType > > &A)
Class which provides internal utilities for the Anasazi solvers.