15#ifndef BELOS_IMGS_ORTHOMANAGER_HPP
16#define BELOS_IMGS_ORTHOMANAGER_HPP
31#include "Teuchos_SerialDenseMatrix.hpp"
32#include "Teuchos_SerialDenseVector.hpp"
34#include "Teuchos_as.hpp"
35#ifdef BELOS_TEUCHOS_TIME_MONITOR
36#include "Teuchos_TimeMonitor.hpp"
42 template<
class ScalarType,
class MV,
class OP>
46 template<
class ScalarType,
class MV,
class OP>
49 template<
class ScalarType,
class MV,
class OP>
54 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
55 typedef typename Teuchos::ScalarTraits<MagnitudeType> MGT;
56 typedef Teuchos::ScalarTraits<ScalarType> SCT;
66 Teuchos::RCP<const OP> Op = Teuchos::null,
71 max_ortho_steps_( max_ortho_steps ),
73 sing_tol_( sing_tol ),
76#ifdef BELOS_TEUCHOS_TIME_MONITOR
78 ss << label_ +
": IMGS[" << max_ortho_steps_ <<
"]";
80 std::string orthoLabel = ss.str() +
": Orthogonalization";
81 timerOrtho_ = Teuchos::TimeMonitor::getNewCounter(orthoLabel);
83 std::string updateLabel = ss.str() +
": Ortho (Update)";
84 timerUpdate_ = Teuchos::TimeMonitor::getNewCounter(updateLabel);
86 std::string normLabel = ss.str() +
": Ortho (Norm)";
87 timerNorm_ = Teuchos::TimeMonitor::getNewCounter(normLabel);
89 std::string ipLabel = ss.str() +
": Ortho (Inner Product)";
90 timerInnerProd_ = Teuchos::TimeMonitor::getNewCounter(ipLabel);
96 const std::string& label =
"Belos",
97 Teuchos::RCP<const OP> Op = Teuchos::null) :
106#ifdef BELOS_TEUCHOS_TIME_MONITOR
107 std::stringstream ss;
108 ss << label_ +
": IMGS[" << max_ortho_steps_ <<
"]";
110 std::string orthoLabel = ss.str() +
": Orthogonalization";
111 timerOrtho_ = Teuchos::TimeMonitor::getNewCounter(orthoLabel);
113 std::string updateLabel = ss.str() +
": Ortho (Update)";
114 timerUpdate_ = Teuchos::TimeMonitor::getNewCounter(updateLabel);
116 std::string normLabel = ss.str() +
": Ortho (Norm)";
117 timerNorm_ = Teuchos::TimeMonitor::getNewCounter(normLabel);
119 std::string ipLabel = ss.str() +
": Ortho (Inner Product)";
120 timerInnerProd_ = Teuchos::TimeMonitor::getNewCounter(ipLabel);
133 using Teuchos::Exceptions::InvalidParameterName;
134 using Teuchos::ParameterList;
135 using Teuchos::parameterList;
139 RCP<ParameterList> params;
140 if (plist.is_null()) {
141 params = parameterList (*defaultParams);
156 int maxNumOrthogPasses;
157 MagnitudeType blkTol;
158 MagnitudeType singTol;
161 maxNumOrthogPasses = params->get<
int> (
"maxNumOrthogPasses");
162 }
catch (InvalidParameterName&) {
163 maxNumOrthogPasses = defaultParams->get<
int> (
"maxNumOrthogPasses");
164 params->set (
"maxNumOrthogPasses", maxNumOrthogPasses);
175 blkTol = params->get<MagnitudeType> (
"blkTol");
176 }
catch (InvalidParameterName&) {
178 blkTol = params->get<MagnitudeType> (
"depTol");
181 params->remove (
"depTol");
182 }
catch (InvalidParameterName&) {
183 blkTol = defaultParams->get<MagnitudeType> (
"blkTol");
185 params->set (
"blkTol", blkTol);
189 singTol = params->get<MagnitudeType> (
"singTol");
190 }
catch (InvalidParameterName&) {
191 singTol = defaultParams->get<MagnitudeType> (
"singTol");
192 params->set (
"singTol", singTol);
195 max_ortho_steps_ = maxNumOrthogPasses;
199 this->setMyParamList (params);
202 Teuchos::RCP<const Teuchos::ParameterList>
205 if (defaultParams_.is_null()) {
209 return defaultParams_;
218 void setBlkTol(
const MagnitudeType blk_tol ) { blk_tol_ = blk_tol; }
221 void setSingTol(
const MagnitudeType sing_tol ) { sing_tol_ = sing_tol; }
262 void project ( MV &X, Teuchos::RCP<MV> MX,
263 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
264 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const;
270 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
271 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const {
301 int normalize ( MV &X, Teuchos::RCP<MV> MX,
302 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B)
const;
307 int normalize ( MV &X, Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B )
const {
356 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
357 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
358 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const;
368 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
377 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
383 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
392 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
393 orthogError(
const MV &X1, Teuchos::RCP<const MV> MX1,
const MV &X2)
const;
402 void setLabel(
const std::string& label);
406 const std::string&
getLabel()
const {
return label_; }
432 int max_ortho_steps_;
434 MagnitudeType blk_tol_;
436 MagnitudeType sing_tol_;
440#ifdef BELOS_TEUCHOS_TIME_MONITOR
441 Teuchos::RCP<Teuchos::Time> timerOrtho_, timerUpdate_, timerNorm_, timerInnerProd_;
445 mutable Teuchos::RCP<Teuchos::ParameterList> defaultParams_;
448 int findBasis(MV &X, Teuchos::RCP<MV> MX,
449 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > C,
450 bool completeBasis,
int howMany = -1 )
const;
453 bool blkOrtho1 ( MV &X, Teuchos::RCP<MV> MX,
454 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
455 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const;
458 bool blkOrtho ( MV &X, Teuchos::RCP<MV> MX,
459 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
460 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const;
475 int blkOrthoSing ( MV &X, Teuchos::RCP<MV> MX,
476 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
477 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
478 Teuchos::ArrayView<Teuchos::RCP<const MV> > QQ)
const;
482 template<
class ScalarType,
class MV,
class OP>
485 template<
class ScalarType,
class MV,
class OP>
486 const typename IMGSOrthoManager<ScalarType,MV,OP>::MagnitudeType
488 = 10*Teuchos::ScalarTraits<typename IMGSOrthoManager<ScalarType,MV,OP>::MagnitudeType>::squareroot(
489 Teuchos::ScalarTraits<
typename IMGSOrthoManager<ScalarType,MV,OP>::MagnitudeType>::eps() );
491 template<
class ScalarType,
class MV,
class OP>
492 const typename IMGSOrthoManager<ScalarType,MV,OP>::MagnitudeType
494 = 10*Teuchos::ScalarTraits<typename IMGSOrthoManager<ScalarType,MV,OP>::MagnitudeType>::eps();
496 template<
class ScalarType,
class MV,
class OP>
499 template<
class ScalarType,
class MV,
class OP>
500 const typename IMGSOrthoManager<ScalarType,MV,OP>::MagnitudeType
502 = Teuchos::ScalarTraits<typename IMGSOrthoManager<ScalarType,MV,OP>::MagnitudeType>::zero();
504 template<
class ScalarType,
class MV,
class OP>
505 const typename IMGSOrthoManager<ScalarType,MV,OP>::MagnitudeType
507 = Teuchos::ScalarTraits<typename IMGSOrthoManager<ScalarType,MV,OP>::MagnitudeType>::zero();
511 template<
class ScalarType,
class MV,
class OP>
514 if (label != label_) {
516#ifdef BELOS_TEUCHOS_TIME_MONITOR
517 std::stringstream ss;
518 ss << label_ +
": IMGS[" << max_ortho_steps_ <<
"]";
520 std::string orthoLabel = ss.str() +
": Orthogonalization";
521 timerOrtho_ = Teuchos::TimeMonitor::getNewCounter(orthoLabel);
523 std::string updateLabel = ss.str() +
": Ortho (Update)";
524 timerUpdate_ = Teuchos::TimeMonitor::getNewCounter(updateLabel);
526 std::string normLabel = ss.str() +
": Ortho (Norm)";
527 timerNorm_ = Teuchos::TimeMonitor::getNewCounter(normLabel);
529 std::string ipLabel = ss.str() +
": Ortho (Inner Product)";
530 timerInnerProd_ = Teuchos::TimeMonitor::getNewCounter(ipLabel);
537 template<
class ScalarType,
class MV,
class OP>
538 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
540 const ScalarType ONE = SCT::one();
542 Teuchos::SerialDenseMatrix<int,ScalarType> xTx(rank,rank);
544 for (
int i=0; i<rank; i++) {
547 return xTx.normFrobenius();
552 template<
class ScalarType,
class MV,
class OP>
553 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
557 Teuchos::SerialDenseMatrix<int,ScalarType> xTx(r2,r1);
559 return xTx.normFrobenius();
564 template<
class ScalarType,
class MV,
class OP>
569 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
570 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
571 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const
573 using Teuchos::Array;
575 using Teuchos::is_null;
578 using Teuchos::SerialDenseMatrix;
579 typedef SerialDenseMatrix< int, ScalarType > serial_dense_matrix_type;
580 typedef typename Array< RCP< const MV > >::size_type size_type;
582#ifdef BELOS_TEUCHOS_TIME_MONITOR
583 Teuchos::TimeMonitor orthotimer(*timerOrtho_);
586 ScalarType ONE = SCT::one();
587 const MagnitudeType ZERO = MGT::zero();
598 B = rcp (
new serial_dense_matrix_type (xc, xc));
608 for (size_type k = 0; k < nq; ++k)
611 const int numCols = xc;
614 C[k] = rcp (
new serial_dense_matrix_type (numRows, numCols));
615 else if (C[k]->numRows() != numRows || C[k]->numCols() != numCols)
617 int err = C[k]->reshape (numRows, numCols);
618 TEUCHOS_TEST_FOR_EXCEPTION(err != 0, std::runtime_error,
619 "IMGS orthogonalization: failed to reshape "
620 "C[" << k <<
"] (the array of block "
621 "coefficients resulting from projecting X "
622 "against Q[1:" << nq <<
"]).");
628 if (MX == Teuchos::null) {
636 MX = Teuchos::rcp( &X,
false );
643 TEUCHOS_TEST_FOR_EXCEPTION( xc == 0 || xr == 0, std::invalid_argument,
"Belos::IMGSOrthoManager::projectAndNormalize(): X must be non-empty" );
646 for (
int i=0; i<nq; i++) {
651 TEUCHOS_TEST_FOR_EXCEPTION( B->numRows() != xc || B->numCols() != xc, std::invalid_argument,
652 "Belos::IMGSOrthoManager::projectAndNormalize(): Size of X must be consistant with size of B" );
654 TEUCHOS_TEST_FOR_EXCEPTION( xc<0 || xr<0 || mxc<0 || mxr<0, std::invalid_argument,
655 "Belos::IMGSOrthoManager::projectAndNormalize(): MVT returned negative dimensions for X,MX" );
657 TEUCHOS_TEST_FOR_EXCEPTION( xc!=mxc || xr!=mxr, std::invalid_argument,
658 "Belos::IMGSOrthoManager::projectAndNormalize(): Size of X must be consistant with size of MX" );
664 bool dep_flg =
false;
667 Teuchos::RCP<MV> tmpX, tmpMX;
677 dep_flg = blkOrtho1( X, MX, C, Q );
680 if ( B == Teuchos::null ) {
681 B = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(xc,xc) );
683 std::vector<ScalarType> diag(xc);
685#ifdef BELOS_TEUCHOS_TIME_MONITOR
686 Teuchos::TimeMonitor normTimer( *timerNorm_ );
690 (*B)(0,0) = SCT::squareroot(SCT::magnitude(diag[0]));
692 if (SCT::magnitude((*B)(0,0)) > ZERO) {
704 dep_flg = blkOrtho( X, MX, C, Q );
710 rank = blkOrthoSing( *tmpX, tmpMX, C, B, Q );
720 rank = findBasis( X, MX, B,
false );
725 rank = blkOrthoSing( *tmpX, tmpMX, C, B, Q );
737 TEUCHOS_TEST_FOR_EXCEPTION( rank > xc || rank < 0, std::logic_error,
738 "Belos::IMGSOrthoManager::projectAndNormalize(): Debug error in rank variable." );
748 template<
class ScalarType,
class MV,
class OP>
750 MV &X, Teuchos::RCP<MV> MX,
751 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B )
const {
753#ifdef BELOS_TEUCHOS_TIME_MONITOR
754 Teuchos::TimeMonitor orthotimer(*timerOrtho_);
758 return findBasis(X, MX, B,
true);
764 template<
class ScalarType,
class MV,
class OP>
766 MV &X, Teuchos::RCP<MV> MX,
767 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
768 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const {
784#ifdef BELOS_TEUCHOS_TIME_MONITOR
785 Teuchos::TimeMonitor orthotimer(*timerOrtho_);
791 std::vector<int> qcs(nq);
793 if (nq == 0 || xc == 0 || xr == 0) {
805 if (MX == Teuchos::null) {
813 MX = Teuchos::rcp( &X,
false );
819 TEUCHOS_TEST_FOR_EXCEPTION( xc<0 || xr<0 || mxc<0 || mxr<0, std::invalid_argument,
820 "Belos::IMGSOrthoManager::project(): MVT returned negative dimensions for X,MX" );
822 TEUCHOS_TEST_FOR_EXCEPTION( xc!=mxc || xr!=mxr || xr!=qr, std::invalid_argument,
823 "Belos::IMGSOrthoManager::project(): Size of X not consistant with MX,Q" );
826 for (
int i=0; i<nq; i++) {
828 "Belos::IMGSOrthoManager::project(): Q lengths not mutually consistant" );
830 TEUCHOS_TEST_FOR_EXCEPTION( qr < qcs[i], std::invalid_argument,
831 "Belos::IMGSOrthoManager::project(): Q has less rows than columns" );
834 if ( C[i] == Teuchos::null ) {
835 C[i] = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(qcs[i],xc) );
838 TEUCHOS_TEST_FOR_EXCEPTION( C[i]->numRows() != qcs[i] || C[i]->numCols() != xc , std::invalid_argument,
839 "Belos::IMGSOrthoManager::project(): Size of Q not consistant with size of C" );
844 blkOrtho( X, MX, C, Q );
851 template<
class ScalarType,
class MV,
class OP>
852 int IMGSOrthoManager<ScalarType, MV, OP>::findBasis(
853 MV &X, Teuchos::RCP<MV> MX,
854 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
855 bool completeBasis,
int howMany )
const {
872 const ScalarType ONE = SCT::one();
873 const MagnitudeType ZERO = SCT::magnitude(SCT::zero());
875 int xc = MVT::GetNumberVecs( X );
876 ptrdiff_t xr = MVT::GetGlobalLength( X );
889 if (MX == Teuchos::null) {
891 MX = MVT::Clone(X,xc);
892 OPT::Apply(*(this->_Op),X,*MX);
899 if ( B == Teuchos::null ) {
900 B = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(xc,xc) );
903 int mxc = (this->_hasOp) ? MVT::GetNumberVecs( *MX ) : xc;
904 ptrdiff_t mxr = (this->_hasOp) ? MVT::GetGlobalLength( *MX ) : xr;
907 TEUCHOS_TEST_FOR_EXCEPTION( xc == 0 || xr == 0, std::invalid_argument,
908 "Belos::IMGSOrthoManager::findBasis(): X must be non-empty" );
909 TEUCHOS_TEST_FOR_EXCEPTION( B->numRows() != xc || B->numCols() != xc, std::invalid_argument,
910 "Belos::IMGSOrthoManager::findBasis(): Size of X not consistant with size of B" );
911 TEUCHOS_TEST_FOR_EXCEPTION( xc != mxc || xr != mxr, std::invalid_argument,
912 "Belos::IMGSOrthoManager::findBasis(): Size of X not consistant with size of MX" );
913 TEUCHOS_TEST_FOR_EXCEPTION( xc > xr, std::invalid_argument,
914 "Belos::IMGSOrthoManager::findBasis(): Size of X not feasible for normalization" );
915 TEUCHOS_TEST_FOR_EXCEPTION( howMany < 0 || howMany > xc, std::invalid_argument,
916 "Belos::IMGSOrthoManager::findBasis(): Invalid howMany parameter" );
921 int xstart = xc - howMany;
923 for (
int j = xstart; j < xc; j++) {
932 std::vector<int> index(1);
934 Teuchos::RCP<MV> Xj = MVT::CloneViewNonConst( X, index );
935 Teuchos::RCP<MV> MXj;
936 if ((this->_hasOp)) {
938 MXj = MVT::CloneViewNonConst( *MX, index );
945 Teuchos::RCP<MV> oldMXj;
947 oldMXj = MVT::CloneCopy( *MXj );
951 Teuchos::SerialDenseVector<int,ScalarType> product(numX);
952 Teuchos::SerialDenseVector<int,ScalarType> P2(1);
953 Teuchos::RCP<const MV> prevX, prevMX;
955 std::vector<ScalarType> oldDot( 1 ), newDot( 1 );
960#ifdef BELOS_TEUCHOS_TIME_MONITOR
961 Teuchos::TimeMonitor normTimer( *timerNorm_ );
963 MVT::MvDot( *Xj, *MXj, oldDot );
966 TEUCHOS_TEST_FOR_EXCEPTION( SCT::real(oldDot[0]) < ZERO,
OrthoError,
967 "Belos::IMGSOrthoManager::findBasis(): Negative definiteness discovered in inner product" );
970 for (
int ii=0; ii<numX; ii++) {
973 prevX = MVT::CloneView( X, index );
975 prevMX = MVT::CloneView( *MX, index );
978 for (
int i=0; i<max_ortho_steps_; ++i) {
982#ifdef BELOS_TEUCHOS_TIME_MONITOR
983 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
991#ifdef BELOS_TEUCHOS_TIME_MONITOR
992 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
994 MVT::MvTimesMatAddMv( -ONE, *prevX, P2, ONE, *Xj );
1002#ifdef BELOS_TEUCHOS_TIME_MONITOR
1003 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1005 MVT::MvTimesMatAddMv( -ONE, *prevMX, P2, ONE, *MXj );
1010 product[ii] = P2[0];
1012 product[ii] += P2[0];
1020#ifdef BELOS_TEUCHOS_TIME_MONITOR
1021 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1023 MVT::MvDot( *Xj, *oldMXj, newDot );
1026 newDot[0] = oldDot[0];
1030 if (completeBasis) {
1034 if ( SCT::magnitude(newDot[0]) < SCT::magnitude(sing_tol_*oldDot[0]) ) {
1039 std::cout <<
"Belos::IMGSOrthoManager::findBasis() --> Random for column " << numX << std::endl;
1042 Teuchos::RCP<MV> tempXj = MVT::Clone( X, 1 );
1043 Teuchos::RCP<MV> tempMXj;
1044 MVT::MvRandom( *tempXj );
1046 tempMXj = MVT::Clone( X, 1 );
1047 OPT::Apply( *(this->_Op), *tempXj, *tempMXj );
1053#ifdef BELOS_TEUCHOS_TIME_MONITOR
1054 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1056 MVT::MvDot( *tempXj, *tempMXj, oldDot );
1060 for (
int ii=0; ii<numX; ii++) {
1063 prevX = MVT::CloneView( X, index );
1065 prevMX = MVT::CloneView( *MX, index );
1068 for (
int num_orth=0; num_orth<max_ortho_steps_; num_orth++){
1070#ifdef BELOS_TEUCHOS_TIME_MONITOR
1071 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1076#ifdef BELOS_TEUCHOS_TIME_MONITOR
1077 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1079 MVT::MvTimesMatAddMv( -ONE, *prevX, P2, ONE, *tempXj );
1082#ifdef BELOS_TEUCHOS_TIME_MONITOR
1083 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1085 MVT::MvTimesMatAddMv( -ONE, *prevMX, P2, ONE, *tempMXj );
1090 product[ii] = P2[0];
1092 product[ii] += P2[0];
1098#ifdef BELOS_TEUCHOS_TIME_MONITOR
1099 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1101 MVT::MvDot( *tempXj, *tempMXj, newDot );
1104 if ( SCT::magnitude(newDot[0]) >= SCT::magnitude(oldDot[0]*sing_tol_) ) {
1106 MVT::Assign( *tempXj, *Xj );
1108 MVT::Assign( *tempMXj, *MXj );
1120 if ( SCT::magnitude(newDot[0]) < SCT::magnitude(oldDot[0]*blk_tol_) ) {
1129 ScalarType diag = SCT::squareroot(SCT::magnitude(newDot[0]));
1130 if (SCT::magnitude(diag) > ZERO) {
1131 MVT::MvScale( *Xj, ONE/diag );
1134 MVT::MvScale( *MXj, ONE/diag );
1148 for (
int i=0; i<numX; i++) {
1149 (*B)(i,j) = product(i);
1160 template<
class ScalarType,
class MV,
class OP>
1162 IMGSOrthoManager<ScalarType, MV, OP>::blkOrtho1 ( MV &X, Teuchos::RCP<MV> MX,
1163 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
1164 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const
1167 int xc = MVT::GetNumberVecs( X );
1168 const ScalarType ONE = SCT::one();
1170 std::vector<int> qcs( nq );
1171 for (
int i=0; i<nq; i++) {
1172 qcs[i] = MVT::GetNumberVecs( *Q[i] );
1176 std::vector<int> index(1);
1177 Teuchos::RCP<const MV> tempQ;
1179 Teuchos::Array<Teuchos::RCP<MV> > MQ(nq);
1181 for (
int i=0; i<nq; i++) {
1184 for (
int ii=0; ii<qcs[i]; ii++) {
1187 tempQ = MVT::CloneView( *Q[i], index );
1188 Teuchos::SerialDenseMatrix<int,ScalarType> tempC( Teuchos::View, *C[i], 1, 1, ii, 0 );
1192#ifdef BELOS_TEUCHOS_TIME_MONITOR
1193 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1199#ifdef BELOS_TEUCHOS_TIME_MONITOR
1200 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1202 MVT::MvTimesMatAddMv( -ONE, *tempQ, tempC, ONE, X );
1209 OPT::Apply( *(this->_Op), X, *MX);
1213 MQ[i] = MVT::Clone( *Q[i], qcs[i] );
1214 OPT::Apply( *(this->_Op), *Q[i], *MQ[i] );
1215 MVT::MvTimesMatAddMv( -ONE, *MQ[i], *C[i], ONE, *MX );
1221 for (
int j = 1; j < max_ortho_steps_; ++j) {
1223 for (
int i=0; i<nq; i++) {
1225 Teuchos::SerialDenseMatrix<int,ScalarType> C2(qcs[i],1);
1228 for (
int ii=0; ii<qcs[i]; ii++) {
1231 tempQ = MVT::CloneView( *Q[i], index );
1232 Teuchos::SerialDenseMatrix<int,ScalarType> tempC( Teuchos::View, *C[i], 1, 1, ii, 0 );
1233 Teuchos::SerialDenseMatrix<int,ScalarType> tempC2( Teuchos::View, C2, 1, 1, ii, 0 );
1237#ifdef BELOS_TEUCHOS_TIME_MONITOR
1238 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1244#ifdef BELOS_TEUCHOS_TIME_MONITOR
1245 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1247 MVT::MvTimesMatAddMv( -ONE, *tempQ, tempC2, ONE, X );
1256 MVT::MvTimesMatAddMv( -ONE, *MQ[i], C2, ONE, *MX );
1258 else if (xc <= qcs[i]) {
1260 OPT::Apply( *(this->_Op), X, *MX);
1271 template<
class ScalarType,
class MV,
class OP>
1273 IMGSOrthoManager<ScalarType, MV, OP>::blkOrtho ( MV &X, Teuchos::RCP<MV> MX,
1274 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
1275 Teuchos::ArrayView<Teuchos::RCP<const MV> > Q)
const
1278 int xc = MVT::GetNumberVecs( X );
1279 bool dep_flg =
false;
1280 const ScalarType ONE = SCT::one();
1282 std::vector<int> qcs( nq );
1283 for (
int i=0; i<nq; i++) {
1284 qcs[i] = MVT::GetNumberVecs( *Q[i] );
1290 std::vector<ScalarType> oldDot( xc );
1292#ifdef BELOS_TEUCHOS_TIME_MONITOR
1293 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1295 MVT::MvDot( X, *MX, oldDot );
1298 std::vector<int> index(1);
1299 Teuchos::Array<Teuchos::RCP<MV> > MQ(nq);
1300 Teuchos::RCP<const MV> tempQ;
1303 for (
int i=0; i<nq; i++) {
1306 for (
int ii=0; ii<qcs[i]; ii++) {
1309 tempQ = MVT::CloneView( *Q[i], index );
1310 Teuchos::SerialDenseMatrix<int,ScalarType> tempC( Teuchos::View, *C[i], 1, xc, ii, 0 );
1314#ifdef BELOS_TEUCHOS_TIME_MONITOR
1315 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1321#ifdef BELOS_TEUCHOS_TIME_MONITOR
1322 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1324 MVT::MvTimesMatAddMv( -ONE, *tempQ, tempC, ONE, X );
1331 OPT::Apply( *(this->_Op), X, *MX);
1335 MQ[i] = MVT::Clone( *Q[i], qcs[i] );
1336 OPT::Apply( *(this->_Op), *Q[i], *MQ[i] );
1337 MVT::MvTimesMatAddMv( -ONE, *MQ[i], *C[i], ONE, *MX );
1343 for (
int j = 1; j < max_ortho_steps_; ++j) {
1345 for (
int i=0; i<nq; i++) {
1346 Teuchos::SerialDenseMatrix<int,ScalarType> C2(qcs[i],xc);
1349 for (
int ii=0; ii<qcs[i]; ii++) {
1352 tempQ = MVT::CloneView( *Q[i], index );
1353 Teuchos::SerialDenseMatrix<int,ScalarType> tempC( Teuchos::View, *C[i], 1, xc, ii, 0 );
1354 Teuchos::SerialDenseMatrix<int,ScalarType> tempC2( Teuchos::View, C2, 1, xc, ii, 0 );
1358#ifdef BELOS_TEUCHOS_TIME_MONITOR
1359 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
1365#ifdef BELOS_TEUCHOS_TIME_MONITOR
1366 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
1368 MVT::MvTimesMatAddMv( -ONE, *tempQ, tempC2, ONE, X );
1376 MVT::MvTimesMatAddMv( -ONE, *MQ[i], C2, ONE, *MX );
1378 else if (xc <= qcs[i]) {
1380 OPT::Apply( *(this->_Op), X, *MX);
1387 std::vector<ScalarType> newDot(xc);
1389#ifdef BELOS_TEUCHOS_TIME_MONITOR
1390 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1392 MVT::MvDot( X, *MX, newDot );
1396 for (
int i=0; i<xc; i++){
1397 if (SCT::magnitude(newDot[i]) < SCT::magnitude(oldDot[i] * blk_tol_)) {
1406 template<
class ScalarType,
class MV,
class OP>
1408 IMGSOrthoManager<ScalarType, MV, OP>::blkOrthoSing ( MV &X, Teuchos::RCP<MV> MX,
1409 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
1410 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
1411 Teuchos::ArrayView<Teuchos::RCP<const MV> > QQ)
const
1413 Teuchos::Array<Teuchos::RCP<const MV> > Q (QQ);
1415 const ScalarType ONE = SCT::one();
1416 const ScalarType ZERO = SCT::zero();
1419 int xc = MVT::GetNumberVecs( X );
1420 std::vector<int> indX( 1 );
1421 std::vector<ScalarType> oldDot( 1 ), newDot( 1 );
1423 std::vector<int> qcs( nq );
1424 for (
int i=0; i<nq; i++) {
1425 qcs[i] = MVT::GetNumberVecs( *Q[i] );
1429 Teuchos::RCP<const MV> lastQ;
1430 Teuchos::RCP<MV> Xj, MXj;
1431 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > lastC;
1434 for (
int j=0; j<xc; j++) {
1436 bool dep_flg =
false;
1440 std::vector<int> index( j );
1441 for (
int ind=0; ind<j; ind++) {
1444 lastQ = MVT::CloneView( X, index );
1447 Q.push_back( lastQ );
1449 qcs.push_back( MVT::GetNumberVecs( *lastQ ) );
1454 Xj = MVT::CloneViewNonConst( X, indX );
1456 MXj = MVT::CloneViewNonConst( *MX, indX );
1464#ifdef BELOS_TEUCHOS_TIME_MONITOR
1465 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1467 MVT::MvDot( *Xj, *MXj, oldDot );
1470 Teuchos::Array<Teuchos::RCP<MV> > MQ(Q.size());
1471 Teuchos::RCP<const MV> tempQ;
1474 for (
int i=0; i<Q.size(); i++) {
1477 for (
int ii=0; ii<qcs[i]; ii++) {
1480 tempQ = MVT::CloneView( *Q[i], indX );
1482 Teuchos::SerialDenseMatrix<int,ScalarType> tempC( Teuchos::View, *C[i], 1, 1, ii, j );
1488 MVT::MvTimesMatAddMv( -ONE, *tempQ, tempC, ONE, *Xj );
1494 OPT::Apply( *(this->_Op), *Xj, *MXj);
1498 MQ[i] = MVT::Clone( *Q[i], qcs[i] );
1499 OPT::Apply( *(this->_Op), *Q[i], *MQ[i] );
1500 Teuchos::SerialDenseMatrix<int,ScalarType> tempC( Teuchos::View, *C[i], qcs[i], 1, 0, j );
1501 MVT::MvTimesMatAddMv( -ONE, *MQ[i], tempC, ONE, *MXj );
1507 for (
int num_ortho_steps=1; num_ortho_steps < max_ortho_steps_; ++num_ortho_steps) {
1509 for (
int i=0; i<Q.size(); i++) {
1510 Teuchos::SerialDenseMatrix<int,ScalarType> C2( qcs[i], 1 );
1513 for (
int ii=0; ii<qcs[i]; ii++) {
1516 tempQ = MVT::CloneView( *Q[i], indX );
1518 Teuchos::SerialDenseMatrix<int,ScalarType> tempC2( Teuchos::View, C2, 1, 1, ii );
1522 MVT::MvTimesMatAddMv( -ONE, *tempQ, tempC2, ONE, *Xj );
1526 Teuchos::SerialDenseMatrix<int,ScalarType> tempC( Teuchos::View, *C[i], qcs[i], 1, 0, j );
1533 MVT::MvTimesMatAddMv( -ONE, *MQ[i], C2, ONE, *MXj );
1535 else if (xc <= qcs[i]) {
1537 OPT::Apply( *(this->_Op), *Xj, *MXj);
1546#ifdef BELOS_TEUCHOS_TIME_MONITOR
1547 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1549 MVT::MvDot( *Xj, *MXj, newDot );
1553 if (SCT::magnitude(newDot[0]) < SCT::magnitude(oldDot[0]*sing_tol_)) {
1559 ScalarType diag = SCT::squareroot(SCT::magnitude(newDot[0]));
1561 MVT::MvScale( *Xj, ONE/diag );
1564 MVT::MvScale( *MXj, ONE/diag );
1572 Teuchos::RCP<MV> tempXj = MVT::Clone( X, 1 );
1573 Teuchos::RCP<MV> tempMXj;
1574 MVT::MvRandom( *tempXj );
1576 tempMXj = MVT::Clone( X, 1 );
1577 OPT::Apply( *(this->_Op), *tempXj, *tempMXj );
1583#ifdef BELOS_TEUCHOS_TIME_MONITOR
1584 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1586 MVT::MvDot( *tempXj, *tempMXj, oldDot );
1589 for (
int num_orth=0; num_orth<max_ortho_steps_; num_orth++) {
1591 for (
int i=0; i<Q.size(); i++) {
1592 Teuchos::SerialDenseMatrix<int,ScalarType> product( qcs[i], 1 );
1595 for (
int ii=0; ii<qcs[i]; ii++) {
1598 tempQ = MVT::CloneView( *Q[i], indX );
1599 Teuchos::SerialDenseMatrix<int,ScalarType> tempC( Teuchos::View, product, 1, 1, ii );
1603 MVT::MvTimesMatAddMv( -ONE, *tempQ, tempC, ONE, *tempXj );
1611 MVT::MvTimesMatAddMv( -ONE, *MQ[i], product, ONE, *tempMXj );
1613 else if (xc <= qcs[i]) {
1615 OPT::Apply( *(this->_Op), *tempXj, *tempMXj);
1623#ifdef BELOS_TEUCHOS_TIME_MONITOR
1624 Teuchos::TimeMonitor normTimer( *timerNorm_ );
1626 MVT::MvDot( *tempXj, *tempMXj, newDot );
1630 if ( SCT::magnitude(newDot[0]) >= SCT::magnitude(oldDot[0]*sing_tol_) ) {
1631 ScalarType diag = SCT::squareroot(SCT::magnitude(newDot[0]));
1637 MVT::MvAddMv( ONE/diag, *tempXj, ZERO, *tempXj, *Xj );
1639 MVT::MvAddMv( ONE/diag, *tempMXj, ZERO, *tempMXj, *MXj );
1659 template<
class ScalarType,
class MV,
class OP>
1662 using Teuchos::ParameterList;
1663 using Teuchos::parameterList;
1666 RCP<ParameterList> params = parameterList (
"IMGS");
1671 "Maximum number of orthogonalization passes (includes the "
1672 "first). Default is 2, since \"twice is enough\" for Krylov "
1675 "Block reorthogonalization threshold.");
1677 "Singular block detection threshold.");
1682 template<
class ScalarType,
class MV,
class OP>
1685 using Teuchos::ParameterList;
1690 params->set (
"maxNumOrthogPasses",
1692 params->set (
"blkTol",
1694 params->set (
"singTol",
Belos 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.
Class which defines basic traits for the operator type.
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &plist)
static const MagnitudeType sing_tol_fast_
Singular block detection threshold (fast).
const std::string & getLabel() const
This method returns the label being used by the timers in the orthogonalization manager.
static const MagnitudeType sing_tol_default_
Singular block detection threshold (default).
int normalize(MV &X, Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > B) const
This method calls normalize(X,Teuchos::null,B); see documentation for that function.
IMGSOrthoManager(const Teuchos::RCP< Teuchos::ParameterList > &plist, const std::string &label="Belos", Teuchos::RCP< const OP > Op=Teuchos::null)
Constructor that takes a list of parameters.
~IMGSOrthoManager()
Destructor.
Teuchos::ScalarTraits< ScalarType >::magnitudeType orthonormError(const MV &X) const
This method computes the error in orthonormality of a multivector, measured as the Frobenius norm of ...
int normalize(MV &X, Teuchos::RCP< MV > MX, Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > B) const
This method takes a multivector X and attempts to compute an orthonormal basis for ,...
void setLabel(const std::string &label)
This method sets the label used by the timers in the orthogonalization manager.
static const int max_ortho_steps_fast_
Max number of (re)orthogonalization steps, including the first (fast).
void project(MV &X, Teuchos::Array< Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > > C, Teuchos::ArrayView< Teuchos::RCP< const MV > > Q) const
This method calls project(X,Teuchos::null,C,Q); see documentation for that function.
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
void project(MV &X, Teuchos::RCP< MV > MX, Teuchos::Array< Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > > C, Teuchos::ArrayView< Teuchos::RCP< const MV > > Q) const
Given a list of (mutually and internally) orthonormal bases Q, this method takes a multivector X and ...
static const MagnitudeType blk_tol_fast_
Block reorthogonalization threshold (fast).
static const int max_ortho_steps_default_
Max number of (re)orthogonalization steps, including the first (default).
MagnitudeType getBlkTol() const
Return parameter for block re-orthogonalization threshhold.
MagnitudeType getSingTol() const
Return parameter for singular block detection.
void setSingTol(const MagnitudeType sing_tol)
Set parameter for singular block detection.
IMGSOrthoManager(const std::string &label="Belos", Teuchos::RCP< const OP > Op=Teuchos::null, const int max_ortho_steps=max_ortho_steps_default_, const MagnitudeType blk_tol=blk_tol_default_, const MagnitudeType sing_tol=sing_tol_default_)
Constructor specifying re-orthogonalization tolerance.
void setBlkTol(const MagnitudeType blk_tol)
Set parameter for block re-orthogonalization threshhold.
static const MagnitudeType blk_tol_default_
Block reorthogonalization threshold (default).
virtual int projectAndNormalizeWithMxImpl(MV &X, Teuchos::RCP< MV > MX, Teuchos::Array< Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > > C, Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > B, Teuchos::ArrayView< Teuchos::RCP< const MV > > Q) const
Given a set of bases Q[i] and a multivector X, this method computes an orthonormal basis for .
Teuchos::ScalarTraits< ScalarType >::magnitudeType orthogError(const MV &X1, const MV &X2) const
This method computes the error in orthogonality of two multivectors, measured as the Frobenius norm o...
MatOrthoManager(Teuchos::RCP< const OP > Op=Teuchos::null)
Default constructor.
void innerProd(const MV &X, const MV &Y, Teuchos::SerialDenseMatrix< int, ScalarType > &Z) const
Provides the inner product defining the orthogonality concepts, using the provided operator.
Teuchos::RCP< const OP > _Op
Traits class which defines basic operations on multivectors.
static void MvScale(MV &mv, const ScalarType alpha)
Scale each element of the vectors in mv with alpha.
static Teuchos::RCP< MV > CloneCopy(const MV &mv)
Creates a new MV and copies contents of mv into the new vector (deep copy).
static ptrdiff_t GetGlobalLength(const MV &mv)
Return the number of rows in the given multivector mv.
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 Teuchos::RCP< MV > Clone(const MV &mv, const int numvecs)
Creates a new empty MV containing numvecs columns.
static int GetNumberVecs(const MV &mv)
Obtain the number of vectors in mv.
static void Assign(const MV &A, MV &mv)
mv := A
Class which defines basic traits for the operator type.
static void Apply(const OP &Op, const MV &x, MV &y, ETrans trans=NOTRANS)
Apply Op to x, putting the result into y.
Exception thrown to signal error in an orthogonalization manager method.
Teuchos::RCP< Teuchos::ParameterList > getIMGSFastParameters()
"Fast" but possibly unsafe or less accurate parameters.
Teuchos::RCP< Teuchos::ParameterList > getIMGSDefaultParameters()
"Default" parameters for robustness and accuracy.