14 #ifndef TRACEMIN_RITZ_OP_HPP
15 #define TRACEMIN_RITZ_OP_HPP
22 #ifdef HAVE_ANASAZI_BELOS
23 #include "BelosMultiVecTraits.hpp"
24 #include "BelosLinearProblem.hpp"
25 #include "BelosPseudoBlockGmresSolMgr.hpp"
26 #include "BelosOperator.hpp"
27 #ifdef HAVE_ANASAZI_TPETRA
28 #include "BelosTpetraAdapter.hpp"
30 #ifdef HAVE_ANASAZI_EPETRA
31 #include "BelosEpetraAdapter.hpp"
43 namespace Experimental {
52 template <
class Scalar,
class MV,
class OP>
56 virtual ~TraceMinOp() { };
57 virtual void Apply(
const MV& X, MV& Y)
const =0;
58 virtual void removeIndices(
const std::vector<int>& indicesToRemove) =0;
69 template <
class Scalar,
class MV,
class OP>
84 void Apply(
const MV& X, MV& Y)
const;
87 void removeIndices(
const std::vector<int>& indicesToRemove);
94 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
106 template <
class Scalar,
class MV,
class OP>
107 class TraceMinRitzOp :
public TraceMinOp<Scalar,MV,OP>
109 template <
class Scalar_,
class MV_,
class OP_>
friend class TraceMinProjRitzOp;
110 template <
class Scalar_,
class MV_,
class OP_>
friend class TraceMinProjRitzOpWithPrec;
111 template <
class Scalar_,
class MV_,
class OP_>
friend class TraceMinProjectedPrecOp;
123 ~TraceMinRitzOp() { };
126 void setRitzShifts(std::vector<Scalar> shifts) {ritzShifts_ = shifts;};
128 Scalar getRitzShift(
const int subscript) {
return ritzShifts_[subscript]; };
133 void setInnerTol(
const std::vector<Scalar>& tolerances) { tolerances_ = tolerances; };
135 void getInnerTol(std::vector<Scalar>& tolerances)
const { tolerances = tolerances_; };
137 void setMaxIts(
const int maxits) { maxits_ = maxits; };
139 int getMaxIts()
const {
return maxits_; };
142 void Apply(
const MV& X, MV& Y)
const;
145 void ApplyInverse(
const MV& X, MV& Y);
147 void removeIndices(
const std::vector<int>& indicesToRemove);
154 std::vector<Scalar> ritzShifts_;
155 std::vector<Scalar> tolerances_;
159 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
172 template <
class Scalar,
class MV,
class OP>
173 class TraceMinProjRitzOp :
public TraceMinOp<Scalar,MV,OP>
184 void Apply(
const MV& X, MV& Y)
const;
188 void ApplyInverse(
const MV& X, MV& Y);
190 void removeIndices(
const std::vector<int>& indicesToRemove);
208 template <
class Scalar,
class MV,
class OP>
209 class TraceMinProjectedPrecOp :
public TraceMinOp<Scalar,MV,OP>
220 ~TraceMinProjectedPrecOp();
222 void Apply(
const MV& X, MV& Y)
const;
224 void removeIndices(
const std::vector<int>& indicesToRemove);
242 #ifdef HAVE_ANASAZI_BELOS
243 template <
class Scalar,
class MV,
class OP>
244 class TraceMinProjRitzOpWithPrec :
public TraceMinOp<Scalar,MV,OP>
255 void Apply(
const MV& X, MV& Y)
const;
259 void ApplyInverse(
const MV& X, MV& Y);
261 void removeIndices(
const std::vector<int>& indicesToRemove);
284 template <
class Scalar,
class MV,
class OP>
285 class OperatorTraits <Scalar, MV, Experimental::TraceMinOp<Scalar,MV,OP> >
289 Apply (
const Experimental::TraceMinOp<Scalar,MV,OP>& Op,
291 MV& y) {Op.Apply(x,y);};
295 HasApplyTranspose (
const Experimental::TraceMinOp<Scalar,MV,OP>& Op) {
return true;};
300 #ifdef HAVE_ANASAZI_BELOS
303 template <
class Scalar,
class MV,
class OP>
304 class OperatorTraits <Scalar, MV, Anasazi::Experimental::TraceMinOp<Scalar,MV,OP> >
308 Apply (
const Anasazi::Experimental::TraceMinOp<Scalar,MV,OP>& Op,
310 MV& y, Belos::ETrans trans = NOTRANS) {Op.Apply(x,y);};
314 HasApplyTranspose (
const Anasazi::Experimental::TraceMinOp<Scalar,MV,OP>& Op) {
return true;};
323 template <
class Scalar,
class MV,
class OP>
324 class OperatorTraits <Scalar, MV, Experimental::TraceMinRitzOp<Scalar,MV,OP> >
328 Apply (
const Experimental::TraceMinRitzOp<Scalar,MV,OP>& Op,
330 MV& y) {Op.Apply(x,y);};
334 HasApplyTranspose (
const Experimental::TraceMinRitzOp<Scalar,MV,OP>& Op) {
return true;};
342 template <
class Scalar,
class MV,
class OP>
343 class OperatorTraits <Scalar, MV, Experimental::TraceMinProjRitzOp<Scalar,MV,OP> >
347 Apply (
const Experimental::TraceMinProjRitzOp<Scalar,MV,OP>& Op,
349 MV& y) {Op.Apply(x,y);};
353 HasApplyTranspose (
const Experimental::TraceMinProjRitzOp<Scalar,MV,OP>& Op) {
return true;};
361 template <
class Scalar,
class MV,
class OP>
362 class OperatorTraits <Scalar, MV, Experimental::TraceMinProjectedPrecOp<Scalar,MV,OP> >
366 Apply (
const Experimental::TraceMinProjectedPrecOp<Scalar,MV,OP>& Op,
368 MV& y) {Op.Apply(x,y);};
372 HasApplyTranspose (
const Experimental::TraceMinProjectedPrecOp<Scalar,MV,OP>& Op) {
return true;};
379 namespace Experimental {
385 template <
class Scalar,
class MV,
class OP>
387 ONE(Teuchos::ScalarTraits<Scalar>::one())
389 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
395 if(orthman_ != Teuchos::null && B_ != Teuchos::null)
396 orthman_->setOp(Teuchos::null);
400 if(B_ != Teuchos::null)
404 if(orthman_ != Teuchos::null)
408 orthman_->normalizeMat(*helperMV);
409 projVecs_.push_back(helperMV);
413 std::vector<Scalar> normvec(nvec);
415 for(
int i=0; i<nvec; i++)
416 normvec[i] = ONE/normvec[i];
419 projVecs_.push_back(helperMV);
427 template <
class Scalar,
class MV,
class OP>
429 ONE(Teuchos::ScalarTraits<Scalar>::one())
431 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
437 if(B_ != Teuchos::null)
438 orthman_->setOp(Teuchos::null);
444 if(B_ != Teuchos::null)
448 orthman_->normalizeMat(*helperMV);
449 projVecs_.push_back(helperMV);
458 template <
class Scalar,
class MV,
class OP>
459 TraceMinProjOp<Scalar,MV,OP>::~TraceMinProjOp()
461 if(orthman_ != Teuchos::null)
467 template <
class Scalar,
class MV,
class OP>
468 void TraceMinProjOp<Scalar,MV,OP>::Apply(
const MV& X, MV& Y)
const
470 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
474 if(orthman_ != Teuchos::null)
477 orthman_->projectMat(Y,projVecs_);
481 int nvec = MVT::GetNumberVecs(X);
482 std::vector<Scalar> dotProducts(nvec);
483 MVT::MvDot(*projVecs_[0],X,dotProducts);
485 MVT::MvScale(*helper,dotProducts);
486 MVT::MvAddMv(ONE,X,-ONE,*helper,Y);
492 template <
class Scalar,
class MV,
class OP>
493 void TraceMinProjOp<Scalar,MV,OP>::removeIndices(
const std::vector<int>& indicesToRemove)
495 if (orthman_ == Teuchos::null) {
496 const int nprojvecs = projVecs_.size();
497 const int nvecs = MVT::GetNumberVecs(*projVecs_[nprojvecs-1]);
498 const int numRemoving = indicesToRemove.size();
499 std::vector<int> helper(nvecs), indicesToLeave(nvecs-numRemoving);
501 for (
int i=0; i<nvecs; i++) {
505 std::set_difference(helper.begin(), helper.end(), indicesToRemove.begin(), indicesToRemove.end(), indicesToLeave.begin());
507 Teuchos::RCP<MV> helperMV = MVT::CloneCopy(*projVecs_[nprojvecs-1],indicesToLeave);
508 projVecs_[nprojvecs-1] = helperMV;
518 template <
class Scalar,
class MV,
class OP>
520 ONE(Teuchos::ScalarTraits<Scalar>::one()),
521 ZERO(Teuchos::ScalarTraits<Scalar>::zero())
528 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
538 if(Prec != Teuchos::null)
539 Prec_ =
Teuchos::rcp(
new TraceMinRitzOp<Scalar,MV,OP>(Prec) );
542 solver_ =
Teuchos::rcp(
new PseudoBlockMinres< Scalar,MV,TraceMinRitzOp<Scalar,MV,OP> >(linSolOp,Prec_) );
547 template <
class Scalar,
class MV,
class OP>
548 void TraceMinRitzOp<Scalar,MV,OP>::Apply(
const MV& X, MV& Y)
const
550 int nvecs = MVT::GetNumberVecs(X);
552 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
558 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
566 if(ritzShifts_.size() > 0)
569 std::vector<int> nonzeroRitzIndices;
570 nonzeroRitzIndices.reserve(nvecs);
571 for(
int i=0; i<nvecs; i++)
573 if(ritzShifts_[i] != ZERO)
574 nonzeroRitzIndices.push_back(i);
578 int numRitzShifts = nonzeroRitzIndices.size();
579 if(numRitzShifts > 0)
586 std::vector<Scalar> nonzeroRitzShifts(numRitzShifts);
587 for(
int i=0; i<numRitzShifts; i++)
588 nonzeroRitzShifts[i] = ritzShifts_[nonzeroRitzIndices[i]];
591 if(B_ != Teuchos::null)
594 OPT::Apply(*B_,*ritzX,*BX);
595 MVT::MvScale(*BX,nonzeroRitzShifts);
596 MVT::MvAddMv(ONE,*ritzY,-ONE,*BX,*ritzY);
602 MVT::MvScale(*scaledX,nonzeroRitzShifts);
603 MVT::MvAddMv(ONE,*ritzY,-ONE,*scaledX,*ritzY);
611 template <
class Scalar,
class MV,
class OP>
612 void TraceMinRitzOp<Scalar,MV,OP>::ApplyInverse(
const MV& X, MV& Y)
614 int nvecs = MVT::GetNumberVecs(X);
615 std::vector<int> indices(nvecs);
616 for(
int i=0; i<nvecs; i++)
623 solver_->setTol(tolerances_);
624 solver_->setMaxIter(maxits_);
627 solver_->setSol(rcpY);
628 solver_->setRHS(rcpX);
636 template <
class Scalar,
class MV,
class OP>
637 void TraceMinRitzOp<Scalar,MV,OP>::removeIndices(
const std::vector<int>& indicesToRemove)
639 int nvecs = tolerances_.size();
640 int numRemoving = indicesToRemove.size();
641 std::vector<int> helper(nvecs), indicesToLeave(nvecs-numRemoving);
642 std::vector<Scalar> helperS(nvecs-numRemoving);
644 for(
int i=0; i<nvecs; i++)
647 std::set_difference(helper.begin(), helper.end(), indicesToRemove.begin(), indicesToRemove.end(), indicesToLeave.begin());
649 for(
int i=0; i<nvecs-numRemoving; i++)
650 helperS[i] = ritzShifts_[indicesToLeave[i]];
651 ritzShifts_ = helperS;
653 for(
int i=0; i<nvecs-numRemoving; i++)
654 helperS[i] = tolerances_[indicesToLeave[i]];
655 tolerances_ = helperS;
665 template <
class Scalar,
class MV,
class OP>
671 projector_ =
Teuchos::rcp(
new TraceMinProjOp<Scalar,MV,OP>(projVecs, Op_->B_, orthman) );
678 solver_ =
Teuchos::rcp(
new PseudoBlockMinres< Scalar,MV,TraceMinProjRitzOp<Scalar,MV,OP> >(linSolOp) );
682 template <
class Scalar,
class MV,
class OP>
688 projector_ =
Teuchos::rcp(
new TraceMinProjOp<Scalar,MV,OP>(projVecs, Op_->B_, orthman, auxVecs) );
695 solver_ =
Teuchos::rcp(
new PseudoBlockMinres< Scalar,MV,TraceMinProjRitzOp<Scalar,MV,OP> >(linSolOp) );
701 template <
class Scalar,
class MV,
class OP>
702 void TraceMinProjRitzOp<Scalar,MV,OP>::Apply(
const MV& X, MV& Y)
const
704 int nvecs = MVT::GetNumberVecs(X);
712 OPT::Apply(*Op_,X,*APX);
715 projector_->Apply(*APX,Y);
720 template <
class Scalar,
class MV,
class OP>
721 void TraceMinProjRitzOp<Scalar,MV,OP>::ApplyInverse(
const MV& X, MV& Y)
723 int nvecs = MVT::GetNumberVecs(X);
724 std::vector<int> indices(nvecs);
725 for(
int i=0; i<nvecs; i++)
730 projector_->Apply(X,*PX);
733 solver_->setTol(Op_->tolerances_);
734 solver_->setMaxIter(Op_->maxits_);
737 solver_->setSol(rcpY);
746 template <
class Scalar,
class MV,
class OP>
747 void TraceMinProjRitzOp<Scalar,MV,OP>::removeIndices(
const std::vector<int>& indicesToRemove)
749 Op_->removeIndices(indicesToRemove);
751 projector_->removeIndices(indicesToRemove);
757 #ifdef HAVE_ANASAZI_BELOS
763 template <
class Scalar,
class MV,
class OP>
765 ONE(Teuchos::ScalarTraits<Scalar>::one())
774 problem_ =
Teuchos::rcp(
new Belos::LinearProblem< Scalar,MV,TraceMinOp<Scalar,MV,OP> >());
777 problem_->setOperator(linSolOp);
781 Prec_ =
Teuchos::rcp(
new TraceMinProjectedPrecOp<Scalar,MV,OP>(Op_->Prec_->A_, projVecs, orthman) );
786 solver_ =
Teuchos::rcp(
new Belos::PseudoBlockGmresSolMgr< Scalar,MV,TraceMinOp<Scalar,MV,OP> >());
790 template <
class Scalar,
class MV,
class OP>
792 ONE(Teuchos::ScalarTraits<Scalar>::one())
801 problem_ =
Teuchos::rcp(
new Belos::LinearProblem< Scalar,MV,TraceMinOp<Scalar,MV,OP> >());
804 problem_->setOperator(linSolOp);
808 Prec_ =
Teuchos::rcp(
new TraceMinProjectedPrecOp<Scalar,MV,OP>(Op_->Prec_->A_, projVecs, orthman, auxVecs) );
813 solver_ =
Teuchos::rcp(
new Belos::PseudoBlockGmresSolMgr< Scalar,MV,TraceMinOp<Scalar,MV,OP> >());
817 template <
class Scalar,
class MV,
class OP>
818 void TraceMinProjRitzOpWithPrec<Scalar,MV,OP>::Apply(
const MV& X, MV& Y)
const
820 int nvecs = MVT::GetNumberVecs(X);
821 RCP<MV> Ydot = MVT::Clone(Y,nvecs);
822 OPT::Apply(*Op_,X,*Ydot);
823 Prec_->Apply(*Ydot,Y);
827 template <
class Scalar,
class MV,
class OP>
828 void TraceMinProjRitzOpWithPrec<Scalar,MV,OP>::ApplyInverse(
const MV& X, MV& Y)
830 int nvecs = MVT::GetNumberVecs(X);
831 std::vector<int> indices(nvecs);
832 for(
int i=0; i<nvecs; i++)
838 Prec_->Apply(X,*rcpX);
841 problem_->setProblem(rcpY,rcpX);
844 solver_->setProblem(problem_);
851 pl->
set(
"Convergence Tolerance", Op_->tolerances_[0]);
852 pl->
set(
"Block Size", nvecs);
855 pl->
set(
"Maximum Iterations", Op_->getMaxIts());
856 pl->
set(
"Num Blocks", Op_->getMaxIts());
864 template <
class Scalar,
class MV,
class OP>
865 void TraceMinProjRitzOpWithPrec<Scalar,MV,OP>::removeIndices(
const std::vector<int>& indicesToRemove)
867 Op_->removeIndices(indicesToRemove);
869 Prec_->removeIndices(indicesToRemove);
879 template <
class Scalar,
class MV,
class OP>
881 ONE (Teuchos::ScalarTraits<Scalar>::one())
892 if(orthman_ != Teuchos::null)
895 B_ = orthman_->getOp();
896 orthman_->setOp(Op_);
901 const int rank = orthman_->normalizeMat (*locProjVecs, Teuchos::null, helperMV);
904 TEUCHOS_TEST_FOR_EXCEPTION(rank != nvecs, std::runtime_error,
"Belos::TraceMinProjectedPrecOp: constructor: Loss of orthogonality detected.");
906 orthman_->setOp(Teuchos::null);
910 std::vector<Scalar> dotprods(nvecs);
913 for(
int i=0; i<nvecs; i++)
914 dotprods[i] = ONE/sqrt(dotprods[i]);
919 projVecs_.push_back(helperMV);
923 template <
class Scalar,
class MV,
class OP>
925 ONE(Teuchos::ScalarTraits<Scalar>::one())
934 if(auxVecs.size() > 0)
938 for(
int i=0; i<auxVecs.size(); i++)
946 std::vector<int> locind(nvecs);
949 for (
size_t i = 0; i<locind.size(); i++) {
950 locind[i] = startIndex + i;
952 startIndex += locind.size();
955 for (
size_t i=0; i < static_cast<size_t> (auxVecs.size ()); ++i)
958 for(
size_t j=0; j<locind.size(); j++) locind[j] = startIndex + j;
959 startIndex += locind.size();
976 B_ = orthman_->getOp();
977 orthman_->setOp(Op_);
980 const int rank = orthman_->normalizeMat(*locProjVecs,Teuchos::null,helperMV);
982 projVecs_.push_back(helperMV);
988 rank != nvecs, std::runtime_error,
989 "Belos::TraceMinProjectedPrecOp: constructor: Loss of orthogonality detected.");
991 orthman_->setOp(Teuchos::null);
995 template <
class Scalar,
class MV,
class OP>
996 TraceMinProjectedPrecOp<Scalar,MV,OP>::~TraceMinProjectedPrecOp()
998 if(orthman_ != Teuchos::null)
1004 template <
class Scalar,
class MV,
class OP>
1005 void TraceMinProjectedPrecOp<Scalar,MV,OP>::Apply(
const MV& X, MV& Y)
const
1007 int nvecsX = MVT::GetNumberVecs(X);
1009 if(orthman_ != Teuchos::null)
1012 int nvecsP = MVT::GetNumberVecs(*projVecs_[0]);
1013 OPT::Apply(*Op_,X,Y);
1017 MVT::MvTransMv(ONE, *projVecs_[0], X, *projX);
1019 MVT::MvTimesMatAddMv(-ONE, *projVecs_[0], *projX, ONE, Y);
1024 OPT::Apply(*Op_,X,*MX);
1026 std::vector<Scalar> dotprods(nvecsX);
1027 MVT::MvDot(*projVecs_[0], X, dotprods);
1030 MVT::MvScale(*helper, dotprods);
1031 MVT::MvAddMv(ONE, *MX, -ONE, *helper, Y);
1036 template <
class Scalar,
class MV,
class OP>
1037 void TraceMinProjectedPrecOp<Scalar,MV,OP>::removeIndices(
const std::vector<int>& indicesToRemove)
1039 if(orthman_ == Teuchos::null)
1041 int nvecs = MVT::GetNumberVecs(*projVecs_[0]);
1042 int numRemoving = indicesToRemove.size();
1043 std::vector<int> helper(nvecs), indicesToLeave(nvecs-numRemoving);
1045 for(
int i=0; i<nvecs; i++)
1048 std::set_difference(helper.begin(), helper.end(), indicesToRemove.begin(), indicesToRemove.end(), indicesToLeave.begin());
1051 projVecs_[0] = helperMV;
Abstract base class for trace minimization eigensolvers.
Templated virtual class for providing orthogonalization/orthonormalization methods with matrix-based ...
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Virtual base class which defines basic traits for the operator type.
static void MvDot(const MV &mv, const MV &A, std::vector< ScalarType > &b)
Compute a vector b where the components are the individual dot-products of the i-th columns of A and ...
static void Apply(const OP &Op, const MV &x, MV &y)
Application method which performs operation y = Op*x. An OperatorError exception is thrown if there i...
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
static RCP< Time > getNewTimer(const std::string &name)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Traits class which defines basic operations on multivectors.
static Teuchos::RCP< MV > CloneCopy(const MV &mv)
Creates a new MV and copies contents of mv into the new vector (deep copy).
static void MvScale(MV &mv, const ScalarType alpha)
Scale each element of the vectors in mv with alpha.
Anasazi header file which uses auto-configuration information to include necessary C++ headers...
static void MvNorm(const MV &mv, std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > &normvec)
Compute the 2-norm of each individual vector of mv. Upon return, normvec[i] holds the value of ...
ParameterList & setParameters(const ParameterList &source)
static void SetBlock(const MV &A, const std::vector< int > &index, MV &mv)
Copy the vectors in A to a set of vectors in mv indicated by the indices given in index...
static int GetNumberVecs(const MV &mv)
Obtain the number of vectors in mv.
static Teuchos::RCP< MV > Clone(const MV &mv, const int numvecs)
Creates a new empty MV containing numvecs columns.