42 #ifndef _TEUCHOS_SERIALDENSESOLVER_HPP_ 
   43 #define _TEUCHOS_SERIALDENSESOLVER_HPP_ 
   56 #ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
   57 #include "Eigen/Dense" 
  136   template<
typename OrdinalType, 
typename ScalarType>
 
  138                             public LAPACK<OrdinalType, ScalarType>
 
  144 #ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  145     typedef typename Eigen::Matrix<ScalarType,Eigen::Dynamic,Eigen::Dynamic,Eigen::ColMajor> EigenMatrix;
 
  146     typedef typename Eigen::Matrix<ScalarType,Eigen::Dynamic,1> EigenVector;
 
  147     typedef typename Eigen::InnerStride<Eigen::Dynamic> EigenInnerStride;
 
  148     typedef typename Eigen::OuterStride<Eigen::Dynamic> EigenOuterStride;
 
  149     typedef typename Eigen::Map<EigenVector,0,EigenInnerStride > EigenVectorMap;
 
  150     typedef typename Eigen::Map<const EigenVector,0,EigenInnerStride > EigenConstVectorMap;
 
  151     typedef typename Eigen::Map<EigenMatrix,0,EigenOuterStride > EigenMatrixMap;
 
  152     typedef typename Eigen::Map<const EigenMatrix,0,EigenOuterStride > EigenConstMatrixMap;
 
  153     typedef typename Eigen::PermutationMatrix<Eigen::Dynamic,Eigen::Dynamic,OrdinalType> EigenPermutationMatrix;
 
  154     typedef typename Eigen::Array<OrdinalType,Eigen::Dynamic,1> EigenOrdinalArray;
 
  155     typedef typename Eigen::Map<EigenOrdinalArray> EigenOrdinalArrayMap;
 
  156     typedef typename Eigen::Array<ScalarType,Eigen::Dynamic,1> EigenScalarArray;
 
  157     typedef typename Eigen::Map<EigenScalarArray> EigenScalarArrayMap;
 
  357     std::vector<MagnitudeType> 
FERR()
  const {
return(
FERR_);}
 
  360     std::vector<MagnitudeType> 
BERR()
  const {
return(
BERR_);}
 
  363     std::vector<MagnitudeType> 
R()
  const {
return(
R_);}
 
  366     std::vector<MagnitudeType> 
C()
  const {
return(
C_);}
 
  371     void Print(std::ostream& os) 
const;
 
  423     std::vector<MagnitudeType> 
R_;
 
  424     std::vector<MagnitudeType> 
C_;
 
  425 #ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  426     Eigen::PartialPivLU<EigenMatrix> lu_;
 
  455 template<
typename OrdinalType, 
typename ScalarType>
 
  459     shouldEquilibrate_(false),
 
  460     equilibratedA_(false),
 
  461     equilibratedB_(false),
 
  464     estimateSolutionErrors_(false),
 
  465     solutionErrorsEstimated_(false),
 
  468     reciprocalConditionEstimated_(false),
 
  469     refineSolution_(false),
 
  470     solutionRefined_(false),
 
  491 template<
typename OrdinalType, 
typename ScalarType>
 
  497 template<
typename OrdinalType, 
typename ScalarType>
 
  502   reciprocalConditionEstimated_ = 
false;
 
  503   solutionRefined_ = 
false;
 
  505   solutionErrorsEstimated_ = 
false;
 
  506   equilibratedB_ = 
false;
 
  510 template<
typename OrdinalType, 
typename ScalarType>
 
  514   equilibratedA_ = 
false;
 
  536 template<
typename OrdinalType, 
typename ScalarType>
 
  553 template<
typename OrdinalType, 
typename ScalarType>
 
  559                      "SerialDenseSolver<T>::setVectors: X and B are not the same size!");
 
  561                      "SerialDenseSolver<T>::setVectors: B is an empty SerialDenseMatrix<T>!");
 
  563                      "SerialDenseSolver<T>::setVectors: X is an empty SerialDenseMatrix<T>!");
 
  565                      "SerialDenseSolver<T>::setVectors: B has an invalid stride!");
 
  567                      "SerialDenseSolver<T>::setVectors: X has an invalid stride!");
 
  576 template<
typename OrdinalType, 
typename ScalarType>
 
  579   estimateSolutionErrors_ = flag;
 
  582   refineSolution_ = refineSolution_ || flag;
 
  586 template<
typename OrdinalType, 
typename ScalarType>
 
  589   if (factored()) 
return(0); 
 
  592                      "SerialDenseSolver<T>::factor: Cannot factor an inverted matrix!");
 
  594   ANORM_ = Matrix_->normOne(); 
 
  601     if (refineSolution_ ) {
 
  603       AF_ = Factor_->values();
 
  604       LDAF_ = Factor_->stride();
 
  608   if (equilibrate_) ierr = equilibrateMatrix();
 
  610   if (ierr!=0) 
return(ierr);
 
  612   if ((
int)IPIV_.size()!=Min_MN_) IPIV_.resize( Min_MN_ ); 
 
  616 #ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  617   EigenMatrixMap aMap( AF_, M_, N_, EigenOuterStride(LDAF_) );
 
  618   EigenPermutationMatrix p;
 
  619   EigenOrdinalArray ind;
 
  620   EigenOrdinalArrayMap ipivMap( &IPIV_[0], Min_MN_ );
 
  623   p = lu_.permutationP();
 
  626   EigenMatrix luMat = lu_.matrixLU();
 
  627   for (OrdinalType j=0; j<aMap.outerSize(); j++) {
 
  628     for (OrdinalType i=0; i<aMap.innerSize(); i++) {
 
  629       aMap(i,j) = luMat(i,j);
 
  632   for (OrdinalType i=0; i<ipivMap.innerSize(); i++) {
 
  636   this->GETRF(M_, N_, AF_, LDAF_, &IPIV_[0], &INFO_);
 
  646 template<
typename OrdinalType, 
typename ScalarType>
 
  660     ierr = equilibrateRHS();
 
  662   if (ierr != 0) 
return(ierr);  
 
  665                      "SerialDenseSolver<T>::solve: No right-hand side vector (RHS) has been set for the linear system!");
 
  667                      "SerialDenseSolver<T>::solve: No solution vector (LHS) has been set for the linear system!");
 
  672                         "SerialDenseSolver<T>::solve: X and B must be different vectors if matrix is inverted.");
 
  674                                  std::logic_error, 
"SerialDenseSolver<T>::solve: Matrix and vectors must be similarly scaled!");
 
  678                RHS_->values(), RHS_->stride(), 0.0, LHS_->values(), LHS_->stride());
 
  679     if (INFO_!=0) 
return(INFO_);
 
  684     if (!factored()) factor(); 
 
  687                                  std::logic_error, 
"SerialDenseSolver<T>::solve: Matrix and vectors must be similarly scaled!");
 
  689     if (RHS_->values()!=LHS_->values()) {
 
  694 #ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  695     EigenMatrixMap rhsMap( RHS_->values(), RHS_->numRows(), RHS_->numCols(), EigenOuterStride(RHS_->stride()) );
 
  696     EigenMatrixMap lhsMap( LHS_->values(), LHS_->numRows(), LHS_->numCols(), EigenOuterStride(LHS_->stride()) );
 
  698       lhsMap = lu_.solve(rhsMap);
 
  700       lu_.matrixLU().template triangularView<Eigen::Upper>().transpose().solveInPlace(lhsMap);
 
  701       lu_.matrixLU().template triangularView<Eigen::UnitLower>().transpose().solveInPlace(lhsMap);
 
  702       EigenMatrix x = lu_.permutationP().transpose() * lhsMap;
 
  705       lu_.matrixLU().template triangularView<Eigen::Upper>().adjoint().solveInPlace(lhsMap);
 
  706       lu_.matrixLU().template triangularView<Eigen::UnitLower>().adjoint().solveInPlace(lhsMap);
 
  707       EigenMatrix x = lu_.permutationP().transpose() * lhsMap;
 
  711     this->GETRS(
ETranspChar[TRANS_], N_, RHS_->numCols(), AF_, LDAF_, &IPIV_[0], LHS_->values(), LHS_->stride(), &INFO_);
 
  714     if (INFO_!=0) 
return(INFO_);
 
  720   if (shouldEquilibrate() && !equilibratedA_)
 
  721     std::cout << 
"WARNING!  SerialDenseSolver<T>::solve: System should be equilibrated!" << std::endl;
 
  724   if (refineSolution_ && !inverted()) ierr1 = applyRefinement();
 
  728   if (equilibrate_) ierr1 = unequilibrateLHS();
 
  733 template<
typename OrdinalType, 
typename ScalarType>
 
  737                      "SerialDenseSolver<T>::applyRefinement: Must have an existing solution!");
 
  739                      "SerialDenseSolver<T>::applyRefinement: Cannot apply refinement if no original copy of A!");
 
  741 #ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  746   OrdinalType NRHS = RHS_->numCols();
 
  747   FERR_.resize( NRHS );
 
  748   BERR_.resize( NRHS );
 
  752   std::vector<typename details::lapack_traits<ScalarType>::iwork_type> GERFS_WORK( N_ );
 
  753   this->GERFS(
ETranspChar[TRANS_], N_, NRHS, A_, LDA_, AF_, LDAF_, &IPIV_[0],
 
  754               RHS_->values(), RHS_->stride(), LHS_->values(), LHS_->stride(),
 
  755               &FERR_[0], &BERR_[0], &WORK_[0], &GERFS_WORK[0], &INFO_);
 
  757   solutionErrorsEstimated_ = 
true;
 
  758   reciprocalConditionEstimated_ = 
true;
 
  759   solutionRefined_ = 
true;
 
  767 template<
typename OrdinalType, 
typename ScalarType>
 
  770   if (R_.size()!=0) 
return(0); 
 
  776   this->GEEQU (M_, N_, AF_, LDAF_, &R_[0], &C_[0], &ROWCND_, &COLCND_, &AMAX_, &INFO_);
 
  781     shouldEquilibrate_ = 
true;
 
  788 template<
typename OrdinalType, 
typename ScalarType>
 
  794   if (equilibratedA_) 
return(0); 
 
  795   if (R_.size()==0) ierr = computeEquilibrateScaling(); 
 
  796   if (ierr!=0) 
return(ierr);     
 
  799     for (j=0; j<N_; j++) {
 
  801       ScalarType s1 = C_[j];
 
  802       for (i=0; i<M_; i++) {
 
  803         *ptr = *ptr*s1*R_[i];
 
  811     for (j=0; j<N_; j++) {
 
  813       ptr1 = AF_ + j*LDAF_;
 
  814       ScalarType s1 = C_[j];
 
  815       for (i=0; i<M_; i++) {
 
  816         *ptr = *ptr*s1*R_[i];
 
  818         *ptr1 = *ptr1*s1*R_[i];
 
  824   equilibratedA_ = 
true;
 
  831 template<
typename OrdinalType, 
typename ScalarType>
 
  837   if (equilibratedB_) 
return(0); 
 
  838   if (R_.size()==0) ierr = computeEquilibrateScaling(); 
 
  839   if (ierr!=0) 
return(ierr);     
 
  842   if (transpose_) R_tmp = &C_[0];
 
  844   OrdinalType LDB = RHS_->stride(), NRHS = RHS_->numCols();
 
  845   ScalarType * 
B = RHS_->values();
 
  847   for (j=0; j<NRHS; j++) {
 
  849     for (i=0; i<M_; i++) {
 
  850       *ptr = *ptr*R_tmp[i];
 
  855   equilibratedB_ = 
true;
 
  862 template<
typename OrdinalType, 
typename ScalarType>
 
  867   if (!equilibratedB_) 
return(0); 
 
  870   if (transpose_) C_tmp = &R_[0];
 
  872   OrdinalType LDX = LHS_->stride(), NLHS = LHS_->numCols();
 
  873   ScalarType * X = LHS_->values();
 
  875   for (j=0; j<NLHS; j++) {
 
  877     for (i=0; i<N_; i++) {
 
  878       *ptr = *ptr*C_tmp[i];
 
  888 template<
typename OrdinalType, 
typename ScalarType>
 
  892   if (!factored()) factor(); 
 
  894 #ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  895   EigenMatrixMap invMap( AF_, M_, N_, EigenOuterStride(LDAF_) );
 
  896   EigenMatrix invMat = lu_.inverse();
 
  897   for (OrdinalType j=0; j<invMap.outerSize(); j++) {
 
  898     for (OrdinalType i=0; i<invMap.innerSize(); i++) {
 
  899       invMap(i,j) = invMat(i,j);
 
  919   this->GETRI( N_, AF_, LDAF_, &IPIV_[0], &WORK_[0], LWORK_, &INFO_);
 
  931 template<
typename OrdinalType, 
typename ScalarType>
 
  934 #ifdef HAVE_TEUCHOSNUMERICS_EIGEN 
  938   if (reciprocalConditionEstimated()) {
 
  946   if (!factored()) ierr = factor(); 
 
  947   if (ierr!=0) 
return(ierr);
 
  953   std::vector<typename details::lapack_traits<ScalarType>::iwork_type> GECON_WORK( 2*N_ );
 
  954   this->GECON( 
'1', N_, AF_, LDAF_, ANORM_, &RCOND_, &WORK_[0], &GECON_WORK[0], &INFO_);
 
  956   reciprocalConditionEstimated_ = 
true;
 
  964 template<
typename OrdinalType, 
typename ScalarType>
 
  967   if (Matrix_!=
Teuchos::null) os << 
"Solver Matrix"          << std::endl << *Matrix_ << std::endl;
 
  968   if (Factor_!=
Teuchos::null) os << 
"Solver Factored Matrix" << std::endl << *Factor_ << std::endl;
 
  969   if (LHS_   !=
Teuchos::null) os << 
"Solver LHS"             << std::endl << *LHS_    << std::endl;
 
  970   if (RHS_   !=
Teuchos::null) os << 
"Solver RHS"             << std::endl << *RHS_    << std::endl;
 
int equilibrateMatrix()
Equilibrates the this matrix. 
 
void Print(std::ostream &os) const 
Print service methods; defines behavior of ostream << operator. 
 
Templated serial dense matrix class. 
 
void solveWithTranspose(bool flag)
If flag is true, causes all subsequent function calls to work with the transpose of this matrix...
 
SerialDenseSolver & operator=(const SerialDenseSolver< OrdinalType, ScalarType > &Source)
 
std::vector< MagnitudeType > R() const 
Returns a pointer to the row scaling vector used for equilibration. 
 
Templated interface class to BLAS routines. 
 
std::vector< MagnitudeType > C_
 
bool solutionErrorsEstimated_
 
int solve()
Computes the solution X to AX = B for the this matrix and the B provided to SetVectors().. 
 
ScalarTraits< T >::magnitudeType iwork_type
 
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging. 
 
bool solved()
Returns true if the current set of vectors has been solved. 
 
bool solutionRefined()
Returns true if the current set of vectors has been refined. 
 
Teuchos header file which uses auto-configuration information to include necessary C++ headers...
 
bool reciprocalConditionEstimated_
 
std::vector< MagnitudeType > FERR_
 
bool reciprocalConditionEstimated()
Returns true if the condition number of the this matrix has been computed (value available via Recipr...
 
std::vector< ScalarType > WORK_
 
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getFactoredMatrix() const 
Returns pointer to factored matrix (assuming factorization has been performed). 
 
Object for storing data and providing functionality that is common to all computational classes...
 
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > Matrix_
 
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getRHS() const 
Returns pointer to current RHS. 
 
std::vector< MagnitudeType > FERR() const 
Returns a pointer to the forward error estimates computed by LAPACK. 
 
This structure defines some basic traits for a scalar field type. 
 
int unequilibrateLHS()
Unscales the solution vectors if equilibration was used to solve the system. 
 
void solveToRefinedSolution(bool flag)
Causes all solves to compute solution to best ability using iterative refinement. ...
 
bool factored()
Returns true if matrix is factored (factor available via getFactoredMatrix()). 
 
Functionality and data that is common to all computational classes. 
 
Templated interface class to LAPACK routines. 
 
bool estimateSolutionErrors_
 
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getLHS() const 
Returns pointer to current LHS. 
 
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated. 
 
bool shouldEquilibrate()
Returns true if the LAPACK general rules for equilibration suggest you should equilibrate the system...
 
bool inverted()
Returns true if matrix inverse has been computed (inverse available via getFactoredMatrix()). 
 
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...
 
std::vector< OrdinalType > IPIV_
 
void solveWithTransposeFlag(Teuchos::ETransp trans)
All subsequent function calls will work with the transpose-type set by this method (Teuchos::NO_TRANS...
 
int invert()
Inverts the this matrix. 
 
bool transpose()
Returns true if transpose of this matrix has and will be used. 
 
int applyRefinement()
Apply Iterative Refinement. 
 
int computeEquilibrateScaling()
Computes the scaling vector S(i) = 1/sqrt(A(i,i)) of the this matrix. 
 
void estimateSolutionErrors(bool flag)
Causes all solves to estimate the forward and backward solution error. 
 
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()). 
 
SerialDenseSolver()
Default constructor; matrix should be set using setMatrix(), LHS and RHS set with setVectors()...
 
bool solutionErrorsEstimated()
Returns true if forward and backward error estimated have been computed (available via FERR() and BER...
 
The Templated LAPACK Wrapper Class. 
 
std::vector< MagnitudeType > R_
 
virtual ~SerialDenseSolver()
SerialDenseSolver destructor. 
 
std::vector< OrdinalType > IPIV() const 
Returns pointer to pivot vector (if factorization has been computed), zero otherwise. 
 
OrdinalType numRows() const 
Returns row dimension of system. 
 
std::vector< MagnitudeType > C() const 
Returns a pointer to the column scale vector used for equilibration. 
 
int equilibrateRHS()
Equilibrates the current RHS. 
 
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). 
 
MagnitudeType COLCND() const 
Ratio of smallest to largest column scale factors for the this matrix (returns -1 if not yet computed...
 
MagnitudeType ROWCND() const 
Ratio of smallest to largest row scale factors for the this matrix (returns -1 if not yet computed)...
 
std::vector< MagnitudeType > BERR() const 
Returns a pointer to the backward error estimates computed by LAPACK. 
 
MagnitudeType AMAX() const 
Returns the absolute value of the largest entry of the this matrix (returns -1 if not yet computed)...
 
Defines basic traits for the scalar field type. 
 
TEUCHOSNUMERICS_LIB_DLL_EXPORT const char ETranspChar[]
 
Teuchos::ScalarTraits< ScalarType >::magnitudeType MagnitudeType
 
OrdinalType numCols() const 
Returns column dimension of system. 
 
Smart reference counting pointer class for automatic garbage collection. 
 
int factor()
Computes the in-place LU factorization of the matrix using the LAPACK routine _GETRF. 
 
std::vector< MagnitudeType > BERR_
 
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > Factor_
 
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > RHS_
 
bool equilibratedA()
Returns true if factor is equilibrated (factor available via getFactoredMatrix()). 
 
#define TEUCHOS_MIN(x, y)
 
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getMatrix() const 
Returns pointer to current matrix. 
 
Reference-counted pointer class and non-member templated function implementations. 
 
static T one()
Returns representation of one for this scalar type. 
 
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > LHS_
 
A class for solving dense linear problems. 
 
MagnitudeType RCOND() const 
Returns the reciprocal of the condition number of the this matrix (returns -1 if not yet computed)...
 
int setMatrix(const RCP< SerialDenseMatrix< OrdinalType, ScalarType > > &A)
Sets the pointers for coefficient matrix. 
 
This class creates and provides basic support for dense rectangular matrix of templated type...