15#ifndef ANASAZI_ICSG_ORTHOMANAGER_HPP
16#define ANASAZI_ICSG_ORTHOMANAGER_HPP
29#include "Teuchos_TimeMonitor.hpp"
30#include "Teuchos_LAPACK.hpp"
31#include "Teuchos_BLAS.hpp"
32#ifdef ANASAZI_ICGS_DEBUG
33# include <Teuchos_FancyOStream.hpp>
38 template<
class ScalarType,
class MV,
class OP>
42 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
43 typedef Teuchos::ScalarTraits<ScalarType> SCT;
52 ICGSOrthoManager( Teuchos::RCP<const OP> Op = Teuchos::null,
int numIters = 2,
53 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType eps = 0.0,
54 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType tol = 0.20 );
148 Teuchos::Array<Teuchos::RCP<const MV> > X,
149 Teuchos::Array<Teuchos::RCP<const MV> > Y,
151 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C
152 = Teuchos::tuple(Teuchos::RCP< Teuchos::SerialDenseMatrix<int,ScalarType> >(Teuchos::null)),
153 Teuchos::RCP<MV> MS = Teuchos::null,
154 Teuchos::Array<Teuchos::RCP<const MV> > MX = Teuchos::tuple(Teuchos::RCP<const MV>(Teuchos::null)),
155 Teuchos::Array<Teuchos::RCP<const MV> > MY = Teuchos::tuple(Teuchos::RCP<const MV>(Teuchos::null))
252 Teuchos::Array<Teuchos::RCP<const MV> > X,
253 Teuchos::Array<Teuchos::RCP<const MV> > Y,
255 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C
256 = Teuchos::tuple(Teuchos::RCP< Teuchos::SerialDenseMatrix<int,ScalarType> >(Teuchos::null)),
257 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B = Teuchos::null,
258 Teuchos::RCP<MV> MS = Teuchos::null,
259 Teuchos::Array<Teuchos::RCP<const MV> > MX = Teuchos::tuple(Teuchos::RCP<const MV>(Teuchos::null)),
260 Teuchos::Array<Teuchos::RCP<const MV> > MY = Teuchos::tuple(Teuchos::RCP<const MV>(Teuchos::null))
284 Teuchos::Array<Teuchos::RCP<const MV> > Q,
285 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C
286 = Teuchos::tuple(Teuchos::RCP< Teuchos::SerialDenseMatrix<int,ScalarType> >(Teuchos::null)),
287 Teuchos::RCP<MV> MX = Teuchos::null,
288 Teuchos::Array<Teuchos::RCP<const MV> > MQ = Teuchos::tuple(Teuchos::RCP<const MV>(Teuchos::null))
302 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B = Teuchos::null,
303 Teuchos::RCP<MV> MX = Teuchos::null
317 Teuchos::Array<Teuchos::RCP<const MV> > Q,
318 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C
319 = Teuchos::tuple(Teuchos::RCP< Teuchos::SerialDenseMatrix<int,ScalarType> >(Teuchos::null)),
320 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B = Teuchos::null,
321 Teuchos::RCP<MV> MX = Teuchos::null,
322 Teuchos::Array<Teuchos::RCP<const MV> > MQ = Teuchos::tuple(Teuchos::RCP<const MV>(Teuchos::null))
334 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
341 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
342 orthogErrorMat(
const MV &X1,
const MV &X2, Teuchos::RCP<const MV> MX1, Teuchos::RCP<const MV> MX2)
const;
351 numIters_ = numIters;
352 TEUCHOS_TEST_FOR_EXCEPTION(numIters_ < 1,std::invalid_argument,
353 "Anasazi::ICGSOrthoManager::setNumIters(): input must be >= 1.");
369 int findBasis(MV &X, Teuchos::RCP<MV> MX,
370 Teuchos::SerialDenseMatrix<int,ScalarType> &B,
371 bool completeBasis,
int howMany = -1)
const;
378 template<
class ScalarType,
class MV,
class OP>
381 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType eps,
382 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType tol) :
386 TEUCHOS_TEST_FOR_EXCEPTION(eps_ < SCT::magnitude(SCT::zero()),std::invalid_argument,
387 "Anasazi::ICGSOrthoManager::ICGSOrthoManager(): argument \"eps\" must be non-negative.");
389 Teuchos::LAPACK<int,MagnitudeType> lapack;
390 eps_ = lapack.LAMCH(
'E');
391 eps_ = Teuchos::ScalarTraits<MagnitudeType>::pow(eps_,.50);
393 TEUCHOS_TEST_FOR_EXCEPTION(
394 tol_ < SCT::magnitude(SCT::zero()) || tol_ > SCT::magnitude(SCT::one()),
395 std::invalid_argument,
396 "Anasazi::ICGSOrthoManager::ICGSOrthoManager(): argument \"tol\" must be in [0,1].");
403 template<
class ScalarType,
class MV,
class OP>
404 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
406 const ScalarType ONE = SCT::one();
407 int rank = MVT::GetNumberVecs(X);
408 Teuchos::SerialDenseMatrix<int,ScalarType> xTx(rank,rank);
410 for (
int i=0; i<rank; i++) {
413 return xTx.normFrobenius();
420 template<
class ScalarType,
class MV,
class OP>
421 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
423 int r1 = MVT::GetNumberVecs(X1);
424 int r2 = MVT::GetNumberVecs(X2);
425 Teuchos::SerialDenseMatrix<int,ScalarType> xTx(r1,r2);
427 return xTx.normFrobenius();
433 template<
class ScalarType,
class MV,
class OP>
436 Teuchos::Array<Teuchos::RCP<const MV> > Q,
437 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
439 Teuchos::Array<Teuchos::RCP<const MV> > MQ
442 projectGen(X,Q,Q,
true,C,MX,MQ,MQ);
449 template<
class ScalarType,
class MV,
class OP>
452 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
453 Teuchos::RCP<MV> MX)
const
458 int xc = MVT::GetNumberVecs(X);
459 ptrdiff_t xr = MVT::GetGlobalLength(X);
464 if (MX == Teuchos::null) {
466 MX = MVT::Clone(X,xc);
467 OPT::Apply(*(this->_Op),X,*MX);
468 this->_OpCounter += MVT::GetNumberVecs(X);
474 if ( B == Teuchos::null ) {
475 B = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(xc,xc) );
478 int mxc = (this->_hasOp) ? MVT::GetNumberVecs( *MX ) : xc;
479 ptrdiff_t mxr = (this->_hasOp) ? MVT::GetGlobalLength( *MX ) : xr;
482 TEUCHOS_TEST_FOR_EXCEPTION( xc == 0 || xr == 0, std::invalid_argument,
483 "Anasazi::ICGSOrthoManager::normalizeMat(): X must be non-empty" );
484 TEUCHOS_TEST_FOR_EXCEPTION( B->numRows() != xc || B->numCols() != xc, std::invalid_argument,
485 "Anasazi::ICGSOrthoManager::normalizeMat(): Size of X not consistent with size of B" );
486 TEUCHOS_TEST_FOR_EXCEPTION( xc != mxc || xr != mxr, std::invalid_argument,
487 "Anasazi::ICGSOrthoManager::normalizeMat(): Size of X not consistent with size of MX" );
488 TEUCHOS_TEST_FOR_EXCEPTION(
static_cast<ptrdiff_t
>(xc) > xr, std::invalid_argument,
489 "Anasazi::ICGSOrthoManager::normalizeMat(): Size of X not feasible for normalization" );
491 return findBasis(X, MX, *B,
true );
498 template<
class ScalarType,
class MV,
class OP>
501 Teuchos::Array<Teuchos::RCP<const MV> > Q,
502 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
503 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
505 Teuchos::Array<Teuchos::RCP<const MV> > MQ
508 return projectAndNormalizeGen(X,Q,Q,
true,C,B,MX,MQ,MQ);
514 template<
class ScalarType,
class MV,
class OP>
517 Teuchos::Array<Teuchos::RCP<const MV> > X,
518 Teuchos::Array<Teuchos::RCP<const MV> > Y,
520 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
522 Teuchos::Array<Teuchos::RCP<const MV> > MX,
523 Teuchos::Array<Teuchos::RCP<const MV> > MY
541#ifdef ANASAZI_ICGS_DEBUG
543 Teuchos::RCP<Teuchos::FancyOStream>
544 out = Teuchos::getFancyOStream(Teuchos::rcpFromRef(std::cout));
545 out->setShowAllFrontMatter(
false).setShowProcRank(
true);
546 *out <<
"Entering Anasazi::ICGSOrthoManager::projectGen(...)\n";
549 const ScalarType ONE = SCT::one();
550 const MagnitudeType ZERO = SCT::magnitude(SCT::zero());
551 Teuchos::LAPACK<int,ScalarType> lapack;
552 Teuchos::BLAS<int,ScalarType> blas;
554 int sc = MVT::GetNumberVecs( S );
555 ptrdiff_t sr = MVT::GetGlobalLength( S );
556 int numxy = X.length();
557 TEUCHOS_TEST_FOR_EXCEPTION(X.length() != Y.length(),std::invalid_argument,
558 "Anasazi::ICGSOrthoManager::projectGen(): X and Y must contain the same number of multivectors.");
559 std::vector<int> xyc(numxy);
561 if (numxy == 0 || sc == 0 || sr == 0) {
562#ifdef ANASAZI_ICGS_DEBUG
563 *out <<
"Leaving Anasazi::ICGSOrthoManager::projectGen(...)\n";
577 TEUCHOS_TEST_FOR_EXCEPTION( sc<0 || sr<0, std::invalid_argument,
578 "Anasazi::ICGSOrthoManager::projectGen(): MVT returned negative dimensions for S." );
581 if (this->_hasOp ==
true) {
582 if (MS != Teuchos::null) {
583 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*MS) != sr, std::invalid_argument,
584 "Anasazi::ICGSOrthoManager::projectGen(): MS length not consistent with S." );
585 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetNumberVecs(*MS) != sc, std::invalid_argument,
586 "Anasazi::ICGSOrthoManager::projectGen(): MS width not consistent with S." );
591 ptrdiff_t sumxyc = 0;
594 for (
int i=0; i<numxy; i++) {
595 if (X[i] != Teuchos::null && Y[i] != Teuchos::null) {
596 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*X[i]) != sr, std::invalid_argument,
597 "Anasazi::ICGSOrthoManager::projectGen(): X[" << i <<
"] length not consistent with S." );
598 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*Y[i]) != sr, std::invalid_argument,
599 "Anasazi::ICGSOrthoManager::projectGen(): Y[" << i <<
"] length not consistent with S." );
600 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetNumberVecs(*X[i]) != MVT::GetNumberVecs(*Y[i]), std::invalid_argument,
601 "Anasazi::ICGSOrthoManager::projectGen(): X[" << i <<
"] and Y[" << i <<
"] widths not consistent." );
603 xyc[i] = MVT::GetNumberVecs( *X[i] );
604 TEUCHOS_TEST_FOR_EXCEPTION( sr <
static_cast<ptrdiff_t
>(xyc[i]), std::invalid_argument,
605 "Anasazi::ICGSOrthoManager::projectGen(): X[" << i <<
"],Y[" << i <<
"] have less rows than columns, and therefore cannot be full rank." );
609 if ( C[i] == Teuchos::null ) {
610 C[i] = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(xyc[i],sc) );
613 TEUCHOS_TEST_FOR_EXCEPTION( C[i]->numRows() != xyc[i] || C[i]->numCols() != sc , std::invalid_argument,
614 "Anasazi::ICGSOrthoManager::projectGen(): Size of Q not consistent with size of C." );
618 if (MX[i] != Teuchos::null) {
619 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*MX[i]) != sr || MVT::GetNumberVecs(*MX[i]) != xyc[i], std::invalid_argument,
620 "Anasazi::ICGSOrthoManager::projectGen(): Size of MX[" << i <<
"] not consistent with size of X[" << i <<
"]." );
625 if (MY[i] != Teuchos::null) {
626 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*MY[i]) != sr || MVT::GetNumberVecs(*MY[i]) != xyc[i], std::invalid_argument,
627 "Anasazi::ICGSOrthoManager::projectGen(): Size of MY[" << i <<
"] not consistent with size of Y[" << i <<
"]." );
635 TEUCHOS_TEST_FOR_EXCEPTION(X[i] != Teuchos::null || Y[i] != Teuchos::null, std::invalid_argument,
636 "Anasazi::ICGSOrthoManager::projectGen(): "
637 << (X[i] == Teuchos::null ?
"Y[" :
"X[") << i <<
"] was provided but "
638 << (X[i] == Teuchos::null ?
"X[" :
"Y[") << i <<
"] was not.");
643 TEUCHOS_TEST_FOR_EXCEPTION(sumxyc > sr, std::invalid_argument,
644 "Anasazi::ICGSOrthoManager::projectGen(): dimension of all X[i],Y[i] is "
645 << sumxyc <<
", but length of vectors is only " << sr <<
". This is infeasible.");
680 if (MXmissing == 0) {
683 if (MYmissing == 0) {
690 switch (whichAlloc) {
706 if (MS == Teuchos::null) {
707#ifdef ANASAZI_ICGS_DEBUG
708 *out <<
"Allocating MS...\n";
710 MS = MVT::Clone(S,MVT::GetNumberVecs(S));
711 OPT::Apply(*(this->_Op),S,*MS);
712 this->_OpCounter += MVT::GetNumberVecs(S);
716 if (whichAlloc == 0) {
718 for (
int i=0; i<numxy; i++) {
719 if (MX[i] == Teuchos::null) {
720#ifdef ANASAZI_ICGS_DEBUG
721 *out <<
"Allocating MX[" << i <<
"]...\n";
723 Teuchos::RCP<MV> tmpMX = MVT::Clone(*X[i],xyc[i]);
724 OPT::Apply(*(this->_Op),*X[i],*tmpMX);
726 this->_OpCounter += xyc[i];
733 MS = Teuchos::rcpFromRef(S);
736 TEUCHOS_TEST_FOR_EXCEPTION(updateMS == -1,std::logic_error,
737 "Anasazi::ICGSOrthoManager::projectGen(): Error in updateMS logic.");
746 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > YMX(numxy);
747 if (isBiortho ==
false) {
748 for (
int i=0; i<numxy; i++) {
749#ifdef ANASAZI_ICGS_DEBUG
750 *out <<
"Computing YMX[" << i <<
"] and its Cholesky factorization...\n";
752 YMX[i] = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(xyc[i],xyc[i]) );
754#ifdef ANASAZI_ICGS_DEBUG
761 MagnitudeType err = ZERO;
762 for (
int jj=0; jj<YMX[i]->numCols(); jj++) {
763 err =+ SCT::magnitude(SCT::imag((*YMX[i])(jj,jj)));
764 for (
int ii=jj; ii<YMX[i]->numRows(); ii++) {
765 err += SCT::magnitude( (*YMX[i])(ii,jj) - SCT::conjugate((*YMX[i])(jj,ii)) );
768 *out <<
"Symmetry error in YMX[" << i <<
"] == " << err <<
"\n";
773 lapack.POTRF(
'U',YMX[i]->numRows(),YMX[i]->values(),YMX[i]->stride(),&info);
774 TEUCHOS_TEST_FOR_EXCEPTION(info != 0,std::logic_error,
775 "Anasazi::ICGSOrthoManager::projectGen(): Error computing Cholesky factorization of Y[i]^T * M * X[i] using POTRF: returned info " << info);
780#ifdef ANASAZI_ICGS_DEBUG
781 std::vector<MagnitudeType> oldNorms(sc);
783 *out <<
"oldNorms = { ";
784 std::copy(oldNorms.begin(), oldNorms.end(), std::ostream_iterator<MagnitudeType>(*out,
" "));
790 Teuchos::Array<Teuchos::SerialDenseMatrix<int,ScalarType> > Ccur(numxy);
791 for (
int i=0; i<numxy; i++) {
792 C[i]->putScalar(ZERO);
793 Ccur[i].reshape(C[i]->numRows(),C[i]->numCols());
796 for (
int iter=0; iter < numIters_; iter++) {
797#ifdef ANASAZI_ICGS_DEBUG
798 *out <<
"beginning iteration " << iter+1 <<
"\n";
802 for (
int i=0; i<numxy; i++) {
805 if (isBiortho ==
false) {
808 lapack.POTRS(
'U',YMX[i]->numCols(),Ccur[i].numCols(),
809 YMX[i]->values(),YMX[i]->stride(),
810 Ccur[i].values(),Ccur[i].stride(), &info);
811 TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::logic_error,
812 "Anasazi::ICGSOrthoManager::projectGen(): Error code " << info <<
" from lapack::POTRS." );
816#ifdef ANASAZI_ICGS_DEBUG
817 *out <<
"Applying projector P_{X[" << i <<
"],Y[" << i <<
"]}...\n";
819 MVT::MvTimesMatAddMv( -ONE, *X[i], Ccur[i], ONE, S );
826#ifdef ANASAZI_ICGS_DEBUG
827 *out <<
"Updating MS...\n";
829 OPT::Apply( *(this->_Op), S, *MS);
830 this->_OpCounter += sc;
832 else if (updateMS == 2) {
833#ifdef ANASAZI_ICGS_DEBUG
834 *out <<
"Updating MS...\n";
836 MVT::MvTimesMatAddMv( -ONE, *MX[i], Ccur[i], ONE, *MS );
841#ifdef ANASAZI_ICGS_DEBUG
842 std::vector<MagnitudeType> newNorms(sc);
844 *out <<
"newNorms = { ";
845 std::copy(newNorms.begin(), newNorms.end(), std::ostream_iterator<MagnitudeType>(*out,
" "));
850#ifdef ANASAZI_ICGS_DEBUG
851 *out <<
"Leaving Anasazi::ICGSOrthoManager::projectGen(...)\n";
859 template<
class ScalarType,
class MV,
class OP>
862 Teuchos::Array<Teuchos::RCP<const MV> > X,
863 Teuchos::Array<Teuchos::RCP<const MV> > Y,
865 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
866 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
868 Teuchos::Array<Teuchos::RCP<const MV> > MX,
869 Teuchos::Array<Teuchos::RCP<const MV> > MY
887#ifdef ANASAZI_ICGS_DEBUG
889 Teuchos::RCP<Teuchos::FancyOStream>
890 out = Teuchos::getFancyOStream(Teuchos::rcpFromRef(std::cout));
891 out->setShowAllFrontMatter(
false).setShowProcRank(
true);
892 *out <<
"Entering Anasazi::ICGSOrthoManager::projectAndNormalizeGen(...)\n";
896 int sc = MVT::GetNumberVecs( S );
897 ptrdiff_t sr = MVT::GetGlobalLength( S );
898 int numxy = X.length();
899 TEUCHOS_TEST_FOR_EXCEPTION(X.length() != Y.length(),std::invalid_argument,
900 "Anasazi::ICGSOrthoManager::projectAndNormalizeGen(): X and Y must contain the same number of multivectors.");
901 std::vector<int> xyc(numxy);
903 if (sc == 0 || sr == 0) {
904#ifdef ANASAZI_ICGS_DEBUG
905 *out <<
"Leaving Anasazi::ICGSOrthoManager::projectGen(...)\n";
919 TEUCHOS_TEST_FOR_EXCEPTION( sc<0 || sr<0, std::invalid_argument,
920 "Anasazi::ICGSOrthoManager::projectAndNormalizeGen(): MVT returned negative dimensions for S." );
923 if (this->_hasOp ==
true) {
924 if (MS != Teuchos::null) {
925 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*MS) != sr, std::invalid_argument,
926 "Anasazi::ICGSOrthoManager::projectAndNormalizeGen(): MS length not consistent with S." );
927 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetNumberVecs(*MS) != sc, std::invalid_argument,
928 "Anasazi::ICGSOrthoManager::projectAndNormalizeGen(): MS width not consistent with S." );
933 ptrdiff_t sumxyc = 0;
936 for (
int i=0; i<numxy; i++) {
937 if (X[i] != Teuchos::null && Y[i] != Teuchos::null) {
938 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*X[i]) != sr, std::invalid_argument,
939 "Anasazi::ICGSOrthoManager::projectAndNormalizeGen(): X[" << i <<
"] length not consistent with S." );
940 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*Y[i]) != sr, std::invalid_argument,
941 "Anasazi::ICGSOrthoManager::projectAndNormalizeGen(): Y[" << i <<
"] length not consistent with S." );
942 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetNumberVecs(*X[i]) != MVT::GetNumberVecs(*Y[i]), std::invalid_argument,
943 "Anasazi::ICGSOrthoManager::projectAndNormalizeGen(): X[" << i <<
"] and Y[" << i <<
"] widths not consistent." );
945 xyc[i] = MVT::GetNumberVecs( *X[i] );
946 TEUCHOS_TEST_FOR_EXCEPTION( sr <
static_cast<ptrdiff_t
>(xyc[i]), std::invalid_argument,
947 "Anasazi::ICGSOrthoManager::projectAndNormalizeGen(): X[" << i <<
"],Y[" << i <<
"] have less rows than columns, and therefore cannot be full rank." );
951 if ( C[i] == Teuchos::null ) {
952 C[i] = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(xyc[i],sc) );
955 TEUCHOS_TEST_FOR_EXCEPTION( C[i]->numRows() != xyc[i] || C[i]->numCols() != sc , std::invalid_argument,
956 "Anasazi::ICGSOrthoManager::projectAndNormalizeGen(): Size of Q not consistent with size of C." );
960 if (MX[i] != Teuchos::null) {
961 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*MX[i]) != sr || MVT::GetNumberVecs(*MX[i]) != xyc[i], std::invalid_argument,
962 "Anasazi::ICGSOrthoManager::projectAndNormalizeGen(): Size of MX[" << i <<
"] not consistent with size of X[" << i <<
"]." );
967 if (MY[i] != Teuchos::null) {
968 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*MY[i]) != sr || MVT::GetNumberVecs(*MY[i]) != xyc[i], std::invalid_argument,
969 "Anasazi::ICGSOrthoManager::projectAndNormalizeGen(): Size of MY[" << i <<
"] not consistent with size of Y[" << i <<
"]." );
977 TEUCHOS_TEST_FOR_EXCEPTION(X[i] != Teuchos::null || Y[i] != Teuchos::null, std::invalid_argument,
978 "Anasazi::ICGSOrthoManager::projectAndNormalizeGen(): "
979 << (X[i] == Teuchos::null ?
"Y[" :
"X[") << i <<
"] was provided but "
980 << (X[i] == Teuchos::null ?
"X[" :
"Y[") << i <<
"] was not.");
985 TEUCHOS_TEST_FOR_EXCEPTION(sumxyc + sc > sr, std::invalid_argument,
986 "Anasazi::ICGSOrthoManager::projectAndNormalizeGen(): dimension of all X[i],Y[i] is "
987 << sumxyc <<
" and requested " << sc <<
"-dimensional basis, but length of vectors is only "
988 << sr <<
". This is infeasible.");
1023 if (MXmissing == 0) {
1026 if (MYmissing == 0) {
1033 switch (whichAlloc) {
1049 if (MS == Teuchos::null) {
1050#ifdef ANASAZI_ICGS_DEBUG
1051 *out <<
"Allocating MS...\n";
1053 MS = MVT::Clone(S,MVT::GetNumberVecs(S));
1054 OPT::Apply(*(this->_Op),S,*MS);
1055 this->_OpCounter += MVT::GetNumberVecs(S);
1059 if (whichAlloc == 0) {
1061 for (
int i=0; i<numxy; i++) {
1062 if (MX[i] == Teuchos::null) {
1063#ifdef ANASAZI_ICGS_DEBUG
1064 *out <<
"Allocating MX[" << i <<
"]...\n";
1066 Teuchos::RCP<MV> tmpMX = MVT::Clone(*X[i],xyc[i]);
1067 OPT::Apply(*(this->_Op),*X[i],*tmpMX);
1069 this->_OpCounter += xyc[i];
1076 MS = Teuchos::rcpFromRef(S);
1079 TEUCHOS_TEST_FOR_EXCEPTION(updateMS == -1,std::logic_error,
1080 "Anasazi::ICGSOrthoManager::projectGen(): Error in updateMS logic.");
1085 if ( B == Teuchos::null ) {
1086 B = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(sc,sc) );
1090 TEUCHOS_TEST_FOR_EXCEPTION( B->numRows() != sc || B->numCols() != sc, std::invalid_argument,
1091 "Anasazi::ICGSOrthoManager::projectAndNormalizeGen(): Size of S must be consistent with size of B" );
1096 projectGen(S,X,Y,isBiortho,C,MS,MX,MY);
1098 Teuchos::SerialDenseMatrix<int,ScalarType> oldCoeff(sc,1);
1104 int curssize = sc - rank;
1109#ifdef ANASAZI_ICGS_DEBUG
1110 *out <<
"Attempting to find orthonormal basis for X...\n";
1112 rank = findBasis(S,MS,*B,
false,curssize);
1114 if (oldrank != -1 && rank != oldrank) {
1120 for (
int i=0; i<sc; i++) {
1121 (*B)(i,oldrank) = oldCoeff(i,0);
1126 if (rank != oldrank) {
1134 for (
int i=0; i<sc; i++) {
1135 oldCoeff(i,0) = (*B)(i,rank);
1142#ifdef ANASAZI_ICGS_DEBUG
1143 *out <<
"Finished computing basis.\n";
1148 TEUCHOS_TEST_FOR_EXCEPTION( rank < oldrank,
OrthoError,
1149 "Anasazi::ICGSOrthoManager::projectAndNormalizeGen(): basis lost rank; this shouldn't happen");
1151 if (rank != oldrank) {
1159 if (numTries <= 0) {
1167#ifdef ANASAZI_ICGS_DEBUG
1168 *out <<
"Inserting random vector in X[" << rank <<
"]. Attempt " << 10-numTries <<
".\n";
1170 Teuchos::RCP<MV> curS, curMS;
1171 std::vector<int> ind(1);
1173 curS = MVT::CloneViewNonConst(S,ind);
1174 MVT::MvRandom(*curS);
1176#ifdef ANASAZI_ICGS_DEBUG
1177 *out <<
"Applying operator to random vector.\n";
1179 curMS = MVT::CloneViewNonConst(*MS,ind);
1180 OPT::Apply( *(this->_Op), *curS, *curMS );
1181 this->_OpCounter += MVT::GetNumberVecs(*curS);
1189 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > dummyC(0);
1190 projectGen(*curS,X,Y,isBiortho,dummyC,curMS,MX,MY);
1196 TEUCHOS_TEST_FOR_EXCEPTION( rank > sc || rank < 0, std::logic_error,
1197 "Anasazi::ICGSOrthoManager::projectAndNormalizeGen(): Debug error in rank variable." );
1199#ifdef ANASAZI_ICGS_DEBUG
1200 *out <<
"Returning " << rank <<
" from Anasazi::ICGSOrthoManager::projectAndNormalizeGen(...)\n";
1211 template<
class ScalarType,
class MV,
class OP>
1213 MV &X, Teuchos::RCP<MV> MX,
1214 Teuchos::SerialDenseMatrix<int,ScalarType> &B,
1215 bool completeBasis,
int howMany )
const {
1232#ifdef ANASAZI_ICGS_DEBUG
1234 Teuchos::RCP<Teuchos::FancyOStream>
1235 out = Teuchos::getFancyOStream(Teuchos::rcpFromRef(std::cout));
1236 out->setShowAllFrontMatter(
false).setShowProcRank(
true);
1237 *out <<
"Entering Anasazi::ICGSOrthoManager::findBasis(...)\n";
1240 const ScalarType ONE = SCT::one();
1241 const MagnitudeType ZERO = SCT::magnitude(SCT::zero());
1243 int xc = MVT::GetNumberVecs( X );
1245 if (howMany == -1) {
1252 TEUCHOS_TEST_FOR_EXCEPTION(this->_hasOp ==
true && MX == Teuchos::null, std::logic_error,
1253 "Anasazi::ICGSOrthoManager::findBasis(): calling routine did not specify MS.");
1254 TEUCHOS_TEST_FOR_EXCEPTION( howMany < 0 || howMany > xc, std::logic_error,
1255 "Anasazi::ICGSOrthoManager::findBasis(): Invalid howMany parameter" );
1260 int xstart = xc - howMany;
1262 for (
int j = xstart; j < xc; j++) {
1271 for (
int i=j+1; i<xc; ++i) {
1276 std::vector<int> index(1);
1278 Teuchos::RCP<MV> Xj = MVT::CloneViewNonConst( X, index );
1279 Teuchos::RCP<MV> MXj;
1280 if ((this->_hasOp)) {
1282 MXj = MVT::CloneViewNonConst( *MX, index );
1290 std::vector<int> prev_idx( numX );
1291 Teuchos::RCP<const MV> prevX, prevMX;
1294 for (
int i=0; i<numX; ++i) prev_idx[i] = i;
1295 prevX = MVT::CloneView( X, prev_idx );
1297 prevMX = MVT::CloneView( *MX, prev_idx );
1301 bool rankDef =
true;
1306 for (
int numTrials = 0; numTrials < 10; numTrials++) {
1307#ifdef ANASAZI_ICGS_DEBUG
1308 *out <<
"Trial " << numTrials <<
" for vector " << j <<
"\n";
1312 Teuchos::SerialDenseMatrix<int,ScalarType> product(numX, 1);
1313 std::vector<MagnitudeType> origNorm(1), newNorm(1), newNorm2(1);
1318 Teuchos::RCP<MV> oldMXj = MVT::CloneCopy( *MXj );
1320#ifdef ANASAZI_ICGS_DEBUG
1321 *out <<
"origNorm = " << origNorm[0] <<
"\n";
1332#ifdef ANASAZI_ICGS_DEBUG
1333 *out <<
"Orthogonalizing X[" << j <<
"]...\n";
1335 MVT::MvTimesMatAddMv( -ONE, *prevX, product, ONE, *Xj );
1342#ifdef ANASAZI_ICGS_DEBUG
1343 *out <<
"Updating MX[" << j <<
"]...\n";
1345 MVT::MvTimesMatAddMv( -ONE, *prevMX, product, ONE, *MXj );
1350 MagnitudeType product_norm = product.normOne();
1352#ifdef ANASAZI_ICGS_DEBUG
1353 *out <<
"newNorm = " << newNorm[0] <<
"\n";
1354 *out <<
"prodoct_norm = " << product_norm <<
"\n";
1358 if ( product_norm/newNorm[0] >= tol_ || newNorm[0] < eps_*origNorm[0]) {
1359#ifdef ANASAZI_ICGS_DEBUG
1360 if (product_norm/newNorm[0] >= tol_) {
1361 *out <<
"product_norm/newNorm == " << product_norm/newNorm[0] <<
"... another step of Gram-Schmidt.\n";
1364 *out <<
"eps*origNorm == " << eps_*origNorm[0] <<
"... another step of Gram-Schmidt.\n";
1369 Teuchos::SerialDenseMatrix<int,ScalarType> P2(numX,1);
1372#ifdef ANASAZI_ICGS_DEBUG
1373 *out <<
"Orthogonalizing X[" << j <<
"]...\n";
1375 MVT::MvTimesMatAddMv( -ONE, *prevX, P2, ONE, *Xj );
1376 if ((this->_hasOp)) {
1377#ifdef ANASAZI_ICGS_DEBUG
1378 *out <<
"Updating MX[" << j <<
"]...\n";
1380 MVT::MvTimesMatAddMv( -ONE, *prevMX, P2, ONE, *MXj );
1384 product_norm = P2.normOne();
1385#ifdef ANASAZI_ICGS_DEBUG
1386 *out <<
"newNorm2 = " << newNorm2[0] <<
"\n";
1387 *out <<
"product_norm = " << product_norm <<
"\n";
1389 if ( product_norm/newNorm2[0] >= tol_ || newNorm2[0] < eps_*origNorm[0] ) {
1391#ifdef ANASAZI_ICGS_DEBUG
1392 if (product_norm/newNorm2[0] >= tol_) {
1393 *out <<
"product_norm/newNorm2 == " << product_norm/newNorm2[0] <<
"... setting vector to zero.\n";
1395 else if (newNorm[0] < newNorm2[0]) {
1396 *out <<
"newNorm2 > newNorm... setting vector to zero.\n";
1399 *out <<
"eps*origNorm == " << eps_*origNorm[0] <<
"... setting vector to zero.\n";
1402 MVT::MvInit(*Xj,ZERO);
1403 if ((this->_hasOp)) {
1404#ifdef ANASAZI_ICGS_DEBUG
1405 *out <<
"Setting MX[" << j <<
"] to zero as well.\n";
1407 MVT::MvInit(*MXj,ZERO);
1414 if (numTrials == 0) {
1415 for (
int i=0; i<numX; i++) {
1416 B(i,j) = product(i,0);
1422 if ( newNorm[0] != ZERO && newNorm[0] > SCT::sfmin() ) {
1423#ifdef ANASAZI_ICGS_DEBUG
1424 *out <<
"Normalizing X[" << j <<
"], norm(X[" << j <<
"]) = " << newNorm[0] <<
"\n";
1428 MVT::MvScale( *Xj, ONE/newNorm[0]);
1430#ifdef ANASAZI_ICGS_DEBUG
1431 *out <<
"Normalizing M*X[" << j <<
"]...\n";
1434 MVT::MvScale( *MXj, ONE/newNorm[0]);
1438 if (numTrials == 0) {
1439 B(j,j) = newNorm[0];
1447#ifdef ANASAZI_ICGS_DEBUG
1448 *out <<
"Not normalizing M*X[" << j <<
"]...\n";
1455 if (completeBasis) {
1457#ifdef ANASAZI_ICGS_DEBUG
1458 *out <<
"Inserting random vector in X[" << j <<
"]...\n";
1460 MVT::MvRandom( *Xj );
1462#ifdef ANASAZI_ICGS_DEBUG
1463 *out <<
"Updating M*X[" << j <<
"]...\n";
1465 OPT::Apply( *(this->_Op), *Xj, *MXj );
1466 this->_OpCounter += MVT::GetNumberVecs(*Xj);
1477 if (rankDef ==
true) {
1478 TEUCHOS_TEST_FOR_EXCEPTION( rankDef && completeBasis, OrthoError,
1479 "Anasazi::ICGSOrthoManager::findBasis(): Unable to complete basis" );
1480#ifdef ANASAZI_ICGS_DEBUG
1481 *out <<
"Returning early, rank " << j <<
" from Anasazi::ICGSOrthoManager::findBasis(...)\n";
1488#ifdef ANASAZI_ICGS_DEBUG
1489 *out <<
"Returning " << xc <<
" from Anasazi::ICGSOrthoManager::findBasis(...)\n";
Anasazi header file which uses auto-configuration information to include necessary C++ headers.
Templated virtual class for providing orthogonalization/orthonormalization methods with matrix-based ...
Declaration of basic traits for the multivector type.
Virtual base class which defines basic traits for the operator type.
An implementation of the Anasazi::GenOrthoManager that performs orthogonalization using iterated clas...
void setNumIters(int numIters)
Set parameter for re-orthogonalization threshold.
ICGSOrthoManager(Teuchos::RCP< const OP > Op=Teuchos::null, int numIters=2, typename Teuchos::ScalarTraits< ScalarType >::magnitudeType eps=0.0, typename Teuchos::ScalarTraits< ScalarType >::magnitudeType tol=0.20)
Constructor specifying the operator defining the inner product as well as the number of orthogonaliza...
~ICGSOrthoManager()
Destructor.
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 ,...
void projectGen(MV &S, Teuchos::Array< Teuchos::RCP< const MV > > X, Teuchos::Array< Teuchos::RCP< const MV > > Y, bool isBiOrtho, Teuchos::Array< Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > > C=Teuchos::tuple(Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > >(Teuchos::null)), Teuchos::RCP< MV > MS=Teuchos::null, Teuchos::Array< Teuchos::RCP< const MV > > MX=Teuchos::tuple(Teuchos::RCP< const MV >(Teuchos::null)), Teuchos::Array< Teuchos::RCP< const MV > > MY=Teuchos::tuple(Teuchos::RCP< const MV >(Teuchos::null))) const
Applies a series of generic projectors.
int getNumIters() const
Return parameter for re-orthogonalization threshold.
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 ...
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...
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 .
Teuchos::ScalarTraits< ScalarType >::magnitudeType orthogErrorMat(const MV &X1, const MV &X2, Teuchos::RCP< const MV > MX1, Teuchos::RCP< const MV > MX2) const
This method computes the error in orthogonality of two multivectors, measured as the Frobenius norm o...
int projectAndNormalizeGen(MV &S, Teuchos::Array< Teuchos::RCP< const MV > > X, Teuchos::Array< Teuchos::RCP< const MV > > Y, bool isBiOrtho, 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 > MS=Teuchos::null, Teuchos::Array< Teuchos::RCP< const MV > > MX=Teuchos::tuple(Teuchos::RCP< const MV >(Teuchos::null)), Teuchos::Array< Teuchos::RCP< const MV > > MY=Teuchos::tuple(Teuchos::RCP< const MV >(Teuchos::null))) const
Applies a series of generic projectors and returns an orthonormal basis for the residual data.
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.
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.
Traits class which defines basic operations on multivectors.
Virtual base class which defines basic traits for the operator type.
Exception thrown to signal error in an orthogonalization manager method.
Namespace Anasazi contains the classes, structs, enums and utilities used by the Anasazi package.