00001
00002
00003
00004 #ifndef ANASAZI_IRTR_HPP
00005 #define ANASAZI_IRTR_HPP
00006
00007 #include "AnasaziTypes.hpp"
00008 #include "AnasaziRTRBase.hpp"
00009
00010 #include "AnasaziEigensolver.hpp"
00011 #include "AnasaziMultiVecTraits.hpp"
00012 #include "AnasaziOperatorTraits.hpp"
00013 #include "Teuchos_ScalarTraits.hpp"
00014
00015 #include "Teuchos_LAPACK.hpp"
00016 #include "Teuchos_BLAS.hpp"
00017 #include "Teuchos_SerialDenseMatrix.hpp"
00018 #include "Teuchos_ParameterList.hpp"
00019 #include "Teuchos_TimeMonitor.hpp"
00020
00040
00041
00042
00043 namespace Anasazi {
00044
00045 template <class ScalarType, class MV, class OP>
00046 class IRTR : public RTRBase<ScalarType,MV,OP> {
00047 public:
00048
00050
00051
00063 IRTR( const Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > &problem,
00064 const Teuchos::RCP<SortManager<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > &sorter,
00065 const Teuchos::RCP<OutputManager<ScalarType> > &printer,
00066 const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > &tester,
00067 const Teuchos::RCP<GenOrthoManager<ScalarType,MV,OP> > &ortho,
00068 Teuchos::ParameterList ¶ms
00069 );
00070
00072 virtual ~IRTR() {};
00073
00075
00077
00078
00080 void iterate();
00081
00083
00085
00086
00088 void currentStatus(std::ostream &os);
00089
00091
00092 private:
00093
00094
00095
00096 typedef SolverUtils<ScalarType,MV,OP> Utils;
00097 typedef MultiVecTraits<ScalarType,MV> MVT;
00098 typedef OperatorTraits<ScalarType,MV,OP> OPT;
00099 typedef Teuchos::ScalarTraits<ScalarType> SCT;
00100 typedef typename SCT::magnitudeType MagnitudeType;
00101 typedef Teuchos::ScalarTraits<MagnitudeType> MAT;
00102 enum trRetType {
00103 UNINITIALIZED = 0,
00104 MAXIMUM_ITERATIONS,
00105 NEGATIVE_CURVATURE,
00106 EXCEEDED_TR,
00107 KAPPA_CONVERGENCE,
00108 THETA_CONVERGENCE
00109 };
00110
00111 std::vector<std::string> stopReasons_;
00112
00113
00114
00115 const MagnitudeType ZERO;
00116 const MagnitudeType ONE;
00117
00118
00119
00121 void solveTRSubproblem();
00122
00123
00124 MagnitudeType rho_prime_;
00125
00126
00127 MagnitudeType normgradf0_;
00128
00129
00130 trRetType innerStop_;
00131
00132
00133 int innerIters_, totalInnerIters_;
00134
00135
00136 bool useSA_;
00137 };
00138
00139
00140
00141
00143
00144 template <class ScalarType, class MV, class OP>
00145 IRTR<ScalarType,MV,OP>::IRTR(
00146 const Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > &problem,
00147 const Teuchos::RCP<SortManager<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > &sorter,
00148 const Teuchos::RCP<OutputManager<ScalarType> > &printer,
00149 const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > &tester,
00150 const Teuchos::RCP<GenOrthoManager<ScalarType,MV,OP> > &ortho,
00151 Teuchos::ParameterList ¶ms
00152 ) :
00153 RTRBase<ScalarType,MV,OP>(problem,sorter,printer,tester,ortho,params,"IRTR",false),
00154 ZERO(MAT::zero()),
00155 ONE(MAT::one()),
00156 totalInnerIters_(0)
00157 {
00158
00159 stopReasons_.push_back("n/a");
00160 stopReasons_.push_back("maximum iterations");
00161 stopReasons_.push_back("negative curvature");
00162 stopReasons_.push_back("exceeded TR");
00163 stopReasons_.push_back("kappa convergence");
00164 stopReasons_.push_back("theta convergence");
00165
00166 rho_prime_ = params.get("Rho Prime",0.5);
00167 TEST_FOR_EXCEPTION(rho_prime_ <= 0 || rho_prime_ >= 1,std::invalid_argument,
00168 "Anasazi::IRTR::constructor: rho_prime must be in (0,1).");
00169
00170 useSA_ = params.get<bool>("Use SA",false);
00171 }
00172
00173
00175
00176
00177
00178
00179
00180
00181
00182
00183 template <class ScalarType, class MV, class OP>
00184 void IRTR<ScalarType,MV,OP>::solveTRSubproblem() {
00185
00186
00187
00188
00189
00190
00191
00192
00193 using Teuchos::RCP;
00194 using Teuchos::tuple;
00195 using Teuchos::null;
00196 using Teuchos::TimeMonitor;
00197 using std::endl;
00198 typedef Teuchos::RCP<const MV> PCMV;
00199 typedef Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > PSDM;
00200
00201 innerStop_ = MAXIMUM_ITERATIONS;
00202
00203 const int n = MVT::GetVecLength(*this->eta_);
00204 const int p = this->blockSize_;
00205 const int d = n*p - (p*p+p)/2;
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 const double D2 = ONE/rho_prime_ - ONE;
00220
00221 std::vector<MagnitudeType> d_Hd(p), alpha(p), beta(p), z_r(p), zold_rold(p);
00222 std::vector<MagnitudeType> eBe(p), eBd(p), dBd(p), new_eBe(p);
00223 MagnitudeType r0_norm;
00224
00225 MVT::MvInit(*this->eta_ ,0.0);
00226 MVT::MvInit(*this->Aeta_,0.0);
00227 if (this->hasBOp_) {
00228 MVT::MvInit(*this->Beta_,0.0);
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 {
00244 TimeMonitor lcltimer( *this->timerOrtho_ );
00245 this->orthman_->projectGen(
00246 *this->R_,
00247 tuple<PCMV>(this->BV_),tuple<PCMV>(this->V_),false,
00248 tuple<PSDM>(null),
00249 null,tuple<PCMV>(null), tuple<PCMV>(this->BV_));
00250 if (this->leftMost_) {
00251 MVT::MvScale(*this->R_,2.0);
00252 }
00253 else {
00254 MVT::MvScale(*this->R_,-2.0);
00255 }
00256 }
00257
00258 r0_norm = MAT::squareroot( ginner(*this->R_) );
00259
00260
00261
00262
00263 MagnitudeType kconv = r0_norm * this->conv_kappa_;
00264
00265
00266 MagnitudeType tconv = MAT::pow(r0_norm,this->conv_theta_+ONE);
00267 if (this->om_->isVerbosity(Debug)) {
00268 this->om_->stream(Debug)
00269 << " >> |r0| : " << r0_norm << endl
00270 << " >> kappa conv : " << kconv << endl
00271 << " >> theta conv : " << tconv << endl;
00272 }
00273
00274
00275
00276
00277
00278
00279 if (this->hasPrec_ && this->olsenPrec_)
00280 {
00281 std::vector<int> ind(this->blockSize_);
00282 for (int i=0; i<this->blockSize_; ++i) ind[i] = this->numAuxVecs_+i;
00283 Teuchos::RCP<MV> PBX = MVT::CloneViewNonConst(*this->PBV_,ind);
00284 {
00285 TimeMonitor prectimer( *this->timerPrec_ );
00286 OPT::Apply(*this->Prec_,*this->BX_,*PBX);
00287 this->counterPrec_ += this->blockSize_;
00288 }
00289 PBX = Teuchos::null;
00290 }
00291
00292
00293
00294
00295
00296 if (this->hasPrec_)
00297 {
00298 TimeMonitor prectimer( *this->timerPrec_ );
00299 OPT::Apply(*this->Prec_,*this->R_,*this->Z_);
00300 this->counterPrec_ += this->blockSize_;
00301
00302 if (this->olsenPrec_) {
00303 TimeMonitor orthtimer( *this->timerOrtho_ );
00304 this->orthman_->projectGen(
00305 *this->Z_,
00306 tuple<PCMV>(this->PBV_),tuple<PCMV>(this->V_),false,
00307 tuple<PSDM>(null),
00308 null,tuple<PCMV>(null), tuple<PCMV>(this->BV_));
00309 }
00310 else {
00311 TimeMonitor orthtimer( *this->timerOrtho_ );
00312 this->orthman_->projectGen(
00313 *this->Z_,
00314 tuple<PCMV>(this->BV_),tuple<PCMV>(this->V_),false,
00315 tuple<PSDM>(null),
00316 null,tuple<PCMV>(null), tuple<PCMV>(this->BV_));
00317 }
00318 ginnersep(*this->R_,*this->Z_,z_r);
00319 }
00320 else {
00321 ginnersep(*this->R_,z_r);
00322 }
00323
00324 if (this->om_->isVerbosity( Debug )) {
00325
00326 typename RTRBase<ScalarType,MV,OP>::CheckList chk;
00327 chk.checkBR = true;
00328 if (this->hasPrec_) chk.checkZ = true;
00329 this->om_->print( Debug, this->accuracyCheck(chk, "after computing gradient") );
00330 }
00331 else if (this->om_->isVerbosity( OrthoDetails )) {
00332
00333 typename RTRBase<ScalarType,MV,OP>::CheckList chk;
00334 chk.checkBR = true;
00335 if (this->hasPrec_) chk.checkZ = true;
00336 this->om_->print( OrthoDetails, this->accuracyCheck(chk, "after computing gradient") );
00337 }
00338
00339
00340 MVT::MvAddMv(-ONE,*this->Z_,ZERO,*this->Z_,*this->delta_);
00341
00342 if (this->om_->isVerbosity(Debug)) {
00343 RCP<MV> Heta = MVT::Clone(*this->eta_,this->blockSize_);
00344
00345 MVT::MvAddMv(ONE,*this->Beta_,ZERO,*this->Beta_,*Heta);
00346 std::vector<ScalarType> theta_comp(this->theta_.begin(),this->theta_.end());
00347 MVT::MvScale(*Heta,theta_comp);
00348 if (this->leftMost_) {
00349 MVT::MvAddMv( 2.0,*this->Aeta_,-2.0,*Heta,*Heta);
00350 }
00351 else {
00352 MVT::MvAddMv(-2.0,*this->Aeta_, 2.0,*Heta,*Heta);
00353 }
00354
00355 {
00356 TimeMonitor lcltimer( *this->timerOrtho_ );
00357 this->orthman_->projectGen(
00358 *Heta,
00359 tuple<PCMV>(this->BV_),tuple<PCMV>(this->V_),false,
00360 tuple<PSDM>(null),
00361 null,tuple<PCMV>(null), tuple<PCMV>(this->BV_));
00362 }
00363
00364 std::vector<MagnitudeType> eg(this->blockSize_),
00365 eHe(this->blockSize_);
00366 ginnersep(*this->eta_,*this->AX_,eg);
00367 ginnersep(*this->eta_,*Heta,eHe);
00368 if (this->leftMost_) {
00369 for (int j=0; j<this->blockSize_; ++j) {
00370 eg[j] = this->theta_[j] + 2*eg[j] + .5*eHe[j];
00371 }
00372 }
00373 else {
00374 for (int j=0; j<this->blockSize_; ++j) {
00375 eg[j] = -this->theta_[j] - 2*eg[j] + .5*eHe[j];
00376 }
00377 }
00378 this->om_->stream(Debug)
00379 << " Debugging checks: IRTR inner iteration " << innerIters_ << endl
00380 << " >> m_X(eta) : " << std::accumulate(eg.begin(),eg.end(),0.0) << endl;
00381 for (int j=0; j<this->blockSize_; ++j) {
00382 this->om_->stream(Debug)
00383 << " >> m_X(eta_" << j << ") : " << eg[j] << endl;
00384 }
00385 }
00386
00389
00390 for (innerIters_=1; innerIters_<=d; ++innerIters_) {
00391
00392
00393
00394
00395
00396
00397 {
00398 TimeMonitor lcltimer( *this->timerAOp_ );
00399 OPT::Apply(*this->AOp_,*this->delta_,*this->Adelta_);
00400 this->counterAOp_ += this->blockSize_;
00401 }
00402 if (this->hasBOp_) {
00403 TimeMonitor lcltimer( *this->timerBOp_ );
00404 OPT::Apply(*this->BOp_,*this->delta_,*this->Bdelta_);
00405 this->counterBOp_ += this->blockSize_;
00406 }
00407 else {
00408 MVT::MvAddMv(ONE,*this->delta_,ZERO,*this->delta_,*this->Bdelta_);
00409 }
00410
00411
00412 ginnersep(*this->eta_ ,*this->Bdelta_,eBd);
00413 ginnersep(*this->delta_,*this->Bdelta_,dBd);
00414
00415 MVT::MvAddMv(ONE,*this->Bdelta_,ZERO,*this->Bdelta_,*this->Hdelta_);
00416 {
00417 std::vector<ScalarType> theta_comp(this->theta_.begin(),this->theta_.end());
00418 MVT::MvScale(*this->Hdelta_,theta_comp);
00419 }
00420 if (this->leftMost_) {
00421 MVT::MvAddMv( 2.0,*this->Adelta_,-2.0,*this->Hdelta_,*this->Hdelta_);
00422 }
00423 else {
00424 MVT::MvAddMv(-2.0,*this->Adelta_, 2.0,*this->Hdelta_,*this->Hdelta_);
00425 }
00426
00427 {
00428 TimeMonitor lcltimer( *this->timerOrtho_ );
00429 this->orthman_->projectGen(
00430 *this->Hdelta_,
00431 tuple<PCMV>(this->BV_),tuple<PCMV>(this->V_),false,
00432 tuple<PSDM>(null),
00433 null,tuple<PCMV>(null), tuple<PCMV>(this->BV_));
00434 }
00435 ginnersep(*this->delta_,*this->Hdelta_,d_Hd);
00436
00437
00438
00439 for (unsigned int j=0; j<alpha.size(); ++j)
00440 {
00441 alpha[j] = z_r[j]/d_Hd[j];
00442 }
00443
00444
00445 for (unsigned int j=0; j<alpha.size(); ++j)
00446 {
00447 new_eBe[j] = eBe[j] + 2*alpha[j]*eBd[j] + alpha[j]*alpha[j]*dBd[j];
00448 }
00449
00450 if (this->om_->isVerbosity(Debug)) {
00451 for (unsigned int j=0; j<alpha.size(); j++) {
00452 this->om_->stream(Debug)
00453 << " >> z_r[" << j << "] : " << z_r[j]
00454 << " d_Hd[" << j << "] : " << d_Hd[j] << endl
00455 << " >> eBe[" << j << "] : " << eBe[j]
00456 << " neweBe[" << j << "] : " << new_eBe[j] << endl
00457 << " >> eBd[" << j << "] : " << eBd[j]
00458 << " dBd[" << j << "] : " << dBd[j] << endl;
00459 }
00460 }
00461
00462
00463 std::vector<int> trncstep;
00464 trncstep.reserve(p);
00465
00466
00467 bool atleastonenegcur = false;
00468 for (unsigned int j=0; j<d_Hd.size(); ++j) {
00469 if (d_Hd[j] <= 0) {
00470 trncstep.push_back(j);
00471 atleastonenegcur = true;
00472 }
00473 else if (new_eBe[j] > D2) {
00474 trncstep.push_back(j);
00475 }
00476 }
00477
00478 if (!trncstep.empty())
00479 {
00480
00481 if (this->om_->isVerbosity(Debug)) {
00482 for (unsigned int j=0; j<trncstep.size(); ++j) {
00483 this->om_->stream(Debug)
00484 << " >> alpha[" << trncstep[j] << "] : " << alpha[trncstep[j]] << endl;
00485 }
00486 }
00487 for (unsigned int j=0; j<trncstep.size(); ++j) {
00488 int jj = trncstep[j];
00489 alpha[jj] = ( -eBd[jj] + MAT::squareroot(eBd[jj]*eBd[jj] + dBd[jj]*(D2-eBe[jj]) ) ) / dBd[jj];
00490 }
00491 if (this->om_->isVerbosity(Debug)) {
00492 for (unsigned int j=0; j<trncstep.size(); ++j) {
00493 this->om_->stream(Debug)
00494 << " >> tau[" << trncstep[j] << "] : " << alpha[trncstep[j]] << endl;
00495 }
00496 }
00497 if (atleastonenegcur) {
00498 innerStop_ = NEGATIVE_CURVATURE;
00499 }
00500 else {
00501 innerStop_ = EXCEEDED_TR;
00502 }
00503 }
00504
00505
00506
00507
00508
00509 {
00510 std::vector<ScalarType> alpha_comp(alpha.begin(),alpha.end());
00511 MVT::MvScale(*this->delta_,alpha_comp);
00512 MVT::MvScale(*this->Adelta_,alpha_comp);
00513 if (this->hasBOp_) {
00514 MVT::MvScale(*this->Bdelta_,alpha_comp);
00515 }
00516 MVT::MvScale(*this->Hdelta_,alpha_comp);
00517 }
00518 MVT::MvAddMv(ONE,*this->delta_ ,ONE,*this->eta_ ,*this->eta_);
00519 MVT::MvAddMv(ONE,*this->Adelta_,ONE,*this->Aeta_,*this->Aeta_);
00520 if (this->hasBOp_) {
00521 MVT::MvAddMv(ONE,*this->Bdelta_,ONE,*this->Beta_,*this->Beta_);
00522 }
00523
00524
00525 eBe = new_eBe;
00526
00527
00528
00529 if (this->om_->isVerbosity(Debug)) {
00530 RCP<MV> Heta = MVT::Clone(*this->eta_,this->blockSize_);
00531
00532 MVT::MvAddMv(ONE,*this->Beta_,ZERO,*this->Beta_,*Heta);
00533 {
00534 std::vector<ScalarType> theta_comp(this->theta_.begin(),this->theta_.end());
00535 MVT::MvScale(*Heta,theta_comp);
00536 }
00537 if (this->leftMost_) {
00538 MVT::MvAddMv( 2.0,*this->Aeta_,-2.0,*Heta,*Heta);
00539 }
00540 else {
00541 MVT::MvAddMv(-2.0,*this->Aeta_, 2.0,*Heta,*Heta);
00542 }
00543
00544 {
00545 TimeMonitor lcltimer( *this->timerOrtho_ );
00546 this->orthman_->projectGen(
00547 *Heta,
00548 tuple<PCMV>(this->BV_),tuple<PCMV>(this->V_),false,
00549 tuple<PSDM>(null),
00550 null,tuple<PCMV>(null), tuple<PCMV>(this->BV_));
00551 }
00552
00553 std::vector<MagnitudeType> eg(this->blockSize_),
00554 eHe(this->blockSize_);
00555 ginnersep(*this->eta_,*this->AX_,eg);
00556 ginnersep(*this->eta_,*Heta,eHe);
00557 if (this->leftMost_) {
00558 for (int j=0; j<this->blockSize_; ++j) {
00559 eg[j] = this->theta_[j] + 2*eg[j] + .5*eHe[j];
00560 }
00561 }
00562 else {
00563 for (int j=0; j<this->blockSize_; ++j) {
00564 eg[j] = -this->theta_[j] - 2*eg[j] + .5*eHe[j];
00565 }
00566 }
00567 this->om_->stream(Debug)
00568 << " Debugging checks: IRTR inner iteration " << innerIters_ << endl
00569 << " >> m_X(eta) : " << std::accumulate(eg.begin(),eg.end(),0.0) << endl;
00570 for (int j=0; j<this->blockSize_; ++j) {
00571 this->om_->stream(Debug)
00572 << " >> m_X(eta_" << j << ") : " << eg[j] << endl;
00573 }
00574 }
00575
00576
00577
00578 if (!trncstep.empty()) {
00579 break;
00580 }
00581
00582
00583
00584
00585
00586 MVT::MvAddMv(ONE,*this->Hdelta_,ONE,*this->R_,*this->R_);
00587 {
00588
00589 TimeMonitor lcltimer( *this->timerOrtho_ );
00590 this->orthman_->projectGen(
00591 *this->R_,
00592 tuple<PCMV>(this->BV_),tuple<PCMV>(this->V_),false,
00593 tuple<PSDM>(null),
00594 null,tuple<PCMV>(null), tuple<PCMV>(this->BV_));
00595 }
00596
00597
00598
00599 MagnitudeType r_norm = MAT::squareroot(ginner(*this->R_,*this->R_));
00600
00601
00602
00603
00604
00605
00606
00607 if (this->om_->isVerbosity(Debug)) {
00608 this->om_->stream(Debug)
00609 << " >> |r" << innerIters_ << "| : " << r_norm << endl;
00610 }
00611 if ( r_norm <= ANASAZI_MIN(tconv,kconv) ) {
00612 if (tconv <= kconv) {
00613 innerStop_ = THETA_CONVERGENCE;
00614 }
00615 else {
00616 innerStop_ = KAPPA_CONVERGENCE;
00617 }
00618 break;
00619 }
00620
00621
00622
00623
00624
00625 zold_rold = z_r;
00626 if (this->hasPrec_)
00627 {
00628 TimeMonitor prectimer( *this->timerPrec_ );
00629 OPT::Apply(*this->Prec_,*this->R_,*this->Z_);
00630 this->counterPrec_ += this->blockSize_;
00631
00632 if (this->olsenPrec_) {
00633 TimeMonitor orthtimer( *this->timerOrtho_ );
00634 this->orthman_->projectGen(
00635 *this->Z_,
00636 tuple<PCMV>(this->PBV_),tuple<PCMV>(this->V_),false,
00637 tuple<PSDM>(null),
00638 null,tuple<PCMV>(null), tuple<PCMV>(this->BV_));
00639 }
00640 else {
00641 TimeMonitor orthtimer( *this->timerOrtho_ );
00642 this->orthman_->projectGen(
00643 *this->Z_,
00644 tuple<PCMV>(this->BV_),tuple<PCMV>(this->V_),false,
00645 tuple<PSDM>(null),
00646 null,tuple<PCMV>(null), tuple<PCMV>(this->BV_));
00647 }
00648 ginnersep(*this->R_,*this->Z_,z_r);
00649 }
00650 else {
00651 ginnersep(*this->R_,z_r);
00652 }
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667 for (unsigned int j=0; j<beta.size(); ++j) {
00668 beta[j] = z_r[j]/(zold_rold[j]*alpha[j]);
00669 }
00670 {
00671 std::vector<ScalarType> beta_comp(beta.begin(),beta.end());
00672 MVT::MvScale(*this->delta_,beta_comp);
00673 }
00674 MVT::MvAddMv(-ONE,*this->Z_,ONE,*this->delta_,*this->delta_);
00675
00676 }
00677
00680 if (innerIters_ > d) innerIters_ = d;
00681
00682 this->om_->stream(Debug)
00683 << " >> stop reason is " << stopReasons_[innerStop_] << endl
00684 << endl;
00685
00686 }
00687
00688
00690
00691 template <class ScalarType, class MV, class OP>
00692 void IRTR<ScalarType,MV,OP>::iterate() {
00693
00694 using Teuchos::RCP;
00695 using Teuchos::null;
00696 using Teuchos::tuple;
00697 using Teuchos::TimeMonitor;
00698 using std::endl;
00699 typedef Teuchos::RCP<const MV> PCMV;
00700 typedef Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > PSDM;
00701
00702
00703
00704
00705 if (this->initialized_ == false) {
00706 this->initialize();
00707 }
00708
00709 Teuchos::SerialDenseMatrix<int,ScalarType> AA, BB, S;
00710 if (useSA_ == true) {
00711 AA.reshape(2*this->blockSize_,2*this->blockSize_);
00712 BB.reshape(2*this->blockSize_,2*this->blockSize_);
00713 S.reshape(2*this->blockSize_,2*this->blockSize_);
00714 }
00715 else {
00716 AA.reshape(this->blockSize_,this->blockSize_);
00717 BB.reshape(this->blockSize_,this->blockSize_);
00718 S.reshape(this->blockSize_,this->blockSize_);
00719 }
00720
00721
00722 innerIters_ = -1;
00723 innerStop_ = UNINITIALIZED;
00724
00725
00726 while (this->tester_->checkStatus(this) != Passed) {
00727
00728
00729 if (this->om_->isVerbosity(Debug)) {
00730 this->currentStatus( this->om_->stream(Debug) );
00731 }
00732 else if (this->om_->isVerbosity(IterationDetails)) {
00733 this->currentStatus( this->om_->stream(IterationDetails) );
00734 }
00735
00736
00737 this->iter_++;
00738
00739
00740 solveTRSubproblem();
00741 totalInnerIters_ += innerIters_;
00742
00743
00744 if (this->om_->isVerbosity( Debug ) ) {
00745 typename RTRBase<ScalarType,MV,OP>::CheckList chk;
00746
00747 chk.checkBR = true;
00748 chk.checkEta = true;
00749 chk.checkAEta = true;
00750 chk.checkBEta = true;
00751 this->om_->print( Debug, this->accuracyCheck(chk, "in iterate() after solveTRSubproblem()") );
00752 this->om_->stream(Debug)
00753 << " >> norm(Eta) : " << MAT::squareroot(ginner(*this->eta_)) << endl
00754 << endl;
00755 }
00756
00757 if (useSA_ == false) {
00758
00759
00760 {
00761 TimeMonitor lcltimer( *this->timerLocalUpdate_ );
00762 MVT::MvAddMv(ONE,*this->X_,ONE,*this->eta_,*this->delta_);
00763 MVT::MvAddMv(ONE,*this->AX_,ONE,*this->Aeta_,*this->Adelta_);
00764 if (this->hasBOp_) {
00765 MVT::MvAddMv(ONE,*this->BX_,ONE,*this->Beta_,*this->Bdelta_);
00766 }
00767 }
00768
00769 if (this->om_->isVerbosity( Debug ) ) {
00770
00771
00772
00773 Teuchos::SerialDenseMatrix<int,ScalarType> XE(this->blockSize_,this->blockSize_),
00774 E(this->blockSize_,this->blockSize_);
00775 MVT::MvTransMv(ONE,*this->delta_,*this->Bdelta_,XE);
00776 MVT::MvTransMv(ONE,*this->eta_,*this->Beta_,E);
00777 this->om_->stream(Debug)
00778 << " >> Error in AX+AEta == A(X+Eta) : " << Utils::errorEquality(*this->delta_,*this->Adelta_,this->AOp_) << endl
00779 << " >> Error in BX+BEta == B(X+Eta) : " << Utils::errorEquality(*this->delta_,*this->Bdelta_,this->BOp_) << endl
00780 << " >> norm( (X+Eta)^T B (X+Eta) ) : " << XE.normFrobenius() << endl
00781 << " >> norm( Eta^T B Eta ) : " << E.normFrobenius() << endl
00782 << endl;
00783 }
00784 }
00785
00786
00787
00788
00789
00790 MagnitudeType oldfx = this->fx_;
00791 std::vector<MagnitudeType> oldtheta(this->theta_), newtheta(AA.numRows());
00792 int rank, ret;
00793 rank = AA.numRows();
00794 if (useSA_ == true) {
00795 TimeMonitor lcltimer( *this->timerLocalProj_ );
00796 Teuchos::SerialDenseMatrix<int,ScalarType> AA11(Teuchos::View,AA,this->blockSize_,this->blockSize_,0,0),
00797 AA12(Teuchos::View,AA,this->blockSize_,this->blockSize_,0,this->blockSize_),
00798 AA22(Teuchos::View,AA,this->blockSize_,this->blockSize_,this->blockSize_,this->blockSize_);
00799 Teuchos::SerialDenseMatrix<int,ScalarType> BB11(Teuchos::View,BB,this->blockSize_,this->blockSize_,0,0),
00800 BB12(Teuchos::View,BB,this->blockSize_,this->blockSize_,0,this->blockSize_),
00801 BB22(Teuchos::View,BB,this->blockSize_,this->blockSize_,this->blockSize_,this->blockSize_);
00802 MVT::MvTransMv(ONE,*this->X_ ,*this->AX_ ,AA11);
00803 MVT::MvTransMv(ONE,*this->X_ ,*this->Aeta_,AA12);
00804 MVT::MvTransMv(ONE,*this->eta_,*this->Aeta_,AA22);
00805 MVT::MvTransMv(ONE,*this->X_ ,*this->BX_ ,BB11);
00806 MVT::MvTransMv(ONE,*this->X_ ,*this->Beta_,BB12);
00807 MVT::MvTransMv(ONE,*this->eta_,*this->Beta_,BB22);
00808 }
00809 else {
00810 TimeMonitor lcltimer( *this->timerLocalProj_ );
00811 MVT::MvTransMv(ONE,*this->delta_,*this->Adelta_,AA);
00812 MVT::MvTransMv(ONE,*this->delta_,*this->Bdelta_,BB);
00813 }
00814 this->om_->stream(Debug) << "AA: " << std::endl << AA << std::endl;;
00815 this->om_->stream(Debug) << "BB: " << std::endl << BB << std::endl;;
00816 {
00817 TimeMonitor lcltimer( *this->timerDS_ );
00818 ret = Utils::directSolver(AA.numRows(),AA,Teuchos::rcpFromRef(BB),S,newtheta,rank,1);
00819 }
00820 this->om_->stream(Debug) << "S: " << std::endl << S << std::endl;;
00821 TEST_FOR_EXCEPTION(ret != 0,std::logic_error,"Anasazi::IRTR::iterate(): failure solving projected eigenproblem after retraction. ret == " << ret);
00822 TEST_FOR_EXCEPTION(rank != AA.numRows(),RTRRitzFailure,"Anasazi::IRTR::iterate(): retracted iterate failed in Ritz analysis. rank == " << rank);
00823
00824
00825
00826
00827 {
00828 TimeMonitor lcltimer( *this->timerSort_ );
00829 std::vector<int> order(newtheta.size());
00830
00831 this->sm_->sort(newtheta, Teuchos::rcpFromRef(order), -1);
00832
00833 Utils::permuteVectors(order,S);
00834 }
00835
00836
00837 std::copy(newtheta.begin(), newtheta.begin()+this->blockSize_, this->theta_.begin());
00838
00839
00840 this->fx_ = std::accumulate(this->theta_.begin(),this->theta_.end(),ZERO);
00841
00842
00843
00844 if (this->om_->isVerbosity( Debug ) ) {
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855 MagnitudeType rhonum, rhoden, mxeta;
00856 std::vector<MagnitudeType> eBe(this->blockSize_);
00857 ginnersep(*this->eta_,*this->Beta_,eBe);
00858
00859
00860 rhonum = oldfx - this->fx_;
00861
00862
00863 rhoden = -2.0*ginner(*this->AX_ ,*this->eta_)
00864 -ginner(*this->Aeta_,*this->eta_);
00865 for (int i=0; i<this->blockSize_; ++i) {
00866 rhoden += eBe[i]*oldtheta[i];
00867 }
00868 mxeta = oldfx - rhoden;
00869 this->rho_ = rhonum / rhoden;
00870 this->om_->stream(Debug)
00871 << " >> old f(x) is : " << oldfx << endl
00872 << " >> new f(x) is : " << this->fx_ << endl
00873 << " >> m_x(eta) is : " << mxeta << endl
00874 << " >> rhonum is : " << rhonum << endl
00875 << " >> rhoden is : " << rhoden << endl
00876 << " >> rho is : " << this->rho_ << endl;
00877
00878 for (int j=0; j<this->blockSize_; ++j) {
00879 this->om_->stream(Debug)
00880 << " >> rho[" << j << "] : " << 1.0/(1.0+eBe[j]) << endl;
00881 }
00882 }
00883
00884
00885
00886
00887
00888 {
00889
00890
00891 this->X_ = Teuchos::null;
00892 this->BX_ = Teuchos::null;
00893 std::vector<int> ind(this->blockSize_);
00894 for (int i=0; i<this->blockSize_; ++i) ind[i] = this->numAuxVecs_+i;
00895 Teuchos::RCP<MV> X, BX;
00896 X = MVT::CloneViewNonConst(*this->V_,ind);
00897 if (this->hasBOp_) {
00898 BX = MVT::CloneViewNonConst(*this->BV_,ind);
00899 }
00900 if (useSA_ == false) {
00901
00902
00903
00904 TimeMonitor lcltimer( *this->timerLocalUpdate_ );
00905 MVT::MvTimesMatAddMv(ONE,*this->delta_,S,ZERO,*X);
00906 MVT::MvTimesMatAddMv(ONE,*this->Adelta_,S,ZERO,*this->AX_);
00907 if (this->hasBOp_) {
00908 MVT::MvTimesMatAddMv(ONE,*this->Bdelta_,S,ZERO,*BX);
00909 }
00910 }
00911 else {
00912
00913
00914
00915
00916 Teuchos::SerialDenseMatrix<int,ScalarType> Sx(Teuchos::View,S,this->blockSize_,this->blockSize_,0,0),
00917 Se(Teuchos::View,S,this->blockSize_,this->blockSize_,this->blockSize_,0);
00918 TimeMonitor lcltimer( *this->timerLocalUpdate_ );
00919
00920 MVT::MvTimesMatAddMv(ONE,* X ,Sx,ZERO,*this->delta_);
00921 MVT::MvTimesMatAddMv(ONE,*this->eta_,Se,ONE ,*this->delta_);
00922 MVT::MvAddMv(ONE,*this->delta_,ZERO,*this->delta_,*X);
00923
00924 MVT::MvTimesMatAddMv(ONE,*this->AX_ ,Sx,ZERO,*this->delta_);
00925 MVT::MvTimesMatAddMv(ONE,*this->Aeta_,Se,ONE ,*this->delta_);
00926 MVT::MvAddMv(ONE,*this->delta_,ZERO,*this->delta_,*this->AX_);
00927 if (this->hasBOp_) {
00928
00929 MVT::MvTimesMatAddMv(ONE,* BX ,Sx,ZERO,*this->delta_);
00930 MVT::MvTimesMatAddMv(ONE,*this->Beta_,Se,ONE ,*this->delta_);
00931 MVT::MvAddMv(ONE,*this->delta_,ZERO,*this->delta_,*BX);
00932 }
00933 }
00934
00935 X = Teuchos::null;
00936 BX = Teuchos::null;
00937 this->X_ = MVT::CloneView(static_cast<const MV&>(*this->V_ ),ind);
00938 this->BX_ = MVT::CloneView(static_cast<const MV&>(*this->BV_),ind);
00939 }
00940
00941
00942
00943 {
00944 TimeMonitor lcltimer( *this->timerCompRes_ );
00945 MVT::MvAddMv( ONE, *this->BX_, ZERO, *this->BX_, *this->R_ );
00946 std::vector<ScalarType> theta_comp(this->theta_.begin(),this->theta_.end());
00947 MVT::MvScale( *this->R_, theta_comp );
00948 MVT::MvAddMv( ONE, *this->AX_, -ONE, *this->R_, *this->R_ );
00949 }
00950
00951
00952 this->Rnorms_current_ = false;
00953 this->R2norms_current_ = false;
00954
00955
00956
00957
00958 if (this->om_->isVerbosity( Debug ) ) {
00959
00960 typename RTRBase<ScalarType,MV,OP>::CheckList chk;
00961 chk.checkX = true;
00962 chk.checkAX = true;
00963 chk.checkBX = true;
00964 chk.checkR = true;
00965 this->om_->print( Debug, this->accuracyCheck(chk, "after local update") );
00966 }
00967 else if (this->om_->isVerbosity( OrthoDetails )) {
00968 typename RTRBase<ScalarType,MV,OP>::CheckList chk;
00969 chk.checkX = true;
00970 chk.checkR = true;
00971 this->om_->print( OrthoDetails, this->accuracyCheck(chk, "after local update") );
00972 }
00973
00974 }
00975
00976 }
00977
00978
00980
00981 template <class ScalarType, class MV, class OP>
00982 void
00983 IRTR<ScalarType,MV,OP>::currentStatus(std::ostream &os)
00984 {
00985 using std::endl;
00986 os.setf(std::ios::scientific, std::ios::floatfield);
00987 os.precision(6);
00988 os <<endl;
00989 os <<"================================================================================" << endl;
00990 os << endl;
00991 os <<" IRTR Solver Status" << endl;
00992 os << endl;
00993 os <<"The solver is "<<(this->initialized_ ? "initialized." : "not initialized.") << endl;
00994 os <<"The number of iterations performed is " << this->iter_ << endl;
00995 os <<"The current block size is " << this->blockSize_ << endl;
00996 os <<"The number of auxiliary vectors is " << this->numAuxVecs_ << endl;
00997 os <<"The number of operations A*x is " << this->counterAOp_ << endl;
00998 os <<"The number of operations B*x is " << this->counterBOp_ << endl;
00999 os <<"The number of operations B*x by the orthomanager is " << this->orthman_->getOpCounter() << endl;
01000 os <<"The number of operations Prec*x is " << this->counterPrec_ << endl;
01001 os <<"Parameter rho_prime is " << rho_prime_ << endl;
01002 os <<"Inner stopping condition was " << stopReasons_[innerStop_] << endl;
01003 os <<"Number of inner iterations was " << innerIters_ << endl;
01004 os <<"Total number of inner iterations is " << totalInnerIters_ << endl;
01005 os <<"f(x) is " << this->fx_ << endl;
01006
01007 os.setf(std::ios_base::right, std::ios_base::adjustfield);
01008
01009 if (this->initialized_) {
01010 os << endl;
01011 os <<"CURRENT EIGENVALUE ESTIMATES "<<endl;
01012 os << std::setw(20) << "Eigenvalue"
01013 << std::setw(20) << "Residual(B)"
01014 << std::setw(20) << "Residual(2)"
01015 << endl;
01016 os <<"--------------------------------------------------------------------------------"<<endl;
01017 for (int i=0; i<this->blockSize_; i++) {
01018 os << std::setw(20) << this->theta_[i];
01019 if (this->Rnorms_current_) os << std::setw(20) << this->Rnorms_[i];
01020 else os << std::setw(20) << "not current";
01021 if (this->R2norms_current_) os << std::setw(20) << this->R2norms_[i];
01022 else os << std::setw(20) << "not current";
01023 os << endl;
01024 }
01025 }
01026 os <<"================================================================================" << endl;
01027 os << endl;
01028 }
01029
01030
01031 }
01032
01033 #endif // ANASAZI_IRTR_HPP