16 #ifndef ANASAZI_SVQB_ORTHOMANAGER_HPP 
   17 #define ANASAZI_SVQB_ORTHOMANAGER_HPP 
   36   template<
class ScalarType, 
class MV, 
class OP>
 
  264                    bool normalize_in ) 
const;
 
  270   template<
class ScalarType, 
class MV, 
class OP>
 
  272     : 
MatOrthoManager<ScalarType,MV,OP>(Op), dbgstr(
"                    *** "), debug_(debug) {
 
  275     eps_ = lapack.
LAMCH(
'E');
 
  277       std::cout << 
"eps_ == " << eps_ << std::endl;
 
  284   template<
class ScalarType, 
class MV, 
class OP>
 
  287     const ScalarType ONE = SCT::one();
 
  288     int rank = MVT::GetNumberVecs(X);
 
  291     for (
int i=0; i<rank; i++) {
 
  299   template<
class ScalarType, 
class MV, 
class OP>
 
  307     int r1 = MVT::GetNumberVecs(X);
 
  308     int r2 = MVT::GetNumberVecs(Y);
 
  317   template<
class ScalarType, 
class MV, 
class OP>
 
  325     findBasis(X,MX,C,Teuchos::null,Q,
false);
 
  332   template<
class ScalarType, 
class MV, 
class OP>
 
  339     return findBasis(X,MX,C,B,Q,
true);
 
  346   template<
class ScalarType, 
class MV, 
class OP>
 
  355     return findBasis(X,MX,C,B,Q,
true);
 
  387   template<
class ScalarType, 
class MV, 
class OP>
 
  393                 bool normalize_in)
 const {
 
  395     const ScalarType ONE  = SCT::one();
 
  396     const MagnitudeType MONE = SCTM::one();
 
  397     const MagnitudeType ZERO = SCTM::zero();
 
  404     int xc = MVT::GetNumberVecs(X);
 
  405     ptrdiff_t xr = MVT::GetGlobalLength( X );
 
  409     ptrdiff_t qr = (nq == 0) ? 0 : MVT::GetGlobalLength(*Q[0]);
 
  411     std::vector<int> qcs(nq);
 
  412     for (
int i=0; i<nq; i++) {
 
  413       qcs[i] = MVT::GetNumberVecs(*Q[i]);
 
  417     if (normalize_in == 
true && qsize + xc > xr) {
 
  420                           "Anasazi::SVQBOrthoManager::findBasis(): Orthogonalization constraints not feasible" );
 
  424     if (normalize_in == 
false && (qsize == 0 || xc == 0)) {
 
  428     else if (normalize_in == 
true && (xc == 0 || xr == 0)) {
 
  431                           "Anasazi::SVQBOrthoManager::findBasis(): X must be non-empty" );
 
  436                         "Anasazi::SVQBOrthoManager::findBasis(): Size of X not consistant with size of Q" );
 
  445     for (
int i=0; i<nq; i++) {
 
  448                           "Anasazi::SVQBOrthoManager::findBasis(): Size of Q not mutually consistant" );
 
  450                           "Anasazi::SVQBOrthoManager::findBasis(): Q has less rows than columns" );
 
  452       if ( C[i] == Teuchos::null ) {
 
  457                             "Anasazi::SVQBOrthoManager::findBasis(): Size of Q not consistant with C" );
 
  460       C[i]->putScalar(ZERO);
 
  470     if (normalize_in == 
true) {
 
  471       if ( B == Teuchos::null ) {
 
  475                           "Anasazi::SVQBOrthoManager::findBasis(): Size of B not consistant with X" );
 
  478       for (
int i=0; i<xc; i++) {
 
  492       workX = MVT::Clone(X,xc);
 
  495       if (MX == Teuchos::null) {
 
  497         MX = MVT::Clone(X,xc);
 
  498         OPT::Apply(*(this->_Op),X,*MX);
 
  499         this->_OpCounter += MVT::GetNumberVecs(X);
 
  503       MX = Teuchos::rcpFromRef(X);
 
  505     std::vector<ScalarType> normX(xc), invnormX(xc);
 
  512     std::vector<ScalarType> work;
 
  513     std::vector<MagnitudeType> lambda, lambdahi, rwork;
 
  516       int lwork = lapack.
ILAENV(1,
"hetrd",
"VU",xc,-1,-1,-1);
 
  520                           "Anasazi::SVQBOrthoManager::findBasis(): Error code from ILAENV" );
 
  522       lwork = (lwork+2)*xc;
 
  525       lwork = (3*xc-2 > 1) ? 3*xc - 2 : 1;
 
  530       workU.reshape(xc,xc);
 
  534     int mxc = (this->_hasOp) ? MVT::GetNumberVecs( *MX ) : xc;
 
  535     ptrdiff_t mxr = (this->_hasOp) ? MVT::GetGlobalLength( *MX )  : xr;
 
  537                         "Anasazi::SVQBOrthoManager::findBasis(): Size of X not consistant with MX" );
 
  540     bool doGramSchmidt = 
true;          
 
  542     MagnitudeType tolerance = MONE/SCTM::squareroot(eps_);
 
  545     while (doGramSchmidt) {
 
  555           std::vector<MagnitudeType> normX_mag(xc);
 
  557           for (
int i=0; i<xc; ++i) {
 
  558             normX[i] = normX_mag[i];
 
  559             invnormX[i] = (normX_mag[i] == ZERO) ? ZERO : MONE/normX_mag[i]; 
 
  563         MVT::MvScale(X,invnormX);
 
  565           MVT::MvScale(*MX,invnormX);
 
  569           std::vector<MagnitudeType> nrm2(xc);
 
  570           std::cout << dbgstr << 
"max post-scale norm: (with/without MX) : ";
 
  571           MagnitudeType maxpsnw = ZERO, maxpsnwo = ZERO;
 
  573           for (
int i=0; i<xc; i++) {
 
  574             maxpsnw = (nrm2[i] > maxpsnw ? nrm2[i] : maxpsnw);
 
  577           for (
int i=0; i<xc; i++) {
 
  578             maxpsnwo = (nrm2[i] > maxpsnwo ? nrm2[i] : maxpsnwo);
 
  580           std::cout << 
"(" << maxpsnw << 
"," << maxpsnwo << 
")" << std::endl;
 
  583         for (
int i=0; i<nq; i++) {
 
  587         for (
int i=0; i<nq; i++) {
 
  588           MVT::MvTimesMatAddMv(-ONE,*Q[i],*newC[i],ONE,X);
 
  591         MVT::MvScale(X,normX);
 
  594           OPT::Apply(*(this->_Op),X,*MX);
 
  595           this->_OpCounter += MVT::GetNumberVecs(X);
 
  603         MagnitudeType maxNorm = ZERO;
 
  604         for  (
int j=0; j<xc; j++) {
 
  605           MagnitudeType sum = ZERO;
 
  606           for (
int k=0; k<nq; k++) {
 
  607             for (
int i=0; i<qcs[k]; i++) {
 
  608               sum += SCT::magnitude((*newC[k])(i,j))*SCT::magnitude((*newC[k])(i,j));
 
  611           maxNorm = (sum > maxNorm) ? sum : maxNorm;
 
  615         if (maxNorm < 0.36) {
 
  616           doGramSchmidt = 
false;
 
  620         for (
int k=0; k<nq; k++) {
 
  621           for (
int j=0; j<xc; j++) {
 
  622             for (
int i=0; i<qcs[k]; i++) {
 
  623               (*newC[k])(i,j) *= normX[j];
 
  631           for (
int i=0; i<nq; i++) {
 
  633             TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::logic_error, 
"Anasazi::SVQBOrthoManager::findBasis(): Input error to SerialDenseMatrix::multiply.");
 
  638           for (
int i=0; i<nq; i++) {
 
  645         doGramSchmidt = 
false;
 
  653         MagnitudeType condT = tolerance;
 
  655         while (condT >= tolerance) {
 
  663           std::vector<MagnitudeType> Dh(xc), Dhi(xc);
 
  664           for (
int i=0; i<xc; i++) {
 
  665             Dh[i]  = SCT::magnitude(SCT::squareroot(XtMX(i,i)));
 
  666             Dhi[i] = (Dh[i] == ZERO ? ZERO : MONE/Dh[i]);
 
  669           for (
int i=0; i<xc; i++) {
 
  670             for (
int j=0; j<xc; j++) {
 
  671               XtMX(i,j) *= Dhi[i]*Dhi[j];
 
  677           lapack.
HEEV(
'V', 
'U', xc, XtMX.values(), XtMX.stride(), &lambda[0], &work[0], work.size(), &rwork[0], &info);
 
  678           std::stringstream os;
 
  679           os << 
"Anasazi::SVQBOrthoManager::findBasis(): Error code " << info << 
" from HEEV";
 
  683             std::cout << dbgstr << 
"eigenvalues of XtMX: (";
 
  684             for (
int i=0; i<xc-1; i++) {
 
  685               std::cout << lambda[i] << 
",";
 
  687             std::cout << lambda[xc-1] << 
")" << std::endl;
 
  692           MagnitudeType maxLambda = lambda[xc-1],
 
  693                         minLambda = lambda[0];
 
  695           for (
int i=0; i<xc; i++) {
 
  696             if (lambda[i] <= 10*eps_*maxLambda) {      
 
  708               lambda[i] = SCTM::squareroot(lambda[i]);
 
  709               lambdahi[i] = MONE/lambda[i];
 
  716           std::vector<int> ind(xc);
 
  717           for (
int i=0; i<xc; i++) {ind[i] = i;}
 
  718           MVT::SetBlock(X,ind,*workX);
 
  722           for (
int j=0; j<xc; j++) {
 
  723             for (
int i=0; i<xc; i++) {
 
  724               workU(i,j) *= Dhi[i]*lambdahi[j];
 
  728           MVT::MvTimesMatAddMv(ONE,*workX,workU,ZERO,X);
 
  734             if (maxLambda >= tolerance * minLambda) {
 
  736               OPT::Apply(*(this->_Op),X,*MX);
 
  737               this->_OpCounter += MVT::GetNumberVecs(X);
 
  742               MVT::SetBlock(*MX,ind,*workX);
 
  745               MVT::MvTimesMatAddMv(ONE,*workX,workU,ZERO,*MX);
 
  751           for (
int j=0; j<xc; j++) {
 
  752             for (
int i=0; i<xc; i++) {
 
  753               workU(i,j) = Dh[i] * (*B)(i,j);
 
  757           TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::logic_error, 
"Anasazi::SVQBOrthoManager::findBasis(): Input error to SerialDenseMatrix::multiply.");
 
  758           for (
int j=0; j<xc ;j++) {
 
  759             for (
int i=0; i<xc; i++) {
 
  760               (*B)(i,j) *= lambda[i];
 
  767               std::cout << dbgstr << 
"augmenting multivec with " << iZeroMax+1 << 
" random directions" << std::endl;
 
  772             std::vector<int> ind2(iZeroMax+1);
 
  773             for (
int i=0; i<iZeroMax+1; i++) {
 
  777             Xnull = MVT::CloneViewNonConst(X,ind2);
 
  778             MVT::MvRandom(*Xnull);
 
  780               MXnull = MVT::CloneViewNonConst(*MX,ind2);
 
  781               OPT::Apply(*(this->_Op),*Xnull,*MXnull);
 
  782               this->_OpCounter += MVT::GetNumberVecs(*Xnull);
 
  783               MXnull = Teuchos::null;
 
  785             Xnull = Teuchos::null;
 
  787             doGramSchmidt = 
true;
 
  791           condT = SCTM::magnitude(maxLambda / minLambda);
 
  793             std::cout << dbgstr << 
"condT: " << condT << 
", tolerance = " << tolerance << std::endl;
 
  797           if ((doGramSchmidt == 
false) && (condT > SCTM::squareroot(tolerance))) {
 
  798             doGramSchmidt = 
true;
 
  808       std::cout << dbgstr << 
"(numGS,numSVQB,numRand)                : "  
  820 #endif // ANASAZI_SVQB_ORTHOMANAGER_HPP 
OrdinalType ILAENV(const OrdinalType &ispec, const std::string &NAME, const std::string &OPTS, const OrdinalType &N1=-1, const OrdinalType &N2=-1, const OrdinalType &N3=-1, const OrdinalType &N4=-1) const 
Templated virtual class for providing orthogonalization/orthonormalization methods with matrix-based ...
Declaration of basic traits for the multivector type. 
int normalizeMat(MV &X, Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > B=Teuchos::null, Teuchos::RCP< MV > MX=Teuchos::null) const 
This method takes a multivector X and attempts to compute an orthonormal basis for ...
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Virtual base class which defines basic traits for the operator type. 
void innerProdMat(const MV &X, const MV &Y, Teuchos::SerialDenseMatrix< int, ScalarType > &Z, Teuchos::RCP< const MV > MX=Teuchos::null, Teuchos::RCP< const MV > MY=Teuchos::null) const 
Provides a matrix-based inner product. 
An implementation of the Anasazi::MatOrthoManager that performs orthogonalization using the SVQB iter...
ScalarTraits< ScalarType >::magnitudeType normFrobenius() const 
int projectAndNormalizeMat(MV &X, Teuchos::Array< Teuchos::RCP< const MV > > Q, Teuchos::Array< Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > > C=Teuchos::tuple(Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > >(Teuchos::null)), Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > B=Teuchos::null, Teuchos::RCP< MV > MX=Teuchos::null, Teuchos::Array< Teuchos::RCP< const MV > > MQ=Teuchos::tuple(Teuchos::RCP< const MV >(Teuchos::null))) const 
Given a set of bases Q[i] and a multivector X, this method computes an orthonormal basis for ...
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)
Teuchos::ScalarTraits< ScalarType >::magnitudeType orthogErrorMat(const MV &X, const MV &Y, Teuchos::RCP< const MV > MX=Teuchos::null, Teuchos::RCP< const MV > MY=Teuchos::null) const 
This method computes the error in orthogonality of two multivectors, measured as the Frobenius norm o...
Traits class which defines basic operations on multivectors. 
Virtual base class which defines basic traits for the operator type. 
Anasazi header file which uses auto-configuration information to include necessary C++ headers...
Teuchos::ScalarTraits< ScalarType >::magnitudeType orthonormErrorMat(const MV &X, Teuchos::RCP< const MV > MX=Teuchos::null) const 
This method computes the error in orthonormality of a multivector, measured as the Frobenius norm of ...
~SVQBOrthoManager()
Destructor. 
void HEEV(const char &JOBZ, const char &UPLO, const OrdinalType &n, ScalarType *A, const OrdinalType &lda, MagnitudeType *W, ScalarType *WORK, const OrdinalType &lwork, MagnitudeType *RWORK, OrdinalType *info) const 
void projectMat(MV &X, Teuchos::Array< Teuchos::RCP< const MV > > Q, Teuchos::Array< Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > > C=Teuchos::tuple(Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > >(Teuchos::null)), Teuchos::RCP< MV > MX=Teuchos::null, Teuchos::Array< Teuchos::RCP< const MV > > MQ=Teuchos::tuple(Teuchos::RCP< const MV >(Teuchos::null))) const 
Given a list of mutually orthogonal and internally orthonormal bases Q, this method projects a multiv...
ScalarType LAMCH(const char &CMACH) const 
SVQBOrthoManager(Teuchos::RCP< const OP > Op=Teuchos::null, bool debug=false)
Constructor specifying re-orthogonalization tolerance. 
void normMat(const MV &X, std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > &normvec, Teuchos::RCP< const MV > MX=Teuchos::null) const 
Provides the norm induced by the matrix-based inner product.