10#ifndef _TEUCHOS_SERIALQRDENSESOLVER_HPP_ 
   11#define _TEUCHOS_SERIALQRDENSESOLVER_HPP_ 
   25#ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
   99  template<
typename OrdinalType, 
typename ScalarType>
 
  101                              public LAPACK<OrdinalType, ScalarType>
 
  107#ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  108    typedef typename Eigen::Matrix<ScalarType,Eigen::Dynamic,Eigen::Dynamic,Eigen::ColMajor> 
EigenMatrix;
 
  109    typedef typename Eigen::Matrix<ScalarType,Eigen::Dynamic,1> 
EigenVector;
 
  112    typedef typename Eigen::Map<EigenVector,0,EigenInnerStride > 
EigenVectorMap;
 
  114    typedef typename Eigen::Map<EigenMatrix,0,EigenOuterStride > 
EigenMatrixMap;
 
  116    typedef typename Eigen::PermutationMatrix<Eigen::Dynamic,Eigen::Dynamic,OrdinalType> 
EigenPermutationMatrix;
 
  119    typedef typename Eigen::Array<ScalarType,Eigen::Dynamic,1> 
EigenScalarArray;
 
  288    std::vector<ScalarType> 
tau()
  const {
return(TAU_);}
 
  298    void Print(std::ostream& os) 
const;
 
  302    void allocateWORK() { LWORK_ = 4*N_; WORK_.resize( LWORK_ ); 
return;}
 
  308    bool shouldEquilibrate_;
 
  311    OrdinalType equilibrationModeA_;
 
  312    OrdinalType equilibrationModeB_;
 
  332    std::vector<ScalarType> TAU_;
 
  334    MagnitudeType ANORM_;
 
  335    MagnitudeType BNORM_;
 
  337    RCP<SerialDenseMatrix<OrdinalType, ScalarType> > Matrix_;
 
  338    RCP<SerialDenseMatrix<OrdinalType, ScalarType> > LHS_;
 
  339    RCP<SerialDenseMatrix<OrdinalType, ScalarType> > TMP_;
 
  340    RCP<SerialDenseMatrix<OrdinalType, ScalarType> > RHS_;
 
  341    RCP<SerialDenseMatrix<OrdinalType, ScalarType> > Factor_;
 
  342    RCP<SerialDenseMatrix<OrdinalType, ScalarType> > FactorQ_;
 
  343    RCP<SerialDenseMatrix<OrdinalType, ScalarType> > FactorR_;
 
  349    std::vector<ScalarType> WORK_;
 
  350#ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  351    Eigen::HouseholderQR<EigenMatrix> qr_;
 
  358    SerialQRDenseSolver & operator=(
const SerialQRDenseSolver<OrdinalType, ScalarType>& Source);
 
 
  367template<
typename OrdinalType, 
typename ScalarType>
 
  371    shouldEquilibrate_(
false),
 
  372    equilibratedA_(
false),
 
  373    equilibratedB_(
false),
 
  374    equilibrationModeA_(0),
 
  375    equilibrationModeB_(0),
 
  379    matrixIsZero_(
false),
 
 
  403template<
typename OrdinalType, 
typename ScalarType>
 
  409template<
typename OrdinalType, 
typename ScalarType>
 
  412  LHS_ = Teuchos::null;
 
  413  TMP_ = Teuchos::null;
 
  414  RHS_ = Teuchos::null;
 
  416  equilibratedB_ = 
false;
 
  420template<
typename OrdinalType, 
typename ScalarType>
 
  421void SerialQRDenseSolver<OrdinalType,ScalarType>::resetMatrix()
 
  424  equilibratedA_ = 
false;
 
  425  equilibrationModeA_ = 0;
 
  426  equilibrationModeB_ = 0;
 
  428  matrixIsZero_ = 
false;
 
  449template<
typename OrdinalType, 
typename ScalarType>
 
  453                     "SerialQRDenseSolver<T>::setMatrix: the matrix A must have A.numRows() >= A.numCols()!");
 
  462  Min_MN_ = TEUCHOS_MIN(M_,N_);
 
 
  476template<
typename OrdinalType, 
typename ScalarType>
 
  482                     "SerialQRDenseSolver<T>::setVectors: X and B have different numbers of columns!");
 
  484                     "SerialQRDenseSolver<T>::setVectors: B is an empty SerialDenseMatrix<T>!");
 
  486                     "SerialQRDenseSolver<T>::setVectors: X is an empty SerialDenseMatrix<T>!");
 
  488                     "SerialQRDenseSolver<T>::setVectors: B has an invalid stride!");
 
  490                     "SerialQRDenseSolver<T>::setVectors: X has an invalid stride!");
 
 
  500template<
typename OrdinalType, 
typename ScalarType>
 
  503  if (factored()) 
return(0);
 
  507  if (equilibrate_) 
ierr = equilibrateMatrix();
 
  511  if ((
int)TAU_.size()!=Min_MN_) TAU_.resize( Min_MN_ );
 
  516#ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  532  this->GEQRF(M_, N_, AF_, LDAF_, &TAU_[0], &WORK_[0], LWORK_, &INFO_);
 
 
  542template<
typename OrdinalType, 
typename ScalarType>
 
  554    ierr = equilibrateRHS();
 
  559                     "SerialQRDenseSolver<T>::solve: No right-hand side vector (RHS) has been set for the linear system!");
 
  561                     "SerialQRDenseSolver<T>::solve: No solution vector (LHS) has been set for the linear system!");
 
  564                     "SerialQRDenseSolver<T>::solve: No transpose: must have LHS_->numRows() = N_");
 
  567                     "SerialQRDenseSolver<T>::solve: Transpose: must have LHS_->numRows() = M_");
 
  570  if (shouldEquilibrate() && !equilibratedA_)
 
  571    std::cout << 
"WARNING!  SerialQRDenseSolver<T>::solve: System should be equilibrated!" << std::endl;
 
  574  if (!factored()) factor();
 
  577                     std::logic_error, 
"SerialQRDenseSolver<T>::solve: Matrix and vectors must be similarly scaled!");
 
  582      (*TMP_)(
i,
j) = (*RHS_)(
i,
j);
 
  609      (*LHS_)(
i, 
j) = (*TMP_)(
i,
j);
 
  617    ierr = unequilibrateLHS();
 
 
  628template<
typename OrdinalType, 
typename ScalarType>
 
  643  for (
j = 0; 
j < N_; 
j++) {
 
  644    for (
i = 0; 
i < M_; 
i++) {
 
  653    shouldEquilibrate_ = 
true;
 
  654  } 
else if (ANORM_ > 
bignum) {
 
  656    shouldEquilibrate_ = 
true;
 
  657  } 
else if (ANORM_ == 
mZero) {
 
  659    matrixIsZero_ = 
true;
 
 
  667template<
typename OrdinalType, 
typename ScalarType>
 
  670  if (equilibratedA_) 
return(0);
 
  685  for (
j = 0; 
j < N_; 
j++) {
 
  686    for (
i = 0; 
i < M_; 
i++) {
 
  696    equilibrationModeA_ = 1;
 
  697  } 
else if (ANORM_ > 
bignum) {
 
  700    equilibrationModeA_ = 2;
 
  701  } 
else if (ANORM_ == 
mZero) {
 
  703    matrixIsZero_ = 
true;
 
  706  equilibratedA_ = 
true;
 
 
  713template<
typename OrdinalType, 
typename ScalarType>
 
  716  if (equilibratedB_) 
return(0);
 
  731  for (
j = 0; 
j <RHS_->numCols(); 
j++) {
 
  732    for (
i = 0; 
i < RHS_->numRows(); 
i++) {
 
  743                RHS_->values(), RHS_->stride(), &INFO_);
 
  744    equilibrationModeB_ = 1;
 
  745  } 
else if (BNORM_ > 
bignum) {
 
  748                RHS_->values(), RHS_->stride(), &INFO_);
 
  749    equilibrationModeB_ = 2;
 
  752  equilibratedB_ = 
true;
 
 
  759template<
typename OrdinalType, 
typename ScalarType>
 
  762  if (!equilibratedB_) 
return(0);
 
  776  if (equilibrationModeA_ == 1) {
 
  778                LHS_->values(), LHS_->stride(), &INFO_);
 
  779  } 
else if (equilibrationModeA_ == 2) {
 
  781                LHS_->values(), LHS_->stride(), &INFO_);
 
  783  if (equilibrationModeB_ == 1) {
 
  785                LHS_->values(), LHS_->stride(), &INFO_);
 
  786  } 
else if (equilibrationModeB_ == 2) {
 
  788                LHS_->values(), LHS_->stride(), &INFO_);
 
 
  796template<
typename OrdinalType, 
typename ScalarType>
 
  800  if (!factored()) factor();
 
  805    Q_ = FactorQ_->values();
 
  806    LDQ_ = FactorQ_->stride();
 
  812#ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  821  this->UNGQR(M_, N_, N_, Q_, LDQ_, &TAU_[0], &WORK_[0], LWORK_, &INFO_);
 
  824  if (INFO_!=0) 
return(INFO_);
 
 
  833template<
typename OrdinalType, 
typename ScalarType>
 
  837  if (!factored()) factor();
 
  842    R_ = FactorR_->values();
 
  843    LDR_ = FactorR_->stride();
 
  849      (*FactorR_)(
i,
j) = (*Factor_)(
i,
j);
 
 
  860template<
typename OrdinalType, 
typename ScalarType>
 
  866                     "SerialQRDenseSolver<T>::multiplyQ: C.numRows() != M_!");
 
  868                     "SerialQRDenseSolver<T>::multiplyQ: C is an empty SerialDenseMatrix<T>!");
 
  871  if (!factored()) factor();
 
  876#ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  898    this->UNMQR(ESideChar[
SIDE], ETranspChar[
NO_TRANS], M_, C.numCols(), N_, AF_, LDAF_,
 
  899                &TAU_[0], C.values(), C.stride(), &WORK_[0], LWORK_, &INFO_);
 
  904    this->UNMQR(ESideChar[
SIDE], ETranspChar[
TRANS], M_, C.numCols(), N_, AF_, LDAF_,
 
  905                &TAU_[0], C.values(), C.stride(), &WORK_[0], LWORK_, &INFO_);
 
 
  921template<
typename OrdinalType, 
typename ScalarType>
 
  927                     "SerialQRDenseSolver<T>::solveR: must have N_ < C.numRows() < M_!");
 
  929                     "SerialQRDenseSolver<T>::solveR: C is an empty SerialDenseMatrix<T>!");
 
  932  if (!factored()) factor();
 
  937#ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  965    this->TRTRS(EUploChar[UPLO], ETranspChar[
NO_TRANS], EDiagChar[
DIAG], N_, C.numCols(),
 
  966                RMAT, 
LDRMAT, C.values(), C.stride(), &INFO_);
 
  971    this->TRTRS(EUploChar[UPLO], ETranspChar[
TRANS], EDiagChar[
DIAG], N_, C.numCols(),
 
  972                RMAT, 
LDRMAT, C.values(), C.stride(), &INFO_);
 
 
  983template<
typename OrdinalType, 
typename ScalarType>
 
  986  if (Matrix_!=Teuchos::null) os << 
"Solver Matrix"          << std::endl << *Matrix_ << std::endl;
 
  987  if (Factor_!=Teuchos::null) os << 
"Solver Factored Matrix" << std::endl << *Factor_ << std::endl;
 
  988  if (Q_!=Teuchos::null) os << 
"Solver Factor Q" << std::endl << *Q_ << std::endl;
 
  989  if (LHS_   !=Teuchos::null) os << 
"Solver LHS"             << std::endl << *LHS_    << std::endl;
 
  990  if (RHS_   !=Teuchos::null) os << 
"Solver RHS"             << std::endl << *RHS_    << std::endl;
 
 
Templated interface class to BLAS routines.
 
Object for storing data and providing functionality that is common to all computational classes.
 
Teuchos header file which uses auto-configuration information to include necessary C++ headers.
 
Templated interface class to LAPACK routines.
 
Reference-counted pointer class and non-member templated function implementations.
 
Defines basic traits for the scalar field type.
 
Templated serial dense matrix class.
 
Templated class for solving dense linear problems.
 
Functionality and data that is common to all computational classes.
 
The Templated LAPACK Wrapper Class.
 
Smart reference counting pointer class for automatic garbage collection.
 
RCP< T > rcp(const boost::shared_ptr< T > &sptr)
Conversion function that takes in a boost::shared_ptr object and spits out a Teuchos::RCP object.
 
A class for solving dense linear problems.
 
void factorWithEquilibration(bool flag)
Causes equilibration to be called just before the matrix factorization as part of the call to factor.
 
int solveR(ETransp transr, SerialDenseMatrix< OrdinalType, ScalarType > &C)
Solve input matrix on the left with the upper triangular matrix R or its adjoint.
 
bool solved()
Returns true if the current set of vectors has been solved.
 
bool equilibratedB()
Returns true if RHS is equilibrated (RHS available via getRHS()).
 
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getLHS() const
Returns pointer to current LHS.
 
bool formedR()
Returns true if R has been formed explicitly.
 
int formR()
Explicitly forms the upper triangular matrix R.
 
bool shouldEquilibrate()
Returns true if the LAPACK general rules for equilibration suggest you should equilibrate the system.
 
int setVectors(const RCP< SerialDenseMatrix< OrdinalType, ScalarType > > &X, const RCP< SerialDenseMatrix< OrdinalType, ScalarType > > &B)
Sets the pointers for left and right hand side vector(s).
 
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getMatrix() const
Returns pointer to current matrix.
 
void solveWithTranspose(bool flag)
If flag is true, causes all subsequent function calls to work with the adjoint of this matrix,...
 
bool transpose()
Returns true if adjoint of this matrix has and will be used.
 
int multiplyQ(ETransp transq, SerialDenseMatrix< OrdinalType, ScalarType > &C)
Left multiply the input matrix by the unitary matrix Q or its adjoint.
 
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getQ() const
Returns pointer to Q (assuming factorization has been performed).
 
MagnitudeType ANORM() const
Returns the absolute value of the largest element of this matrix (returns -1 if not yet computed).
 
OrdinalType numCols() const
Returns column dimension of system.
 
bool formedQ()
Returns true if Q has been formed explicitly.
 
std::vector< ScalarType > tau() const
Returns pointer to pivot vector (if factorization has been computed), zero otherwise.
 
OrdinalType numRows() const
Returns row dimension of system.
 
virtual ~SerialQRDenseSolver()
SerialQRDenseSolver destructor.
 
int factor()
Computes the in-place QR factorization of the matrix using the LAPACK routine _GETRF or the Eigen cla...
 
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getFactoredMatrix() const
Returns pointer to factored matrix (assuming factorization has been performed).
 
int solve()
Computes the solution X to AX = B for the this matrix and the B provided to SetVectors()....
 
SerialQRDenseSolver()
Default constructor; matrix should be set using setMatrix(), LHS and RHS set with setVectors().
 
void solveWithTransposeFlag(Teuchos::ETransp trans)
All subsequent function calls will work with the transpose-type set by this method (Teuchos::NO_TRANS...
 
bool factored()
Returns true if matrix is factored (factor available via getFactoredMatrix()).
 
void Print(std::ostream &os) const
Print service methods; defines behavior of ostream << operator.
 
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getR() const
Returns pointer to R (assuming factorization has been performed).
 
int setMatrix(const RCP< SerialDenseMatrix< OrdinalType, ScalarType > > &A)
Sets the pointers for coefficient matrix.
 
int formQ()
Explicitly forms the unitary matrix Q.
 
int equilibrateMatrix()
Equilibrates the this matrix.
 
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getRHS() const
Returns pointer to current RHS.
 
int equilibrateRHS()
Equilibrates the current RHS.
 
bool equilibratedA()
Returns true if factor is equilibrated (factor available via getFactoredMatrix()).
 
int computeEquilibrateScaling()
Determines if this matrix should be scaled.
 
int unequilibrateLHS()
Unscales the solution vectors if equilibration was used to solve the system.
 
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
 
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos,...
 
Teuchos implementation details.
 
This structure defines some basic traits for a scalar field type.
 
static magnitudeType magnitude(T a)
Returns the magnitudeType of the scalar type a.
 
static T one()
Returns representation of one for this scalar type.
 
static T zero()
Returns representation of zero for this scalar type.
 
static magnitudeType sfmin()
Returns safe minimum (sfmin), such that 1/sfmin does not overflow.
 
static magnitudeType prec()
Returns eps*base.