00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00034 #ifndef BELOS_ICGS_ORTHOMANAGER_HPP
00035 #define BELOS_ICGS_ORTHOMANAGER_HPP
00036
00044
00045
00046 #include "BelosConfigDefs.hpp"
00047 #include "BelosMultiVecTraits.hpp"
00048 #include "BelosOperatorTraits.hpp"
00049 #include "BelosMatOrthoManager.hpp"
00050
00051 namespace Belos {
00052
00053 template<class ScalarType, class MV, class OP>
00054 class ICGSOrthoManager : public MatOrthoManager<ScalarType,MV,OP> {
00055
00056 private:
00057 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
00058 typedef typename Teuchos::ScalarTraits<MagnitudeType> MGT;
00059 typedef Teuchos::ScalarTraits<ScalarType> SCT;
00060 typedef MultiVecTraits<ScalarType,MV> MVT;
00061 typedef OperatorTraits<ScalarType,MV,OP> OPT;
00062
00063 public:
00064
00066
00067
00068 ICGSOrthoManager( const std::string& label = "Belos",
00069 Teuchos::RCP<const OP> Op = Teuchos::null,
00070 const int max_ortho_steps = 2,
00071 const MagnitudeType blk_tol = 10*MGT::squareroot( MGT::eps() ),
00072 const MagnitudeType sing_tol = 10*MGT::eps() )
00073 : MatOrthoManager<ScalarType,MV,OP>(Op),
00074 max_ortho_steps_( max_ortho_steps ),
00075 blk_tol_( blk_tol ),
00076 sing_tol_( sing_tol ),
00077 label_( label )
00078 {
00079 std::string orthoLabel = label_ + ": Orthogonalization";
00080 timerOrtho_ = Teuchos::TimeMonitor::getNewTimer(orthoLabel);
00081
00082 std::string updateLabel = label_ + ": Ortho (Update)";
00083 timerUpdate_ = Teuchos::TimeMonitor::getNewTimer(updateLabel);
00084
00085 std::string normLabel = label_ + ": Ortho (Norm)";
00086 timerNorm_ = Teuchos::TimeMonitor::getNewTimer(normLabel);
00087
00088 std::string ipLabel = label_ + ": Ortho (Inner Product)";
00089 timerInnerProd_ = Teuchos::TimeMonitor::getNewTimer(ipLabel);
00090 };
00091
00093 ~ICGSOrthoManager() {}
00095
00096
00098
00099
00101 void setBlkTol( const MagnitudeType blk_tol ) { blk_tol_ = blk_tol; }
00102
00104 void setSingTol( const MagnitudeType sing_tol ) { sing_tol_ = sing_tol; }
00105
00107 MagnitudeType getBlkTol() const { return blk_tol_; }
00108
00110 MagnitudeType getSingTol() const { return sing_tol_; }
00111
00113
00114
00116
00117
00145 void project ( MV &X, Teuchos::RCP<MV> MX,
00146 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
00147 Teuchos::Array<Teuchos::RCP<const MV> > Q) const;
00148
00149
00152 void project ( MV &X,
00153 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
00154 Teuchos::Array<Teuchos::RCP<const MV> > Q) const {
00155 project(X,Teuchos::null,C,Q);
00156 }
00157
00158
00159
00184 int normalize ( MV &X, Teuchos::RCP<MV> MX,
00185 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B) const;
00186
00187
00190 int normalize ( MV &X, Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B ) const {
00191 return normalize(X,Teuchos::null,B);
00192 }
00193
00194
00227 int projectAndNormalize ( MV &X, Teuchos::RCP<MV> MX,
00228 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
00229 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
00230 Teuchos::Array<Teuchos::RCP<const MV> > Q) const;
00231
00234 int projectAndNormalize ( MV &X,
00235 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
00236 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
00237 Teuchos::Array<Teuchos::RCP<const MV> > Q ) const {
00238 return projectAndNormalize(X,Teuchos::null,C,B,Q);
00239 }
00240
00242
00244
00245
00249 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
00250 orthonormError(const MV &X) const {
00251 return orthonormError(X,Teuchos::null);
00252 }
00253
00258 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
00259 orthonormError(const MV &X, Teuchos::RCP<const MV> MX) const;
00260
00264 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
00265 orthogError(const MV &X1, const MV &X2) const {
00266 return orthogError(X1,Teuchos::null,X2);
00267 }
00268
00273 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
00274 orthogError(const MV &X1, Teuchos::RCP<const MV> MX1, const MV &X2) const;
00275
00277
00279
00280
00283 void setLabel(const std::string& label);
00284
00287 const std::string& getLabel() const { return label_; }
00288
00290
00291 private:
00292
00294 int max_ortho_steps_;
00295 MagnitudeType blk_tol_;
00296 MagnitudeType sing_tol_;
00297
00299 std::string label_;
00300 Teuchos::RCP<Teuchos::Time> timerOrtho_, timerUpdate_,
00301 timerNorm_, timerScale_, timerInnerProd_;
00302
00304 int findBasis(MV &X, Teuchos::RCP<MV> MX,
00305 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > C,
00306 bool completeBasis, int howMany = -1 ) const;
00307
00309 bool blkOrtho1 ( MV &X, Teuchos::RCP<MV> MX,
00310 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
00311 Teuchos::Array<Teuchos::RCP<const MV> > Q) const;
00312
00314 bool blkOrtho ( MV &X, Teuchos::RCP<MV> MX,
00315 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
00316 Teuchos::Array<Teuchos::RCP<const MV> > Q) const;
00317
00318 int blkOrthoSing ( MV &X, Teuchos::RCP<MV> MX,
00319 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
00320 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
00321 Teuchos::Array<Teuchos::RCP<const MV> > Q) const;
00322 };
00323
00325
00326 template<class ScalarType, class MV, class OP>
00327 void ICGSOrthoManager<ScalarType,MV,OP>::setLabel(const std::string& label)
00328 {
00329 if (label != label_) {
00330 label_ = label;
00331 std::string orthoLabel = label_ + ": Orthogonalization";
00332 timerOrtho_ = Teuchos::TimeMonitor::getNewTimer(orthoLabel);
00333
00334 std::string updateLabel = label_ + ": Ortho (Update)";
00335 timerUpdate_ = Teuchos::TimeMonitor::getNewTimer(updateLabel);
00336
00337 std::string normLabel = label_ + ": Ortho (Norm)";
00338 timerNorm_ = Teuchos::TimeMonitor::getNewTimer(normLabel);
00339
00340 std::string ipLabel = label_ + ": Ortho (Inner Product)";
00341 timerInnerProd_ = Teuchos::TimeMonitor::getNewTimer(ipLabel);
00342 }
00343 }
00344
00346
00347 template<class ScalarType, class MV, class OP>
00348 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
00349 ICGSOrthoManager<ScalarType,MV,OP>::orthonormError(const MV &X, Teuchos::RCP<const MV> MX) const {
00350 const ScalarType ONE = SCT::one();
00351 int rank = MVT::GetNumberVecs(X);
00352 Teuchos::SerialDenseMatrix<int,ScalarType> xTx(rank,rank);
00353 innerProd(X,X,MX,xTx);
00354 for (int i=0; i<rank; i++) {
00355 xTx(i,i) -= ONE;
00356 }
00357 return xTx.normFrobenius();
00358 }
00359
00361
00362 template<class ScalarType, class MV, class OP>
00363 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
00364 ICGSOrthoManager<ScalarType,MV,OP>::orthogError(const MV &X1, Teuchos::RCP<const MV> MX1, const MV &X2) const {
00365 int r1 = MVT::GetNumberVecs(X1);
00366 int r2 = MVT::GetNumberVecs(X2);
00367 Teuchos::SerialDenseMatrix<int,ScalarType> xTx(r2,r1);
00368 innerProd(X2,X1,MX1,xTx);
00369 return xTx.normFrobenius();
00370 }
00371
00373
00374 template<class ScalarType, class MV, class OP>
00375 int ICGSOrthoManager<ScalarType, MV, OP>::projectAndNormalize(
00376 MV &X, Teuchos::RCP<MV> MX,
00377 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
00378 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
00379 Teuchos::Array<Teuchos::RCP<const MV> > Q ) const {
00380
00381 Teuchos::TimeMonitor orthotimer(*timerOrtho_);
00382
00383 ScalarType ONE = SCT::one();
00384 ScalarType ZERO = SCT::zero();
00385
00386 int nq = Q.length();
00387 int xc = MVT::GetNumberVecs( X );
00388 int xr = MVT::GetVecLength( X );
00389 int rank = xc;
00390
00391
00392
00393
00394 if ( B == Teuchos::null ) {
00395 B = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>(xc,xc) );
00396 }
00397
00398
00399 if (this->_hasOp) {
00400 if (MX == Teuchos::null) {
00401
00402 MX = MVT::Clone(X,MVT::GetNumberVecs(X));
00403 OPT::Apply(*(this->_Op),X,*MX);
00404 }
00405 }
00406 else {
00407
00408 MX = Teuchos::rcp( &X, false );
00409 }
00410
00411 int mxc = MVT::GetNumberVecs( *MX );
00412 int mxr = MVT::GetVecLength( *MX );
00413
00414
00415 TEST_FOR_EXCEPTION( xc == 0 || xr == 0, std::invalid_argument, "Belos::ICGSOrthoManager::projectAndNormalize(): X must be non-empty" );
00416
00417 int numbas = 0;
00418 for (int i=0; i<nq; i++) {
00419 numbas += MVT::GetNumberVecs( *Q[i] );
00420 }
00421
00422
00423 TEST_FOR_EXCEPTION( B->numRows() != xc || B->numCols() != xc, std::invalid_argument,
00424 "Belos::ICGSOrthoManager::projectAndNormalize(): Size of X must be consistant with size of B" );
00425
00426 TEST_FOR_EXCEPTION( xc<0 || xr<0 || mxc<0 || mxr<0, std::invalid_argument,
00427 "Belos::ICGSOrthoManager::projectAndNormalize(): MVT returned negative dimensions for X,MX" );
00428
00429 TEST_FOR_EXCEPTION( xc!=mxc || xr!=mxr, std::invalid_argument,
00430 "Belos::ICGSOrthoManager::projectAndNormalize(): Size of X must be consistant with size of MX" );
00431
00432
00433
00434
00435
00436 bool dep_flg = false;
00437
00438
00439 Teuchos::RCP<MV> tmpX, tmpMX;
00440 tmpX = MVT::CloneCopy(X);
00441 if (this->_hasOp) {
00442 tmpMX = MVT::CloneCopy(*MX);
00443 }
00444
00445 if (xc == 1) {
00446
00447
00448
00449 dep_flg = blkOrtho1( X, MX, C, Q );
00450
00451
00452 {
00453 Teuchos::TimeMonitor normTimer( *timerNorm_ );
00454 if ( B == Teuchos::null ) {
00455 B = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>(xc,xc) );
00456 }
00457 std::vector<ScalarType> diag(xc);
00458 MVT::MvDot( X, *MX, diag );
00459 (*B)(0,0) = SCT::squareroot(SCT::magnitude(diag[0]));
00460 rank = 1;
00461 MVT::MvAddMv( ONE/(*B)(0,0), X, ZERO, X, X );
00462 if (this->_hasOp) {
00463
00464 MVT::MvAddMv( ONE/(*B)(0,0), *MX, ZERO, *MX, *MX );
00465 }
00466 }
00467
00468 }
00469 else {
00470
00471
00472 dep_flg = blkOrtho( X, MX, C, Q );
00473
00474
00475
00476 if (dep_flg) {
00477 rank = blkOrthoSing( *tmpX, tmpMX, C, B, Q );
00478
00479
00480 MVT::MvAddMv( ONE, *tmpX, ZERO, *tmpX, X );
00481 if (this->_hasOp) {
00482 MVT::MvAddMv( ONE, *tmpMX, ZERO, *tmpMX, *MX );
00483 }
00484 }
00485 else {
00486
00487 rank = findBasis( X, MX, B, false );
00488 if (rank < xc) {
00489
00490
00491 rank = blkOrthoSing( *tmpX, tmpMX, C, B, Q );
00492
00493
00494 MVT::MvAddMv( ONE, *tmpX, ZERO, *tmpX, X );
00495 if (this->_hasOp) {
00496 MVT::MvAddMv( ONE, *tmpMX, ZERO, *tmpMX, *MX );
00497 }
00498 }
00499 }
00500 }
00501
00502
00503 TEST_FOR_EXCEPTION( rank > xc || rank < 0, std::logic_error,
00504 "Belos::ICGSOrthoManager::projectAndNormalize(): Debug error in rank variable." );
00505
00506
00507 return rank;
00508 }
00509
00510
00511
00513
00514 template<class ScalarType, class MV, class OP>
00515 int ICGSOrthoManager<ScalarType, MV, OP>::normalize(
00516 MV &X, Teuchos::RCP<MV> MX,
00517 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B ) const {
00518
00519 Teuchos::TimeMonitor orthotimer(*timerOrtho_);
00520
00521
00522 return findBasis(X, MX, B, true);
00523 }
00524
00525
00526
00528 template<class ScalarType, class MV, class OP>
00529 void ICGSOrthoManager<ScalarType, MV, OP>::project(
00530 MV &X, Teuchos::RCP<MV> MX,
00531 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
00532 Teuchos::Array<Teuchos::RCP<const MV> > Q) const {
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548 Teuchos::TimeMonitor orthotimer(*timerOrtho_);
00549
00550 int xc = MVT::GetNumberVecs( X );
00551 int xr = MVT::GetVecLength( X );
00552 int nq = Q.length();
00553 std::vector<int> qcs(nq);
00554
00555 if (nq == 0 || xc == 0 || xr == 0) {
00556 return;
00557 }
00558 int qr = MVT::GetVecLength ( *Q[0] );
00559
00560
00561
00562 C.resize(nq);
00563
00564
00565
00566 if (this->_hasOp) {
00567 if (MX == Teuchos::null) {
00568
00569 MX = MVT::Clone(X,MVT::GetNumberVecs(X));
00570 OPT::Apply(*(this->_Op),X,*MX);
00571 }
00572 }
00573 else {
00574
00575 MX = Teuchos::rcp( &X, false );
00576 }
00577 int mxc = MVT::GetNumberVecs( *MX );
00578 int mxr = MVT::GetVecLength( *MX );
00579
00580
00581 TEST_FOR_EXCEPTION( xc<0 || xr<0 || mxc<0 || mxr<0, std::invalid_argument,
00582 "Belos::ICGSOrthoManager::project(): MVT returned negative dimensions for X,MX" );
00583
00584 TEST_FOR_EXCEPTION( xc!=mxc || xr!=mxr || xr!=qr, std::invalid_argument,
00585 "Belos::ICGSOrthoManager::project(): Size of X not consistant with MX,Q" );
00586
00587
00588 int baslen = 0;
00589 for (int i=0; i<nq; i++) {
00590 TEST_FOR_EXCEPTION( MVT::GetVecLength( *Q[i] ) != qr, std::invalid_argument,
00591 "Belos::ICGSOrthoManager::project(): Q lengths not mutually consistant" );
00592 qcs[i] = MVT::GetNumberVecs( *Q[i] );
00593 TEST_FOR_EXCEPTION( qr < qcs[i], std::invalid_argument,
00594 "Belos::ICGSOrthoManager::project(): Q has less rows than columns" );
00595 baslen += qcs[i];
00596
00597
00598 if ( C[i] == Teuchos::null ) {
00599 C[i] = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>(qcs[i],xc) );
00600 }
00601 else {
00602 TEST_FOR_EXCEPTION( C[i]->numRows() != qcs[i] || C[i]->numCols() != xc , std::invalid_argument,
00603 "Belos::ICGSOrthoManager::project(): Size of Q not consistant with size of C" );
00604 }
00605 }
00606
00607
00608 blkOrtho( X, MX, C, Q );
00609
00610 }
00611
00613
00614
00615 template<class ScalarType, class MV, class OP>
00616 int ICGSOrthoManager<ScalarType, MV, OP>::findBasis(
00617 MV &X, Teuchos::RCP<MV> MX,
00618 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
00619 bool completeBasis, int howMany ) const {
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636 Teuchos::TimeMonitor normTimer( *timerNorm_ );
00637
00638 const ScalarType ONE = SCT::one();
00639 const MagnitudeType ZERO = SCT::magnitude(SCT::zero());
00640
00641 int xc = MVT::GetNumberVecs( X );
00642 int xr = MVT::GetVecLength( X );
00643
00644 if (howMany == -1) {
00645 howMany = xc;
00646 }
00647
00648
00649
00650
00651
00652
00653
00654 if (this->_hasOp) {
00655 if (MX == Teuchos::null) {
00656
00657 MX = MVT::Clone(X,xc);
00658 OPT::Apply(*(this->_Op),X,*MX);
00659 }
00660 }
00661
00662
00663
00664
00665 if ( B == Teuchos::null ) {
00666 B = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>(xc,xc) );
00667 }
00668
00669 int mxc = (this->_hasOp) ? MVT::GetNumberVecs( *MX ) : xc;
00670 int mxr = (this->_hasOp) ? MVT::GetVecLength( *MX ) : xr;
00671
00672
00673 TEST_FOR_EXCEPTION( xc == 0 || xr == 0, std::invalid_argument,
00674 "Belos::ICGSOrthoManager::findBasis(): X must be non-empty" );
00675 TEST_FOR_EXCEPTION( B->numRows() != xc || B->numCols() != xc, std::invalid_argument,
00676 "Belos::ICGSOrthoManager::findBasis(): Size of X not consistant with size of B" );
00677 TEST_FOR_EXCEPTION( xc != mxc || xr != mxr, std::invalid_argument,
00678 "Belos::ICGSOrthoManager::findBasis(): Size of X not consistant with size of MX" );
00679 TEST_FOR_EXCEPTION( xc > xr, std::invalid_argument,
00680 "Belos::ICGSOrthoManager::findBasis(): Size of X not feasible for normalization" );
00681 TEST_FOR_EXCEPTION( howMany < 0 || howMany > xc, std::invalid_argument,
00682 "Belos::ICGSOrthoManager::findBasis(): Invalid howMany parameter" );
00683
00684
00685
00686
00687 int xstart = xc - howMany;
00688
00689 for (int j = xstart; j < xc; j++) {
00690
00691
00692
00693
00694 int numX = j;
00695 bool addVec = false;
00696
00697
00698 std::vector<int> index(1);
00699 index[0] = numX;
00700 Teuchos::RCP<MV> Xj = MVT::CloneView( X, index );
00701 Teuchos::RCP<MV> MXj;
00702 if ((this->_hasOp)) {
00703
00704 MXj = MVT::CloneView( *MX, index );
00705 }
00706 else {
00707
00708 MXj = Xj;
00709 }
00710
00711
00712 std::vector<int> prev_idx( numX );
00713 Teuchos::RCP<const MV> prevX, prevMX;
00714
00715 if (numX > 0) {
00716 for (int i=0; i<numX; i++) {
00717 prev_idx[i] = i;
00718 }
00719 prevX = MVT::CloneView( X, prev_idx );
00720 if (this->_hasOp) {
00721 prevMX = MVT::CloneView( *MX, prev_idx );
00722 }
00723 }
00724
00725
00726 Teuchos::SerialDenseMatrix<int,ScalarType> product(numX, 1);
00727 std::vector<ScalarType> oldDot( 1 ), newDot( 1 );
00728
00729
00730
00731 Teuchos::RCP<MV> oldMXj = MVT::CloneCopy( *MXj );
00732 MVT::MvDot( *Xj, *MXj, oldDot );
00733
00734 TEST_FOR_EXCEPTION( SCT::real(oldDot[0]) < ZERO, OrthoError,
00735 "Belos::ICGSOrthoManager::findBasis(): Negative definiteness discovered in inner product" );
00736
00737 if (numX > 0) {
00738
00739 Teuchos::SerialDenseMatrix<int,ScalarType> P2(numX,1);
00740
00741 for (int i=0; i<max_ortho_steps_; ++i) {
00742
00743
00744 {
00745 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
00746 innerProd(*prevX,*Xj,MXj,P2);
00747 }
00748
00749
00750
00751 {
00752 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
00753 MVT::MvTimesMatAddMv( -ONE, *prevX, P2, ONE, *Xj );
00754 }
00755
00756
00757 if (this->_hasOp) {
00758
00759
00760
00761 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
00762 MVT::MvTimesMatAddMv( -ONE, *prevMX, P2, ONE, *MXj );
00763 }
00764
00765
00766 if ( i==0 )
00767 product = P2;
00768 else
00769 product += P2;
00770 }
00771
00772 }
00773
00774
00775 MVT::MvDot( *Xj, *oldMXj, newDot );
00776
00777
00778 if (completeBasis) {
00779
00780
00781
00782 if ( SCT::magnitude(newDot[0]) < SCT::magnitude(sing_tol_*oldDot[0]) ) {
00783
00784
00785 addVec = true;
00786 #ifdef ORTHO_DEBUG
00787 std::cout << "Belos::ICGSOrthoManager::findBasis() --> Random for column " << numX << std::endl;
00788 #endif
00789
00790 Teuchos::RCP<MV> tempXj = MVT::Clone( X, 1 );
00791 Teuchos::RCP<MV> tempMXj;
00792 MVT::MvRandom( *tempXj );
00793 if (this->_hasOp) {
00794 tempMXj = MVT::Clone( X, 1 );
00795 OPT::Apply( *(this->_Op), *tempXj, *tempMXj );
00796 }
00797 else {
00798 tempMXj = tempXj;
00799 }
00800 MVT::MvDot( *tempXj, *tempMXj, oldDot );
00801
00802 for (int num_orth=0; num_orth<max_ortho_steps_; num_orth++){
00803 {
00804 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
00805 innerProd(*prevX,*tempXj,tempMXj,product);
00806 }
00807 {
00808 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
00809 MVT::MvTimesMatAddMv( -ONE, *prevX, product, ONE, *tempXj );
00810 }
00811 if (this->_hasOp) {
00812 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
00813 MVT::MvTimesMatAddMv( -ONE, *prevMX, product, ONE, *tempMXj );
00814 }
00815 }
00816
00817 MVT::MvDot( *tempXj, *tempMXj, newDot );
00818
00819 if ( SCT::magnitude(newDot[0]) >= SCT::magnitude(oldDot[0]*sing_tol_) ) {
00820
00821 MVT::MvAddMv( ONE, *tempXj, ZERO, *tempXj, *Xj );
00822 if (this->_hasOp) {
00823 MVT::MvAddMv( ONE, *tempMXj, ZERO, *tempMXj, *MXj );
00824 }
00825 }
00826 else {
00827 return numX;
00828 }
00829 }
00830 }
00831 else {
00832
00833
00834
00835 if ( SCT::magnitude(newDot[0]) < SCT::magnitude(oldDot[0]*blk_tol_) ) {
00836 return numX;
00837 }
00838 }
00839
00840
00841
00842
00843 ScalarType diag = SCT::squareroot(SCT::magnitude(newDot[0]));
00844 {
00845 MVT::MvAddMv( ONE/diag, *Xj, ZERO, *Xj, *Xj );
00846 if (this->_hasOp) {
00847
00848 MVT::MvAddMv( ONE/diag, *MXj, ZERO, *MXj, *MXj );
00849 }
00850 }
00851
00852
00853 if (addVec) {
00854 (*B)(j,j) = ZERO;
00855 }
00856 else {
00857 (*B)(j,j) = diag;
00858 }
00859
00860
00861 if (!addVec) {
00862 for (int i=0; i<numX; i++) {
00863 (*B)(i,j) = product(i,0);
00864 }
00865 }
00866
00867 }
00868
00869 return xc;
00870 }
00871
00873
00874 template<class ScalarType, class MV, class OP>
00875 bool
00876 ICGSOrthoManager<ScalarType, MV, OP>::blkOrtho1 ( MV &X, Teuchos::RCP<MV> MX,
00877 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
00878 Teuchos::Array<Teuchos::RCP<const MV> > Q) const
00879 {
00880 int nq = Q.length();
00881 int xc = MVT::GetNumberVecs( X );
00882 const ScalarType ONE = SCT::one();
00883
00884 std::vector<int> qcs( nq );
00885 for (int i=0; i<nq; i++) {
00886 qcs[i] = MVT::GetNumberVecs( *Q[i] );
00887 }
00888
00889
00890
00891 Teuchos::Array<Teuchos::RCP<MV> > MQ(nq);
00892
00893 for (int i=0; i<nq; i++) {
00894
00895 {
00896 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
00897 innerProd(*Q[i],X,MX,*C[i]);
00898 }
00899
00900 {
00901 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
00902 MVT::MvTimesMatAddMv( -ONE, *Q[i], *C[i], ONE, X );
00903 }
00904
00905
00906 if (this->_hasOp) {
00907 if (xc <= qcs[i]) {
00908 OPT::Apply( *(this->_Op), X, *MX);
00909 }
00910 else {
00911
00912 MQ[i] = MVT::Clone( *Q[i], qcs[i] );
00913 OPT::Apply( *(this->_Op), *Q[i], *MQ[i] );
00914 MVT::MvTimesMatAddMv( -ONE, *MQ[i], *C[i], ONE, *MX );
00915 }
00916 }
00917 }
00918
00919
00920 for (int j = 1; j < max_ortho_steps_; ++j) {
00921
00922 for (int i=0; i<nq; i++) {
00923 Teuchos::SerialDenseMatrix<int,ScalarType> C2(*C[i]);
00924
00925
00926 {
00927 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
00928 innerProd(*Q[i],X,MX,C2);
00929 }
00930 *C[i] += C2;
00931 {
00932 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
00933 MVT::MvTimesMatAddMv( -ONE, *Q[i], C2, ONE, X );
00934 }
00935
00936
00937 if (this->_hasOp) {
00938 if (MQ[i].get()) {
00939
00940 MVT::MvTimesMatAddMv( -ONE, *MQ[i], C2, ONE, *MX );
00941 }
00942 else if (xc <= qcs[i]) {
00943
00944 OPT::Apply( *(this->_Op), X, *MX);
00945 }
00946 }
00947 }
00948 }
00949
00950 return false;
00951 }
00952
00954
00955 template<class ScalarType, class MV, class OP>
00956 bool
00957 ICGSOrthoManager<ScalarType, MV, OP>::blkOrtho ( MV &X, Teuchos::RCP<MV> MX,
00958 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
00959 Teuchos::Array<Teuchos::RCP<const MV> > Q) const
00960 {
00961 int nq = Q.length();
00962 int xc = MVT::GetNumberVecs( X );
00963 bool dep_flg = false;
00964 const ScalarType ONE = SCT::one();
00965
00966 std::vector<int> qcs( nq );
00967 for (int i=0; i<nq; i++) {
00968 qcs[i] = MVT::GetNumberVecs( *Q[i] );
00969 }
00970
00971
00972
00973
00974 std::vector<ScalarType> oldDot( xc );
00975 MVT::MvDot( X, *MX, oldDot );
00976
00977 Teuchos::Array<Teuchos::RCP<MV> > MQ(nq);
00978
00979 for (int i=0; i<nq; i++) {
00980
00981 {
00982 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
00983 innerProd(*Q[i],X,MX,*C[i]);
00984 }
00985
00986 {
00987 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
00988 MVT::MvTimesMatAddMv( -ONE, *Q[i], *C[i], ONE, X );
00989 }
00990
00991 if (this->_hasOp) {
00992 if (xc <= qcs[i]) {
00993 OPT::Apply( *(this->_Op), X, *MX);
00994 }
00995 else {
00996
00997 MQ[i] = MVT::Clone( *Q[i], qcs[i] );
00998 OPT::Apply( *(this->_Op), *Q[i], *MQ[i] );
00999 MVT::MvTimesMatAddMv( -ONE, *MQ[i], *C[i], ONE, *MX );
01000 }
01001 }
01002 }
01003
01004
01005 for (int j = 1; j < max_ortho_steps_; ++j) {
01006
01007 for (int i=0; i<nq; i++) {
01008 Teuchos::SerialDenseMatrix<int,ScalarType> C2(*C[i]);
01009
01010
01011 {
01012 Teuchos::TimeMonitor innerProdTimer( *timerInnerProd_ );
01013 innerProd(*Q[i],X,MX,C2);
01014 }
01015 *C[i] += C2;
01016 {
01017 Teuchos::TimeMonitor updateTimer( *timerUpdate_ );
01018 MVT::MvTimesMatAddMv( -ONE, *Q[i], C2, ONE, X );
01019 }
01020
01021
01022 if (this->_hasOp) {
01023 if (MQ[i].get()) {
01024
01025 MVT::MvTimesMatAddMv( -ONE, *MQ[i], C2, ONE, *MX );
01026 }
01027 else if (xc <= qcs[i]) {
01028
01029 OPT::Apply( *(this->_Op), X, *MX);
01030 }
01031 }
01032 }
01033 }
01034
01035
01036 std::vector<ScalarType> newDot(xc);
01037 MVT::MvDot( X, *MX, newDot );
01038
01039
01040 for (int i=0; i<xc; i++){
01041 if (SCT::magnitude(newDot[i]) < SCT::magnitude(oldDot[i] * blk_tol_)) {
01042 dep_flg = true;
01043 break;
01044 }
01045 }
01046
01047 return dep_flg;
01048 }
01049
01051
01052 template<class ScalarType, class MV, class OP>
01053 int
01054 ICGSOrthoManager<ScalarType, MV, OP>::blkOrthoSing ( MV &X, Teuchos::RCP<MV> MX,
01055 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
01056 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
01057 Teuchos::Array<Teuchos::RCP<const MV> > Q) const
01058 {
01059 const ScalarType ONE = SCT::one();
01060 const ScalarType ZERO = SCT::zero();
01061
01062 int nq = Q.length();
01063 int xc = MVT::GetNumberVecs( X );
01064 std::vector<int> indX( 1 );
01065 std::vector<ScalarType> oldDot( 1 ), newDot( 1 );
01066
01067 std::vector<int> qcs( nq );
01068 for (int i=0; i<nq; i++) {
01069 qcs[i] = MVT::GetNumberVecs( *Q[i] );
01070 }
01071
01072
01073 Teuchos::RCP<const MV> lastQ;
01074 Teuchos::RCP<MV> Xj, MXj;
01075 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > lastC;
01076
01077
01078 for (int j=0; j<xc; j++) {
01079
01080 bool dep_flg = false;
01081
01082
01083 if (j > 0) {
01084 std::vector<int> index( j );
01085 for (int ind=0; ind<j; ind++) {
01086 index[ind] = ind;
01087 }
01088 lastQ = MVT::CloneView( X, index );
01089
01090
01091 Q.push_back( lastQ );
01092 C.push_back( B );
01093 qcs.push_back( MVT::GetNumberVecs( *lastQ ) );
01094 }
01095
01096
01097 indX[0] = j;
01098 Xj = MVT::CloneView( X, indX );
01099 if (this->_hasOp) {
01100 MXj = MVT::CloneView( *MX, indX );
01101 }
01102 else {
01103 MXj = Xj;
01104 }
01105
01106
01107 MVT::MvDot( *Xj, *MXj, oldDot );
01108
01109 Teuchos::Array<Teuchos::RCP<MV> > MQ(Q.length());
01110
01111 for (int i=0; i<Q.length(); i++) {
01112
01113
01114 Teuchos::SerialDenseMatrix<int,ScalarType> tempC( Teuchos::View, *C[i], qcs[i], 1, 0, j );
01115
01116
01117 innerProd(*Q[i],*Xj,MXj,tempC);
01118
01119 MVT::MvTimesMatAddMv( -ONE, *Q[i], tempC, ONE, *Xj );
01120
01121
01122 if (this->_hasOp) {
01123 if (xc <= qcs[i]) {
01124 OPT::Apply( *(this->_Op), *Xj, *MXj);
01125 }
01126 else {
01127
01128 MQ[i] = MVT::Clone( *Q[i], qcs[i] );
01129 OPT::Apply( *(this->_Op), *Q[i], *MQ[i] );
01130 MVT::MvTimesMatAddMv( -ONE, *MQ[i], tempC, ONE, *MXj );
01131 }
01132 }
01133 }
01134
01135
01136 for (int num_ortho_steps=1; num_ortho_steps < max_ortho_steps_; ++num_ortho_steps) {
01137
01138 for (int i=0; i<Q.length(); i++) {
01139 Teuchos::SerialDenseMatrix<int,ScalarType> tempC( Teuchos::View, *C[i], qcs[i], 1, 0, j );
01140 Teuchos::SerialDenseMatrix<int,ScalarType> C2( qcs[i], 1 );
01141
01142
01143 innerProd(*Q[i],*Xj,MXj,C2);
01144 tempC += C2;
01145 MVT::MvTimesMatAddMv( -ONE, *Q[i], C2, ONE, *Xj );
01146
01147
01148 if (this->_hasOp) {
01149 if (MQ[i].get()) {
01150
01151 MVT::MvTimesMatAddMv( -ONE, *MQ[i], C2, ONE, *MXj );
01152 }
01153 else if (xc <= qcs[i]) {
01154
01155 OPT::Apply( *(this->_Op), *Xj, *MXj);
01156 }
01157 }
01158 }
01159
01160 }
01161
01162
01163 if (SCT::magnitude(newDot[0]) < SCT::magnitude(oldDot[0]*sing_tol_)) {
01164 dep_flg = true;
01165 }
01166
01167
01168 if (!dep_flg) {
01169 ScalarType diag = SCT::squareroot(SCT::magnitude(newDot[0]));
01170
01171 MVT::MvAddMv( ONE/diag, *Xj, ZERO, *Xj, *Xj );
01172 if (this->_hasOp) {
01173
01174 MVT::MvAddMv( ONE/diag, *MXj, ZERO, *MXj, *MXj );
01175 }
01176
01177
01178 (*B)(j,j) = diag;
01179 }
01180 else {
01181
01182 Teuchos::RCP<MV> tempXj = MVT::Clone( X, 1 );
01183 Teuchos::RCP<MV> tempMXj;
01184 MVT::MvRandom( *tempXj );
01185 if (this->_hasOp) {
01186 tempMXj = MVT::Clone( X, 1 );
01187 OPT::Apply( *(this->_Op), *tempXj, *tempMXj );
01188 }
01189 else {
01190 tempMXj = tempXj;
01191 }
01192 MVT::MvDot( *tempXj, *tempMXj, oldDot );
01193
01194 for (int num_orth=0; num_orth<max_ortho_steps_; num_orth++) {
01195
01196 for (int i=0; i<Q.length(); i++) {
01197 Teuchos::SerialDenseMatrix<int,ScalarType> product( qcs[i], 1 );
01198
01199
01200 innerProd(*Q[i],*tempXj,tempMXj,product);
01201 MVT::MvTimesMatAddMv( -ONE, *Q[i], product, ONE, *tempXj );
01202
01203
01204 if (this->_hasOp) {
01205 if (MQ[i].get()) {
01206
01207 MVT::MvTimesMatAddMv( -ONE, *MQ[i], product, ONE, *tempMXj );
01208 }
01209 else if (xc <= qcs[i]) {
01210
01211 OPT::Apply( *(this->_Op), *tempXj, *tempMXj);
01212 }
01213 }
01214 }
01215
01216 }
01217
01218
01219 MVT::MvDot( *tempXj, *tempMXj, newDot );
01220
01221
01222 if ( SCT::magnitude(newDot[0]) >= SCT::magnitude(oldDot[0]*sing_tol_) ) {
01223 ScalarType diag = SCT::squareroot(SCT::magnitude(newDot[0]));
01224
01225
01226 (*B)(j,j) = ZERO;
01227
01228
01229 MVT::MvAddMv( ONE/diag, *tempXj, ZERO, *tempXj, *Xj );
01230 if (this->_hasOp) {
01231 MVT::MvAddMv( ONE/diag, *tempMXj, ZERO, *tempMXj, *MXj );
01232 }
01233 }
01234 else {
01235 return j;
01236 }
01237 }
01238
01239
01240 if (j > 0) {
01241 Q.resize( nq );
01242 C.resize( nq );
01243 qcs.resize( nq );
01244 }
01245
01246 }
01247
01248 return xc;
01249 }
01250
01251 }
01252
01253 #endif // BELOS_ICGS_ORTHOMANAGER_HPP
01254