11#ifndef TEUCHOS_SERIALSPDDENSESOLVER_H 
   12#define TEUCHOS_SERIALSPDDENSESOLVER_H 
   27#ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  100  template<
typename OrdinalType, 
typename ScalarType>
 
  102                            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;
 
  284    MagnitudeType 
ANORM()
  const {
return(ANORM_);}
 
  287    MagnitudeType 
RCOND()
  const {
return(RCOND_);}
 
  292    MagnitudeType 
SCOND() {
return(SCOND_);};
 
  295    MagnitudeType 
AMAX()
  const {
return(AMAX_);}
 
  298    std::vector<MagnitudeType> 
FERR()
  const {
return(FERR_);}
 
  301    std::vector<MagnitudeType> 
BERR()
  const {
return(BERR_);}
 
  304    std::vector<MagnitudeType> 
R()
  const {
return(R_);}
 
  311    void Print(std::ostream& os) 
const;
 
  316    void allocateWORK() { LWORK_ = 4*numRowCols_; WORK_.resize( LWORK_ ); 
return;}
 
  317    void allocateIWORK() { IWORK_.resize( numRowCols_ ); 
return;}
 
  322    bool shouldEquilibrate_;
 
  327    bool estimateSolutionErrors_;
 
  328    bool solutionErrorsEstimated_;
 
  331    bool reciprocalConditionEstimated_;
 
  332    bool refineSolution_;
 
  333    bool solutionRefined_;
 
  335    OrdinalType numRowCols_;
 
  341    std::vector<int> IWORK_;
 
  343    MagnitudeType ANORM_;
 
  344    MagnitudeType RCOND_;
 
  345    MagnitudeType SCOND_;
 
  348    RCP<SerialSymDenseMatrix<OrdinalType, ScalarType> > Matrix_;
 
  349    RCP<SerialDenseMatrix<OrdinalType, ScalarType> > LHS_;
 
  350    RCP<SerialDenseMatrix<OrdinalType, ScalarType> > RHS_;
 
  351    RCP<SerialSymDenseMatrix<OrdinalType, ScalarType> > Factor_;
 
  355    std::vector<MagnitudeType> FERR_;
 
  356    std::vector<MagnitudeType> BERR_;
 
  357    std::vector<ScalarType> WORK_;
 
  358    std::vector<MagnitudeType> R_;
 
  359#ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  360    Eigen::LLT<EigenMatrix,Eigen::Upper> lltu_;
 
  361    Eigen::LLT<EigenMatrix,Eigen::Lower> lltl_;
 
 
  377template<
typename OrdinalType, 
typename ScalarType>
 
  381    shouldEquilibrate_(
false),
 
  382    equilibratedA_(
false),
 
  383    equilibratedB_(
false),
 
  386    estimateSolutionErrors_(
false),
 
  387    solutionErrorsEstimated_(
false),
 
  390    reciprocalConditionEstimated_(
false),
 
  391    refineSolution_(
false),
 
  392    solutionRefined_(
false),
 
 
  409template<
typename OrdinalType, 
typename ScalarType>
 
  415template<
typename OrdinalType, 
typename ScalarType>
 
  418  LHS_ = Teuchos::null;
 
  419  RHS_ = Teuchos::null;
 
  420  reciprocalConditionEstimated_ = 
false;
 
  421  solutionRefined_ = 
false;
 
  423  solutionErrorsEstimated_ = 
false;
 
  424  equilibratedB_ = 
false;
 
  428template<
typename OrdinalType, 
typename ScalarType>
 
  429void SerialSpdDenseSolver<OrdinalType,ScalarType>::resetMatrix()
 
  432  equilibratedA_ = 
false;
 
  450template<
typename OrdinalType, 
typename ScalarType>
 
  456  numRowCols_ = 
A->numRows();
 
 
  465template<
typename OrdinalType, 
typename ScalarType>
 
  471                     "SerialSpdDenseSolver<T>::setVectors: X and B are not the same size!");
 
  473                     "SerialSpdDenseSolver<T>::setVectors: B is an empty SerialDenseMatrix<T>!");
 
  475                     "SerialSpdDenseSolver<T>::setVectors: X is an empty SerialDenseMatrix<T>!");
 
  477                     "SerialSpdDenseSolver<T>::setVectors: B has an invalid stride!");
 
  479                     "SerialSpdDenseSolver<T>::setVectors: X has an invalid stride!");
 
 
  488template<
typename OrdinalType, 
typename ScalarType>
 
  491  estimateSolutionErrors_ = 
flag;
 
  494  refineSolution_ = refineSolution_ || 
flag;
 
 
  498template<
typename OrdinalType, 
typename ScalarType>
 
  501  if (factored()) 
return(0); 
 
  504                     "SerialSpdDenseSolver<T>::factor: Cannot factor an inverted matrix!");
 
  506  ANORM_ = Matrix_->normOne(); 
 
  513    if (refineSolution_ ) {
 
  515      AF_ = Factor_->values();
 
  516      LDAF_ = Factor_->stride();
 
  520  if (equilibrate_) 
ierr = equilibrateMatrix();
 
  526#ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  529  if (Matrix_->upper())
 
  535  this->POTRF(Matrix_->UPLO(), numRowCols_, AF_, LDAF_, &INFO_);
 
 
  545template<
typename OrdinalType, 
typename ScalarType>
 
  559    ierr = equilibrateRHS();
 
  564                     "SerialSpdDenseSolver<T>::solve: No right-hand side vector (RHS) has been set for the linear system!");
 
  566                     "SerialSpdDenseSolver<T>::solve: No solution vector (LHS) has been set for the linear system!");
 
  571                        "SerialSpdDenseSolver<T>::solve: X and B must be different vectors if matrix is inverted.");
 
  573                        std::logic_error, 
"SerialSpdDenseSolver<T>::solve: Matrix and vectors must be similarly scaled!");
 
  577               numRowCols_, 1.0, AF_, LDAF_, RHS_->values(), RHS_->stride(), 0.0,
 
  578               LHS_->values(), LHS_->stride());
 
  579    if (INFO_!=0) 
return(INFO_);
 
  584    if (!factored()) factor(); 
 
  587                        std::logic_error, 
"SerialSpdDenseSolver<T>::solve: Matrix and vectors must be similarly scaled!");
 
  589    if (RHS_->values()!=LHS_->values()) {
 
  594#ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  598  if (Matrix_->upper())
 
  604    this->POTRS(Matrix_->UPLO(), numRowCols_, RHS_->numCols(), AF_, LDAF_, LHS_->values(), LHS_->stride(), &INFO_);
 
  607    if (INFO_!=0) 
return(INFO_);
 
  613  if (shouldEquilibrate() && !equilibratedA_)
 
  614    std::cout << 
"WARNING!  SerialSpdDenseSolver<T>::solve: System should be equilibrated!" << std::endl;
 
  617  if (refineSolution_ && !inverted()) 
ierr1 = applyRefinement();
 
  621  if (equilibrate_) 
ierr1 = unequilibrateLHS();
 
 
  626template<
typename OrdinalType, 
typename ScalarType>
 
  630                     "SerialSpdDenseSolver<T>::applyRefinement: Must have an existing solution!");
 
  632                     "SerialSpdDenseSolver<T>::applyRefinement: Cannot apply refinement if no original copy of A!");
 
  635#ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  640  FERR_.resize( 
NRHS );
 
  641  BERR_.resize( 
NRHS );
 
  646  std::vector<typename details::lapack_traits<ScalarType>::iwork_type> 
PORFS_WORK( numRowCols_ );
 
  647  this->PORFS(Matrix_->UPLO(), numRowCols_, 
NRHS, A_, LDA_, AF_, LDAF_,
 
  648              RHS_->values(), RHS_->stride(), LHS_->values(), LHS_->stride(),
 
  649              &FERR_[0], &BERR_[0], &WORK_[0], &
PORFS_WORK[0], &INFO_);
 
  651  solutionErrorsEstimated_ = 
true;
 
  652  reciprocalConditionEstimated_ = 
true;
 
  653  solutionRefined_ = 
true;
 
 
  661template<
typename OrdinalType, 
typename ScalarType>
 
  664  if (R_.size()!=0) 
return(0); 
 
  666  R_.resize( numRowCols_ );
 
  669  this->POEQU (numRowCols_, AF_, LDAF_, &R_[0], &SCOND_, &AMAX_, &INFO_);
 
  673    shouldEquilibrate_ = 
true;
 
 
  680template<
typename OrdinalType, 
typename ScalarType>
 
  686  if (equilibratedA_) 
return(0); 
 
  687  if (R_.size()==0) 
ierr = computeEquilibrateScaling(); 
 
  689  if (Matrix_->upper()) {
 
  692      for (
j=0; 
j<numRowCols_; 
j++) {
 
  695        for (
i=0; 
i<=
j; 
i++) {
 
  704      for (
j=0; 
j<numRowCols_; 
j++) {
 
  706        ptr1 = AF_ + 
j*LDAF_;
 
  708        for (
i=0; 
i<=
j; 
i++) {
 
  720      for (
j=0; 
j<numRowCols_; 
j++) {
 
  721        ptr = A_ + 
j + 
j*LDA_;
 
  723        for (
i=
j; 
i<numRowCols_; 
i++) {
 
  732      for (
j=0; 
j<numRowCols_; 
j++) {
 
  733        ptr = A_ + 
j + 
j*LDA_;
 
  736        for (
i=
j; 
i<numRowCols_; 
i++) {
 
  746  equilibratedA_ = 
true;
 
 
  753template<
typename OrdinalType, 
typename ScalarType>
 
  759  if (equilibratedB_) 
return(0); 
 
  760  if (R_.size()==0) 
ierr = computeEquilibrateScaling(); 
 
  768    for (
i=0; 
i<numRowCols_; 
i++) {
 
  774  equilibratedB_ = 
true;
 
 
  781template<
typename OrdinalType, 
typename ScalarType>
 
  786  if (!equilibratedB_) 
return(0); 
 
  793    for (
i=0; 
i<numRowCols_; 
i++) {
 
 
  804template<
typename OrdinalType, 
typename ScalarType>
 
  807#ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  811  if (!factored()) factor(); 
 
  814  this->POTRI( Matrix_->UPLO(), numRowCols_, AF_, LDAF_, &INFO_);
 
  817  if (Matrix_->upper())
 
 
  831template<
typename OrdinalType, 
typename ScalarType>
 
  834#ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  838  if (reciprocalConditionEstimated()) {
 
  846  if (!factored()) 
ierr = factor(); 
 
  854  std::vector<typename details::lapack_traits<ScalarType>::iwork_type> 
POCON_WORK( numRowCols_ );
 
  855  this->POCON( Matrix_->UPLO(), numRowCols_, AF_, LDAF_, ANORM_, &RCOND_, &WORK_[0], &
POCON_WORK[0], &INFO_);
 
  856  reciprocalConditionEstimated_ = 
true;
 
 
  864template<
typename OrdinalType, 
typename ScalarType>
 
  867  if (Matrix_!=Teuchos::null) os << 
"Solver Matrix"          << std::endl << *Matrix_ << std::endl;
 
  868  if (Factor_!=Teuchos::null) os << 
"Solver Factored Matrix" << std::endl << *Factor_ << std::endl;
 
  869  if (LHS_   !=Teuchos::null) os << 
"Solver LHS"             << std::endl << *LHS_    << std::endl;
 
  870  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.
 
Templated serial dense matrix class.
 
Templated class for solving dense linear problems.
 
Templated serial, dense, symmetric 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 constructing and using Hermitian positive definite dense matrices.
 
MagnitudeType SCOND()
Ratio of smallest to largest equilibration scale factors for the this matrix (returns -1 if not yet c...
 
int setMatrix(const RCP< SerialSymDenseMatrix< OrdinalType, ScalarType > > &A_in)
Sets the pointers for coefficient matrix.
 
OrdinalType numCols() const
Returns column dimension of system.
 
std::vector< MagnitudeType > FERR() const
Returns a pointer to the forward error estimates computed by LAPACK.
 
int applyRefinement()
Apply Iterative Refinement.
 
bool transpose()
Returns true if transpose of this matrix has and will be used.
 
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.
 
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).
 
int factor()
Computes the in-place Cholesky factorization of the matrix using the LAPACK routine DPOTRF.
 
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getRHS() const
Returns pointer to current RHS.
 
void estimateSolutionErrors(bool flag)
Causes all solves to estimate the forward and backward solution error.
 
bool solutionRefined()
Returns true if the current set of vectors has been refined.
 
virtual ~SerialSpdDenseSolver()
SerialSpdDenseSolver destructor.
 
RCP< SerialSymDenseMatrix< OrdinalType, ScalarType > > getMatrix() const
Returns pointer to current matrix.
 
bool solved()
Returns true if the current set of vectors has been solved.
 
bool reciprocalConditionEstimated()
Returns true if the condition number of the this matrix has been computed (value available via Recipr...
 
RCP< SerialSymDenseMatrix< OrdinalType, ScalarType > > getFactoredMatrix() const
Returns pointer to factored matrix (assuming factorization has been performed).
 
void solveToRefinedSolution(bool flag)
Causes all solves to compute solution to best ability using iterative refinement.
 
OrdinalType numRows() const
Returns row dimension of system.
 
MagnitudeType ANORM() const
Returns the 1-Norm of the this matrix (returns -1 if not yet computed).
 
bool solutionErrorsEstimated()
Returns true if forward and backward error estimated have been computed (available via FERR() and BER...
 
MagnitudeType AMAX() const
Returns the absolute value of the largest entry of the this matrix (returns -1 if not yet computed).
 
bool factored()
Returns true if matrix is factored (factor available via AF() and LDAF()).
 
void Print(std::ostream &os) const
Print service methods; defines behavior of ostream << operator.
 
SerialSpdDenseSolver()
Default constructor; matrix should be set using setMatrix(), LHS and RHS set with setVectors().
 
std::vector< MagnitudeType > BERR() const
Returns a pointer to the backward error estimates computed by LAPACK.
 
int unequilibrateLHS()
Unscales the solution vectors if equilibration was used to solve the system.
 
void factorWithEquilibration(bool flag)
Causes equilibration to be called just before the matrix factorization as part of the call to factor.
 
int equilibrateMatrix()
Equilibrates the this matrix.
 
int invert()
Inverts the this matrix.
 
int reciprocalConditionEstimate(MagnitudeType &Value)
Returns the reciprocal of the 1-norm condition number of the this matrix.
 
bool equilibratedB()
Returns true if RHS is equilibrated (RHS available via B() and LDB()).
 
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getLHS() const
Returns pointer to current LHS.
 
bool inverted()
Returns true if matrix inverse has been computed (inverse available via AF() and LDAF()).
 
int computeEquilibrateScaling()
Computes the scaling vector S(i) = 1/sqrt(A(i,i) of the this matrix.
 
MagnitudeType RCOND() const
Returns the reciprocal of the condition number of the this matrix (returns -1 if not yet computed).
 
int equilibrateRHS()
Equilibrates the current RHS.
 
bool shouldEquilibrate()
Returns true if the LAPACK general rules for equilibration suggest you should equilibrate the system.
 
bool equilibratedA()
Returns true if factor is equilibrated (factor available via AF() and LDAF()).
 
#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.