48 #ifndef ANASAZI_TRACEMIN_BASE_HPP
49 #define ANASAZI_TRACEMIN_BASE_HPP
64 #include "Teuchos_ParameterList.hpp"
65 #include "Teuchos_ScalarTraits.hpp"
66 #include "Teuchos_SerialDenseMatrix.hpp"
67 #include "Teuchos_SerialDenseSolver.hpp"
68 #include "Teuchos_TimeMonitor.hpp"
93 template <
class ScalarType,
class MV>
115 RCP<const std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> >
T;
121 RCP<const Teuchos::SerialDenseMatrix<int,ScalarType> >
KK;
123 RCP<const Teuchos::SerialDenseMatrix<int,ScalarType> >
RV;
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>
215 const RCP<
SortManager<
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > &sorter,
219 Teuchos::ParameterList ¶ms
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();
436 void setAuxVecs(
const Teuchos::Array<RCP<const MV> > &auxvecs);
439 Teuchos::Array<RCP<const MV> >
getAuxVecs()
const;
452 void setSize(
int blockSize,
int numBlocks);
469 typedef Teuchos::ScalarTraits<ScalarType> SCT;
470 typedef typename SCT::magnitudeType MagnitudeType;
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;
480 const RCP<Eigenproblem<ScalarType,MV,OP> > problem_;
481 const RCP<SortManager<MagnitudeType> > sm_;
482 const RCP<OutputManager<ScalarType> > om_;
483 RCP<StatusTest<ScalarType,MV,OP> > tester_;
484 const RCP<MatOrthoManager<ScalarType,MV,OP> > orthman_;
496 RCP<Teuchos::Time> timerOp_, timerMOp_, timerSaddle_, timerSortEval_, timerDS_,
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_;
548 RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > KK_, ritzVecs_;
551 Teuchos::Array<RCP<const MV> > auxVecs_, MauxVecs_;
558 std::vector<MagnitudeType> theta_, Rnorms_, R2norms_;
561 bool Rnorms_current_, R2norms_current_;
564 RCP<tracemin_ritz_op_type> ritzOp_;
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();
635 virtual void addToBasis(
const RCP<const MV> Delta) =0;
636 virtual void harmonicAddToBasis(
const RCP<const MV> Delta) =0;
652 template <
class ScalarType,
class MV,
class OP>
655 const RCP<
SortManager<
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > &sorter,
659 Teuchos::ParameterList ¶ms
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),
703 TEUCHOS_TEST_FOR_EXCEPTION(problem_ == Teuchos::null,std::invalid_argument,
704 "Anasazi::TraceMinBase::constructor: user passed null problem pointer.");
705 TEUCHOS_TEST_FOR_EXCEPTION(sm_ == Teuchos::null,std::invalid_argument,
706 "Anasazi::TraceMinBase::constructor: user passed null sort manager pointer.");
707 TEUCHOS_TEST_FOR_EXCEPTION(om_ == Teuchos::null,std::invalid_argument,
708 "Anasazi::TraceMinBase::constructor: user passed null output manager pointer.");
709 TEUCHOS_TEST_FOR_EXCEPTION(tester_ == Teuchos::null,std::invalid_argument,
710 "Anasazi::TraceMinBase::constructor: user passed null status test pointer.");
711 TEUCHOS_TEST_FOR_EXCEPTION(orthman_ == Teuchos::null,std::invalid_argument,
712 "Anasazi::TraceMinBase::constructor: user passed null orthogonalization manager pointer.");
713 TEUCHOS_TEST_FOR_EXCEPTION(problem_->isHermitian() ==
false, std::invalid_argument,
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);
733 TEUCHOS_TEST_FOR_EXCEPTION(traceThresh_ < 0, std::invalid_argument,
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");
745 TEUCHOS_TEST_FOR_EXCEPTION(shiftNorm_ !=
"2" && shiftNorm_ !=
"M", std::invalid_argument,
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
1174 Teuchos::TimeMonitor inittimer( *timerInit_ );
1177 previouslyLeveled_ =
false;
1181 harmonicInitialize(newstate);
1185 std::vector<int> bsind(blockSize_);
1186 for (
int i=0; i<blockSize_; ++i) bsind[i] = i;
1210 RCP<MV> lclV, lclKV, lclMV;
1211 RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > lclKK, lclRV;
1214 if (newstate.
V != Teuchos::null) {
1215 om_->stream(
Debug) <<
"Copying V from the user\n";
1217 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*newstate.
V) != MVT::GetGlobalLength(*V_), std::invalid_argument,
1218 "Anasazi::TraceMinBase::initialize(newstate): Vector length of V not correct." );
1219 TEUCHOS_TEST_FOR_EXCEPTION( newstate.
curDim < blockSize_, std::invalid_argument,
1220 "Anasazi::TraceMinBase::initialize(newstate): Rank of new state must be at least blockSize().");
1221 TEUCHOS_TEST_FOR_EXCEPTION( newstate.
curDim > blockSize_*numBlocks_, std::invalid_argument,
1222 "Anasazi::TraceMinBase::initialize(newstate): Rank of new state must be less than getMaxSubspaceDim().");
1224 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetNumberVecs(*newstate.
V) < newstate.
curDim, std::invalid_argument,
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_;
1231 TEUCHOS_TEST_FOR_EXCEPTION( curDim_ != newstate.
curDim, std::invalid_argument,
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);
1248 RCP<const MV> ivec = problem_->getInitVec();
1249 TEUCHOS_TEST_FOR_EXCEPTION(ivec == Teuchos::null,std::invalid_argument,
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_) {
1302 RCP<const MV> helperMV = MVT::CloneView(*newstate.
V,nevind);
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
1329 Teuchos::TimeMonitor lcltimer( *timerMOp_ );
1331 count_ApplyM_+= curDim_;
1335 lclMV = MVT::CloneViewNonConst(*MV_,dimind);
1336 OPT::Apply(*MOp_,*lclV,*lclMV);
1341 om_->stream(
Debug) <<
"Copying MV\n";
1343 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*newstate.
MopV) != MVT::GetGlobalLength(*MV_), std::invalid_argument,
1344 "Anasazi::TraceMinBase::initialize(newstate): Vector length of MV not correct." );
1346 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetNumberVecs(*newstate.
MopV) < curDim_, std::invalid_argument,
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
1372 Teuchos::TimeMonitor lcltimer( *timerOrtho_ );
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_,
1389 Teuchos::tuple(RCP< Teuchos::SerialDenseMatrix< int, ScalarType > >(Teuchos::null)),
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
1407 Teuchos::TimeMonitor lcltimer( *timerOp_ );
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";
1429 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*newstate.
KV) != MVT::GetGlobalLength(*KV_), std::invalid_argument,
1430 "Anasazi::TraceMinBase::initialize(newstate): Vector length of MV not correct." );
1432 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetNumberVecs(*newstate.
KV) < curDim_, std::invalid_argument,
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;
1468 lclKK = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::View,*KK_,curDim_,curDim_) );
1471 MVT::MvTransMv(ONE,*lclV,*lclKV,*lclKK);
1476 om_->stream(
Debug) <<
"Copying KK\n";
1479 TEUCHOS_TEST_FOR_EXCEPTION( newstate.
KK->numRows() < curDim_ || newstate.
KK->numCols() < curDim_, std::invalid_argument,
1480 "Anasazi::TraceMinBase::initialize(newstate): Projected matrix in new state must be as large as specified state rank.");
1483 lclKK = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::View,*KK_,curDim_,curDim_) );
1484 if (newstate.
KK != KK_) {
1485 if (newstate.
KK->numRows() > curDim_ || newstate.
KK->numCols() > curDim_) {
1486 newstate.
KK = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::View,*newstate.
KK,curDim_,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";
1512 TEUCHOS_TEST_FOR_EXCEPTION((
signed int)(newstate.
T->size()) != curDim_,
1513 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of T must be consistent with dimension of V.");
1515 TEUCHOS_TEST_FOR_EXCEPTION( newstate.
RV->numRows() < curDim_ || newstate.
RV->numCols() < curDim_, std::invalid_argument,
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());
1520 lclRV = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::View,*ritzVecs_,curDim_,curDim_) );
1521 if (newstate.
RV != ritzVecs_) {
1522 if (newstate.
RV->numRows() > curDim_ || newstate.
RV->numCols() > curDim_) {
1523 newstate.
RV = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::View,*newstate.
RV,curDim_,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)
1585 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*newstate.
KX) != blockSize_ || MVT::GetGlobalLength(*newstate.
KX) != MVT::GetGlobalLength(*KX_),
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_);
1594 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*newstate.
KX) != curDim_ || MVT::GetGlobalLength(*newstate.
KX) != MVT::GetGlobalLength(*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)
1607 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*newstate.
MX) != blockSize_ || MVT::GetGlobalLength(*newstate.
MX) != MVT::GetGlobalLength(*MX_),
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_);
1616 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*newstate.
MX) != curDim_ || MVT::GetGlobalLength(*newstate.
MX) != MVT::GetGlobalLength(*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)
1640 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetGlobalLength(*newstate.
R) != MVT::GetGlobalLength(*X_),
1641 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): vector length of newstate.R not correct." );
1642 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*newstate.
R) != blockSize_,
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_);
1650 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetGlobalLength(*newstate.
R) != MVT::GetGlobalLength(*X_),
1651 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): vector length of newstate.R not correct." );
1652 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*newstate.
R) != curDim_,
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;
1754 RCP<MV> lclV, lclKV, lclMV;
1755 RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > lclKK, lclRV;
1758 if (newstate.
V != Teuchos::null) {
1759 om_->stream(
Debug) <<
"Copying V from the user\n";
1761 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*newstate.
V) != MVT::GetGlobalLength(*V_), std::invalid_argument,
1762 "Anasazi::TraceMinBase::initialize(newstate): Vector length of V not correct." );
1763 TEUCHOS_TEST_FOR_EXCEPTION( newstate.
curDim < blockSize_, std::invalid_argument,
1764 "Anasazi::TraceMinBase::initialize(newstate): Rank of new state must be at least blockSize().");
1765 TEUCHOS_TEST_FOR_EXCEPTION( newstate.
curDim > blockSize_*numBlocks_, std::invalid_argument,
1766 "Anasazi::TraceMinBase::initialize(newstate): Rank of new state must be less than getMaxSubspaceDim().");
1768 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetNumberVecs(*newstate.
V) < newstate.
curDim, std::invalid_argument,
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_;
1775 TEUCHOS_TEST_FOR_EXCEPTION( curDim_ != newstate.
curDim, std::invalid_argument,
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);
1792 RCP<const MV> ivec = problem_->getInitVec();
1793 TEUCHOS_TEST_FOR_EXCEPTION(ivec == Teuchos::null,std::invalid_argument,
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_) {
1846 RCP<const MV> helperMV = MVT::CloneView(*newstate.
V,nevind);
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
1891 Teuchos::TimeMonitor lcltimer( *timerOp_ );
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";
1912 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*newstate.
KV) != MVT::GetGlobalLength(*KV_), std::invalid_argument,
1913 "Anasazi::TraceMinBase::initialize(newstate): Vector length of KV not correct." );
1915 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetNumberVecs(*newstate.
KV) < curDim_, std::invalid_argument,
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
1942 Teuchos::TimeMonitor lcltimer( *timerOrtho_ );
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;
1956 RCP< Teuchos::SerialDenseMatrix<int,ScalarType> > gamma = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(curDim_,curDim_));
1957 int rank = orthman_->normalizeMat(*lclKV,gamma);
1960 Teuchos::SerialDenseSolver<int,ScalarType> SDsolver;
1961 SDsolver.setMatrix(gamma);
1963 RCP<MV> tempMV = MVT::CloneCopy(*lclV);
1964 MVT::MvTimesMatAddMv(ONE,*tempMV,*gamma,ZERO,*lclV);
1966 TEUCHOS_TEST_FOR_EXCEPTION(rank != curDim_,TraceMinBaseInitFailure,
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
1976 Teuchos::TimeMonitor lcltimer( *timerMOp_ );
1978 count_ApplyM_+= curDim_;
1981 lclMV = MVT::CloneViewNonConst(*MV_,dimind);
1982 OPT::Apply(*MOp_,*lclV,*lclMV);
1987 om_->stream(
Debug) <<
"Copying MV\n";
1989 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*newstate.
MopV) != MVT::GetGlobalLength(*MV_), std::invalid_argument,
1990 "Anasazi::TraceMinBase::initialize(newstate): Vector length of MV not correct." );
1992 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetNumberVecs(*newstate.
MopV) < curDim_, std::invalid_argument,
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;
2029 lclKK = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::View,*KK_,curDim_,curDim_) );
2032 MVT::MvTransMv(ONE,*lclV,*lclKV,*lclKK);
2037 om_->stream(
Debug) <<
"Copying KK\n";
2040 TEUCHOS_TEST_FOR_EXCEPTION( newstate.
KK->numRows() < curDim_ || newstate.
KK->numCols() < curDim_, std::invalid_argument,
2041 "Anasazi::TraceMinBase::initialize(newstate): Projected matrix in new state must be as large as specified state rank.");
2044 lclKK = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::View,*KK_,curDim_,curDim_) );
2045 if (newstate.
KK != KK_) {
2046 if (newstate.
KK->numRows() > curDim_ || newstate.
KK->numCols() > curDim_) {
2047 newstate.
KK = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::View,*newstate.
KK,curDim_,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";
2073 TEUCHOS_TEST_FOR_EXCEPTION((
signed int)(newstate.
T->size()) != curDim_,
2074 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): Size of T must be consistent with dimension of V.");
2076 TEUCHOS_TEST_FOR_EXCEPTION( newstate.
RV->numRows() < curDim_ || newstate.
RV->numCols() < curDim_, std::invalid_argument,
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());
2081 lclRV = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::View,*ritzVecs_,curDim_,curDim_) );
2082 if (newstate.
RV != ritzVecs_) {
2083 if (newstate.
RV->numRows() > curDim_ || newstate.
RV->numCols() > curDim_) {
2084 newstate.
RV = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::View,*newstate.
RV,curDim_,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)
2146 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*newstate.
KX) != blockSize_ || MVT::GetGlobalLength(*newstate.
KX) != MVT::GetGlobalLength(*KX_),
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_);
2155 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*newstate.
KX) != curDim_ || MVT::GetGlobalLength(*newstate.
KX) != MVT::GetGlobalLength(*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)
2168 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*newstate.
MX) != blockSize_ || MVT::GetGlobalLength(*newstate.
MX) != MVT::GetGlobalLength(*MX_),
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_);
2177 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*newstate.
MX) != curDim_ || MVT::GetGlobalLength(*newstate.
MX) != MVT::GetGlobalLength(*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_;
2191 Teuchos::Range1D dimind2 (0, nvecs-1);
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)
2230 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetGlobalLength(*newstate.
R) != MVT::GetGlobalLength(*X_),
2231 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): vector length of newstate.R not correct." );
2232 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*newstate.
R) != blockSize_,
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_);
2240 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetGlobalLength(*newstate.
R) != MVT::GetGlobalLength(*X_),
2241 std::invalid_argument,
"Anasazi::TraceMinBase::initialize(newstate): vector length of newstate.R not correct." );
2242 TEUCHOS_TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*newstate.
R) != curDim_,
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();
2332 TEUCHOS_TEST_FOR_EXCEPTION(tmp == Teuchos::null,std::invalid_argument,
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);
2425 KK_ = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(newsd,newsd) );
2426 ritzVecs_ = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(newsd,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>
2454 typedef typename Teuchos::Array<RCP<const MV> >::iterator tarcpmv;
2460 MauxVecs_.resize(0);
2463 for (tarcpmv i=auxVecs_.begin(); i != auxVecs_.end(); ++i) {
2464 numAuxVecs_ += MVT::GetNumberVecs(**i);
2468 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
2469 Teuchos::TimeMonitor lcltimer( *timerMOp_ );
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++)
2506 RCP<const MV> locR = MVT::CloneView(*R_,curind);
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++)
2548 RCP<const MV> locR = MVT::CloneView(*R_,curind);
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>
2582 TEUCHOS_TEST_FOR_EXCEPTION(test == Teuchos::null,std::invalid_argument,
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
2947 Teuchos::TimeMonitor lcltimer( *timerSaddle_ );
2951 if(Op_ == Teuchos::null)
2954 Teuchos::SerialDenseSolver<int,ScalarType> My_Solver;
2957 RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > lclS = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(blockSize_,blockSize_) );
2962 std::vector<int> curind(blockSize_);
2963 for(
int i=0; i<blockSize_; i++)
2967 RCP<const MV> lclMX = MVT::CloneView(*MX_, curind);
2970 MVT::MvTransMv(ONE,*lclMX,*lclMX,*lclS);
2973 My_Solver.setMatrix(lclS);
2977 RCP<const MV> lclX = MVT::CloneView(*X_, curind);
2978 MVT::Assign(*lclX,*Delta);
2979 MVT::MvTimesMatAddMv( -ONE, *lclMX, *lclS, ONE, *Delta);
2984 MVT::MvTransMv(ONE,*MX_,*MX_,*lclS);
2987 My_Solver.setMatrix(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
3088 RCP<TraceMinProjRitzOp<ScalarType,MV,OP> > projOp;
3093 std::vector<int> curind(blockSize_);
3094 for(
int i=0; i<blockSize_; i++)
3097 RCP<const MV> locMX = MVT::CloneView(*MX_, curind);
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);
3116 RCP<const MV> locR = MVT::CloneView(*R_, curind);
3117 projOp->ApplyInverse(*locR, *Delta);
3121 RCP<const MV> locKX = MVT::CloneView(*KX_, curind);
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
3160 RCP<TraceMinProjRitzOpWithPrec<ScalarType,MV,OP> > projOp;
3166 dimension = curDim_;
3168 dimension = blockSize_;
3171 std::vector<int> curind(dimension);
3172 for(
int i=0; i<dimension; i++)
3175 RCP<const MV> locMX = MVT::CloneView(*MX_, curind);
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++)
3198 RCP<const MV> locR = MVT::CloneView(*R_, dimind);
3199 projOp->ApplyInverse(*locR, *Delta);
3200 MVT::MvScale(*Delta, -ONE);
3204 RCP<const MV> locKX = MVT::CloneView(*KX_, dimind);
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
3243 Teuchos::SerialDenseSolver<int,ScalarType> My_Solver;
3245 RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > lclL;
3246 RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > lclS = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(blockSize_,blockSize_) );
3251 std::vector<int> curind(blockSize_);
3252 for(
int i=0; i<blockSize_; i++)
3257 RCP<const MV> lclMX = MVT::CloneView(*MX_, curind);
3259 #ifdef USE_APPLY_INVERSE
3260 Op_->ApplyInverse(*lclMX,*Z_);
3262 ritzOp_->ApplyInverse(*lclMX,*Z_);
3266 MVT::MvTransMv(ONE,*Z_,*lclMX,*lclS);
3269 My_Solver.setMatrix(lclS);
3274 RCP<const MV> lclX = MVT::CloneView(*X_, curind);
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);
3291 My_Solver.setMatrix(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
3307 RCP<MV> locKX, locMX;
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);
3323 RCP<saddle_op_type> sadOp = rcp(
new saddle_op_type(ritzOp_,locMX));
3326 RCP<saddle_container_type> sadRHS = rcp(
new saddle_container_type(locKX));
3333 MVT::MvInit(*Delta);
3334 RCP<saddle_container_type> sadSol = rcp(
new saddle_container_type(Delta));
3337 RCP<PseudoBlockMinres<ScalarType,saddle_container_type,saddle_op_type > > sadSolver;
3338 if(Prec_ != Teuchos::null)
3340 RCP<saddle_op_type> sadPrec = rcp(
new saddle_op_type(ritzOp_->getPrec(),locMX,BD_PREC));
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;
3376 RCP<MV> locKX, locMX;
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);
3392 RCP<saddle_op_type> sadOp = rcp(
new saddle_op_type(ritzOp_,locMX,NONSYM));
3395 RCP<saddle_container_type> sadRHS = rcp(
new saddle_container_type(locKX));
3398 MVT::MvInit(*Delta);
3399 RCP<saddle_container_type> sadSol = rcp(
new saddle_container_type(Delta));
3402 RCP<Teuchos::ParameterList> pl = rcp(
new Teuchos::ParameterList());
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)
3429 RCP<saddle_op_type> sadPrec = rcp(
new saddle_op_type(ritzOp_->getPrec(),locMX,HSS_PREC,alpha_));
3430 problem->setLeftPrec(sadPrec);
3434 problem->setProblem();
3437 RCP<GmresSolMgr> sadSolver = rcp(
new GmresSolMgr(problem,pl)) ;
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++)
3460 RCP<const MV> lclV = MVT::CloneView(*V_,curind);
3463 curind.resize(blockSize_);
3464 for(
int i=0; i<blockSize_; i++)
3465 curind[i] = curDim_-blockSize_+i;
3466 RCP<const MV> lclKV = MVT::CloneView(*KV_,curind);
3469 RCP< Teuchos::SerialDenseMatrix<int,ScalarType> > lclKK =
3470 rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::View,*KK_,curDim_,blockSize_,0,curDim_-blockSize_) );
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()
3491 RCP< Teuchos::SerialDenseMatrix<int,ScalarType> > lclKK =
3492 rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::View,*KK_,curDim_,curDim_) );
3495 RCP< Teuchos::SerialDenseMatrix<int,ScalarType> > lclRV =
3496 rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::View,*ritzVecs_,curDim_,curDim_) );
3500 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
3501 Teuchos::TimeMonitor lcltimer( *timerDS_ );
3504 Utils::directSolver(curDim_, *lclKK, Teuchos::null, *lclRV, theta_, rank, 10);
3507 TEUCHOS_TEST_FOR_EXCEPTION(rank != curDim_,TraceMinBaseOrthoFailure,
3508 "Anasazi::TraceMinBase::computeRitzPairs(): Failed to compute all eigenpairs of KK.");
3513 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
3514 Teuchos::TimeMonitor lcltimer( *timerSortEval_ );
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
3541 Teuchos::TimeMonitor lcltimer( *timerLocal_ );
3545 std::vector<int> curind(curDim_);
3546 for(
int i=0; i<curDim_; i++)
3550 RCP<const MV> lclV = MVT::CloneView(*V_,curind);
3555 RCP< Teuchos::SerialDenseMatrix<int,ScalarType> > relevantEvecs =
3556 rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::View,*ritzVecs_,curDim_,curDim_) );
3559 RCP<MV> lclX = MVT::CloneViewNonConst(*X_,curind);
3560 MVT::MvTimesMatAddMv( ONE, *lclV, *relevantEvecs, ZERO, *lclX );
3565 RCP< Teuchos::SerialDenseMatrix<int,ScalarType> > relevantEvecs =
3566 rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::View,*ritzVecs_,curDim_,blockSize_) );
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
3579 Teuchos::TimeMonitor lcltimer( *timerLocal_ );
3583 std::vector<int> curind(curDim_);
3584 for(
int i=0; i<curDim_; i++)
3588 RCP<const MV> lclV = MVT::CloneView(*V_,curind);
3589 RCP<const MV> lclKV = MVT::CloneView(*KV_,curind);
3594 RCP< Teuchos::SerialDenseMatrix<int,ScalarType> > relevantEvecs =
3595 rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::View,*ritzVecs_,curDim_,curDim_) );
3598 RCP<MV> lclKX = MVT::CloneViewNonConst(*KX_,curind);
3599 MVT::MvTimesMatAddMv( ONE, *lclKV, *relevantEvecs, ZERO, *lclKX );
3602 RCP<const MV> lclMV = MVT::CloneView(*MV_,curind);
3603 RCP<MV> lclMX = MVT::CloneViewNonConst(*MX_,curind);
3604 MVT::MvTimesMatAddMv( ONE, *lclMV, *relevantEvecs, ZERO, *lclMX );
3610 RCP< Teuchos::SerialDenseMatrix<int,ScalarType> > relevantEvecs =
3611 rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::View,*ritzVecs_,curDim_,blockSize_) );
3614 MVT::MvTimesMatAddMv( ONE, *lclKV, *relevantEvecs, ZERO, *KX_ );
3617 RCP<const MV> lclMV = MVT::CloneView(*MV_,curind);
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
3628 Teuchos::TimeMonitor lcltimer( *timerCompRes_ );
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);
3650 RCP<const MV> locKX = MVT::CloneView(*KX_,curind);
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_) {
3749 RCP<const MV> lclMX;
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_) {
3759 RCP<const MV> lclKX;
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_) {
3771 Teuchos::SerialDenseMatrix<int,ScalarType> curKK(curDim_,curDim_);
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);
3780 Teuchos::SerialDenseMatrix<int,ScalarType> subKK(Teuchos::View,*KK_,curDim_,curDim_);
3782 os <<
" >> Error in V^H K V == KK : " << curKK.normFrobenius() << endl;
3784 Teuchos::SerialDenseMatrix<int,ScalarType> SDMerr(curDim_,curDim_);
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;