43 #ifndef TEUCHOS_SERIALSPDDENSESOLVER_H 
   44 #define TEUCHOS_SERIALSPDDENSESOLVER_H 
   59 #ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
   60 #include "Eigen/Dense" 
  132   template<
typename OrdinalType, 
typename ScalarType>
 
  134                             public LAPACK<OrdinalType, ScalarType>
 
  139 #ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  140     typedef typename Eigen::Matrix<ScalarType,Eigen::Dynamic,Eigen::Dynamic,Eigen::ColMajor> EigenMatrix;
 
  141     typedef typename Eigen::Matrix<ScalarType,Eigen::Dynamic,1> EigenVector;
 
  142     typedef typename Eigen::InnerStride<Eigen::Dynamic> EigenInnerStride;
 
  143     typedef typename Eigen::OuterStride<Eigen::Dynamic> EigenOuterStride;
 
  144     typedef typename Eigen::Map<EigenVector,0,EigenInnerStride > EigenVectorMap;
 
  145     typedef typename Eigen::Map<const EigenVector,0,EigenInnerStride > EigenConstVectorMap;
 
  146     typedef typename Eigen::Map<EigenMatrix,0,EigenOuterStride > EigenMatrixMap;
 
  147     typedef typename Eigen::Map<const EigenMatrix,0,EigenOuterStride > EigenConstMatrixMap;
 
  148     typedef typename Eigen::PermutationMatrix<Eigen::Dynamic,Eigen::Dynamic,OrdinalType> EigenPermutationMatrix;
 
  149     typedef typename Eigen::Array<OrdinalType,Eigen::Dynamic,1> EigenOrdinalArray;
 
  150     typedef typename Eigen::Map<EigenOrdinalArray> EigenOrdinalArrayMap;
 
  151     typedef typename Eigen::Array<ScalarType,Eigen::Dynamic,1> EigenScalarArray;
 
  152     typedef typename Eigen::Map<EigenScalarArray> EigenScalarArrayMap;
 
  310     OrdinalType 
numRows()
  const {
return(numRowCols_);}
 
  313     OrdinalType 
numCols()
  const {
return(numRowCols_);}
 
  316     MagnitudeType 
ANORM()
  const {
return(ANORM_);}
 
  319     MagnitudeType 
RCOND()
  const {
return(RCOND_);}
 
  324     MagnitudeType 
SCOND() {
return(SCOND_);};
 
  327     MagnitudeType 
AMAX()
  const {
return(AMAX_);}
 
  330     std::vector<MagnitudeType> 
FERR()
  const {
return(FERR_);}
 
  333     std::vector<MagnitudeType> 
BERR()
  const {
return(BERR_);}
 
  336     std::vector<MagnitudeType> 
R()
  const {
return(R_);}
 
  342     void Print(std::ostream& os) 
const;
 
  348     void allocateWORK() { LWORK_ = 4*numRowCols_; WORK_.resize( LWORK_ ); 
return;}
 
  349     void allocateIWORK() { IWORK_.resize( numRowCols_ ); 
return;}
 
  354     bool shouldEquilibrate_;
 
  359     bool estimateSolutionErrors_;
 
  360     bool solutionErrorsEstimated_;
 
  363     bool reciprocalConditionEstimated_;
 
  364     bool refineSolution_;
 
  365     bool solutionRefined_;
 
  367     OrdinalType numRowCols_;
 
  373     std::vector<int> IWORK_;
 
  375     MagnitudeType ANORM_;
 
  376     MagnitudeType RCOND_;
 
  377     MagnitudeType SCOND_;
 
  380     RCP<SerialSymDenseMatrix<OrdinalType, ScalarType> > Matrix_;
 
  381     RCP<SerialDenseMatrix<OrdinalType, ScalarType> > LHS_;
 
  382     RCP<SerialDenseMatrix<OrdinalType, ScalarType> > RHS_;
 
  383     RCP<SerialSymDenseMatrix<OrdinalType, ScalarType> > Factor_;
 
  387     std::vector<MagnitudeType> FERR_;
 
  388     std::vector<MagnitudeType> BERR_;
 
  389     std::vector<ScalarType> WORK_;
 
  390     std::vector<MagnitudeType> R_;
 
  391 #ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  392     Eigen::LLT<EigenMatrix,Eigen::Upper> lltu_;
 
  393     Eigen::LLT<EigenMatrix,Eigen::Lower> lltl_;
 
  405   using namespace details;
 
  409 template<
typename OrdinalType, 
typename ScalarType>
 
  413     shouldEquilibrate_(false),
 
  414     equilibratedA_(false),
 
  415     equilibratedB_(false),
 
  418     estimateSolutionErrors_(false),
 
  419     solutionErrorsEstimated_(false),
 
  422     reciprocalConditionEstimated_(false),
 
  423     refineSolution_(false),
 
  424     solutionRefined_(false),
 
  441 template<
typename OrdinalType, 
typename ScalarType>
 
  447 template<
typename OrdinalType, 
typename ScalarType>
 
  450   LHS_ = Teuchos::null;
 
  451   RHS_ = Teuchos::null;
 
  452   reciprocalConditionEstimated_ = 
false;
 
  453   solutionRefined_ = 
false;
 
  455   solutionErrorsEstimated_ = 
false;
 
  456   equilibratedB_ = 
false;
 
  460 template<
typename OrdinalType, 
typename ScalarType>
 
  461 void SerialSpdDenseSolver<OrdinalType,ScalarType>::resetMatrix()
 
  464   equilibratedA_ = 
false;
 
  482 template<
typename OrdinalType, 
typename ScalarType>
 
  488   numRowCols_ = A->numRows();
 
  497 template<
typename OrdinalType, 
typename ScalarType>
 
  503                      "SerialSpdDenseSolver<T>::setVectors: X and B are not the same size!");
 
  505                      "SerialSpdDenseSolver<T>::setVectors: B is an empty SerialDenseMatrix<T>!");
 
  507                      "SerialSpdDenseSolver<T>::setVectors: X is an empty SerialDenseMatrix<T>!");
 
  509                      "SerialSpdDenseSolver<T>::setVectors: B has an invalid stride!");
 
  511                      "SerialSpdDenseSolver<T>::setVectors: X has an invalid stride!");
 
  520 template<
typename OrdinalType, 
typename ScalarType>
 
  523   estimateSolutionErrors_ = flag;
 
  526   refineSolution_ = refineSolution_ || flag;
 
  530 template<
typename OrdinalType, 
typename ScalarType>
 
  533   if (factored()) 
return(0); 
 
  536                      "SerialSpdDenseSolver<T>::factor: Cannot factor an inverted matrix!");
 
  538   ANORM_ = Matrix_->normOne(); 
 
  545     if (refineSolution_ ) {
 
  547       AF_ = Factor_->values();
 
  548       LDAF_ = Factor_->stride();
 
  552   if (equilibrate_) ierr = equilibrateMatrix();
 
  554   if (ierr!=0) 
return(ierr);
 
  558 #ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  559   EigenMatrixMap aMap( AF_, numRowCols_, numRowCols_, EigenOuterStride(LDAF_) );
 
  561   if (Matrix_->upper())
 
  567   this->POTRF(Matrix_->UPLO(), numRowCols_, AF_, LDAF_, &INFO_);
 
  577 template<
typename OrdinalType, 
typename ScalarType>
 
  591     ierr = equilibrateRHS();
 
  593   if (ierr != 0) 
return(ierr);  
 
  596                      "SerialSpdDenseSolver<T>::solve: No right-hand side vector (RHS) has been set for the linear system!");
 
  598                      "SerialSpdDenseSolver<T>::solve: No solution vector (LHS) has been set for the linear system!");
 
  603                         "SerialSpdDenseSolver<T>::solve: X and B must be different vectors if matrix is inverted.");
 
  605                         std::logic_error, 
"SerialSpdDenseSolver<T>::solve: Matrix and vectors must be similarly scaled!");
 
  609                numRowCols_, 1.0, AF_, LDAF_, RHS_->values(), RHS_->stride(), 0.0,
 
  610                LHS_->values(), LHS_->stride());
 
  611     if (INFO_!=0) 
return(INFO_);
 
  616     if (!factored()) factor(); 
 
  619                         std::logic_error, 
"SerialSpdDenseSolver<T>::solve: Matrix and vectors must be similarly scaled!");
 
  621     if (RHS_->values()!=LHS_->values()) {
 
  626 #ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  627     EigenMatrixMap rhsMap( RHS_->values(), RHS_->numRows(), RHS_->numCols(), EigenOuterStride(RHS_->stride()) );
 
  628     EigenMatrixMap lhsMap( LHS_->values(), LHS_->numRows(), LHS_->numCols(), EigenOuterStride(LHS_->stride()) );
 
  630   if (Matrix_->upper())
 
  631     lhsMap = lltu_.solve(rhsMap);
 
  633     lhsMap = lltl_.solve(rhsMap);
 
  636     this->POTRS(Matrix_->UPLO(), numRowCols_, RHS_->numCols(), AF_, LDAF_, LHS_->values(), LHS_->stride(), &INFO_);
 
  639     if (INFO_!=0) 
return(INFO_);
 
  645   if (shouldEquilibrate() && !equilibratedA_)
 
  646     std::cout << 
"WARNING!  SerialSpdDenseSolver<T>::solve: System should be equilibrated!" << std::endl;
 
  649   if (refineSolution_ && !inverted()) ierr1 = applyRefinement();
 
  653   if (equilibrate_) ierr1 = unequilibrateLHS();
 
  658 template<
typename OrdinalType, 
typename ScalarType>
 
  662                      "SerialSpdDenseSolver<T>::applyRefinement: Must have an existing solution!");
 
  664                      "SerialSpdDenseSolver<T>::applyRefinement: Cannot apply refinement if no original copy of A!");
 
  667 #ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  671   OrdinalType NRHS = RHS_->numCols();
 
  672   FERR_.resize( NRHS );
 
  673   BERR_.resize( NRHS );
 
  678   std::vector<typename details::lapack_traits<ScalarType>::iwork_type> PORFS_WORK( numRowCols_ );
 
  679   this->PORFS(Matrix_->UPLO(), numRowCols_, NRHS, A_, LDA_, AF_, LDAF_,
 
  680               RHS_->values(), RHS_->stride(), LHS_->values(), LHS_->stride(),
 
  681               &FERR_[0], &BERR_[0], &WORK_[0], &PORFS_WORK[0], &INFO_);
 
  683   solutionErrorsEstimated_ = 
true;
 
  684   reciprocalConditionEstimated_ = 
true;
 
  685   solutionRefined_ = 
true;
 
  693 template<
typename OrdinalType, 
typename ScalarType>
 
  696   if (R_.size()!=0) 
return(0); 
 
  698   R_.resize( numRowCols_ );
 
  701   this->POEQU (numRowCols_, AF_, LDAF_, &R_[0], &SCOND_, &AMAX_, &INFO_);
 
  705     shouldEquilibrate_ = 
true;
 
  712 template<
typename OrdinalType, 
typename ScalarType>
 
  718   if (equilibratedA_) 
return(0); 
 
  719   if (R_.size()==0) ierr = computeEquilibrateScaling(); 
 
  720   if (ierr!=0) 
return(ierr);     
 
  721   if (Matrix_->upper()) {
 
  724       for (j=0; j<numRowCols_; j++) {
 
  726         ScalarType s1 = R_[j];
 
  727         for (i=0; i<=j; i++) {
 
  728           *ptr = *ptr*s1*R_[i];
 
  736       for (j=0; j<numRowCols_; j++) {
 
  738         ptr1 = AF_ + j*LDAF_;
 
  739         ScalarType s1 = R_[j];
 
  740         for (i=0; i<=j; i++) {
 
  741           *ptr = *ptr*s1*R_[i];
 
  743           *ptr1 = *ptr1*s1*R_[i];
 
  752       for (j=0; j<numRowCols_; j++) {
 
  753         ptr = A_ + j + j*LDA_;
 
  754         ScalarType s1 = R_[j];
 
  755         for (i=j; i<numRowCols_; i++) {
 
  756           *ptr = *ptr*s1*R_[i];
 
  764       for (j=0; j<numRowCols_; j++) {
 
  765         ptr = A_ + j + j*LDA_;
 
  766         ptr1 = AF_ + j + j*LDAF_;
 
  767         ScalarType s1 = R_[j];
 
  768         for (i=j; i<numRowCols_; i++) {
 
  769           *ptr = *ptr*s1*R_[i];
 
  771           *ptr1 = *ptr1*s1*R_[i];
 
  778   equilibratedA_ = 
true;
 
  785 template<
typename OrdinalType, 
typename ScalarType>
 
  791   if (equilibratedB_) 
return(0); 
 
  792   if (R_.size()==0) ierr = computeEquilibrateScaling(); 
 
  793   if (ierr!=0) 
return(ierr);     
 
  795   OrdinalType LDB = RHS_->stride(), NRHS = RHS_->numCols();
 
  796   ScalarType * B = RHS_->values();
 
  798   for (j=0; j<NRHS; j++) {
 
  800     for (i=0; i<numRowCols_; i++) {
 
  806   equilibratedB_ = 
true;
 
  813 template<
typename OrdinalType, 
typename ScalarType>
 
  818   if (!equilibratedB_) 
return(0); 
 
  820   OrdinalType LDX = LHS_->stride(), NLHS = LHS_->numCols();
 
  821   ScalarType * X = LHS_->values();
 
  823   for (j=0; j<NLHS; j++) {
 
  825     for (i=0; i<numRowCols_; i++) {
 
  836 template<
typename OrdinalType, 
typename ScalarType>
 
  839 #ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  843   if (!factored()) factor(); 
 
  846   this->POTRI( Matrix_->UPLO(), numRowCols_, AF_, LDAF_, &INFO_);
 
  849   if (Matrix_->upper())
 
  863 template<
typename OrdinalType, 
typename ScalarType>
 
  866 #ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  870   if (reciprocalConditionEstimated()) {
 
  878   if (!factored()) ierr = factor(); 
 
  879   if (ierr!=0) 
return(ierr);
 
  886   std::vector<typename details::lapack_traits<ScalarType>::iwork_type> POCON_WORK( numRowCols_ );
 
  887   this->POCON( Matrix_->UPLO(), numRowCols_, AF_, LDAF_, ANORM_, &RCOND_, &WORK_[0], &POCON_WORK[0], &INFO_);
 
  888   reciprocalConditionEstimated_ = 
true;
 
  896 template<
typename OrdinalType, 
typename ScalarType>
 
  899   if (Matrix_!=Teuchos::null) os << 
"Solver Matrix"          << std::endl << *Matrix_ << std::endl;
 
  900   if (Factor_!=Teuchos::null) os << 
"Solver Factored Matrix" << std::endl << *Factor_ << std::endl;
 
  901   if (LHS_   !=Teuchos::null) os << 
"Solver LHS"             << std::endl << *LHS_    << std::endl;
 
  902   if (RHS_   !=Teuchos::null) os << 
"Solver RHS"             << std::endl << *RHS_    << std::endl;
 
MagnitudeType RCOND() const 
Returns the reciprocal of the condition number 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. ...
 
A class for constructing and using Hermitian positive definite dense matrices. 
 
std::vector< MagnitudeType > R() const 
Returns a pointer to the row scaling vector used for equilibration. 
 
T magnitudeType
Mandatory typedef for result of magnitude. 
 
MagnitudeType SCOND()
Ratio of smallest to largest equilibration scale factors for the this matrix (returns -1 if not yet c...
 
OrdinalType numCols() const 
Returns column dimension of system. 
 
Templated serial dense matrix class. 
 
bool transpose()
Returns true if transpose of this matrix has and will be used. 
 
bool solutionErrorsEstimated()
Returns true if forward and backward error estimated have been computed (available via FERR() and BER...
 
Templated interface class to BLAS routines. 
 
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging. 
 
int factor()
Computes the in-place Cholesky factorization of the matrix using the LAPACK routine DPOTRF...
 
Teuchos header file which uses auto-configuration information to include necessary C++ headers...
 
void estimateSolutionErrors(bool flag)
Causes all solves to estimate the forward and backward solution error. 
 
bool factored()
Returns true if matrix is factored (factor available via AF() and LDAF()). 
 
This class creates and provides basic support for symmetric, positive-definite dense matrices of temp...
 
int invert()
Inverts the this matrix. 
 
Object for storing data and providing functionality that is common to all computational classes...
 
MagnitudeType AMAX() const 
Returns the absolute value of the largest entry of the this matrix (returns -1 if not yet computed)...
 
This structure defines some basic traits for a scalar field type. 
 
int equilibrateMatrix()
Equilibrates the this matrix. 
 
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getLHS() const 
Returns pointer to current LHS. 
 
Templated class for solving dense linear problems. 
 
Functionality and data that is common to all computational classes. 
 
Templated interface class to LAPACK routines. 
 
bool shouldEquilibrate()
Returns true if the LAPACK general rules for equilibration suggest you should equilibrate the system...
 
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated. 
 
int setMatrix(const RCP< SerialSymDenseMatrix< OrdinalType, ScalarType > > &A_in)
Sets the pointers for coefficient matrix. 
 
virtual ~SerialSpdDenseSolver()
SerialSpdDenseSolver destructor. 
 
int solve()
Computes the solution X to AX = B for the this matrix and the B provided to 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). 
 
int applyRefinement()
Apply Iterative Refinement. 
 
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getRHS() const 
Returns pointer to current RHS. 
 
The Templated LAPACK Wrapper Class. 
 
MagnitudeType ANORM() const 
Returns the 1-Norm of the this matrix (returns -1 if not yet computed). 
 
bool solved()
Returns true if the current set of vectors has been solved. 
 
Templated serial, dense, symmetric matrix class. 
 
bool equilibratedA()
Returns true if factor is equilibrated (factor available via AF() and LDAF()). 
 
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 factorWithEquilibration(bool flag)
Causes equilibration to be called just before the matrix factorization as part of the call to factor...
 
bool inverted()
Returns true if matrix inverse has been computed (inverse available via AF() and LDAF()). 
 
RCP< SerialSymDenseMatrix< OrdinalType, ScalarType > > getFactoredMatrix() const 
Returns pointer to factored matrix (assuming factorization has been performed). 
 
OrdinalType numRows() const 
Returns row dimension of system. 
 
Smart reference counting pointer class for automatic garbage collection. 
 
bool equilibratedB()
Returns true if RHS is equilibrated (RHS available via B() and LDB()). 
 
int unequilibrateLHS()
Unscales the solution vectors if equilibration was used to solve the system. 
 
int computeEquilibrateScaling()
Computes the scaling vector S(i) = 1/sqrt(A(i,i) of the this matrix. 
 
std::vector< MagnitudeType > FERR() const 
Returns a pointer to the forward error estimates computed by LAPACK. 
 
std::vector< MagnitudeType > BERR() const 
Returns a pointer to the backward error estimates computed by LAPACK. 
 
bool solutionRefined()
Returns true if the current set of vectors has been refined. 
 
RCP< SerialSymDenseMatrix< OrdinalType, ScalarType > > getMatrix() const 
Returns pointer to current matrix. 
 
void Print(std::ostream &os) const 
Print service methods; defines behavior of ostream << operator. 
 
Reference-counted pointer class and non-member templated function implementations. 
 
static T one()
Returns representation of one for this scalar type. 
 
SerialSpdDenseSolver()
Default constructor; matrix should be set using setMatrix(), LHS and RHS set with setVectors()...
 
int equilibrateRHS()
Equilibrates the current RHS. 
 
This class creates and provides basic support for dense rectangular matrix of templated type...