48 #ifndef ANASAZI_TRACEMIN_BASE_HPP
49 #define ANASAZI_TRACEMIN_BASE_HPP
84 namespace Experimental {
93 template <
class ScalarType,
class MV>
133 X(Teuchos::null),
KX(Teuchos::null),
MX(Teuchos::null),
R(Teuchos::null),
134 T(Teuchos::null),
KK(Teuchos::null),
RV(Teuchos::null),
isOrtho(false),
181 template <
class ScalarType,
class MV,
class OP>
255 void harmonicIterate();
360 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
getResNorms();
368 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
getRes2Norms();
378 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
getRitzRes2Norms();
452 void setSize(
int blockSize,
int numBlocks);
471 typedef TraceMinRitzOp<ScalarType,MV,OP> tracemin_ritz_op_type;
472 typedef SaddleContainer<ScalarType,MV> saddle_container_type;
473 typedef SaddleOperator<ScalarType,MV,tracemin_ritz_op_type> saddle_op_type;
474 const MagnitudeType ONE;
475 const MagnitudeType ZERO;
476 const MagnitudeType NANVAL;
497 timerLocal_, timerCompRes_, timerOrtho_, timerInit_;
503 bool checkV, checkX, checkMX,
504 checkKX, checkQ, checkKK;
505 CheckList() : checkV(
false),checkX(
false),
506 checkMX(
false),checkKX(
false),
507 checkQ(
false),checkKK(
false) {};
512 std::string accuracyCheck(
const CheckList &chk,
const std::string &where)
const;
517 int count_ApplyOp_, count_ApplyM_;
544 RCP<MV> X_, KX_, MX_, KV_, MV_, R_, V_;
558 std::vector<MagnitudeType> theta_, Rnorms_, R2norms_;
561 bool Rnorms_current_, R2norms_current_;
565 enum SaddleSolType saddleSolType_;
566 bool previouslyLeveled_;
567 MagnitudeType previousTrace_;
568 bool posSafeToShift_, negSafeToShift_;
569 MagnitudeType largestSafeShift_;
571 std::vector<ScalarType> ritzShifts_;
577 enum WhenToShiftType whenToShift_;
578 enum HowToShiftType howToShift_;
579 bool useMultipleShifts_;
580 bool considerClusters_;
581 bool projectAllVecs_;
582 bool projectLockedVecs_;
586 MagnitudeType traceThresh_;
587 MagnitudeType alpha_;
591 std::string shiftNorm_;
592 MagnitudeType shiftThresh_;
593 bool useRelShiftThresh_;
597 ScalarType getTrace()
const;
603 std::vector<ScalarType> getClusterResids();
606 void computeRitzShifts(
const std::vector<ScalarType>& clusterResids);
609 std::vector<ScalarType> computeTol();
611 void solveSaddlePointProblem(
RCP<MV> Delta);
613 void solveSaddleProj(
RCP<MV> Delta)
const;
616 void solveSaddleProjPrec(
RCP<MV> Delta)
const;
618 void solveSaddleSchur (
RCP<MV> Delta)
const;
620 void solveSaddleBDPrec (
RCP<MV> Delta)
const;
622 void solveSaddleHSSPrec (
RCP<MV> Delta)
const;
626 void computeRitzPairs();
632 void updateResidual();
636 virtual void harmonicAddToBasis(
const RCP<const MV> Delta) =0;
652 template <
class ScalarType,
class MV,
class OP>
661 ONE(Teuchos::ScalarTraits<MagnitudeType>::one()),
662 ZERO(Teuchos::ScalarTraits<MagnitudeType>::zero()),
663 NANVAL(Teuchos::ScalarTraits<MagnitudeType>::nan()),
671 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
672 timerOp_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: TraceMinBase::Operation Op*x")),
673 timerMOp_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: TraceMinBase::Operation M*x")),
674 timerSaddle_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: TraceMinBase::Solving saddle point problem")),
675 timerSortEval_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: TraceMinBase::Sorting eigenvalues")),
676 timerDS_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: TraceMinBase::Direct solve")),
677 timerLocal_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: TraceMinBase::Local update")),
678 timerCompRes_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: TraceMinBase::Computing residuals")),
679 timerOrtho_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: TraceMinBase::Orthogonalization")),
680 timerInit_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: TraceMinBase::Initialization")),
689 auxVecs_( Teuchos::Array<
RCP<const MV> >(0) ),
690 MauxVecs_( Teuchos::Array<
RCP<const MV> >(0) ),
693 Rnorms_current_(false),
694 R2norms_current_(false),
696 previouslyLeveled_(false),
697 previousTrace_(ZERO),
698 posSafeToShift_(false),
699 negSafeToShift_(false),
700 largestSafeShift_(ZERO),
704 "Anasazi::TraceMinBase::constructor: user passed null problem pointer.");
706 "Anasazi::TraceMinBase::constructor: user passed null sort manager pointer.");
708 "Anasazi::TraceMinBase::constructor: user passed null output manager pointer.");
710 "Anasazi::TraceMinBase::constructor: user passed null status test pointer.");
712 "Anasazi::TraceMinBase::constructor: user passed null orthogonalization manager pointer.");
714 "Anasazi::TraceMinBase::constructor: problem is not hermitian.");
717 Op_ = problem_->getOperator();
718 MOp_ = problem_->getM();
719 Prec_ = problem_->getPrec();
720 hasM_ = (MOp_ != Teuchos::null);
723 saddleSolType_ = params.
get(
"Saddle Solver Type", PROJECTED_KRYLOV_SOLVER);
724 TEUCHOS_TEST_FOR_EXCEPTION(saddleSolType_ != PROJECTED_KRYLOV_SOLVER && saddleSolType_ != SCHUR_COMPLEMENT_SOLVER && saddleSolType_ != BD_PREC_MINRES && saddleSolType_ != HSS_PREC_GMRES, std::invalid_argument,
725 "Anasazi::TraceMin::constructor: Invalid value for \"Saddle Solver Type\"; valid options are PROJECTED_KRYLOV_SOLVER, SCHUR_COMPLEMENT_SOLVER, and BD_PREC_MINRES.");
728 whenToShift_ = params.
get(
"When To Shift", ALWAYS_SHIFT);
729 TEUCHOS_TEST_FOR_EXCEPTION(whenToShift_ != NEVER_SHIFT && whenToShift_ != SHIFT_WHEN_TRACE_LEVELS && whenToShift_ != SHIFT_WHEN_RESID_SMALL && whenToShift_ != ALWAYS_SHIFT, std::invalid_argument,
730 "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\".");
732 traceThresh_ = params.
get(
"Trace Threshold", 2e-2);
734 "Anasazi::TraceMin::constructor: Invalid value for \"Trace Threshold\"; Must be positive.");
736 howToShift_ = params.
get(
"How To Choose Shift", ADJUSTED_RITZ_SHIFT);
737 TEUCHOS_TEST_FOR_EXCEPTION(howToShift_ != LARGEST_CONVERGED_SHIFT && howToShift_ != ADJUSTED_RITZ_SHIFT && howToShift_ != RITZ_VALUES_SHIFT && howToShift_ != EXPERIMENTAL_SHIFT, std::invalid_argument,
738 "Anasazi::TraceMin::constructor: Invalid value for \"How To Choose Shift\"; valid options are \"LARGEST_CONVERGED_SHIFT\", \"ADJUSTED_RITZ_SHIFT\", \"RITZ_VALUES_SHIFT\".");
740 useMultipleShifts_ = params.
get(
"Use Multiple Shifts",
true);
742 shiftThresh_ = params.
get(
"Shift Threshold", 1e-2);
743 useRelShiftThresh_ = params.
get(
"Relative Shift Threshold",
true);
744 shiftNorm_ = params.
get(
"Shift Norm",
"2");
746 "Anasazi::TraceMin::constructor: Invalid value for \"Shift Norm\"; valid options are \"2\", \"M\".");
748 considerClusters_ = params.
get(
"Consider Clusters",
true);
750 projectAllVecs_ = params.
get(
"Project All Vectors",
true);
751 projectLockedVecs_ = params.
get(
"Project Locked Vectors",
true);
752 useRHSR_ = params.
get(
"Use Residual as RHS",
true);
753 useHarmonic_ = params.
get(
"Use Harmonic Ritz Values",
false);
754 computeAllRes_ = params.
get(
"Compute All Residuals",
true);
757 int bs = params.
get(
"Block Size", problem_->getNEV());
758 int nb = params.
get(
"Num Blocks", 1);
761 NEV_ = problem_->getNEV();
764 ritzOp_ =
rcp (
new tracemin_ritz_op_type (Op_, MOp_, Prec_));
767 const int innerMaxIts = params.
get (
"Maximum Krylov Iterations", 200);
768 ritzOp_->setMaxIts (innerMaxIts);
770 alpha_ = params.
get (
"HSS: alpha", ONE);
776 template <
class ScalarType,
class MV,
class OP>
783 template <
class ScalarType,
class MV,
class OP>
786 TEUCHOS_TEST_FOR_EXCEPTION(blockSize < 1, std::invalid_argument,
"Anasazi::TraceMinBase::setSize(blocksize,numblocks): blocksize must be strictly positive.");
787 setSize(blockSize,numBlocks_);
793 template <
class ScalarType,
class MV,
class OP>
801 template <
class ScalarType,
class MV,
class OP>
809 template <
class ScalarType,
class MV,
class OP>
817 template <
class ScalarType,
class MV,
class OP>
819 return blockSize_*numBlocks_;
824 template <
class ScalarType,
class MV,
class OP>
826 if (!initialized_)
return 0;
833 template <
class ScalarType,
class MV,
class OP>
834 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
836 return getRes2Norms();
842 template <
class ScalarType,
class MV,
class OP>
844 std::vector<int> ret(curDim_,0);
851 template <
class ScalarType,
class MV,
class OP>
853 std::vector<Value<ScalarType> > ret(curDim_);
854 for (
int i=0; i<curDim_; ++i) {
855 ret[i].realpart = theta_[i];
856 ret[i].imagpart = ZERO;
864 template <
class ScalarType,
class MV,
class OP>
872 template <
class ScalarType,
class MV,
class OP>
880 template <
class ScalarType,
class MV,
class OP>
888 template <
class ScalarType,
class MV,
class OP>
894 if (Op_ != Teuchos::null) {
899 state.
KV = Teuchos::null;
900 state.
KX = Teuchos::null;
907 state.
MopV = Teuchos::null;
908 state.
MX = Teuchos::null;
912 state.
RV = ritzVecs_;
914 state.
T =
rcp(
new std::vector<MagnitudeType>(theta_.begin(),theta_.begin()+curDim_) );
916 state.
T =
rcp(
new std::vector<MagnitudeType>(0));
918 state.
ritzShifts =
rcp(
new std::vector<MagnitudeType>(ritzShifts_.begin(),ritzShifts_.begin()+blockSize_) );
928 template <
class ScalarType,
class MV,
class OP>
939 if (initialized_ ==
false) {
945 const int searchDim = blockSize_*numBlocks_;
948 RCP<MV> Delta = MVT::Clone(*X_,blockSize_);
953 while (tester_->checkStatus(
this) !=
Passed && (numBlocks_ == 1 || curDim_ < searchDim)) {
956 if (om_->isVerbosity(
Debug)) {
957 currentStatus( om_->stream(
Debug) );
966 solveSaddlePointProblem(Delta);
971 if (om_->isVerbosity(
Debug ) ) {
975 om_->print(
Debug, accuracyCheck(chk,
": after addToBasis(Delta)") );
981 if (om_->isVerbosity(
Debug ) ) {
985 om_->print(
Debug, accuracyCheck(chk,
": after computeKK()") );
994 if (om_->isVerbosity(
Debug ) ) {
998 om_->print(
Debug, accuracyCheck(chk,
": after computeX()") );
1004 if (om_->isVerbosity(
Debug ) ) {
1009 om_->print(
Debug, accuracyCheck(chk,
": after updateKXMX()") );
1022 template <
class ScalarType,
class MV,
class OP>
1027 if (initialized_ ==
false) {
1033 const int searchDim = blockSize_*numBlocks_;
1036 RCP<MV> Delta = MVT::Clone(*X_,blockSize_);
1041 while (tester_->checkStatus(
this) !=
Passed && (numBlocks_ == 1 || curDim_ < searchDim)) {
1044 if (om_->isVerbosity(
Debug)) {
1045 currentStatus( om_->stream(
Debug) );
1054 solveSaddlePointProblem(Delta);
1057 harmonicAddToBasis(Delta);
1059 if (om_->isVerbosity(
Debug ) ) {
1063 om_->print(
Debug, accuracyCheck(chk,
": after addToBasis(Delta)") );
1069 if (om_->isVerbosity(
Debug ) ) {
1073 om_->print(
Debug, accuracyCheck(chk,
": after computeKK()") );
1088 std::vector<int> dimind(nvecs);
1089 for(
int i=0; i<nvecs; i++)
1091 RCP<MV> lclX = MVT::CloneViewNonConst(*X_,dimind);
1092 std::vector<ScalarType> normvec(nvecs);
1093 orthman_->normMat(*lclX,normvec);
1096 for(
int i=0; i<nvecs; i++)
1097 normvec[i] = ONE/normvec[i];
1098 MVT::MvScale(*lclX,normvec);
1101 for(
int i=0; i<nvecs; i++)
1103 theta_[i] = theta_[i] * normvec[i] * normvec[i];
1106 if (om_->isVerbosity(
Debug ) ) {
1110 om_->print(
Debug, accuracyCheck(chk,
": after computeX()") );
1117 if(Op_ != Teuchos::null)
1119 RCP<MV> lclKX = MVT::CloneViewNonConst(*KX_,dimind);
1120 MVT::MvScale(*lclKX,normvec);
1124 RCP<MV> lclMX = MVT::CloneViewNonConst(*MX_,dimind);
1125 MVT::MvScale(*lclMX,normvec);
1128 if (om_->isVerbosity(
Debug ) ) {
1133 om_->print(
Debug, accuracyCheck(chk,
": after updateKXMX()") );
1145 template <
class ScalarType,
class MV,
class OP>
1166 template <
class ScalarType,
class MV,
class OP>
1173 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1177 previouslyLeveled_ =
false;
1181 harmonicInitialize(newstate);
1185 std::vector<int> bsind(blockSize_);
1186 for (
int i=0; i<blockSize_; ++i) bsind[i] = i;
1214 if (newstate.
V != Teuchos::null) {
1215 om_->stream(
Debug) <<
"Copying V from the user\n";
1218 "Anasazi::TraceMinBase::initialize(newstate): Vector length of V not correct." );
1220 "Anasazi::TraceMinBase::initialize(newstate): Rank of new state must be at least blockSize().");
1222 "Anasazi::TraceMinBase::initialize(newstate): Rank of new state must be less than getMaxSubspaceDim().");
1225 "Anasazi::TraceMinBase::initialize(newstate): Multivector for basis in new state must be as large as specified state rank.");
1227 curDim_ = newstate.
curDim;
1229 curDim_ = (int)(curDim_ / blockSize_)*blockSize_;
1232 "Anasazi::TraceMinBase::initialize(newstate): Rank of new state must be a multiple of getBlockSize().");
1235 std::vector<int> nevind(curDim_);
1236 for (
int i=0; i<curDim_; ++i) nevind[i] = i;
1237 if (newstate.
V != V_) {
1238 if (curDim_ < MVT::GetNumberVecs(*newstate.
V)) {
1239 newstate.
V = MVT::CloneView(*newstate.
V,nevind);
1241 MVT::SetBlock(*newstate.
V,nevind,*V_);
1243 lclV = MVT::CloneViewNonConst(*V_,nevind);
1250 "Anasazi::TraceMinBase::initialize(newstate): Eigenproblem did not specify initial vectors to clone from.");
1252 newstate.
X = Teuchos::null;
1253 newstate.
MX = Teuchos::null;
1254 newstate.
KX = Teuchos::null;
1255 newstate.
R = Teuchos::null;
1256 newstate.
T = Teuchos::null;
1257 newstate.
RV = Teuchos::null;
1258 newstate.
KK = Teuchos::null;
1259 newstate.
KV = Teuchos::null;
1260 newstate.
MopV = Teuchos::null;
1265 curDim_ = newstate.
curDim;
1267 curDim_ = MVT::GetNumberVecs(*ivec);
1270 curDim_ = (int)(curDim_ / blockSize_)*blockSize_;
1271 if (curDim_ > blockSize_*numBlocks_) {
1274 curDim_ = blockSize_*numBlocks_;
1276 bool userand =
false;
1281 curDim_ = blockSize_;
1284 std::vector<int> nevind(curDim_);
1285 for (
int i=0; i<curDim_; ++i) nevind[i] = i;
1291 lclV = MVT::CloneViewNonConst(*V_,nevind);
1295 MVT::MvRandom(*lclV);
1301 if(MVT::GetNumberVecs(*newstate.
V) > curDim_) {
1303 MVT::SetBlock(*helperMV,nevind,*lclV);
1306 MVT::SetBlock(*newstate.
V,nevind,*lclV);
1310 if(MVT::GetNumberVecs(*ivec) > curDim_) {
1311 ivec = MVT::CloneView(*ivec,nevind);
1314 MVT::SetBlock(*ivec,nevind,*lclV);
1320 std::vector<int> dimind(curDim_);
1321 for (
int i=0; i<curDim_; ++i) dimind[i] = i;
1324 if(hasM_ && newstate.
MopV == Teuchos::null)
1326 om_->stream(
Debug) <<
"Computing MV\n";
1328 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1331 count_ApplyM_+= curDim_;
1335 lclMV = MVT::CloneViewNonConst(*MV_,dimind);
1336 OPT::Apply(*MOp_,*lclV,*lclMV);
1341 om_->stream(
Debug) <<
"Copying MV\n";
1344 "Anasazi::TraceMinBase::initialize(newstate): Vector length of MV not correct." );
1347 "Anasazi::TraceMinBase::initialize(newstate): Number of vectors in MV not correct.");
1349 if(newstate.
MopV != MV_) {
1350 if(curDim_ < MVT::GetNumberVecs(*newstate.
MopV)) {
1351 newstate.
MopV = MVT::CloneView(*newstate.
MopV,dimind);
1353 MVT::SetBlock(*newstate.
MopV,dimind,*MV_);
1355 lclMV = MVT::CloneViewNonConst(*MV_,dimind);
1360 om_->stream(
Debug) <<
"There is no MV\n";
1369 om_->stream(
Debug) <<
"Project and normalize\n";
1371 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1376 newstate.
X = Teuchos::null;
1377 newstate.
MX = Teuchos::null;
1378 newstate.
KX = Teuchos::null;
1379 newstate.
R = Teuchos::null;
1380 newstate.
T = Teuchos::null;
1381 newstate.
RV = Teuchos::null;
1382 newstate.
KK = Teuchos::null;
1383 newstate.
KV = Teuchos::null;
1386 if(auxVecs_.size() > 0)
1388 rank = orthman_->projectAndNormalizeMat(*lclV, auxVecs_,
1390 Teuchos::null, lclMV, MauxVecs_);
1394 rank = orthman_->normalizeMat(*lclV,Teuchos::null,lclMV);
1398 "Anasazi::TraceMinBase::initialize(): Couldn't generate initial basis of full rank.");
1402 if(Op_ != Teuchos::null && newstate.
KV == Teuchos::null)
1404 om_->stream(
Debug) <<
"Computing KV\n";
1406 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1409 count_ApplyOp_+= curDim_;
1412 newstate.
X = Teuchos::null;
1413 newstate.
MX = Teuchos::null;
1414 newstate.
KX = Teuchos::null;
1415 newstate.
R = Teuchos::null;
1416 newstate.
T = Teuchos::null;
1417 newstate.
RV = Teuchos::null;
1418 newstate.
KK = Teuchos::null;
1419 newstate.
KV = Teuchos::null;
1421 lclKV = MVT::CloneViewNonConst(*KV_,dimind);
1422 OPT::Apply(*Op_,*lclV,*lclKV);
1425 else if(Op_ != Teuchos::null)
1427 om_->stream(
Debug) <<
"Copying MV\n";
1430 "Anasazi::TraceMinBase::initialize(newstate): Vector length of MV not correct." );
1433 "Anasazi::TraceMinBase::initialize(newstate): Number of vectors in KV not correct.");
1435 if (newstate.
KV != KV_) {
1436 if (curDim_ < MVT::GetNumberVecs(*newstate.
KV)) {
1437 newstate.
KV = MVT::CloneView(*newstate.
KV,dimind);
1439 MVT::SetBlock(*newstate.
KV,dimind,*KV_);
1441 lclKV = MVT::CloneViewNonConst(*KV_,dimind);
1445 om_->stream(
Debug) <<
"There is no KV\n";
1452 if(newstate.
KK == Teuchos::null)
1454 om_->stream(
Debug) <<
"Computing KK\n";
1457 newstate.
X = Teuchos::null;
1458 newstate.
MX = Teuchos::null;
1459 newstate.
KX = Teuchos::null;
1460 newstate.
R = Teuchos::null;
1461 newstate.
T = Teuchos::null;
1462 newstate.
RV = Teuchos::null;
1471 MVT::MvTransMv(ONE,*lclV,*lclKV,*lclKK);
1476 om_->stream(
Debug) <<
"Copying KK\n";
1480 "Anasazi::TraceMinBase::initialize(newstate): Projected matrix in new state must be as large as specified state rank.");
1484 if (newstate.
KK != KK_) {
1485 if (newstate.
KK->numRows() > curDim_ || newstate.
KK->numCols() > curDim_) {
1488 lclKK->assign(*newstate.
KK);
1493 if(newstate.
T == Teuchos::null || newstate.
RV == Teuchos::null)
1495 om_->stream(
Debug) <<
"Computing Ritz pairs\n";
1498 newstate.
X = Teuchos::null;
1499 newstate.
MX = Teuchos::null;
1500 newstate.
KX = Teuchos::null;
1501 newstate.
R = Teuchos::null;
1502 newstate.
T = Teuchos::null;
1503 newstate.
RV = Teuchos::null;
1510 om_->stream(
Debug) <<
"Copying Ritz pairs\n";
1513 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of T must be consistent with dimension of V.");
1516 "Anasazi::TraceMinBase::initialize(newstate): Ritz vectors in new state must be as large as specified state rank.");
1518 std::copy(newstate.
T->begin(),newstate.
T->end(),theta_.begin());
1521 if (newstate.
RV != ritzVecs_) {
1522 if (newstate.
RV->numRows() > curDim_ || newstate.
RV->numCols() > curDim_) {
1525 lclRV->assign(*newstate.
RV);
1530 if(newstate.
X == Teuchos::null)
1532 om_->stream(
Debug) <<
"Computing X\n";
1535 newstate.
MX = Teuchos::null;
1536 newstate.
KX = Teuchos::null;
1537 newstate.
R = Teuchos::null;
1544 om_->stream(
Debug) <<
"Copying X\n";
1546 if(computeAllRes_ ==
false)
1548 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*newstate.
X) != blockSize_ || MVT::GetGlobalLength(*newstate.
X) != MVT::GetGlobalLength(*X_),
1549 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of X must be consistent with block size and length of V.");
1551 if(newstate.
X != X_) {
1552 MVT::SetBlock(*newstate.
X,bsind,*X_);
1557 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*newstate.
X) != curDim_ || MVT::GetGlobalLength(*newstate.
X) != MVT::GetGlobalLength(*X_),
1558 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of X must be consistent with current dimension and length of V.");
1560 if(newstate.
X != X_) {
1561 MVT::SetBlock(*newstate.
X,dimind,*X_);
1568 if((Op_ != Teuchos::null && newstate.
KX == Teuchos::null) || (hasM_ && newstate.
MX == Teuchos::null))
1570 om_->stream(
Debug) <<
"Computing KX and MX\n";
1573 newstate.
R = Teuchos::null;
1580 om_->stream(
Debug) <<
"Copying KX and MX\n";
1581 if(Op_ != Teuchos::null)
1583 if(computeAllRes_ ==
false)
1586 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of KX must be consistent with block size and length of V.");
1588 if(newstate.
KX != KX_) {
1589 MVT::SetBlock(*newstate.
KX,bsind,*KX_);
1595 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of KX must be consistent with current dimension and length of V.");
1597 if (newstate.
KX != KX_) {
1598 MVT::SetBlock(*newstate.
KX,dimind,*KX_);
1605 if(computeAllRes_ ==
false)
1608 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of MX must be consistent with block size and length of V.");
1610 if (newstate.
MX != MX_) {
1611 MVT::SetBlock(*newstate.
MX,bsind,*MX_);
1617 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of MX must be consistent with current dimension and length of V.");
1619 if (newstate.
MX != MX_) {
1620 MVT::SetBlock(*newstate.
MX,dimind,*MX_);
1627 if(newstate.
R == Teuchos::null)
1629 om_->stream(
Debug) <<
"Computing R\n";
1636 om_->stream(
Debug) <<
"Copying R\n";
1638 if(computeAllRes_ ==
false)
1641 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): vector length of newstate.R not correct." );
1643 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): newstate.R must have at least block size vectors." );
1644 if (newstate.
R != R_) {
1645 MVT::SetBlock(*newstate.
R,bsind,*R_);
1651 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): vector length of newstate.R not correct." );
1653 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): newstate.R must have at least curDim vectors." );
1654 if (newstate.
R != R_) {
1655 MVT::SetBlock(*newstate.
R,dimind,*R_);
1661 Rnorms_current_ =
false;
1662 R2norms_current_ =
false;
1670 om_->stream(
Debug) <<
"Copying Ritz shifts\n";
1675 om_->stream(
Debug) <<
"Setting Ritz shifts to 0\n";
1676 for(
size_t i=0; i<ritzShifts_.size(); i++)
1677 ritzShifts_[i] = ZERO;
1680 for(
size_t i=0; i<ritzShifts_.size(); i++)
1681 om_->stream(
Debug) <<
"Ritz shifts[" << i <<
"] = " << ritzShifts_[i] << std::endl;
1684 initialized_ =
true;
1686 if (om_->isVerbosity(
Debug ) ) {
1695 om_->print(
Debug, accuracyCheck(chk,
": after initialize()") );
1699 if (om_->isVerbosity(
Debug)) {
1700 currentStatus( om_->stream(
Debug) );
1722 template <
class ScalarType,
class MV,
class OP>
1729 std::vector<int> bsind(blockSize_);
1730 for (
int i=0; i<blockSize_; ++i) bsind[i] = i;
1758 if (newstate.
V != Teuchos::null) {
1759 om_->stream(
Debug) <<
"Copying V from the user\n";
1762 "Anasazi::TraceMinBase::initialize(newstate): Vector length of V not correct." );
1764 "Anasazi::TraceMinBase::initialize(newstate): Rank of new state must be at least blockSize().");
1766 "Anasazi::TraceMinBase::initialize(newstate): Rank of new state must be less than getMaxSubspaceDim().");
1769 "Anasazi::TraceMinBase::initialize(newstate): Multivector for basis in new state must be as large as specified state rank.");
1771 curDim_ = newstate.
curDim;
1773 curDim_ = (int)(curDim_ / blockSize_)*blockSize_;
1776 "Anasazi::TraceMinBase::initialize(newstate): Rank of new state must be a multiple of getBlockSize().");
1779 std::vector<int> nevind(curDim_);
1780 for (
int i=0; i<curDim_; ++i) nevind[i] = i;
1781 if (newstate.
V != V_) {
1782 if (curDim_ < MVT::GetNumberVecs(*newstate.
V)) {
1783 newstate.
V = MVT::CloneView(*newstate.
V,nevind);
1785 MVT::SetBlock(*newstate.
V,nevind,*V_);
1787 lclV = MVT::CloneViewNonConst(*V_,nevind);
1794 "Anasazi::TraceMinBase::initialize(newstate): Eigenproblem did not specify initial vectors to clone from.");
1796 newstate.
X = Teuchos::null;
1797 newstate.
MX = Teuchos::null;
1798 newstate.
KX = Teuchos::null;
1799 newstate.
R = Teuchos::null;
1800 newstate.
T = Teuchos::null;
1801 newstate.
RV = Teuchos::null;
1802 newstate.
KK = Teuchos::null;
1803 newstate.
KV = Teuchos::null;
1804 newstate.
MopV = Teuchos::null;
1809 curDim_ = newstate.
curDim;
1811 curDim_ = MVT::GetNumberVecs(*ivec);
1814 curDim_ = (int)(curDim_ / blockSize_)*blockSize_;
1815 if (curDim_ > blockSize_*numBlocks_) {
1818 curDim_ = blockSize_*numBlocks_;
1820 bool userand =
false;
1825 curDim_ = blockSize_;
1828 std::vector<int> nevind(curDim_);
1829 for (
int i=0; i<curDim_; ++i) nevind[i] = i;
1835 lclV = MVT::CloneViewNonConst(*V_,nevind);
1839 MVT::MvRandom(*lclV);
1845 if(MVT::GetNumberVecs(*newstate.
V) > curDim_) {
1847 MVT::SetBlock(*helperMV,nevind,*lclV);
1850 MVT::SetBlock(*newstate.
V,nevind,*lclV);
1854 if(MVT::GetNumberVecs(*ivec) > curDim_) {
1855 ivec = MVT::CloneView(*ivec,nevind);
1858 MVT::SetBlock(*ivec,nevind,*lclV);
1866 newstate.
X = Teuchos::null;
1867 newstate.
MX = Teuchos::null;
1868 newstate.
KX = Teuchos::null;
1869 newstate.
R = Teuchos::null;
1870 newstate.
T = Teuchos::null;
1871 newstate.
RV = Teuchos::null;
1872 newstate.
KK = Teuchos::null;
1873 newstate.
KV = Teuchos::null;
1874 newstate.
MopV = Teuchos::null;
1878 std::vector<int> dimind(curDim_);
1879 for (
int i=0; i<curDim_; ++i) dimind[i] = i;
1882 if(auxVecs_.size() > 0)
1883 orthman_->projectMat(*lclV,auxVecs_);
1886 if(Op_ != Teuchos::null && newstate.
KV == Teuchos::null)
1888 om_->stream(
Debug) <<
"Computing KV\n";
1890 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1893 count_ApplyOp_+= curDim_;
1896 newstate.
X = Teuchos::null;
1897 newstate.
MX = Teuchos::null;
1898 newstate.
KX = Teuchos::null;
1899 newstate.
R = Teuchos::null;
1900 newstate.
T = Teuchos::null;
1901 newstate.
RV = Teuchos::null;
1902 newstate.
KK = Teuchos::null;
1904 lclKV = MVT::CloneViewNonConst(*KV_,dimind);
1905 OPT::Apply(*Op_,*lclV,*lclKV);
1908 else if(Op_ != Teuchos::null)
1910 om_->stream(
Debug) <<
"Copying KV\n";
1913 "Anasazi::TraceMinBase::initialize(newstate): Vector length of KV not correct." );
1916 "Anasazi::TraceMinBase::initialize(newstate): Number of vectors in KV not correct.");
1918 if (newstate.
KV != KV_) {
1919 if (curDim_ < MVT::GetNumberVecs(*newstate.
KV)) {
1920 newstate.
KV = MVT::CloneView(*newstate.
KV,dimind);
1922 MVT::SetBlock(*newstate.
KV,dimind,*KV_);
1924 lclKV = MVT::CloneViewNonConst(*KV_,dimind);
1928 om_->stream(
Debug) <<
"There is no KV\n";
1939 om_->stream(
Debug) <<
"Project and normalize\n";
1941 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1946 newstate.
MopV = Teuchos::null;
1947 newstate.
X = Teuchos::null;
1948 newstate.
MX = Teuchos::null;
1949 newstate.
KX = Teuchos::null;
1950 newstate.
R = Teuchos::null;
1951 newstate.
T = Teuchos::null;
1952 newstate.
RV = Teuchos::null;
1953 newstate.
KK = Teuchos::null;
1957 int rank = orthman_->normalizeMat(*lclKV,gamma);
1963 RCP<MV> tempMV = MVT::CloneCopy(*lclV);
1964 MVT::MvTimesMatAddMv(ONE,*tempMV,*gamma,ZERO,*lclV);
1967 "Anasazi::TraceMinBase::initialize(): Couldn't generate initial basis of full rank.");
1971 if(hasM_ && newstate.
MopV == Teuchos::null)
1973 om_->stream(
Debug) <<
"Computing MV\n";
1975 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1978 count_ApplyM_+= curDim_;
1981 lclMV = MVT::CloneViewNonConst(*MV_,dimind);
1982 OPT::Apply(*MOp_,*lclV,*lclMV);
1987 om_->stream(
Debug) <<
"Copying MV\n";
1990 "Anasazi::TraceMinBase::initialize(newstate): Vector length of MV not correct." );
1993 "Anasazi::TraceMinBase::initialize(newstate): Number of vectors in MV not correct.");
1995 if(newstate.
MopV != MV_) {
1996 if(curDim_ < MVT::GetNumberVecs(*newstate.
MopV)) {
1997 newstate.
MopV = MVT::CloneView(*newstate.
MopV,dimind);
1999 MVT::SetBlock(*newstate.
MopV,dimind,*MV_);
2001 lclMV = MVT::CloneViewNonConst(*MV_,dimind);
2006 om_->stream(
Debug) <<
"There is no MV\n";
2013 if(newstate.
KK == Teuchos::null)
2015 om_->stream(
Debug) <<
"Computing KK\n";
2018 newstate.
X = Teuchos::null;
2019 newstate.
MX = Teuchos::null;
2020 newstate.
KX = Teuchos::null;
2021 newstate.
R = Teuchos::null;
2022 newstate.
T = Teuchos::null;
2023 newstate.
RV = Teuchos::null;
2032 MVT::MvTransMv(ONE,*lclV,*lclKV,*lclKK);
2037 om_->stream(
Debug) <<
"Copying KK\n";
2041 "Anasazi::TraceMinBase::initialize(newstate): Projected matrix in new state must be as large as specified state rank.");
2045 if (newstate.
KK != KK_) {
2046 if (newstate.
KK->numRows() > curDim_ || newstate.
KK->numCols() > curDim_) {
2049 lclKK->assign(*newstate.
KK);
2054 if(newstate.
T == Teuchos::null || newstate.
RV == Teuchos::null)
2056 om_->stream(
Debug) <<
"Computing Ritz pairs\n";
2059 newstate.
X = Teuchos::null;
2060 newstate.
MX = Teuchos::null;
2061 newstate.
KX = Teuchos::null;
2062 newstate.
R = Teuchos::null;
2063 newstate.
T = Teuchos::null;
2064 newstate.
RV = Teuchos::null;
2071 om_->stream(
Debug) <<
"Copying Ritz pairs\n";
2074 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of T must be consistent with dimension of V.");
2077 "Anasazi::TraceMinBase::initialize(newstate): Ritz vectors in new state must be as large as specified state rank.");
2079 std::copy(newstate.
T->begin(),newstate.
T->end(),theta_.begin());
2082 if (newstate.
RV != ritzVecs_) {
2083 if (newstate.
RV->numRows() > curDim_ || newstate.
RV->numCols() > curDim_) {
2086 lclRV->assign(*newstate.
RV);
2091 if(newstate.
X == Teuchos::null)
2093 om_->stream(
Debug) <<
"Computing X\n";
2096 newstate.
MX = Teuchos::null;
2097 newstate.
KX = Teuchos::null;
2098 newstate.
R = Teuchos::null;
2105 om_->stream(
Debug) <<
"Copying X\n";
2107 if(computeAllRes_ ==
false)
2109 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*newstate.
X) != blockSize_ || MVT::GetGlobalLength(*newstate.
X) != MVT::GetGlobalLength(*X_),
2110 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of X must be consistent with block size and length of V.");
2112 if(newstate.
X != X_) {
2113 MVT::SetBlock(*newstate.
X,bsind,*X_);
2118 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*newstate.
X) != curDim_ || MVT::GetGlobalLength(*newstate.
X) != MVT::GetGlobalLength(*X_),
2119 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of X must be consistent with current dimension and length of V.");
2121 if(newstate.
X != X_) {
2122 MVT::SetBlock(*newstate.
X,dimind,*X_);
2129 if((Op_ != Teuchos::null && newstate.
KX == Teuchos::null) || (hasM_ && newstate.
MX == Teuchos::null))
2131 om_->stream(
Debug) <<
"Computing KX and MX\n";
2134 newstate.
R = Teuchos::null;
2141 om_->stream(
Debug) <<
"Copying KX and MX\n";
2142 if(Op_ != Teuchos::null)
2144 if(computeAllRes_ ==
false)
2147 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of KX must be consistent with block size and length of V.");
2149 if(newstate.
KX != KX_) {
2150 MVT::SetBlock(*newstate.
KX,bsind,*KX_);
2156 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of KX must be consistent with current dimension and length of V.");
2158 if (newstate.
KX != KX_) {
2159 MVT::SetBlock(*newstate.
KX,dimind,*KX_);
2166 if(computeAllRes_ ==
false)
2169 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of MX must be consistent with block size and length of V.");
2171 if (newstate.
MX != MX_) {
2172 MVT::SetBlock(*newstate.
MX,bsind,*MX_);
2178 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of MX must be consistent with current dimension and length of V.");
2180 if (newstate.
MX != MX_) {
2181 MVT::SetBlock(*newstate.
MX,dimind,*MX_);
2190 const int nvecs = computeAllRes_ ? curDim_ : blockSize_;
2192 RCP<MV> lclX = MVT::CloneViewNonConst(*X_, dimind2);
2193 std::vector<ScalarType> normvec(nvecs);
2194 orthman_->normMat(*lclX,normvec);
2197 for (
int i = 0; i < nvecs; ++i) {
2198 normvec[i] = ONE / normvec[i];
2200 MVT::MvScale (*lclX, normvec);
2201 if (Op_ != Teuchos::null) {
2202 RCP<MV> lclKX = MVT::CloneViewNonConst (*KX_, dimind2);
2203 MVT::MvScale (*lclKX, normvec);
2206 RCP<MV> lclMX = MVT::CloneViewNonConst (*MX_, dimind2);
2207 MVT::MvScale (*lclMX, normvec);
2211 for (
int i = 0; i < nvecs; ++i) {
2212 theta_[i] = theta_[i] * normvec[i] * normvec[i];
2217 if(newstate.
R == Teuchos::null)
2219 om_->stream(
Debug) <<
"Computing R\n";
2226 om_->stream(
Debug) <<
"Copying R\n";
2228 if(computeAllRes_ ==
false)
2231 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): vector length of newstate.R not correct." );
2233 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): newstate.R must have at least block size vectors." );
2234 if (newstate.
R != R_) {
2235 MVT::SetBlock(*newstate.
R,bsind,*R_);
2241 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): vector length of newstate.R not correct." );
2243 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): newstate.R must have at least curDim vectors." );
2244 if (newstate.
R != R_) {
2245 MVT::SetBlock(*newstate.
R,dimind,*R_);
2251 Rnorms_current_ =
false;
2252 R2norms_current_ =
false;
2260 om_->stream(
Debug) <<
"Copying Ritz shifts\n";
2265 om_->stream(
Debug) <<
"Setting Ritz shifts to 0\n";
2266 for(
size_t i=0; i<ritzShifts_.size(); i++)
2267 ritzShifts_[i] = ZERO;
2270 for(
size_t i=0; i<ritzShifts_.size(); i++)
2271 om_->stream(
Debug) <<
"Ritz shifts[" << i <<
"] = " << ritzShifts_[i] << std::endl;
2274 initialized_ =
true;
2276 if (om_->isVerbosity(
Debug ) ) {
2285 om_->print(
Debug, accuracyCheck(chk,
": after initialize()") );
2289 if (om_->isVerbosity(
Debug)) {
2290 currentStatus( om_->stream(
Debug) );
2300 template <
class ScalarType,
class MV,
class OP>
2306 template <
class ScalarType,
class MV,
class OP>
2312 TEUCHOS_TEST_FOR_EXCEPTION(blockSize < 1, std::invalid_argument,
"Anasazi::TraceMinBase::setSize(blocksize,numblocks): blocksize must be strictly positive.");
2314 if (blockSize == blockSize_ && numBlocks == numBlocks_) {
2319 blockSize_ = blockSize;
2320 numBlocks_ = numBlocks;
2327 if (X_ != Teuchos::null) {
2331 tmp = problem_->getInitVec();
2333 "Anasazi::TraceMinBase::setSize(): eigenproblem did not specify initial vectors to clone from.");
2336 TEUCHOS_TEST_FOR_EXCEPTION(numAuxVecs_+blockSize*static_cast<ptrdiff_t>(numBlocks) > MVT::GetGlobalLength(*tmp),std::invalid_argument,
2337 "Anasazi::TraceMinBase::setSize(): max subspace dimension and auxilliary subspace too large. Potentially impossible orthogonality constraints.");
2340 int newsd = blockSize_*numBlocks_;
2345 ritzShifts_.resize(blockSize_,ZERO);
2346 if(computeAllRes_ ==
false)
2349 Rnorms_.resize(blockSize_,NANVAL);
2350 R2norms_.resize(blockSize_,NANVAL);
2356 KX_ = Teuchos::null;
2357 MX_ = Teuchos::null;
2360 KV_ = Teuchos::null;
2361 MV_ = Teuchos::null;
2363 om_->print(
Debug,
" >> Allocating X_\n");
2364 X_ = MVT::Clone(*tmp,blockSize_);
2365 if(Op_ != Teuchos::null) {
2366 om_->print(
Debug,
" >> Allocating KX_\n");
2367 KX_ = MVT::Clone(*tmp,blockSize_);
2373 om_->print(
Debug,
" >> Allocating MX_\n");
2374 MX_ = MVT::Clone(*tmp,blockSize_);
2379 om_->print(
Debug,
" >> Allocating R_\n");
2380 R_ = MVT::Clone(*tmp,blockSize_);
2385 Rnorms_.resize(newsd,NANVAL);
2386 R2norms_.resize(newsd,NANVAL);
2392 KX_ = Teuchos::null;
2393 MX_ = Teuchos::null;
2396 KV_ = Teuchos::null;
2397 MV_ = Teuchos::null;
2399 om_->print(
Debug,
" >> Allocating X_\n");
2400 X_ = MVT::Clone(*tmp,newsd);
2401 if(Op_ != Teuchos::null) {
2402 om_->print(
Debug,
" >> Allocating KX_\n");
2403 KX_ = MVT::Clone(*tmp,newsd);
2409 om_->print(
Debug,
" >> Allocating MX_\n");
2410 MX_ = MVT::Clone(*tmp,newsd);
2415 om_->print(
Debug,
" >> Allocating R_\n");
2416 R_ = MVT::Clone(*tmp,newsd);
2422 theta_.resize(newsd,NANVAL);
2423 om_->print(
Debug,
" >> Allocating V_\n");
2424 V_ = MVT::Clone(*tmp,newsd);
2428 if(Op_ != Teuchos::null) {
2429 om_->print(
Debug,
" >> Allocating KV_\n");
2430 KV_ = MVT::Clone(*tmp,newsd);
2436 om_->print(
Debug,
" >> Allocating MV_\n");
2437 MV_ = MVT::Clone(*tmp,newsd);
2443 om_->print(
Debug,
" >> done allocating.\n");
2445 initialized_ =
false;
2452 template <
class ScalarType,
class MV,
class OP>
2463 for (tarcpmv i=auxVecs_.begin(); i != auxVecs_.end(); ++i) {
2464 numAuxVecs_ += MVT::GetNumberVecs(**i);
2468 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
2471 count_ApplyM_+= MVT::GetNumberVecs(**i);
2473 RCP<MV> helperMV = MVT::Clone(**i,MVT::GetNumberVecs(**i));
2474 OPT::Apply(*MOp_,**i,*helperMV);
2475 MauxVecs_.push_back(helperMV);
2480 if (numAuxVecs_ > 0 && initialized_) {
2481 initialized_ =
false;
2484 if (om_->isVerbosity(
Debug ) ) {
2488 om_->print(
Debug, accuracyCheck(chk,
": after setAuxVecs()") );
2495 template <
class ScalarType,
class MV,
class OP>
2496 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
2498 if (Rnorms_current_ ==
false) {
2502 std::vector<int> curind(curDim_);
2503 for(
int i=0; i<curDim_; i++)
2507 std::vector<ScalarType> locNorms(curDim_);
2508 orthman_->norm(*locR,locNorms);
2510 for(
int i=0; i<curDim_; i++)
2511 Rnorms_[i] = locNorms[i];
2512 for(
int i=curDim_+1; i<blockSize_*numBlocks_; i++)
2513 Rnorms_[i] = NANVAL;
2515 Rnorms_current_ =
true;
2516 locNorms.resize(blockSize_);
2520 orthman_->norm(*R_,Rnorms_);
2521 Rnorms_current_ =
true;
2523 else if(computeAllRes_)
2525 std::vector<ScalarType> locNorms(blockSize_);
2526 for(
int i=0; i<blockSize_; i++)
2527 locNorms[i] = Rnorms_[i];
2537 template <
class ScalarType,
class MV,
class OP>
2538 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>
2540 if (R2norms_current_ ==
false) {
2544 std::vector<int> curind(curDim_);
2545 for(
int i=0; i<curDim_; i++)
2549 std::vector<ScalarType> locNorms(curDim_);
2550 MVT::MvNorm(*locR,locNorms);
2552 for(
int i=0; i<curDim_; i++)
2554 R2norms_[i] = locNorms[i];
2556 for(
int i=curDim_+1; i<blockSize_*numBlocks_; i++)
2557 R2norms_[i] = NANVAL;
2559 R2norms_current_ =
true;
2560 locNorms.resize(blockSize_);
2564 MVT::MvNorm(*R_,R2norms_);
2565 R2norms_current_ =
true;
2567 else if(computeAllRes_)
2569 std::vector<ScalarType> locNorms(blockSize_);
2570 for(
int i=0; i<blockSize_; i++)
2571 locNorms[i] = R2norms_[i];
2580 template <
class ScalarType,
class MV,
class OP>
2583 "Anasazi::TraceMinBase::setStatusTest() was passed a null StatusTest.");
2589 template <
class ScalarType,
class MV,
class OP>
2596 template <
class ScalarType,
class MV,
class OP>
2602 os.setf(std::ios::scientific, std::ios::floatfield);
2605 os <<
"================================================================================" << endl;
2607 os <<
" TraceMinBase Solver Status" << endl;
2609 os <<
"The solver is "<<(initialized_ ?
"initialized." :
"not initialized.") << endl;
2610 os <<
"The number of iterations performed is " <<iter_<<endl;
2611 os <<
"The block size is " << blockSize_<<endl;
2612 os <<
"The number of blocks is " << numBlocks_<<endl;
2613 os <<
"The current basis size is " << curDim_<<endl;
2614 os <<
"The number of auxiliary vectors is "<< numAuxVecs_ << endl;
2615 os <<
"The number of operations Op*x is "<<count_ApplyOp_<<endl;
2616 os <<
"The number of operations M*x is "<<count_ApplyM_<<endl;
2618 os.setf(std::ios_base::right, std::ios_base::adjustfield);
2622 os <<
"CURRENT EIGENVALUE ESTIMATES "<<endl;
2623 os << std::setw(20) <<
"Eigenvalue"
2624 << std::setw(20) <<
"Residual(M)"
2625 << std::setw(20) <<
"Residual(2)"
2627 os <<
"--------------------------------------------------------------------------------"<<endl;
2628 for (
int i=0; i<blockSize_; ++i) {
2629 os << std::setw(20) << theta_[i];
2630 if (Rnorms_current_) os << std::setw(20) << Rnorms_[i];
2631 else os << std::setw(20) <<
"not current";
2632 if (R2norms_current_) os << std::setw(20) << R2norms_[i];
2633 else os << std::setw(20) <<
"not current";
2637 os <<
"================================================================================" << endl;
2642 template <
class ScalarType,
class MV,
class OP>
2645 ScalarType currentTrace = ZERO;
2647 for(
int i=0; i < blockSize_; i++)
2648 currentTrace += theta_[i];
2650 return currentTrace;
2654 template <
class ScalarType,
class MV,
class OP>
2655 bool TraceMinBase<ScalarType,MV,OP>::traceLeveled()
2657 ScalarType ratioOfChange = traceThresh_;
2659 if(previouslyLeveled_)
2661 om_->stream(
Debug) <<
"The trace already leveled, so we're not going to check it again\n";
2665 ScalarType currentTrace = getTrace();
2667 om_->stream(
Debug) <<
"The current trace is " << currentTrace << std::endl;
2672 if(previousTrace_ != ZERO)
2674 om_->stream(
Debug) <<
"The previous trace was " << previousTrace_ << std::endl;
2676 ratioOfChange = std::abs(previousTrace_-currentTrace)/std::abs(previousTrace_);
2677 om_->stream(
Debug) <<
"The ratio of change is " << ratioOfChange << std::endl;
2680 previousTrace_ = currentTrace;
2682 if(ratioOfChange < traceThresh_)
2684 previouslyLeveled_ =
true;
2693 template <
class ScalarType,
class MV,
class OP>
2694 std::vector<ScalarType> TraceMinBase<ScalarType,MV,OP>::getClusterResids()
2705 std::vector<ScalarType> clusterResids(nvecs);
2706 std::vector<int> clusterIndices;
2707 if(considerClusters_)
2709 for(
int i=0; i < nvecs; i++)
2712 if(clusterIndices.empty() || (theta_[i-1] + R2norms_[i-1] >= theta_[i] - R2norms_[i]))
2715 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;
2716 clusterIndices.push_back(i);
2721 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;
2722 ScalarType totalRes = ZERO;
2723 for(
size_t j=0; j < clusterIndices.size(); j++)
2724 totalRes += (R2norms_[clusterIndices[j]]*R2norms_[clusterIndices[j]]);
2729 if(theta_[clusterIndices[0]] < 0 && theta_[i] < 0)
2730 negSafeToShift_ =
true;
2731 else if(theta_[clusterIndices[0]] > 0 && theta_[i] > 0)
2732 posSafeToShift_ =
true;
2734 for(
size_t j=0; j < clusterIndices.size(); j++)
2735 clusterResids[clusterIndices[j]] = sqrt(totalRes);
2737 clusterIndices.clear();
2738 clusterIndices.push_back(i);
2743 ScalarType totalRes = ZERO;
2744 for(
size_t j=0; j < clusterIndices.size(); j++)
2745 totalRes += R2norms_[clusterIndices[j]];
2746 for(
size_t j=0; j < clusterIndices.size(); j++)
2747 clusterResids[clusterIndices[j]] = totalRes;
2751 for(
int j=0; j < nvecs; j++)
2752 clusterResids[j] = R2norms_[j];
2755 return clusterResids;
2764 template <
class ScalarType,
class MV,
class OP>
2765 void TraceMinBase<ScalarType,MV,OP>::computeRitzShifts(
const std::vector<ScalarType>& clusterResids)
2767 std::vector<ScalarType> thetaMag(theta_);
2768 bool traceHasLeveled = traceLeveled();
2771 for(
int i=0; i<blockSize_; i++)
2772 thetaMag[i] = std::abs(thetaMag[i]);
2780 if(whenToShift_ == ALWAYS_SHIFT || (whenToShift_ == SHIFT_WHEN_TRACE_LEVELS && traceHasLeveled))
2783 if(howToShift_ == LARGEST_CONVERGED_SHIFT)
2785 for(
int i=0; i<blockSize_; i++)
2786 ritzShifts_[i] = largestSafeShift_;
2789 else if(howToShift_ == RITZ_VALUES_SHIFT)
2791 ritzShifts_[0] = theta_[0];
2795 if(useMultipleShifts_)
2797 for(
int i=1; i<blockSize_; i++)
2798 ritzShifts_[i] = theta_[i];
2802 for(
int i=1; i<blockSize_; i++)
2803 ritzShifts_[i] = ritzShifts_[0];
2806 else if(howToShift_ == EXPERIMENTAL_SHIFT)
2808 ritzShifts_[0] = std::max(largestSafeShift_,theta_[0]-clusterResids[0]);
2809 for(
int i=1; i<blockSize_; i++)
2811 ritzShifts_[i] = std::max(ritzShifts_[i-1],theta_[i]-clusterResids[i]);
2815 else if(howToShift_ == ADJUSTED_RITZ_SHIFT)
2817 om_->stream(
Debug) <<
"\nSeeking a shift for theta[0]=" << thetaMag[0] << std::endl;
2821 if((theta_[0] > 0 && posSafeToShift_) || (theta_[0] < 0 && negSafeToShift_) || considerClusters_ ==
false)
2824 ritzShifts_[0] = std::max(largestSafeShift_,thetaMag[0]-clusterResids[0]);
2826 om_->stream(
Debug) <<
"Initializing with a conservative shift, either the most positive converged eigenvalue ("
2827 << largestSafeShift_ <<
") or the eigenvalue adjusted by the residual (" << thetaMag[0] <<
"-"
2828 << clusterResids[0] <<
").\n";
2831 if(R2norms_[0] == clusterResids[0])
2833 ritzShifts_[0] = thetaMag[0];
2834 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;
2837 om_->stream(
Debug) <<
"This eigenvalue is in a cluster, so it would not be safe to use the eigenvalue itself as a shift\n";
2841 if(largestSafeShift_ > std::abs(ritzShifts_[0]))
2843 om_->stream(
Debug) <<
"Initializing with a conservative shift...the most positive converged eigenvalue: " << largestSafeShift_ << std::endl;
2844 ritzShifts_[0] = largestSafeShift_;
2847 om_->stream(
Debug) <<
"Using the previous value of ritzShifts[0]=" << ritzShifts_[0];
2851 om_->stream(
Debug) <<
"ritzShifts[0]=" << ritzShifts_[0] << std::endl;
2853 if(useMultipleShifts_)
2857 for(
int i=1; i < blockSize_; i++)
2859 om_->stream(
Debug) <<
"\nSeeking a shift for theta[" << i <<
"]=" << thetaMag[i] << std::endl;
2862 if(ritzShifts_[i-1] == thetaMag[i-1] && i < blockSize_-1 && thetaMag[i] < thetaMag[i+1] - clusterResids[i+1])
2864 ritzShifts_[i] = thetaMag[i];
2865 om_->stream(
Debug) <<
"Using an aggressive shift: ritzShifts_[" << i <<
"]=" << ritzShifts_[i] << std::endl;
2869 if(ritzShifts_[0] > std::abs(ritzShifts_[i]))
2871 om_->stream(
Debug) <<
"It was unsafe to use the aggressive shift. Choose the shift used by theta[0]="
2872 << thetaMag[0] <<
": ritzShifts[0]=" << ritzShifts_[0] << std::endl;
2875 ritzShifts_[i] = ritzShifts_[0];
2878 om_->stream(
Debug) <<
"It was unsafe to use the aggressive shift. We will use the shift from the previous iteration: " << ritzShifts_[i] << std::endl;
2880 om_->stream(
Debug) <<
"Check whether any less conservative shifts would work (such as the biggest eigenvalue outside of the cluster, namely theta[ell] < "
2881 << thetaMag[i] <<
"-" << clusterResids[i] <<
" (" << thetaMag[i] - clusterResids[i] <<
")\n";
2884 for(
int ell=0; ell < i; ell++)
2886 if(thetaMag[ell] < thetaMag[i] - clusterResids[i])
2888 ritzShifts_[i] = thetaMag[ell];
2889 om_->stream(
Debug) <<
"ritzShifts_[" << i <<
"]=" << ritzShifts_[i] <<
" is valid\n";
2896 om_->stream(
Debug) <<
"ritzShifts[" << i <<
"]=" << ritzShifts_[i] << std::endl;
2901 for(
int i=1; i<blockSize_; i++)
2902 ritzShifts_[i] = ritzShifts_[0];
2908 for(
int i=0; i<blockSize_; i++)
2911 ritzShifts_[i] = -abs(ritzShifts_[i]);
2913 ritzShifts_[i] = abs(ritzShifts_[i]);
2918 template <
class ScalarType,
class MV,
class OP>
2919 std::vector<ScalarType> TraceMinBase<ScalarType,MV,OP>::computeTol()
2922 std::vector<ScalarType> tolerances(blockSize_);
2924 for(
int i=0; i < blockSize_-1; i++)
2926 if(std::abs(theta_[blockSize_-1]) != std::abs(ritzShifts_[i]))
2927 temp1 = std::abs(theta_[i]-ritzShifts_[i])/std::abs(std::abs(theta_[blockSize_-1])-std::abs(ritzShifts_[i]));
2933 tolerances[i] = std::min(temp1*temp1,0.5);
2937 tolerances[blockSize_-1] = tolerances[blockSize_-2];
2943 template <
class ScalarType,
class MV,
class OP>
2944 void TraceMinBase<ScalarType,MV,OP>::solveSaddlePointProblem(
RCP<MV> Delta)
2946 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
2951 if(Op_ == Teuchos::null)
2962 std::vector<int> curind(blockSize_);
2963 for(
int i=0; i<blockSize_; i++)
2970 MVT::MvTransMv(ONE,*lclMX,*lclMX,*lclS);
2978 MVT::Assign(*lclX,*Delta);
2979 MVT::MvTimesMatAddMv( -ONE, *lclMX, *lclS, ONE, *Delta);
2984 MVT::MvTransMv(ONE,*MX_,*MX_,*lclS);
2991 MVT::Assign(*X_,*Delta);
2992 MVT::MvTimesMatAddMv( -ONE, *MX_, *lclS, ONE, *Delta);
2997 std::vector<int> order(curDim_);
2998 std::vector<ScalarType> tempvec(blockSize_);
3002 std::vector<ScalarType> clusterResids;
3015 clusterResids = getClusterResids();
3030 computeRitzShifts(clusterResids);
3033 std::vector<ScalarType> tolerances = computeTol();
3035 for(
int i=0; i<blockSize_; i++)
3037 om_->stream(
IterationDetails) <<
"Choosing Ritz shifts...theta[" << i <<
"]="
3038 << theta_[i] <<
", resids[" << i <<
"]=" << R2norms_[i] <<
", clusterResids[" << i <<
"]=" << clusterResids[i]
3039 <<
", ritzShifts[" << i <<
"]=" << ritzShifts_[i] <<
", and tol[" << i <<
"]=" << tolerances[i] << std::endl;
3043 ritzOp_->setRitzShifts(ritzShifts_);
3047 ritzOp_->setInnerTol(tolerances);
3050 if(saddleSolType_ == PROJECTED_KRYLOV_SOLVER)
3052 if(Prec_ != Teuchos::null)
3053 solveSaddleProjPrec(Delta);
3055 solveSaddleProj(Delta);
3057 else if(saddleSolType_ == SCHUR_COMPLEMENT_SOLVER)
3059 if(Z_ == Teuchos::null || MVT::GetNumberVecs(*Z_) != blockSize_)
3063 Z_ = MVT::Clone(*X_,blockSize_);
3066 solveSaddleSchur(Delta);
3068 else if(saddleSolType_ == BD_PREC_MINRES)
3070 solveSaddleBDPrec(Delta);
3073 else if(saddleSolType_ == HSS_PREC_GMRES)
3075 solveSaddleHSSPrec(Delta);
3078 std::cout <<
"Invalid saddle solver type\n";
3085 template <
class ScalarType,
class MV,
class OP>
3086 void TraceMinBase<ScalarType,MV,OP>::solveSaddleProj (
RCP<MV> Delta)
const
3093 std::vector<int> curind(blockSize_);
3094 for(
int i=0; i<blockSize_; i++)
3102 if(projectLockedVecs_ && numAuxVecs_ > 0)
3103 projOp =
rcp(
new TraceMinProjRitzOp<ScalarType,MV,OP>(ritzOp_,locMX,orthman_,auxVecs_) );
3105 projOp =
rcp(
new TraceMinProjRitzOp<ScalarType,MV,OP>(ritzOp_,locMX,orthman_) );
3108 projOp =
rcp(
new TraceMinProjRitzOp<ScalarType,MV,OP>(ritzOp_,locMX) );
3112 MVT::MvInit(*Delta);
3117 projOp->ApplyInverse(*locR, *Delta);
3122 projOp->ApplyInverse(*locKX, *Delta);
3130 if(projectLockedVecs_ && numAuxVecs_ > 0)
3131 projOp =
rcp(
new TraceMinProjRitzOp<ScalarType,MV,OP>(ritzOp_,MX_,orthman_,auxVecs_) );
3133 projOp =
rcp(
new TraceMinProjRitzOp<ScalarType,MV,OP>(ritzOp_,MX_,orthman_) );
3136 projOp =
rcp(
new TraceMinProjRitzOp<ScalarType,MV,OP>(ritzOp_,MX_) );
3140 MVT::MvInit(*Delta);
3143 projOp->ApplyInverse(*R_, *Delta);
3146 projOp->ApplyInverse(*KX_, *Delta);
3153 template <
class ScalarType,
class MV,
class OP>
3154 void TraceMinBase<ScalarType,MV,OP>::solveSaddleProjPrec (
RCP<MV> Delta)
const
3159 #ifdef HAVE_ANASAZI_BELOS
3166 dimension = curDim_;
3168 dimension = blockSize_;
3171 std::vector<int> curind(dimension);
3172 for(
int i=0; i<dimension; i++)
3180 if(projectLockedVecs_ && numAuxVecs_ > 0)
3181 projOp =
rcp(
new TraceMinProjRitzOpWithPrec<ScalarType,MV,OP>(ritzOp_,locMX,orthman_,auxVecs_) );
3183 projOp =
rcp(
new TraceMinProjRitzOpWithPrec<ScalarType,MV,OP>(ritzOp_,locMX,orthman_) );
3186 projOp =
rcp(
new TraceMinProjRitzOpWithPrec<ScalarType,MV,OP>(ritzOp_,locMX) );
3190 MVT::MvInit(*Delta);
3192 std::vector<int> dimind(blockSize_);
3193 for(
int i=0; i<blockSize_; i++)
3199 projOp->ApplyInverse(*locR, *Delta);
3200 MVT::MvScale(*Delta, -ONE);
3205 projOp->ApplyInverse(*locKX, *Delta);
3213 if(projectLockedVecs_ && numAuxVecs_ > 0)
3214 projOp =
rcp(
new TraceMinProjRitzOpWithPrec<ScalarType,MV,OP>(ritzOp_,MX_,orthman_,auxVecs_) );
3216 projOp =
rcp(
new TraceMinProjRitzOpWithPrec<ScalarType,MV,OP>(ritzOp_,MX_,orthman_) );
3219 projOp =
rcp(
new TraceMinProjRitzOpWithPrec<ScalarType,MV,OP>(ritzOp_,MX_) );
3223 MVT::MvInit(*Delta);
3227 projOp->ApplyInverse(*R_, *Delta);
3228 MVT::MvScale(*Delta,-ONE);
3231 projOp->ApplyInverse(*KX_, *Delta);
3239 template <
class ScalarType,
class MV,
class OP>
3240 void TraceMinBase<ScalarType,MV,OP>::solveSaddleSchur (
RCP<MV> Delta)
const
3251 std::vector<int> curind(blockSize_);
3252 for(
int i=0; i<blockSize_; i++)
3259 #ifdef USE_APPLY_INVERSE
3260 Op_->ApplyInverse(*lclMX,*Z_);
3262 ritzOp_->ApplyInverse(*lclMX,*Z_);
3266 MVT::MvTransMv(ONE,*Z_,*lclMX,*lclS);
3275 MVT::Assign(*lclX,*Delta);
3276 MVT::MvTimesMatAddMv( -ONE, *Z_, *lclL, ONE, *Delta);
3281 #ifdef USE_APPLY_INVERSE
3282 Op_->ApplyInverse(*MX_,*Z_);
3284 ritzOp_->ApplyInverse(*MX_,*Z_);
3288 MVT::MvTransMv(ONE,*Z_,*MX_,*lclS);
3296 MVT::Assign(*X_,*Delta);
3297 MVT::MvTimesMatAddMv( -ONE, *Z_, *lclL, ONE, *Delta);
3304 template <
class ScalarType,
class MV,
class OP>
3305 void TraceMinBase<ScalarType,MV,OP>::solveSaddleBDPrec (
RCP<MV> Delta)
const
3310 std::vector<int> curind(blockSize_);
3311 for(
int i=0; i<blockSize_; i++)
3313 locKX = MVT::CloneViewNonConst(*KX_, curind);
3314 locMX = MVT::CloneViewNonConst(*MX_, curind);
3333 MVT::MvInit(*Delta);
3338 if(Prec_ != Teuchos::null)
3341 sadSolver =
rcp(
new PseudoBlockMinres<ScalarType,saddle_container_type,saddle_op_type>(sadOp, sadPrec));
3344 sadSolver =
rcp(
new PseudoBlockMinres<ScalarType,saddle_container_type,saddle_op_type>(sadOp));
3348 std::vector<ScalarType> tol;
3349 ritzOp_->getInnerTol(tol);
3350 sadSolver->setTol(tol);
3353 sadSolver->setMaxIter(ritzOp_->getMaxIts());
3356 sadSolver->setSol(sadSol);
3359 sadSolver->setRHS(sadRHS);
3369 template <
class ScalarType,
class MV,
class OP>
3370 void TraceMinBase<ScalarType,MV,OP>::solveSaddleHSSPrec (
RCP<MV> Delta)
const
3372 #ifdef HAVE_ANASAZI_BELOS
3373 typedef Belos::LinearProblem<ScalarType,saddle_container_type,saddle_op_type> LP;
3374 typedef Belos::PseudoBlockGmresSolMgr<ScalarType,saddle_container_type,saddle_op_type> GmresSolMgr;
3379 std::vector<int> curind(blockSize_);
3380 for(
int i=0; i<blockSize_; i++)
3382 locKX = MVT::CloneViewNonConst(*KX_, curind);
3383 locMX = MVT::CloneViewNonConst(*MX_, curind);
3398 MVT::MvInit(*Delta);
3405 std::vector<ScalarType> tol;
3406 ritzOp_->getInnerTol(tol);
3407 pl->
set(
"Convergence Tolerance",tol[0]);
3411 pl->
set(
"Maximum Iterations", ritzOp_->getMaxIts());
3412 pl->
set(
"Num Blocks", ritzOp_->getMaxIts());
3417 pl->
set(
"Block Size", blockSize_);
3424 RCP<LP> problem =
rcp(
new LP(sadOp,sadSol,sadRHS));
3427 if(Prec_ != Teuchos::null)
3430 problem->setLeftPrec(sadPrec);
3434 problem->setProblem();
3442 std::cout <<
"No Belos. This is bad\n";
3451 template <
class ScalarType,
class MV,
class OP>
3452 void TraceMinBase<ScalarType,MV,OP>::computeKK()
3455 std::vector<int> curind(curDim_);
3456 for(
int i=0; i<curDim_; i++)
3463 curind.resize(blockSize_);
3464 for(
int i=0; i<blockSize_; i++)
3465 curind[i] = curDim_-blockSize_+i;
3473 MVT::MvTransMv(ONE,*lclV,*lclKV,*lclKK);
3476 for(
int r=0; r<curDim_; r++)
3478 for(
int c=0; c<r; c++)
3480 (*KK_)(r,c) = (*KK_)(c,r);
3487 template <
class ScalarType,
class MV,
class OP>
3488 void TraceMinBase<ScalarType,MV,OP>::computeRitzPairs()
3500 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
3504 Utils::directSolver(curDim_, *lclKK, Teuchos::null, *lclRV, theta_, rank, 10);
3508 "Anasazi::TraceMinBase::computeRitzPairs(): Failed to compute all eigenpairs of KK.");
3513 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
3517 std::vector<int> order(curDim_);
3523 sm.
sort(theta_, Teuchos::rcpFromRef(order), curDim_);
3527 sm_->sort(theta_, Teuchos::rcpFromRef(order), curDim_);
3531 Utils::permuteVectors(order,*lclRV);
3537 template <
class ScalarType,
class MV,
class OP>
3538 void TraceMinBase<ScalarType,MV,OP>::computeX()
3540 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
3545 std::vector<int> curind(curDim_);
3546 for(
int i=0; i<curDim_; i++)
3559 RCP<MV> lclX = MVT::CloneViewNonConst(*X_,curind);
3560 MVT::MvTimesMatAddMv( ONE, *lclV, *relevantEvecs, ZERO, *lclX );
3569 MVT::MvTimesMatAddMv( ONE, *lclV, *relevantEvecs, ZERO, *X_ );
3575 template <
class ScalarType,
class MV,
class OP>
3576 void TraceMinBase<ScalarType,MV,OP>::updateKXMX()
3578 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
3583 std::vector<int> curind(curDim_);
3584 for(
int i=0; i<curDim_; i++)
3598 RCP<MV> lclKX = MVT::CloneViewNonConst(*KX_,curind);
3599 MVT::MvTimesMatAddMv( ONE, *lclKV, *relevantEvecs, ZERO, *lclKX );
3603 RCP<MV> lclMX = MVT::CloneViewNonConst(*MX_,curind);
3604 MVT::MvTimesMatAddMv( ONE, *lclMV, *relevantEvecs, ZERO, *lclMX );
3614 MVT::MvTimesMatAddMv( ONE, *lclKV, *relevantEvecs, ZERO, *KX_ );
3618 MVT::MvTimesMatAddMv( ONE, *lclMV, *relevantEvecs, ZERO, *MX_ );
3625 template <
class ScalarType,
class MV,
class OP>
3626 void TraceMinBase<ScalarType,MV,OP>::updateResidual () {
3627 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
3634 std::vector<int> curind(curDim_);
3635 for(
int i=0; i<curDim_; i++)
3639 RCP<MV> MXT = MVT::CloneCopy(*MX_,curind);
3642 std::vector<ScalarType> locTheta(curDim_);
3643 for(
int i=0; i<curDim_; i++)
3644 locTheta[i] = theta_[i];
3647 MVT::MvScale(*MXT,locTheta);
3651 RCP<MV> locR = MVT::CloneViewNonConst(*R_,curind);
3652 MVT::MvAddMv(ONE,*locKX,-ONE,*MXT,*locR);
3657 RCP<MV> MXT = MVT::CloneCopy(*MX_);
3660 std::vector<ScalarType> locTheta(blockSize_);
3661 for(
int i=0; i<blockSize_; i++)
3662 locTheta[i] = theta_[i];
3665 MVT::MvScale(*MXT,locTheta);
3668 MVT::MvAddMv(ONE,*KX_,-ONE,*MXT,*R_);
3672 Rnorms_current_ =
false;
3673 R2norms_current_ =
false;
3703 template <
class ScalarType,
class MV,
class OP>
3704 std::string TraceMinBase<ScalarType,MV,OP>::accuracyCheck(
const CheckList &chk,
const std::string &where )
const
3708 std::stringstream os;
3710 os.setf(std::ios::scientific, std::ios::floatfield);
3712 os <<
" Debugging checks: iteration " << iter_ << where << endl;
3715 std::vector<int> lclind(curDim_);
3716 for (
int i=0; i<curDim_; ++i) lclind[i] = i;
3719 lclV = MVT::CloneView(*V_,lclind);
3721 if (chk.checkV && initialized_) {
3722 MagnitudeType err = orthman_->orthonormError(*lclV);
3723 os <<
" >> Error in V^H M V == I : " << err << endl;
3724 for (Array_size_type i=0; i<auxVecs_.size(); ++i) {
3725 err = orthman_->orthogError(*lclV,*auxVecs_[i]);
3726 os <<
" >> Error in V^H M Q[" << i <<
"] == 0 : " << err << endl;
3735 lclX = MVT::CloneView(*X_,lclind);
3740 if (chk.checkX && initialized_) {
3741 MagnitudeType err = orthman_->orthonormError(*lclX);
3742 os <<
" >> Error in X^H M X == I : " << err << endl;
3743 for (Array_size_type i=0; i<auxVecs_.size(); ++i) {
3744 err = orthman_->orthogError(*lclX,*auxVecs_[i]);
3745 os <<
" >> Error in X^H M Q[" << i <<
"] == 0 : " << err << endl;
3748 if (chk.checkMX && hasM_ && initialized_) {
3751 lclMX = MVT::CloneView(*MX_,lclind);
3755 MagnitudeType err = Utils::errorEquality(*lclX, *lclMX, MOp_);
3756 os <<
" >> Error in MX == M*X : " << err << endl;
3758 if (Op_ != Teuchos::null && chk.checkKX && initialized_) {
3761 lclKX = MVT::CloneView(*KX_,lclind);
3765 MagnitudeType err = Utils::errorEquality(*lclX, *lclKX, Op_);
3766 os <<
" >> Error in KX == K*X : " << err << endl;
3770 if (chk.checkKK && initialized_) {
3772 if(Op_ != Teuchos::null) {
3773 RCP<MV> lclKV = MVT::Clone(*V_,curDim_);
3774 OPT::Apply(*Op_,*lclV,*lclKV);
3775 MVT::MvTransMv(ONE,*lclV,*lclKV,curKK);
3778 MVT::MvTransMv(ONE,*lclV,*lclV,curKK);
3782 os <<
" >> Error in V^H K V == KK : " << curKK.normFrobenius() << endl;
3785 for (
int j=0; j<curDim_; ++j) {
3786 for (
int i=0; i<curDim_; ++i) {
3787 SDMerr(i,j) = subKK(i,j) - SCT::conjugate(subKK(j,i));
3790 os <<
" >> Error in KK - KK^H == 0 : " << SDMerr.normFrobenius() << endl;
3795 for (Array_size_type i=0; i<auxVecs_.size(); ++i) {
3796 MagnitudeType err = orthman_->orthonormError(*auxVecs_[i]);
3797 os <<
" >> Error in Q[" << i <<
"]^H M Q[" << i <<
"] == I : " << err << endl;
3798 for (Array_size_type j=i+1; j<auxVecs_.size(); ++j) {
3799 err = orthman_->orthogError(*auxVecs_[i],*auxVecs_[j]);
3800 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.
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
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.
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.