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.