Anasazi Version of the Day
Loading...
Searching...
No Matches
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
21#include "Teuchos_ScalarTraits.hpp"
22
23#include "Teuchos_LAPACK.hpp"
24#include "Teuchos_BLAS.hpp"
25#include "Teuchos_SerialDenseMatrix.hpp"
26#include "Teuchos_ParameterList.hpp"
27#include "Teuchos_TimeMonitor.hpp"
28
48// TODO: add randomization
49// TODO: add expensive debug checking on Teuchos_Debug
50
51namespace Anasazi {
52
53 template <class ScalarType, class MV, class OP>
54 class SIRTR : public RTRBase<ScalarType,MV,OP> {
55 public:
56
58
59
71 SIRTR( const Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > &problem,
72 const Teuchos::RCP<SortManager<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > &sorter,
73 const Teuchos::RCP<OutputManager<ScalarType> > &printer,
74 const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > &tester,
75 const Teuchos::RCP<GenOrthoManager<ScalarType,MV,OP> > &ortho,
76 Teuchos::ParameterList &params
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;
107 typedef Teuchos::ScalarTraits<ScalarType> SCT;
108 typedef typename SCT::magnitudeType MagnitudeType;
109 typedef Teuchos::ScalarTraits<MagnitudeType> MAT;
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>
151 const Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > &problem,
152 const Teuchos::RCP<SortManager<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > &sorter,
153 const Teuchos::RCP<OutputManager<ScalarType> > &printer,
154 const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > &tester,
155 const Teuchos::RCP<GenOrthoManager<ScalarType,MV,OP> > &ortho,
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;
204 typedef Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > PSDM;
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
Pure virtual base class which describes the basic interface to the iterative eigensolver.
Declaration of basic traits for the multivector type.
Virtual base class which defines basic traits for the operator type.
Base class for Implicit Riemannian Trust-Region solvers.
Types and exceptions used within Anasazi solvers and interfaces.
This class defines the interface required by an eigensolver and status test class to compute solution...
Traits class which defines basic operations on multivectors.
Virtual base class which defines basic traits for the operator type.
Output managers remove the need for the eigensolver to know any information about the required output...
This class is an abstract base class for Implicit Riemannian Trust-Region based eigensolvers....
RTRRitzFailure is thrown when the RTR solver is unable to continue a call to RTRBase::iterate() due t...
virtual ~SIRTR()
SIRTR destructor
void currentStatus(std::ostream &os)
Impemements Eigensolver. This method requests that the solver print out its current status to screen.
void iterate()
Impemements Eigensolver. The outer IRTR iteration. See RTRBase::iterate().
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.
Anasazi's templated, static class providing utilities for the solvers.
Anasazi's templated pure virtual class for managing the sorting of approximate eigenvalues computed b...
Common interface of stopping criteria for Anasazi's solvers.
Namespace Anasazi contains the classes, structs, enums and utilities used by the Anasazi package.