Anasazi  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
AnasaziSIRTR.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Anasazi: Block Eigensolvers Package
4 //
5 // Copyright 2004 NTESS and the Anasazi contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
10 
11 
12 #ifndef ANASAZI_SIRTR_HPP
13 #define ANASAZI_SIRTR_HPP
14 
15 #include "AnasaziTypes.hpp"
16 #include "AnasaziRTRBase.hpp"
17 
18 #include "AnasaziEigensolver.hpp"
21 #include "Teuchos_ScalarTraits.hpp"
22 
23 #include "Teuchos_LAPACK.hpp"
24 #include "Teuchos_BLAS.hpp"
27 #include "Teuchos_TimeMonitor.hpp"
28 
48 // TODO: add randomization
49 // TODO: add expensive debug checking on Teuchos_Debug
50 
51 namespace Anasazi {
52 
53  template <class ScalarType, class MV, class OP>
54  class SIRTR : public RTRBase<ScalarType,MV,OP> {
55  public:
56 
58 
59 
73  const Teuchos::RCP<OutputManager<ScalarType> > &printer,
77  );
78 
80  virtual ~SIRTR() {};
81 
83 
85 
86 
88  void iterate();
89 
91 
93 
94 
96  void currentStatus(std::ostream &os);
97 
99 
100  private:
101  //
102  // Convenience typedefs
103  //
104  typedef SolverUtils<ScalarType,MV,OP> Utils;
105  typedef MultiVecTraits<ScalarType,MV> MVT;
108  typedef typename SCT::magnitudeType MagnitudeType;
110  enum trRetType {
111  UNINITIALIZED = 0,
112  MAXIMUM_ITERATIONS,
113  NEGATIVE_CURVATURE,
114  EXCEEDED_TR,
115  KAPPA_CONVERGENCE,
116  THETA_CONVERGENCE
117  };
118  // these correspond to above
119  std::vector<std::string> stopReasons_;
120  //
121  // Consts
122  //
123  const MagnitudeType ZERO;
124  const MagnitudeType ONE;
125  //
126  // Internal methods
127  //
129  void solveTRSubproblem();
130  //
131  // rho_prime
132  MagnitudeType rho_prime_;
133  //
134  // norm of initial gradient: this is used for scaling
135  MagnitudeType normgradf0_;
136  //
137  // tr stopping reason
138  trRetType innerStop_;
139  //
140  // number of inner iterations
141  int innerIters_, totalInnerIters_;
142  };
143 
144 
145 
146 
148  // Constructor
149  template <class ScalarType, class MV, class OP>
153  const Teuchos::RCP<OutputManager<ScalarType> > &printer,
156  Teuchos::ParameterList &params
157  ) :
158  RTRBase<ScalarType,MV,OP>(problem,sorter,printer,tester,ortho,params,"SIRTR",true),
159  ZERO(MAT::zero()),
160  ONE(MAT::one()),
161  totalInnerIters_(0)
162  {
163  // set up array of stop reasons
164  stopReasons_.push_back("n/a");
165  stopReasons_.push_back("maximum iterations");
166  stopReasons_.push_back("negative curvature");
167  stopReasons_.push_back("exceeded TR");
168  stopReasons_.push_back("kappa convergence");
169  stopReasons_.push_back("theta convergence");
170 
171  rho_prime_ = params.get("Rho Prime",0.5);
172  TEUCHOS_TEST_FOR_EXCEPTION(rho_prime_ <= 0 || rho_prime_ >= 1,std::invalid_argument,
173  "Anasazi::SIRTR::constructor: rho_prime must be in (0,1).");
174  }
175 
176 
178  // TR subproblem solver
179  //
180  // FINISH:
181  // define pre- and post-conditions
182  //
183  // POST:
184  // delta_,Adelta_,Hdelta_ undefined
185  //
186  template <class ScalarType, class MV, class OP>
188 
189  // return one of:
190  // MAXIMUM_ITERATIONS
191  // NEGATIVE_CURVATURE
192  // EXCEEDED_TR
193  // KAPPA_CONVERGENCE
194  // THETA_CONVERGENCE
195 
196  using Teuchos::RCP;
197  using Teuchos::tuple;
198  using Teuchos::null;
199 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
200  using Teuchos::TimeMonitor;
201 #endif
202  using std::endl;
203  typedef Teuchos::RCP<const MV> PCMV;
205 
206  innerStop_ = MAXIMUM_ITERATIONS;
207 
208  const int n = MVT::GetGlobalLength(*this->eta_);
209  const int p = this->blockSize_;
210  const int d = n*p - (p*p+p)/2;
211 
212  // We have the following:
213  //
214  // X'*B*X = I
215  // X'*A*X = theta_
216  //
217  // We desire to remain in the trust-region:
218  // { eta : rho_Y(eta) \geq rho_prime }
219  // where
220  // rho_Y(eta) = 1/(1+eta'*B*eta)
221  // Therefore, the trust-region is
222  // { eta : eta'*B*eta \leq 1/rho_prime - 1 }
223  //
224  const double D2 = ONE/rho_prime_ - ONE;
225 
226  std::vector<MagnitudeType> d_Hd(p), alpha(p), beta(p), z_r(p), zold_rold(p);
227  std::vector<MagnitudeType> eBe(p), eBd(p), dBd(p), new_eBe(p);
228  MagnitudeType r0_norm;
229 
230  MVT::MvInit(*this->eta_ ,0.0);
231 
232  //
233  // R_ contains direct residuals:
234  // R_ = A X_ - B X_ diag(theta_)
235  //
236  // r0 = grad f(X) = 2 P_BX A X = 2 P_BX (A X - B X diag(theta_) = 2 proj(R_)
237  // We will do this in place.
238  // For seeking the rightmost, we want to maximize f
239  // This is the same as minimizing -f
240  // Substitute all f with -f here. In particular,
241  // grad -f(X) = -grad f(X)
242  // Hess -f(X) = -Hess f(X)
243  //
244  {
245 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
246  TimeMonitor lcltimer( *this->timerOrtho_ );
247 #endif
248  this->orthman_->projectGen(
249  *this->R_, // operating on R
250  tuple<PCMV>(this->BV_),tuple<PCMV>(this->V_),false, // P_{BV,V}, and <BV,V>_B != I
251  tuple<PSDM>(null), // don't care about coeffs
252  null,tuple<PCMV>(null), tuple<PCMV>(this->BV_)); // don't have B*BV, but do have B*V
253  if (this->leftMost_) {
254  MVT::MvScale(*this->R_,2.0);
255  }
256  else {
257  MVT::MvScale(*this->R_,-2.0);
258  }
259  }
260 
261  r0_norm = MAT::squareroot( RTRBase<ScalarType,MV,OP>::ginner(*this->R_) );
262  //
263  // kappa (linear) convergence
264  // theta (superlinear) convergence
265  //
266  MagnitudeType kconv = r0_norm * this->conv_kappa_;
267  // FINISH: consider inserting some scaling here
268  // MagnitudeType tconv = r0_norm * MAT::pow(r0_norm/normgradf0_,this->conv_theta_);
269  MagnitudeType tconv = MAT::pow(r0_norm,this->conv_theta_+ONE);
270  if (this->om_->isVerbosity(Debug)) {
271  this->om_->stream(Debug)
272  << " >> |r0| : " << r0_norm << endl
273  << " >> kappa conv : " << kconv << endl
274  << " >> theta conv : " << tconv << endl;
275  }
276 
277  //
278  // For Olsen preconditioning, the preconditioner is
279  // Z = P_{Prec^-1 BX, BX} Prec^-1 R
280  // for efficiency, we compute Prec^-1 BX once here for use later
281  // Otherwise, we don't need PBX
282  if (this->hasPrec_ && this->olsenPrec_)
283  {
284  std::vector<int> ind(this->blockSize_);
285  for (int i=0; i<this->blockSize_; ++i) ind[i] = this->numAuxVecs_+i;
286  Teuchos::RCP<MV> PBX = MVT::CloneViewNonConst(*this->PBV_,ind);
287  {
288 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
289  TimeMonitor prectimer( *this->timerPrec_ );
290 #endif
291  OPT::Apply(*this->Prec_,*this->BX_,*PBX);
292  this->counterPrec_ += this->blockSize_;
293  }
294  PBX = Teuchos::null;
295  }
296 
297  // Z = P_{Prec^-1 BV, BV} Prec^-1 R
298  // Prec^-1 BV in PBV
299  // or
300  // Z = P_{BV,BV} Prec^-1 R
301  if (this->hasPrec_)
302  {
303 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
304  TimeMonitor prectimer( *this->timerPrec_ );
305 #endif
306  OPT::Apply(*this->Prec_,*this->R_,*this->Z_);
307  this->counterPrec_ += this->blockSize_;
308  // the orthogonalization time counts under Ortho and under Preconditioning
309  if (this->olsenPrec_) {
310 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
311  TimeMonitor orthtimer( *this->timerOrtho_ );
312 #endif
313  this->orthman_->projectGen(
314  *this->Z_, // operating on Z
315  tuple<PCMV>(this->PBV_),tuple<PCMV>(this->V_),false, // P_{PBV,V}, B inner product, and <PBV,V>_B != I
316  tuple<PSDM>(null), // don't care about coeffs
317  null,tuple<PCMV>(null), tuple<PCMV>(this->BV_)); // don't have B*PBV or B*Z, but do have B*V
318  }
319  else {
320 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
321  TimeMonitor orthtimer( *this->timerOrtho_ );
322 #endif
323  this->orthman_->projectGen(
324  *this->Z_, // operating on Z
325  tuple<PCMV>(this->BV_),tuple<PCMV>(this->V_),false, // P_{BV,V}, and <BV,V>_B != I
326  tuple<PSDM>(null), // don't care about coeffs
327  null,tuple<PCMV>(null), tuple<PCMV>(this->BV_)); // don't have B*BV, but do have B*V
328  }
329  RTRBase<ScalarType,MV,OP>::ginnersep(*this->R_,*this->Z_,z_r);
330  }
331  else {
332  // Z = R
333  MVT::MvAddMv(ONE,*this->R_,ZERO,*this->R_,*this->Z_);
334  RTRBase<ScalarType,MV,OP>::ginnersep(*this->R_,z_r);
335  }
336 
337  if (this->om_->isVerbosity( Debug )) {
338  // Check that gradient is B-orthogonal to X
339  typename RTRBase<ScalarType,MV,OP>::CheckList chk;
340  chk.checkBR = true;
341  if (this->hasPrec_) chk.checkZ = true;
342  this->om_->print( Debug, this->accuracyCheck(chk, "after computing gradient") );
343  }
344  else if (this->om_->isVerbosity( OrthoDetails )) {
345  // Check that gradient is B-orthogonal to X
346  typename RTRBase<ScalarType,MV,OP>::CheckList chk;
347  chk.checkBR = true;
348  if (this->hasPrec_) chk.checkZ = true;
349  this->om_->print( OrthoDetails, this->accuracyCheck(chk, "after computing gradient") );
350  }
351 
352  // delta = -z
353  MVT::MvAddMv(-ONE,*this->Z_,ZERO,*this->Z_,*this->delta_);
354 
355  if (this->om_->isVerbosity(Debug)) {
356  // compute the model at eta
357  // we need Heta, which requires A*eta and B*eta
358  // we also need A*X
359  // use Z for storage of these
360  std::vector<MagnitudeType> eAx(this->blockSize_),
361  d_eAe(this->blockSize_),
362  d_eBe(this->blockSize_),
363  d_mxe(this->blockSize_);
364  // compute AX and <eta,AX>
365  {
366 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
367  TimeMonitor lcltimer( *this->timerAOp_ );
368 #endif
369  OPT::Apply(*this->AOp_,*this->X_,*this->Z_);
370  this->counterAOp_ += this->blockSize_;
371  }
372  RTRBase<ScalarType,MV,OP>::ginnersep(*this->eta_,*this->Z_,eAx);
373  // compute A*eta and <eta,A*eta>
374  {
375 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
376  TimeMonitor lcltimer( *this->timerAOp_ );
377 #endif
378  OPT::Apply(*this->AOp_,*this->eta_,*this->Z_);
379  this->counterAOp_ += this->blockSize_;
380  }
381  RTRBase<ScalarType,MV,OP>::ginnersep(*this->eta_,*this->Z_,d_eAe);
382  // compute B*eta and <eta,B*eta>
383  if (this->hasBOp_) {
384 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
385  TimeMonitor lcltimer( *this->timerBOp_ );
386 #endif
387  OPT::Apply(*this->BOp_,*this->eta_,*this->Z_);
388  this->counterBOp_ += this->blockSize_;
389  }
390  else {
391  MVT::MvAddMv(ONE,*this->eta_,ZERO,*this->eta_,*this->Z_);
392  }
393  RTRBase<ScalarType,MV,OP>::ginnersep(*this->eta_,*this->Z_,d_eBe);
394  // compute model:
395  // m_x(eta) = theta + 2*eta'*A*x + eta'*A*eta - eta'*B*eta*theta
396  if (this->leftMost_) {
397  for (int j=0; j<this->blockSize_; ++j) {
398  d_mxe[j] = this->theta_[j] + 2*eAx[j] + d_eAe[j] - d_eBe[j]*this->theta_[j];
399  }
400  }
401  else {
402  for (int j=0; j<this->blockSize_; ++j) {
403  d_mxe[j] = -this->theta_[j] - 2*eAx[j] - d_eAe[j] + d_eBe[j]*this->theta_[j];
404  }
405  }
406  this->om_->stream(Debug)
407  << " Debugging checks: SIRTR inner iteration " << innerIters_ << endl
408  << " >> m_X(eta) : " << std::accumulate(d_mxe.begin(),d_mxe.end(),0.0) << endl;
409  for (int j=0; j<this->blockSize_; ++j) {
410  this->om_->stream(Debug)
411  << " >> m_X(eta_" << j << ") : " << d_mxe[j] << endl;
412  }
413  }
414 
417  // the inner/tCG loop
418  for (innerIters_=1; innerIters_<=d; ++innerIters_) {
419 
420  //
421  // [Hdelta,Adelta,Bdelta] = Hess*delta = 2 Proj(A*delta - B*delta*X'*A*X)
422  // X'*A*X = diag(theta), so that
423  // (B*delta)*diag(theta) can be done on the cheap
424  //
425  {
426 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
427  TimeMonitor lcltimer( *this->timerAOp_ );
428 #endif
429  OPT::Apply(*this->AOp_,*this->delta_,*this->Z_);
430  this->counterAOp_ += this->blockSize_;
431  }
432  if (this->hasBOp_) {
433 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
434  TimeMonitor lcltimer( *this->timerBOp_ );
435 #endif
436  OPT::Apply(*this->BOp_,*this->delta_,*this->Hdelta_);
437  this->counterBOp_ += this->blockSize_;
438  }
439  else {
440  MVT::MvAddMv(ONE,*this->delta_,ZERO,*this->delta_,*this->Hdelta_);
441  }
442  // while we have B*delta, compute <eta,B*delta> and <delta,B*delta>
443  // these will be needed below
444  RTRBase<ScalarType,MV,OP>::ginnersep(*this->eta_ ,*this->Hdelta_,eBd);
445  RTRBase<ScalarType,MV,OP>::ginnersep(*this->delta_,*this->Hdelta_,dBd);
446  // put 2*A*d - 2*B*d*theta --> Hd
447  {
448  std::vector<ScalarType> theta_comp(this->theta_.begin(),this->theta_.end());
449  MVT::MvScale(*this->Hdelta_,theta_comp);
450  }
451  if (this->leftMost_) {
452  MVT::MvAddMv( 2.0,*this->Z_,-2.0,*this->Hdelta_,*this->Hdelta_);
453  }
454  else {
455  MVT::MvAddMv(-2.0,*this->Z_, 2.0,*this->Hdelta_,*this->Hdelta_);
456  }
457  // apply projector
458  {
459 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
460  TimeMonitor lcltimer( *this->timerOrtho_ );
461 #endif
462  this->orthman_->projectGen(
463  *this->Hdelta_, // operating on Hdelta
464  tuple<PCMV>(this->BV_),tuple<PCMV>(this->V_),false, // P_{BV,V}, and <BV,V>_B != I
465  tuple<PSDM>(null), // don't care about coeffs
466  null,tuple<PCMV>(null), tuple<PCMV>(this->BV_)); // don't have B*BV, but do have B*V
467  }
468  RTRBase<ScalarType,MV,OP>::ginnersep(*this->delta_,*this->Hdelta_,d_Hd);
469 
470 
471  // compute update step
472  for (unsigned int j=0; j<alpha.size(); ++j)
473  {
474  alpha[j] = z_r[j]/d_Hd[j];
475  }
476 
477  // compute new B-norms
478  for (unsigned int j=0; j<alpha.size(); ++j)
479  {
480  new_eBe[j] = eBe[j] + 2*alpha[j]*eBd[j] + alpha[j]*alpha[j]*dBd[j];
481  }
482 
483  if (this->om_->isVerbosity(Debug)) {
484  for (unsigned int j=0; j<alpha.size(); j++) {
485  this->om_->stream(Debug)
486  << " >> z_r[" << j << "] : " << z_r[j]
487  << " d_Hd[" << j << "] : " << d_Hd[j] << endl
488  << " >> eBe[" << j << "] : " << eBe[j]
489  << " neweBe[" << j << "] : " << new_eBe[j] << endl
490  << " >> eBd[" << j << "] : " << eBd[j]
491  << " dBd[" << j << "] : " << dBd[j] << endl;
492  }
493  }
494 
495  // check truncation criteria: negative curvature or exceeded trust-region
496  std::vector<int> trncstep;
497  trncstep.reserve(p);
498  // trncstep will contain truncated step, due to
499  // negative curvature or exceeding implicit trust-region
500  bool atleastonenegcur = false;
501  for (unsigned int j=0; j<d_Hd.size(); ++j) {
502  if (d_Hd[j] <= 0) {
503  trncstep.push_back(j);
504  atleastonenegcur = true;
505  }
506  else if (new_eBe[j] > D2) {
507  trncstep.push_back(j);
508  }
509  }
510 
511  if (!trncstep.empty())
512  {
513  // compute step to edge of trust-region, for trncstep vectors
514  if (this->om_->isVerbosity(Debug)) {
515  for (unsigned int j=0; j<trncstep.size(); ++j) {
516  this->om_->stream(Debug)
517  << " >> alpha[" << trncstep[j] << "] : " << alpha[trncstep[j]] << endl;
518  }
519  }
520  for (unsigned int j=0; j<trncstep.size(); ++j) {
521  int jj = trncstep[j];
522  alpha[jj] = ( -eBd[jj] + MAT::squareroot(eBd[jj]*eBd[jj] + dBd[jj]*(D2-eBe[jj]) ) ) / dBd[jj];
523  }
524  if (this->om_->isVerbosity(Debug)) {
525  for (unsigned int j=0; j<trncstep.size(); ++j) {
526  this->om_->stream(Debug)
527  << " >> tau[" << trncstep[j] << "] : " << alpha[trncstep[j]] << endl;
528  }
529  }
530  if (atleastonenegcur) {
531  innerStop_ = NEGATIVE_CURVATURE;
532  }
533  else {
534  innerStop_ = EXCEEDED_TR;
535  }
536  }
537 
538  // compute new eta = eta + alpha*delta
539  // we need delta*diag(alpha)
540  // do this in situ in delta_ and friends (we will note this for below)
541  // then set eta_ = eta_ + delta_
542  {
543  std::vector<ScalarType> alpha_comp(alpha.begin(),alpha.end());
544  MVT::MvScale(*this->delta_,alpha_comp);
545  MVT::MvScale(*this->Hdelta_,alpha_comp);
546  }
547  MVT::MvAddMv(ONE,*this->delta_ ,ONE,*this->eta_ ,*this->eta_);
548 
549  // store new eBe
550  eBe = new_eBe;
551 
552  //
553  // print some debugging info
554  if (this->om_->isVerbosity(Debug)) {
555  // compute the model at eta
556  // we need Heta, which requires A*eta and B*eta
557  // we also need A*X
558  // use Z for storage of these
559  std::vector<MagnitudeType> eAx(this->blockSize_),
560  d_eAe(this->blockSize_),
561  d_eBe(this->blockSize_),
562  d_mxe(this->blockSize_);
563  // compute AX and <eta,AX>
564  {
565 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
566  TimeMonitor lcltimer( *this->timerAOp_ );
567 #endif
568  OPT::Apply(*this->AOp_,*this->X_,*this->Z_);
569  this->counterAOp_ += this->blockSize_;
570  }
571  RTRBase<ScalarType,MV,OP>::ginnersep(*this->eta_,*this->Z_,eAx);
572  // compute A*eta and <eta,A*eta>
573  {
574 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
575  TimeMonitor lcltimer( *this->timerAOp_ );
576 #endif
577  OPT::Apply(*this->AOp_,*this->eta_,*this->Z_);
578  this->counterAOp_ += this->blockSize_;
579  }
580  RTRBase<ScalarType,MV,OP>::ginnersep(*this->eta_,*this->Z_,d_eAe);
581  // compute B*eta and <eta,B*eta>
582  if (this->hasBOp_) {
583 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
584  TimeMonitor lcltimer( *this->timerBOp_ );
585 #endif
586  OPT::Apply(*this->BOp_,*this->eta_,*this->Z_);
587  this->counterBOp_ += this->blockSize_;
588  }
589  else {
590  MVT::MvAddMv(ONE,*this->eta_,ZERO,*this->eta_,*this->Z_);
591  }
592  RTRBase<ScalarType,MV,OP>::ginnersep(*this->eta_,*this->Z_,d_eBe);
593  // compute model:
594  // m_x(eta) = theta + 2*eta'*A*x + eta'*A*eta - eta'*B*eta*theta
595  if (this->leftMost_) {
596  for (int j=0; j<this->blockSize_; ++j) {
597  d_mxe[j] = this->theta_[j] + 2*eAx[j] + d_eAe[j] - d_eBe[j]*this->theta_[j];
598  }
599  }
600  else {
601  for (int j=0; j<this->blockSize_; ++j) {
602  d_mxe[j] = -this->theta_[j] - 2*eAx[j] - d_eAe[j] + d_eBe[j]*this->theta_[j];
603  }
604  }
605  this->om_->stream(Debug)
606  << " Debugging checks: SIRTR inner iteration " << innerIters_ << endl
607  << " >> m_X(eta) : " << std::accumulate(d_mxe.begin(),d_mxe.end(),0.0) << endl;
608  for (int j=0; j<this->blockSize_; ++j) {
609  this->om_->stream(Debug)
610  << " >> m_X(eta_" << j << ") : " << d_mxe[j] << endl;
611  }
612  }
613 
614  //
615  // if we found negative curvature or exceeded trust-region, then quit
616  if (!trncstep.empty()) {
617  break;
618  }
619 
620  // update gradient of m
621  // R = R + Hdelta*diag(alpha)
622  // however, Hdelta_ already stores Hdelta*diag(alpha)
623  // so just add them
624  MVT::MvAddMv(ONE,*this->Hdelta_,ONE,*this->R_,*this->R_);
625  {
626  // re-tangentialize r
627 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
628  TimeMonitor lcltimer( *this->timerOrtho_ );
629 #endif
630  this->orthman_->projectGen(
631  *this->R_, // operating on R
632  tuple<PCMV>(this->BV_),tuple<PCMV>(this->V_),false, // P_{BV,V}, and <BV,V>_B != I
633  tuple<PSDM>(null), // don't care about coeffs
634  null,tuple<PCMV>(null), tuple<PCMV>(this->BV_)); // don't have B*BV, but do have B*V
635  }
636 
637  //
638  // check convergence
639  MagnitudeType r_norm = MAT::squareroot(RTRBase<ScalarType,MV,OP>::ginner(*this->R_,*this->R_));
640 
641  //
642  // check local convergece
643  //
644  // kappa (linear) convergence
645  // theta (superlinear) convergence
646  //
647  if (this->om_->isVerbosity(Debug)) {
648  this->om_->stream(Debug)
649  << " >> |r" << innerIters_ << "| : " << r_norm << endl;
650  }
651  if ( r_norm <= ANASAZI_MIN(tconv,kconv) ) {
652  if (tconv <= kconv) {
653  innerStop_ = THETA_CONVERGENCE;
654  }
655  else {
656  innerStop_ = KAPPA_CONVERGENCE;
657  }
658  break;
659  }
660 
661  // Z = P_{Prec^-1 BV, BV} Prec^-1 R
662  // Prec^-1 BV in PBV
663  // or
664  // Z = P_{BV,BV} Prec^-1 R
665  zold_rold = z_r;
666  if (this->hasPrec_)
667  {
668 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
669  TimeMonitor prectimer( *this->timerPrec_ );
670 #endif
671  OPT::Apply(*this->Prec_,*this->R_,*this->Z_);
672  this->counterPrec_ += this->blockSize_;
673  // the orthogonalization time counts under Ortho and under Preconditioning
674  if (this->olsenPrec_) {
675 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
676  TimeMonitor orthtimer( *this->timerOrtho_ );
677 #endif
678  this->orthman_->projectGen(
679  *this->Z_, // operating on Z
680  tuple<PCMV>(this->PBV_),tuple<PCMV>(this->V_),false, // P_{PBV,V}, B inner product, and <PBV,V>_B != I
681  tuple<PSDM>(null), // don't care about coeffs
682  null,tuple<PCMV>(null), tuple<PCMV>(this->BV_)); // don't have B*PBV or B*Z, but do have B*V
683  }
684  else {
685 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
686  TimeMonitor orthtimer( *this->timerOrtho_ );
687 #endif
688  this->orthman_->projectGen(
689  *this->Z_, // operating on Z
690  tuple<PCMV>(this->BV_),tuple<PCMV>(this->V_),false, // P_{BV,V}, and <BV,V>_B != I
691  tuple<PSDM>(null), // don't care about coeffs
692  null,tuple<PCMV>(null), tuple<PCMV>(this->BV_)); // don't have B*BV, but do have B*V
693  }
694  RTRBase<ScalarType,MV,OP>::ginnersep(*this->R_,*this->Z_,z_r);
695  }
696  else {
697  // Z = R
698  MVT::MvAddMv(ONE,*this->R_,ZERO,*this->R_,*this->Z_);
699  RTRBase<ScalarType,MV,OP>::ginnersep(*this->R_,z_r);
700  }
701 
702  // compute new search direction
703  // below, we need to perform
704  // delta = -Z + delta*diag(beta)
705  // however, delta_ currently stores delta*diag(alpha)
706  // therefore, set
707  // beta_ to beta/alpha
708  // so that
709  // delta_ = delta_*diag(beta_)
710  // will in fact result in
711  // delta_ = delta_*diag(beta_)
712  // = delta*diag(alpha)*diag(beta/alpha)
713  // = delta*diag(beta)
714  // i hope this is numerically sound...
715  for (unsigned int j=0; j<beta.size(); ++j) {
716  beta[j] = z_r[j]/(zold_rold[j]*alpha[j]);
717  }
718  {
719  std::vector<ScalarType> beta_comp(beta.begin(),beta.end());
720  MVT::MvScale(*this->delta_,beta_comp);
721  }
722  MVT::MvAddMv(-ONE,*this->Z_,ONE,*this->delta_,*this->delta_);
723 
724  }
725  // end of the inner iteration loop
728  if (innerIters_ > d) innerIters_ = d;
729 
730  this->om_->stream(Debug)
731  << " >> stop reason is " << stopReasons_[innerStop_] << endl
732  << endl;
733 
734  } // end of solveTRSubproblem
735 
736 
737 #define SIRTR_GET_TEMP_MV(mv,workspace) \
738  { \
739  TEUCHOS_TEST_FOR_EXCEPTION(workspace.size() == 0,std::logic_error,"SIRTR: Request for workspace could not be honored."); \
740  mv = workspace.back(); \
741  workspace.pop_back(); \
742  }
743 
744 #define SIRTR_RELEASE_TEMP_MV(mv,workspace) \
745  { \
746  workspace.push_back(mv); \
747  mv = Teuchos::null; \
748  }
749 
750 
752  // Eigensolver iterate() method
753  template <class ScalarType, class MV, class OP>
755 
756  using Teuchos::RCP;
757  using Teuchos::null;
758  using Teuchos::tuple;
759  using Teuchos::TimeMonitor;
760  using std::endl;
761  // typedef Teuchos::RCP<const MV> PCMV; // unused
762  // typedef Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > PSDM; // unused
763 
764  //
765  // Allocate/initialize data structures
766  //
767  if (this->initialized_ == false) {
768  this->initialize();
769  }
770 
771  Teuchos::SerialDenseMatrix<int,ScalarType> AA(this->blockSize_,this->blockSize_),
772  BB(this->blockSize_,this->blockSize_),
773  S(this->blockSize_,this->blockSize_);
774 
775  // we will often exploit temporarily unused storage for workspace
776  // in order to keep it straight and make for clearer code,
777  // we will put pointers to available multivectors into the following vector
778  // when we need them, we get them out, using a meaningfully-named pointer
779  // when we're done, we put them back
780  std::vector< RCP<MV> > workspace;
781  // we only have 7 multivectors, so that is more than the maximum number that
782  // we could use for temp storage
783  workspace.reserve(7);
784 
785  // set iteration details to invalid, as they don't have any meaning right now
786  innerIters_ = -1;
787  innerStop_ = UNINITIALIZED;
788 
789  // allocate temporary space
790  while (this->tester_->checkStatus(this) != Passed) {
791 
792  // Print information on current status
793  if (this->om_->isVerbosity(Debug)) {
794  this->currentStatus( this->om_->stream(Debug) );
795  }
796  else if (this->om_->isVerbosity(IterationDetails)) {
797  this->currentStatus( this->om_->stream(IterationDetails) );
798  }
799 
800  // increment iteration counter
801  this->iter_++;
802 
803  // solve the trust-region subproblem
804  solveTRSubproblem();
805  totalInnerIters_ += innerIters_;
806 
807  // perform debugging on eta et al.
808  if (this->om_->isVerbosity( Debug ) ) {
810  // this is the residual of the model, should still be in the tangent plane
811  chk.checkBR = true;
812  chk.checkEta = true;
813  this->om_->print( Debug, this->accuracyCheck(chk, "in iterate() after solveTRSubproblem()") );
814  }
815 
816 
817  //
818  // multivectors X, BX (if hasB) and eta contain meaningful information that we need below
819  // the others will be sacrificed to temporary storage
820  // we are not allowed to reference these anymore, RELEASE_TEMP_MV will clear the pointers
821  // the RCP in workspace will keep the MV alive, we will get the MVs back
822  // as we need them using GET_TEMP_MV
823  //
824  // this strategy doesn't cost us much, and it keeps us honest
825  //
826  TEUCHOS_TEST_FOR_EXCEPTION(workspace.size() != 0,std::logic_error,"SIRTR::iterate(): workspace list should be empty.");
827  SIRTR_RELEASE_TEMP_MV(this->delta_ ,workspace); // workspace size is 1
828  SIRTR_RELEASE_TEMP_MV(this->Hdelta_,workspace); // workspace size is 2
829  SIRTR_RELEASE_TEMP_MV(this->R_ ,workspace); // workspace size is 3
830  SIRTR_RELEASE_TEMP_MV(this->Z_ ,workspace); // workspace size is 4
831 
832 
833  // compute the retraction of eta: R_X(eta) = X+eta
834  // we must accept, but we will work out of temporary so that we can multiply back into X below
835  RCP<MV> XpEta;
836  SIRTR_GET_TEMP_MV(XpEta,workspace); // workspace size is 3
837  {
838 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
839  TimeMonitor lcltimer( *this->timerLocalUpdate_ );
840 #endif
841  MVT::MvAddMv(ONE,*this->X_,ONE,*this->eta_,*XpEta);
842  }
843 
844  //
845  // perform rayleigh-ritz for XpEta = X+eta
846  // save an old copy of f(X) for rho analysis below
847  //
848  MagnitudeType oldfx = this->fx_;
849  int rank, ret;
850  rank = this->blockSize_;
851  // compute AA = (X+eta)'*A*(X+eta)
852  // get temporarily storage for A*(X+eta)
853  RCP<MV> AXpEta;
854  SIRTR_GET_TEMP_MV(AXpEta,workspace); // workspace size is 2
855  {
856 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
857  TimeMonitor lcltimer( *this->timerAOp_ );
858 #endif
859  OPT::Apply(*this->AOp_,*XpEta,*AXpEta);
860  this->counterAOp_ += this->blockSize_;
861  }
862  // project A onto X+eta
863  {
864 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
865  TimeMonitor lcltimer( *this->timerLocalProj_ );
866 #endif
867  MVT::MvTransMv(ONE,*XpEta,*AXpEta,AA);
868  }
869  // compute BB = (X+eta)'*B*(X+eta)
870  // get temporary storage for B*(X+eta)
871  RCP<MV> BXpEta;
872  if (this->hasBOp_) {
873  SIRTR_GET_TEMP_MV(BXpEta,workspace); // workspace size is 1
874  {
875 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
876  TimeMonitor lcltimer( *this->timerBOp_ );
877 #endif
878  OPT::Apply(*this->BOp_,*XpEta,*BXpEta);
879  this->counterBOp_ += this->blockSize_;
880  }
881  // project B onto X+eta
882  {
883 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
884  TimeMonitor lcltimer( *this->timerLocalProj_ );
885 #endif
886  MVT::MvTransMv(ONE,*XpEta,*BXpEta,BB);
887  }
888  }
889  else {
890  // project I onto X+eta
891 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
892  TimeMonitor lcltimer( *this->timerLocalProj_ );
893 #endif
894  MVT::MvTransMv(ONE,*XpEta,*XpEta,BB);
895  }
896  this->om_->stream(Debug) << "AA: " << std::endl << printMat(AA) << std::endl;;
897  this->om_->stream(Debug) << "BB: " << std::endl << printMat(BB) << std::endl;;
898  // do the direct solve
899  // save old theta first
900  std::vector<MagnitudeType> oldtheta(this->theta_);
901  {
902 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
903  TimeMonitor lcltimer( *this->timerDS_ );
904 #endif
905  ret = Utils::directSolver(this->blockSize_,AA,Teuchos::rcpFromRef(BB),S,this->theta_,rank,1);
906  }
907  this->om_->stream(Debug) << "S: " << std::endl << printMat(S) << std::endl;;
908  TEUCHOS_TEST_FOR_EXCEPTION(ret != 0,std::logic_error,"Anasazi::SIRTR::iterate(): failure solving projected eigenproblem after retraction. ret == " << ret << "AA: " << printMat(AA) << std::endl << "BB: " << printMat(BB) << std::endl);
909  TEUCHOS_TEST_FOR_EXCEPTION(rank != this->blockSize_,RTRRitzFailure,"Anasazi::SIRTR::iterate(): retracted iterate failed in Ritz analysis. rank == " << rank);
910 
911  //
912  // order the projected ritz values and vectors
913  // this ensures that the ritz vectors produced below are ordered
914  {
915 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
916  TimeMonitor lcltimer( *this->timerSort_ );
917 #endif
918  std::vector<int> order(this->blockSize_);
919  // sort the first blockSize_ values in theta_
920  this->sm_->sort(this->theta_, Teuchos::rcpFromRef(order), this->blockSize_); // don't catch exception
921  // apply the same ordering to the primitive ritz vectors
922  Utils::permuteVectors(order,S);
923  }
924  //
925  // update f(x)
926  this->fx_ = std::accumulate(this->theta_.begin(),this->theta_.end(),ZERO);
927 
928  //
929  // if debugging, do rho analysis before overwriting X,AX,BX
930  RCP<MV> AX;
931  SIRTR_GET_TEMP_MV(AX,workspace); // workspace size is 0
932  if (this->om_->isVerbosity( Debug ) ) {
933  //
934  // compute rho
935  // f(X) - f(X+eta) f(X) - f(X+eta)
936  // rho = ----------------- = -------------------------
937  // m(0) - m(eta) -<2AX,eta> - .5*<Heta,eta>
938  MagnitudeType rhonum, rhoden, mxeta;
939  //
940  // compute rhonum
941  rhonum = oldfx - this->fx_;
942 
943  //
944  // compute rhoden = -<eta,gradfx> - 0.5 <eta,H*eta>
945  // = -2.0*<eta,AX> - <eta,A*eta> + <eta,B*eta*theta>
946  // in three steps (3) (1) (2)
947  //
948  // first, compute seconder-order decrease in model (steps 1 and 2)
949  // get temp storage for second order decrease of model
950  //
951  // do the first-order decrease last, because we need AX below
952  {
953  // compute A*eta and then <eta,A*eta>
954 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
955  TimeMonitor lcltimer( *this->timerAOp_ );
956 #endif
957  OPT::Apply(*this->AOp_,*this->eta_,*AX);
958  this->counterAOp_ += this->blockSize_;
959  }
960  // compute A part of second order decrease into rhoden
961  rhoden = -RTRBase<ScalarType,MV,OP>::ginner(*this->eta_,*AX);
962  if (this->hasBOp_) {
963  // compute B*eta into AX
964 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
965  TimeMonitor lcltimer( *this->timerBOp_ );
966 #endif
967  OPT::Apply(*this->BOp_,*this->eta_,*AX);
968  this->counterBOp_ += this->blockSize_;
969  }
970  else {
971  // put B*eta==eta into AX
972  MVT::MvAddMv(ONE,*this->eta_,ZERO,*this->eta_,*AX);
973  }
974  // we need this below for computing individual rho, get it now
975  std::vector<MagnitudeType> eBe(this->blockSize_);
976  RTRBase<ScalarType,MV,OP>::ginnersep(*this->eta_,*AX,eBe);
977  // scale B*eta by theta
978  {
979  std::vector<ScalarType> oldtheta_complex(oldtheta.begin(),oldtheta.end());
980  MVT::MvScale( *AX, oldtheta_complex);
981  }
982  // accumulate B part of second order decrease into rhoden
983  rhoden += RTRBase<ScalarType,MV,OP>::ginner(*this->eta_,*AX);
984  {
985 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
986  TimeMonitor lcltimer( *this->timerAOp_ );
987 #endif
988  OPT::Apply(*this->AOp_,*this->X_,*AX);
989  this->counterAOp_ += this->blockSize_;
990  }
991  // accumulate first-order decrease of model into rhoden
992  rhoden += -2.0*RTRBase<ScalarType,MV,OP>::ginner(*AX,*this->eta_);
993 
994  mxeta = oldfx - rhoden;
995  this->rho_ = rhonum / rhoden;
996  this->om_->stream(Debug)
997  << " >> old f(x) is : " << oldfx << endl
998  << " >> new f(x) is : " << this->fx_ << endl
999  << " >> m_x(eta) is : " << mxeta << endl
1000  << " >> rhonum is : " << rhonum << endl
1001  << " >> rhoden is : " << rhoden << endl
1002  << " >> rho is : " << this->rho_ << endl;
1003  // compute individual rho
1004  for (int j=0; j<this->blockSize_; ++j) {
1005  this->om_->stream(Debug)
1006  << " >> rho[" << j << "] : " << 1.0/(1.0+eBe[j]) << endl;
1007  }
1008  }
1009 
1010  // compute Ritz vectors back into X,BX,AX
1011  {
1012  // release const views to X, BX
1013  this->X_ = Teuchos::null;
1014  this->BX_ = Teuchos::null;
1015  // get non-const views
1016  std::vector<int> ind(this->blockSize_);
1017  for (int i=0; i<this->blockSize_; ++i) ind[i] = this->numAuxVecs_+i;
1018  Teuchos::RCP<MV> X, BX;
1019  X = MVT::CloneViewNonConst(*this->V_,ind);
1020  if (this->hasBOp_) {
1021  BX = MVT::CloneViewNonConst(*this->BV_,ind);
1022  }
1023  // compute ritz vectors, A,B products into X,AX,BX
1024  {
1025 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1026  TimeMonitor lcltimer( *this->timerLocalUpdate_ );
1027 #endif
1028  MVT::MvTimesMatAddMv(ONE,* XpEta,S,ZERO,*X);
1029  MVT::MvTimesMatAddMv(ONE,*AXpEta,S,ZERO,*AX);
1030  if (this->hasBOp_) {
1031  MVT::MvTimesMatAddMv(ONE,*BXpEta,S,ZERO,*BX);
1032  }
1033  }
1034  // clear non-const views, restore const views
1035  X = Teuchos::null;
1036  BX = Teuchos::null;
1037  this->X_ = MVT::CloneView(static_cast<const MV&>(*this->V_ ),ind);
1038  this->BX_ = MVT::CloneView(static_cast<const MV&>(*this->BV_),ind);
1039  }
1040  //
1041  // return XpEta and BXpEta to temp storage
1042  SIRTR_RELEASE_TEMP_MV(XpEta,workspace); // workspace size is 1
1043  SIRTR_RELEASE_TEMP_MV(AXpEta,workspace); // workspace size is 2
1044  if (this->hasBOp_) {
1045  SIRTR_RELEASE_TEMP_MV(BXpEta,workspace); // workspace size is 3
1046  }
1047 
1048  //
1049  // solveTRSubproblem destroyed R, we must recompute it
1050  // compute R = AX - BX*theta
1051  //
1052  // get R back from temp storage
1053  SIRTR_GET_TEMP_MV(this->R_,workspace); // workspace size is 2
1054  {
1055 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1056  TimeMonitor lcltimer( *this->timerCompRes_ );
1057 #endif
1058  MVT::MvAddMv( ONE, *this->BX_, ZERO, *this->BX_, *this->R_ );
1059  {
1060  std::vector<ScalarType> theta_comp(this->theta_.begin(),this->theta_.end());
1061  MVT::MvScale( *this->R_, theta_comp );
1062  }
1063  MVT::MvAddMv( ONE, *AX, -ONE, *this->R_, *this->R_ );
1064  }
1065  //
1066  // R has been updated; mark the norms as out-of-date
1067  this->Rnorms_current_ = false;
1068  this->R2norms_current_ = false;
1069 
1070  //
1071  // we are done with AX, release it
1072  SIRTR_RELEASE_TEMP_MV(AX,workspace); // workspace size is 3
1073  //
1074  // get data back for delta, Hdelta and Z
1075  SIRTR_GET_TEMP_MV(this->delta_,workspace); // workspace size is 2
1076  SIRTR_GET_TEMP_MV(this->Hdelta_,workspace); // workspace size is 1
1077  SIRTR_GET_TEMP_MV(this->Z_,workspace); // workspace size is 0
1078 
1079  //
1080  // When required, monitor some orthogonalities
1081  if (this->om_->isVerbosity( Debug ) ) {
1082  // Check almost everything here
1084  chk.checkX = true;
1085  chk.checkBX = true;
1086  chk.checkR = true;
1087  this->om_->print( Debug, this->accuracyCheck(chk, "after local update") );
1088  }
1089  else if (this->om_->isVerbosity( OrthoDetails )) {
1091  chk.checkX = true;
1092  chk.checkR = true;
1093  this->om_->print( OrthoDetails, this->accuracyCheck(chk, "after local update") );
1094  }
1095 
1096  } // end while (statusTest == false)
1097 
1098  } // end of iterate()
1099 
1100 
1102  // Print the current status of the solver
1103  template <class ScalarType, class MV, class OP>
1104  void
1106  {
1107  using std::endl;
1108  os.setf(std::ios::scientific, std::ios::floatfield);
1109  os.precision(6);
1110  os <<endl;
1111  os <<"================================================================================" << endl;
1112  os << endl;
1113  os <<" SIRTR Solver Status" << endl;
1114  os << endl;
1115  os <<"The solver is "<<(this->initialized_ ? "initialized." : "not initialized.") << endl;
1116  os <<"The number of iterations performed is " << this->iter_ << endl;
1117  os <<"The current block size is " << this->blockSize_ << endl;
1118  os <<"The number of auxiliary vectors is " << this->numAuxVecs_ << endl;
1119  os <<"The number of operations A*x is " << this->counterAOp_ << endl;
1120  os <<"The number of operations B*x is " << this->counterBOp_ << endl;
1121  os <<"The number of operations B*x by the orthomanager is " << this->orthman_->getOpCounter() << endl;
1122  os <<"The number of operations Prec*x is " << this->counterPrec_ << endl;
1123  os <<"Parameter rho_prime is " << rho_prime_ << endl;
1124  os <<"Inner stopping condition was " << stopReasons_[innerStop_] << endl;
1125  os <<"Number of inner iterations was " << innerIters_ << endl;
1126  os <<"Total number of inner iterations is " << totalInnerIters_ << endl;
1127  os <<"f(x) is " << this->fx_ << endl;
1128 
1129  os.setf(std::ios_base::right, std::ios_base::adjustfield);
1130 
1131  if (this->initialized_) {
1132  os << endl;
1133  os <<"CURRENT EIGENVALUE ESTIMATES "<<endl;
1134  os << std::setw(20) << "Eigenvalue"
1135  << std::setw(20) << "Residual(B)"
1136  << std::setw(20) << "Residual(2)"
1137  << endl;
1138  os <<"--------------------------------------------------------------------------------"<<endl;
1139  for (int i=0; i<this->blockSize_; i++) {
1140  os << std::setw(20) << this->theta_[i];
1141  if (this->Rnorms_current_) os << std::setw(20) << this->Rnorms_[i];
1142  else os << std::setw(20) << "not current";
1143  if (this->R2norms_current_) os << std::setw(20) << this->R2norms_[i];
1144  else os << std::setw(20) << "not current";
1145  os << endl;
1146  }
1147  }
1148  os <<"================================================================================" << endl;
1149  os << endl;
1150  }
1151 
1152 
1153 } // end Anasazi namespace
1154 
1155 #endif // ANASAZI_SIRTR_HPP
This class defines the interface required by an eigensolver and status test class to compute solution...
Base class for Implicit Riemannian Trust-Region solvers.
SerialBandDenseMatrixPrinter< OrdinalType, ScalarType > printMat(const SerialBandDenseMatrix< OrdinalType, ScalarType > &obj)
Declaration of basic traits for the multivector type.
T & get(const std::string &name, T def_value)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
This class is an abstract base class for Implicit Riemannian Trust-Region based eigensolvers. The class provides the interfaces shared by the IRTR solvers (e.g., getState() and initialize()) as well as the shared implementations (e.g., inner products).
Virtual base class which defines basic traits for the operator type.
Pure virtual base class which describes the basic interface to the iterative eigensolver.
Anasazi&#39;s templated, static class providing utilities for the solvers.
Output managers remove the need for the eigensolver to know any information about the required output...
Traits class which defines basic operations on multivectors.
Virtual base class which defines basic traits for the operator type.
SIRTR(const Teuchos::RCP< Eigenproblem< ScalarType, MV, OP > > &problem, const Teuchos::RCP< SortManager< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > > &sorter, const Teuchos::RCP< OutputManager< ScalarType > > &printer, const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > &tester, const Teuchos::RCP< GenOrthoManager< ScalarType, MV, OP > > &ortho, Teuchos::ParameterList &params)
SIRTR constructor with eigenproblem, solver utilities, and parameter list of solver options...
Types and exceptions used within Anasazi solvers and interfaces.
void currentStatus(std::ostream &os)
Impemements Eigensolver. This method requests that the solver print out its current status to screen...
Anasazi&#39;s templated pure virtual class for managing the sorting of approximate eigenvalues computed b...
Common interface of stopping criteria for Anasazi&#39;s solvers.
RTRRitzFailure is thrown when the RTR solver is unable to continue a call to RTRBase::iterate() due t...
void iterate()
Impemements Eigensolver. The outer IRTR iteration. See RTRBase::iterate().
virtual ~SIRTR()
SIRTR destructor