10 #ifndef BELOS_LSQR_ITER_HPP
11 #define BELOS_LSQR_ITER_HPP
42 template<
class ScalarType,
class MV,
class OP>
172 "LSQRIter::setBlockSize(): Cannot use a block size that is not one.");
254 template<
class ScalarType,
class MV,
class OP>
263 stateStorageInitialized_(false),
269 mat_resid_norm_(0.0),
277 template <
class ScalarType,
class MV,
class OP>
280 if (!stateStorageInitialized_) {
285 stateStorageInitialized_ =
false;
297 U_ = MVT::Clone( *rhsMV, 1 );
298 V_ = MVT::Clone( *lhsMV, 1 );
299 W_ = MVT::Clone( *lhsMV, 1 );
303 stateStorageInitialized_ =
true;
311 template <
class ScalarType,
class MV,
class OP>
317 if (!stateStorageInitialized_)
321 "LSQRIter::initialize(): Cannot initialize state storage!");
323 std::string errstr(
"LSQRIter::initialize(): Specified multivectors must have a consistent length and width.");
328 RCP<const MV> lhsMV = lp_->getLHS();
330 const bool debugSerialLSQR =
false;
332 if( debugSerialLSQR )
334 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> lhsNorm(1);
335 MVT::MvNorm( *lhsMV, lhsNorm );
336 std::cout <<
"initializeLSQR lhsNorm " << lhsNorm[0] << std::endl;
340 RCP<const MV> rhsMV = lp_->getInitPrecResVec();
343 MVT::MvAddMv( one, *rhsMV, zero, *U_, *U_);
345 RCP<const OP> M_left = lp_->getLeftPrec();
346 RCP<const OP>
A = lp_->getOperator();
347 RCP<const OP> M_right = lp_->getRightPrec();
349 if( debugSerialLSQR )
351 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> rhsNorm(1);
352 MVT::MvNorm( *U_, rhsNorm );
353 std::cout <<
"initializeLSQR | U_ | : " << rhsNorm[0] << std::endl;
365 if ( M_left.is_null())
373 RCP<MV> tempInRangeOfA = MVT::CloneCopy (*U_);
374 OPT::Apply (*M_left, *U_, *tempInRangeOfA,
CONJTRANS);
375 OPT::Apply (*A, *tempInRangeOfA, *V_,
CONJTRANS);
378 if (! M_right.is_null())
380 RCP<MV> tempInDomainOfA = MVT::CloneCopy (*V_);
382 OPT::Apply (*M_right, *tempInDomainOfA, *V_,
CONJTRANS);
387 MVT::MvAddMv( one, *V_, zero, *V_, *W_);
389 frob_mat_norm_ = zero;
400 template <
class ScalarType,
class MV,
class OP>
406 if (initialized_ ==
false) {
416 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> alpha(1);
417 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> beta(1);
418 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> xi(1);
421 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> wnorm2(1);
422 ScalarType rhobar, phibar, cs1, phi, rho, cs, sn, theta, xxnorm = MTzero, common;
423 ScalarType zetabar, sn1, psi, res = zero, ddnorm = zero, gamma, tau;
424 ScalarType anorm2 = zero;
425 ScalarType cs2 = -one, sn2 = zero, gammabar, zeta = zero, delta;
429 AV = MVT::Clone( *U_, 1);
431 AtU = MVT::Clone( *V_, 1);
432 const bool debugSerialLSQR =
false;
440 "LSQRIter::iterate(): current linear system has more than one vector!" );
444 MVT::MvNorm( *U_, beta );
445 if( SCT::real(beta[0]) > zero )
447 MVT::MvScale( *U_, one / beta[0] );
452 MVT::MvScale( *V_, one / beta[0] );
457 MVT::MvNorm( *V_, alpha );
458 if( debugSerialLSQR )
462 std::cout << iter_ <<
" First alpha " << alpha[0] <<
" beta " << beta[0] <<
" lambda " << lambda_ << std::endl;
464 if( SCT::real(alpha[0]) > zero )
466 MVT::MvScale( *V_, one / alpha[0] );
468 if( beta[0] * alpha[0] > zero )
470 MVT::MvScale( *W_, one / (beta[0] * alpha[0]) );
474 MVT::MvScale( *W_, zero );
478 RCP<const OP> M_left = lp_->getLeftPrec();
479 RCP<const OP>
A = lp_->getOperator();
480 RCP<const OP> M_right = lp_->getRightPrec();
485 resid_norm_ = beta[0];
486 mat_resid_norm_ = alpha[0] * beta[0];
500 if ( M_right.is_null() )
502 OPT::Apply(*A, *V_, *AV);
506 RCP<MV> tempInDomainOfA = MVT::CloneCopy (*V_);
507 OPT::Apply (*M_right, *V_, *tempInDomainOfA);
508 OPT::Apply(*A, *tempInDomainOfA, *AV);
511 if (! M_left.is_null())
513 RCP<MV> tempInRangeOfA = MVT::CloneCopy (*AV);
514 OPT::Apply (*M_left, *tempInRangeOfA, *AV);
518 if ( !( M_left.is_null() && M_right.is_null() )
519 && debugSerialLSQR && iter_ == 1)
525 if (! M_left.is_null())
527 RCP<MV> tempInRangeOfA = MVT::CloneCopy (*U_);
528 OPT::Apply (*M_left, *U_, *tempInRangeOfA,
CONJTRANS);
529 OPT::Apply (*A, *tempInRangeOfA, *AtU,
CONJTRANS);
535 if ( !( M_right.is_null() ) )
537 RCP<MV> tempInDomainOfA = MVT::CloneCopy (*AtU);
538 OPT::Apply (*M_right, *tempInDomainOfA, *AtU,
CONJTRANS);
541 MVT::MvAddMv( one, *AtU, -alpha[0], *V_, *AtU );
542 MVT::MvNorm( *AtU, xi );
543 std::cout <<
"| V alpha - A' u |= " << xi[0] << std::endl;
546 MVT::MvTransMv( one, *U_, *U_, uotuo );
547 std::cout <<
"<U, U> = " <<
printMat(uotuo) << std::endl;
549 std::cout <<
"alpha = " << alpha[0] << std::endl;
552 MVT::MvTransMv( one, *AV, *U_, utav );
553 std::cout <<
"<AV, U> = alpha = " <<
printMat(utav) << std::endl;
556 MVT::MvAddMv( one, *AV, -alpha[0], *U_, *U_ );
557 MVT::MvNorm( *U_, beta);
559 anorm2 += alpha[0]*alpha[0] + beta[0]*beta[0] + lambda_*lambda_;
562 if ( SCT::real(beta[0]) > zero )
565 MVT::MvScale( *U_, one / beta[0] );
567 if (M_left.is_null())
573 RCP<MV> tempInRangeOfA = MVT::CloneCopy (*U_);
574 OPT::Apply (*M_left, *U_, *tempInRangeOfA,
CONJTRANS);
575 OPT::Apply(*A, *tempInRangeOfA, *AtU,
CONJTRANS);
577 if (! M_right.is_null())
579 RCP<MV> tempInDomainOfA = MVT::CloneCopy (*AtU);
580 OPT::Apply (*M_right, *tempInDomainOfA, *AtU,
CONJTRANS);
583 MVT::MvAddMv( one, *AtU, -beta[0], *V_, *V_ );
584 MVT::MvNorm( *V_, alpha );
591 if ( SCT::real(alpha[0]) > zero )
593 MVT::MvScale( *V_, one / alpha[0] );
599 cs1 = rhobar / common;
600 sn1 = lambda_ / common;
602 phibar = cs1 * phibar;
609 theta = sn * alpha[0];
610 rhobar = -cs * alpha[0];
612 phibar = sn * phibar;
616 gammabar = -cs2 * rho;
617 zetabar = (phi - delta*zeta) / gammabar;
620 cs2 = gammabar / gamma;
622 zeta = (phi - delta*zeta) / gamma;
626 if ( M_right.is_null())
628 MVT::MvAddMv( phi / rho, *W_, one, *cur_soln_vec, *cur_soln_vec);
632 RCP<MV> tempInDomainOfA = MVT::CloneCopy (*W_);
633 OPT::Apply (*M_right, *W_, *tempInDomainOfA);
634 MVT::MvAddMv( phi / rho, *tempInDomainOfA, one, *cur_soln_vec, *cur_soln_vec);
637 MVT::MvNorm( *W_, wnorm2 );
638 ddnorm += (one / rho)*(one / rho) * wnorm2[0]*wnorm2[0];
639 MVT::MvAddMv( one, *V_, -theta / rho, *W_, *W_ );
Teuchos::RCP< const MV > U
Bidiagonalization vector.
Collection of types and exceptions used within the Belos solvers.
IterationState contains the data that defines the state of the LSQR solver at any given time...
Belos's basic output manager for sending information of select verbosity levels to the appropriate ou...
const Teuchos::RCP< Belos::StatusTest< ScalarType, MV, OP > > stest_
ScalarType mat_resid_norm_
Class which manages the output and verbosity of the Belos solvers.
const Teuchos::RCP< Belos::OutputManager< ScalarType > > om_
ScalarType resid_norm
The current residual norm.
Teuchos::ScalarTraits< ScalarType >::magnitudeType lambda
The damping value.
void resetNumIters(int iter=0)
Reset the iteration count.
Teuchos::RCP< const MV > getNativeResiduals(std::vector< MagnitudeType > *) const
Get the norms of the residuals native to the solver.
SerialBandDenseMatrixPrinter< OrdinalType, ScalarType > printMat(const SerialBandDenseMatrix< OrdinalType, ScalarType > &obj)
Pure virtual base class for defining the status testing capabilities of Belos.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Declaration of basic traits for the multivector type.
void initializeLSQR(LSQRIterationState< ScalarType, MV > &newstate)
Initialize the solver to an iterate, completing the initial state.
bool stateStorageInitialized_
ScalarType sol_norm
An estimate of the norm of the solution.
ScalarType mat_cond_num
An approximation to the condition number of A.
A pure virtual class for defining the status tests for the Belos iterative solvers.
Belos::OperatorTraits< ScalarType, MV, OP > OPT
Class which defines basic traits for the operator type.
Traits class which defines basic operations on multivectors.
void iterate()
This method performs LSQR iterations until the status test indicates the need to stop or an error occ...
ScalarType frob_mat_norm
An approximation to the Frobenius norm of A.
ScalarType frob_mat_norm_
ScalarType mat_resid_norm
An estimate of the norm of A^T*resid.
Teuchos::RCP< const MV > W
The search direction vector.
Teuchos::RCP< const MV > V
Bidiagonalization vector.
virtual ~LSQRIter()
Destructor.
A linear system to solve, and its associated information.
void setStateSize()
Method for initalizing the state storage needed by LSQR.
Class which describes the linear problem to be solved by the iterative solver.
int getNumIters() const
Get the current iteration count.
LSQRIter(const Teuchos::RCP< Belos::LinearProblem< ScalarType, MV, OP > > &problem, const Teuchos::RCP< Belos::OutputManager< ScalarType > > &printer, const Teuchos::RCP< Belos::StatusTest< ScalarType, MV, OP > > &tester, Teuchos::ParameterList ¶ms)
LSQRIter constructor with linear problem, solver utilities, and parameter list of solver options...
Teuchos::ScalarTraits< ScalarType > SCT
const Teuchos::RCP< Belos::LinearProblem< ScalarType, MV, OP > > lp_
static magnitudeType magnitude(T a)
Teuchos::RCP< MV > getCurrentUpdate() const
Get the current update to the linear system.
Belos::MultiVecTraits< ScalarType, MV > MVT
SCT::magnitudeType MagnitudeType
LSQRIterationState< ScalarType, MV > getState() const
Get the current state of the linear solver.
void initialize()
The solver is initialized using initializeLSQR.
Class which defines basic traits for the operator type.
Implementation of the LSQR iteration.
ScalarType bnorm
The norm of the RHS vector b.
int getBlockSize() const
Get the blocksize to be used by the iterative solver in solving this linear problem.
bool isInitialized()
States whether the solver has been initialized or not.
Structure to contain pointers to LSQRIteration state variables, ...
Belos header file which uses auto-configuration information to include necessary C++ headers...
const Belos::LinearProblem< ScalarType, MV, OP > & getProblem() const
Get a constant reference to the linear problem.
LSQRIterateFailure is thrown when the LSQRIteration object is unable to compute the next iterate in t...
void setBlockSize(int blockSize)
Set the blocksize to be used by the iterative solver to solve this linear problem.