10#ifndef _TEUCHOS_SERIALDENSESOLVER_HPP_ 
   11#define _TEUCHOS_SERIALDENSESOLVER_HPP_ 
   24#ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  104  template<
typename OrdinalType, 
typename ScalarType>
 
  106                            public LAPACK<OrdinalType, ScalarType>
 
  112#ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  113    typedef typename Eigen::Matrix<ScalarType,Eigen::Dynamic,Eigen::Dynamic,Eigen::ColMajor> 
EigenMatrix;
 
  114    typedef typename Eigen::Matrix<ScalarType,Eigen::Dynamic,1> 
EigenVector;
 
  117    typedef typename Eigen::Map<EigenVector,0,EigenInnerStride > 
EigenVectorMap;
 
  119    typedef typename Eigen::Map<EigenMatrix,0,EigenOuterStride > 
EigenMatrixMap;
 
  121    typedef typename Eigen::PermutationMatrix<Eigen::Dynamic,Eigen::Dynamic,OrdinalType> 
EigenPermutationMatrix;
 
  124    typedef typename Eigen::Array<ScalarType,Eigen::Dynamic,1> 
EigenScalarArray;
 
  303    std::vector<OrdinalType> 
IPIV()
  const {
return(IPIV_);}
 
  306    MagnitudeType 
ANORM()
  const {
return(ANORM_);}
 
  309    MagnitudeType 
RCOND()
  const {
return(RCOND_);}
 
  314    MagnitudeType 
ROWCND()
  const {
return(ROWCND_);}
 
  319    MagnitudeType 
COLCND()
  const {
return(COLCND_);}
 
  322    MagnitudeType 
AMAX()
  const {
return(AMAX_);}
 
  325    std::vector<MagnitudeType> 
FERR()
  const {
return(FERR_);}
 
  328    std::vector<MagnitudeType> 
BERR()
  const {
return(BERR_);}
 
  331    std::vector<MagnitudeType> 
R()
  const {
return(R_);}
 
  334    std::vector<MagnitudeType> 
C()
  const {
return(C_);}
 
  340    void Print(std::ostream& os) 
const;
 
  344    void allocateWORK() { LWORK_ = 4*N_; WORK_.resize( LWORK_ ); 
return;}
 
  350    bool shouldEquilibrate_;
 
  355    bool estimateSolutionErrors_;
 
  356    bool solutionErrorsEstimated_;
 
  359    bool reciprocalConditionEstimated_;
 
  360    bool refineSolution_;
 
  361    bool solutionRefined_;
 
  373    std::vector<OrdinalType> IPIV_;
 
  375    MagnitudeType ANORM_;
 
  376    MagnitudeType RCOND_;
 
  377    MagnitudeType ROWCND_;
 
  378    MagnitudeType COLCND_;
 
  381    RCP<SerialDenseMatrix<OrdinalType, ScalarType> > Matrix_;
 
  382    RCP<SerialDenseMatrix<OrdinalType, ScalarType> > LHS_;
 
  383    RCP<SerialDenseMatrix<OrdinalType, ScalarType> > RHS_;
 
  384    RCP<SerialDenseMatrix<OrdinalType, ScalarType> > Factor_;
 
  388    std::vector<MagnitudeType> FERR_;
 
  389    std::vector<MagnitudeType> BERR_;
 
  390    std::vector<ScalarType> WORK_;
 
  391    std::vector<MagnitudeType> R_;
 
  392    std::vector<MagnitudeType> C_;
 
  393#ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  394    Eigen::PartialPivLU<EigenMatrix> lu_;
 
  401    SerialDenseSolver & operator=(
const SerialDenseSolver<OrdinalType, ScalarType>& Source);
 
 
  409    struct lapack_traits {
 
  410      typedef int iwork_type;
 
  415    struct lapack_traits<std::complex<T> > {
 
  423template<
typename OrdinalType, 
typename ScalarType>
 
  427    shouldEquilibrate_(
false),
 
  428    equilibratedA_(
false),
 
  429    equilibratedB_(
false),
 
  432    estimateSolutionErrors_(
false),
 
  433    solutionErrorsEstimated_(
false),
 
  436    reciprocalConditionEstimated_(
false),
 
  437    refineSolution_(
false),
 
  438    solutionRefined_(
false),
 
 
  459template<
typename OrdinalType, 
typename ScalarType>
 
  465template<
typename OrdinalType, 
typename ScalarType>
 
  468  LHS_ = Teuchos::null;
 
  469  RHS_ = Teuchos::null;
 
  470  reciprocalConditionEstimated_ = 
false;
 
  471  solutionRefined_ = 
false;
 
  473  solutionErrorsEstimated_ = 
false;
 
  474  equilibratedB_ = 
false;
 
  478template<
typename OrdinalType, 
typename ScalarType>
 
  479void SerialDenseSolver<OrdinalType,ScalarType>::resetMatrix()
 
  482  equilibratedA_ = 
false;
 
  504template<
typename OrdinalType, 
typename ScalarType>
 
  512  Min_MN_ = TEUCHOS_MIN(M_,N_);
 
 
  521template<
typename OrdinalType, 
typename ScalarType>
 
  527                     "SerialDenseSolver<T>::setVectors: X and B are not the same size!");
 
  529                     "SerialDenseSolver<T>::setVectors: B is an empty SerialDenseMatrix<T>!");
 
  531                     "SerialDenseSolver<T>::setVectors: X is an empty SerialDenseMatrix<T>!");
 
  533                     "SerialDenseSolver<T>::setVectors: B has an invalid stride!");
 
  535                     "SerialDenseSolver<T>::setVectors: X has an invalid stride!");
 
 
  544template<
typename OrdinalType, 
typename ScalarType>
 
  547  estimateSolutionErrors_ = 
flag;
 
  550  refineSolution_ = refineSolution_ || 
flag;
 
 
  554template<
typename OrdinalType, 
typename ScalarType>
 
  557  if (factored()) 
return(0); 
 
  560                     "SerialDenseSolver<T>::factor: Cannot factor an inverted matrix!");
 
  562  ANORM_ = Matrix_->normOne(); 
 
  569    if (refineSolution_ ) {
 
  571      AF_ = Factor_->values();
 
  572      LDAF_ = Factor_->stride();
 
  576  if (equilibrate_) 
ierr = equilibrateMatrix();
 
  580  if ((
int)IPIV_.size()!=Min_MN_) IPIV_.resize( Min_MN_ ); 
 
  584#ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  591  p = 
lu_.permutationP();
 
  604  this->GETRF(M_, N_, AF_, LDAF_, &IPIV_[0], &INFO_);
 
 
  614template<
typename OrdinalType, 
typename ScalarType>
 
  628    ierr = equilibrateRHS();
 
  633                     "SerialDenseSolver<T>::solve: No right-hand side vector (RHS) has been set for the linear system!");
 
  635                     "SerialDenseSolver<T>::solve: No solution vector (LHS) has been set for the linear system!");
 
  640                        "SerialDenseSolver<T>::solve: X and B must be different vectors if matrix is inverted.");
 
  642                                 std::logic_error, 
"SerialDenseSolver<T>::solve: Matrix and vectors must be similarly scaled!");
 
  646               RHS_->values(), RHS_->stride(), 0.0, LHS_->values(), LHS_->stride());
 
  647    if (INFO_!=0) 
return(INFO_);
 
  652    if (!factored()) factor(); 
 
  655                                 std::logic_error, 
"SerialDenseSolver<T>::solve: Matrix and vectors must be similarly scaled!");
 
  657    if (RHS_->values()!=LHS_->values()) {
 
  662#ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  679    this->GETRS(ETranspChar[TRANS_], N_, RHS_->numCols(), AF_, LDAF_, &IPIV_[0], LHS_->values(), LHS_->stride(), &INFO_);
 
  682    if (INFO_!=0) 
return(INFO_);
 
  688  if (shouldEquilibrate() && !equilibratedA_)
 
  689    std::cout << 
"WARNING!  SerialDenseSolver<T>::solve: System should be equilibrated!" << std::endl;
 
  692  if (refineSolution_ && !inverted()) 
ierr1 = applyRefinement();
 
  696  if (equilibrate_) 
ierr1 = unequilibrateLHS();
 
 
  701template<
typename OrdinalType, 
typename ScalarType>
 
  705                     "SerialDenseSolver<T>::applyRefinement: Must have an existing solution!");
 
  707                     "SerialDenseSolver<T>::applyRefinement: Cannot apply refinement if no original copy of A!");
 
  709#ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  715  FERR_.resize( 
NRHS );
 
  716  BERR_.resize( 
NRHS );
 
  720  std::vector<typename details::lapack_traits<ScalarType>::iwork_type> 
GERFS_WORK( N_ );
 
  721  this->GERFS(ETranspChar[TRANS_], N_, 
NRHS, A_, LDA_, AF_, LDAF_, &IPIV_[0],
 
  722              RHS_->values(), RHS_->stride(), LHS_->values(), LHS_->stride(),
 
  723              &FERR_[0], &BERR_[0], &WORK_[0], &
GERFS_WORK[0], &INFO_);
 
  725  solutionErrorsEstimated_ = 
true;
 
  726  reciprocalConditionEstimated_ = 
true;
 
  727  solutionRefined_ = 
true;
 
 
  735template<
typename OrdinalType, 
typename ScalarType>
 
  738  if (R_.size()!=0) 
return(0); 
 
  744  this->GEEQU (M_, N_, AF_, LDAF_, &R_[0], &C_[0], &ROWCND_, &COLCND_, &AMAX_, &INFO_);
 
  749    shouldEquilibrate_ = 
true;
 
 
  756template<
typename OrdinalType, 
typename ScalarType>
 
  762  if (equilibratedA_) 
return(0); 
 
  763  if (R_.size()==0) 
ierr = computeEquilibrateScaling(); 
 
  767    for (
j=0; 
j<N_; 
j++) {
 
  770      for (
i=0; 
i<M_; 
i++) {
 
  779    for (
j=0; 
j<N_; 
j++) {
 
  781      ptr1 = AF_ + 
j*LDAF_;
 
  783      for (
i=0; 
i<M_; 
i++) {
 
  792  equilibratedA_ = 
true;
 
 
  799template<
typename OrdinalType, 
typename ScalarType>
 
  805  if (equilibratedB_) 
return(0); 
 
  806  if (R_.size()==0) 
ierr = computeEquilibrateScaling(); 
 
  809  MagnitudeType * 
R_tmp = &R_[0];
 
  810  if (transpose_) 
R_tmp = &C_[0];
 
  817    for (
i=0; 
i<M_; 
i++) {
 
  823  equilibratedB_ = 
true;
 
 
  830template<
typename OrdinalType, 
typename ScalarType>
 
  835  if (!equilibratedB_) 
return(0); 
 
  837  MagnitudeType * 
C_tmp = &C_[0];
 
  838  if (transpose_) 
C_tmp = &R_[0];
 
  845    for (
i=0; 
i<N_; 
i++) {
 
 
  856template<
typename OrdinalType, 
typename ScalarType>
 
  860  if (!factored()) factor(); 
 
  862#ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  887  this->GETRI( N_, AF_, LDAF_, &IPIV_[0], &WORK_[0], LWORK_, &INFO_);
 
 
  899template<
typename OrdinalType, 
typename ScalarType>
 
  902#ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  906  if (reciprocalConditionEstimated()) {
 
  914  if (!factored()) 
ierr = factor(); 
 
  921  std::vector<typename details::lapack_traits<ScalarType>::iwork_type> 
GECON_WORK( 2*N_ );
 
  922  this->GECON( 
'1', N_, AF_, LDAF_, ANORM_, &RCOND_, &WORK_[0], &
GECON_WORK[0], &INFO_);
 
  924  reciprocalConditionEstimated_ = 
true;
 
 
  932template<
typename OrdinalType, 
typename ScalarType>
 
  935  if (Matrix_!=Teuchos::null) os << 
"Solver Matrix"          << std::endl << *Matrix_ << std::endl;
 
  936  if (Factor_!=Teuchos::null) os << 
"Solver Factored Matrix" << std::endl << *Factor_ << std::endl;
 
  937  if (LHS_   !=Teuchos::null) os << 
"Solver LHS"             << std::endl << *LHS_    << std::endl;
 
  938  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.
 
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.
 
Ptr< T > ptr() const
Get a safer wrapper raw C++ pointer to the underlying object.
 
A class for solving dense linear problems.
 
std::vector< MagnitudeType > BERR() const
Returns a pointer to the backward error estimates computed by LAPACK.
 
MagnitudeType ROWCND() const
Ratio of smallest to largest row scale factors for the this matrix (returns -1 if not yet computed).
 
bool solutionRefined()
Returns true if the current set of vectors has been refined.
 
void factorWithEquilibration(bool flag)
Causes equilibration to be called just before the matrix factorization as part of the call to factor.
 
OrdinalType numRows() const
Returns row dimension of system.
 
bool factored()
Returns true if matrix is factored (factor available via getFactoredMatrix()).
 
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getRHS() const
Returns pointer to current RHS.
 
MagnitudeType RCOND() const
Returns the reciprocal of the condition number of the this matrix (returns -1 if not yet computed).
 
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getLHS() const
Returns pointer to current LHS.
 
std::vector< MagnitudeType > C() const
Returns a pointer to the column scale vector used for equilibration.
 
int setMatrix(const RCP< SerialDenseMatrix< OrdinalType, ScalarType > > &A)
Sets the pointers for coefficient matrix.
 
int computeEquilibrateScaling()
Computes the scaling vector S(i) = 1/sqrt(A(i,i)) of the this matrix.
 
int equilibrateRHS()
Equilibrates the current RHS.
 
bool inverted()
Returns true if matrix inverse has been computed (inverse available via getFactoredMatrix()).
 
bool equilibratedA()
Returns true if factor is equilibrated (factor available via getFactoredMatrix()).
 
MagnitudeType COLCND() const
Ratio of smallest to largest column scale factors for the this matrix (returns -1 if not yet computed...
 
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getMatrix() const
Returns pointer to current matrix.
 
bool shouldEquilibrate()
Returns true if the LAPACK general rules for equilibration suggest you should equilibrate the system.
 
bool solved()
Returns true if the current set of vectors has been solved.
 
std::vector< MagnitudeType > FERR() const
Returns a pointer to the forward error estimates computed by LAPACK.
 
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getFactoredMatrix() const
Returns pointer to factored matrix (assuming factorization has been performed).
 
void estimateSolutionErrors(bool flag)
Causes all solves to estimate the forward and backward solution error.
 
int invert()
Inverts the this matrix.
 
int factor()
Computes the in-place LU factorization of the matrix using the LAPACK routine _GETRF.
 
int equilibrateMatrix()
Equilibrates the this matrix.
 
void solveWithTransposeFlag(Teuchos::ETransp trans)
All subsequent function calls will work with the transpose-type set by this method (Teuchos::NO_TRANS...
 
bool reciprocalConditionEstimated()
Returns true if the condition number of the this matrix has been computed (value available via Recipr...
 
int reciprocalConditionEstimate(MagnitudeType &Value)
Returns the reciprocal of the 1-norm condition number of the this matrix.
 
void Print(std::ostream &os) const
Print service methods; defines behavior of ostream << operator.
 
int applyRefinement()
Apply Iterative Refinement.
 
int unequilibrateLHS()
Unscales the solution vectors if equilibration was used to solve the system.
 
MagnitudeType AMAX() const
Returns the absolute value of the largest entry of the this matrix (returns -1 if not yet computed).
 
void solveToRefinedSolution(bool flag)
Causes all solves to compute solution to best ability using iterative refinement.
 
void solveWithTranspose(bool flag)
If flag is true, causes all subsequent function calls to work with the transpose of this matrix,...
 
virtual ~SerialDenseSolver()
SerialDenseSolver destructor.
 
SerialDenseSolver()
Default constructor; matrix should be set using setMatrix(), LHS and RHS set with setVectors().
 
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).
 
OrdinalType numCols() const
Returns column dimension of system.
 
bool transpose()
Returns true if transpose of this matrix has and will be used.
 
std::vector< OrdinalType > IPIV() const
Returns pointer to pivot vector (if factorization has been computed), zero otherwise.
 
MagnitudeType ANORM() const
Returns the 1-Norm of the this matrix (returns -1 if not yet computed).
 
bool equilibratedB()
Returns true if RHS is equilibrated (RHS available via getRHS()).
 
int solve()
Computes the solution X to AX = B for the this matrix and the B provided to SetVectors()....
 
std::vector< MagnitudeType > R() const
Returns a pointer to the row scaling vector used for equilibration.
 
bool solutionErrorsEstimated()
Returns true if forward and backward error estimated have been computed (available via FERR() and BER...
 
#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 T one()
Returns representation of one for this scalar type.
 
T magnitudeType
Mandatory typedef for result of magnitude.