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;
110 typedef typename Eigen::InnerStride<Eigen::Dynamic> EigenInnerStride;
111 typedef typename Eigen::OuterStride<Eigen::Dynamic> EigenOuterStride;
112 typedef typename Eigen::Map<EigenVector,0,EigenInnerStride > EigenVectorMap;
113 typedef typename Eigen::Map<const EigenVector,0,EigenInnerStride > EigenConstVectorMap;
114 typedef typename Eigen::Map<EigenMatrix,0,EigenOuterStride > EigenMatrixMap;
115 typedef typename Eigen::Map<const EigenMatrix,0,EigenOuterStride > EigenConstMatrixMap;
116 typedef typename Eigen::PermutationMatrix<Eigen::Dynamic,Eigen::Dynamic,OrdinalType> EigenPermutationMatrix;
117 typedef typename Eigen::Array<OrdinalType,Eigen::Dynamic,1> EigenOrdinalArray;
118 typedef typename Eigen::Map<EigenOrdinalArray> EigenOrdinalArrayMap;
119 typedef typename Eigen::Array<ScalarType,Eigen::Dynamic,1> EigenScalarArray;
120 typedef typename Eigen::Map<EigenScalarArray> EigenScalarArrayMap;
278 OrdinalType
numRows()
const {
return(numRowCols_);}
281 OrdinalType
numCols()
const {
return(numRowCols_);}
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_;
373 using namespace details;
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>
416void SerialSpdDenseSolver<OrdinalType,ScalarType>::resetVectors()
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>
504 "SerialSpdDenseSolver<T>::factor: Cannot factor an inverted matrix!");
506 ANORM_ = Matrix_->normOne();
513 if (refineSolution_ ) {
515 AF_ = Factor_->values();
516 LDAF_ = Factor_->stride();
522 if (ierr!=0)
return(ierr);
526#ifdef HAVE_TEUCHOSNUMERICS_EIGEN
527 EigenMatrixMap aMap( AF_, numRowCols_, numRowCols_, EigenOuterStride(LDAF_) );
529 if (Matrix_->upper())
535 this->
POTRF(Matrix_->UPLO(), numRowCols_, AF_, LDAF_, &INFO_);
545template<
typename OrdinalType,
typename ScalarType>
561 if (ierr != 0)
return(ierr);
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_);
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
595 EigenMatrixMap rhsMap( RHS_->values(), RHS_->numRows(), RHS_->numCols(), EigenOuterStride(RHS_->stride()) );
596 EigenMatrixMap lhsMap( LHS_->values(), LHS_->numRows(), LHS_->numCols(), EigenOuterStride(LHS_->stride()) );
598 if (Matrix_->upper())
599 lhsMap = lltu_.solve(rhsMap);
601 lhsMap = lltl_.solve(rhsMap);
604 this->
POTRS(Matrix_->UPLO(), numRowCols_, RHS_->numCols(), AF_, LDAF_, LHS_->values(), LHS_->stride(), &INFO_);
607 if (INFO_!=0)
return(INFO_);
614 std::cout <<
"WARNING! SerialSpdDenseSolver<T>::solve: System should be equilibrated!" << std::endl;
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
639 OrdinalType NRHS = RHS_->numCols();
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);
688 if (ierr!=0)
return(ierr);
689 if (Matrix_->upper()) {
692 for (j=0; j<numRowCols_; j++) {
694 ScalarType s1 = R_[j];
695 for (i=0; i<=j; i++) {
704 for (j=0; j<numRowCols_; j++) {
706 ptr1 = AF_ + j*LDAF_;
707 ScalarType s1 = R_[j];
708 for (i=0; i<=j; i++) {
711 *ptr1 = *ptr1*s1*R_[i];
720 for (j=0; j<numRowCols_; j++) {
721 ptr = A_ + j + j*LDA_;
722 ScalarType s1 = R_[j];
723 for (i=j; i<numRowCols_; i++) {
732 for (j=0; j<numRowCols_; j++) {
733 ptr = A_ + j + j*LDA_;
734 ptr1 = AF_ + j + j*LDAF_;
735 ScalarType s1 = R_[j];
736 for (i=j; i<numRowCols_; i++) {
739 *ptr1 = *ptr1*s1*R_[i];
746 equilibratedA_ =
true;
753template<
typename OrdinalType,
typename ScalarType>
759 if (equilibratedB_)
return(0);
761 if (ierr!=0)
return(ierr);
763 OrdinalType LDB = RHS_->stride(), NRHS = RHS_->numCols();
764 ScalarType * B = RHS_->values();
766 for (j=0; j<NRHS; j++) {
768 for (i=0; i<numRowCols_; i++) {
774 equilibratedB_ =
true;
781template<
typename OrdinalType,
typename ScalarType>
786 if (!equilibratedB_)
return(0);
788 OrdinalType LDX = LHS_->stride(), NLHS = LHS_->numCols();
789 ScalarType * X = LHS_->values();
791 for (j=0; j<NLHS; j++) {
793 for (i=0; i<numRowCols_; i++) {
804template<
typename OrdinalType,
typename ScalarType>
807#ifdef HAVE_TEUCHOSNUMERICS_EIGEN
814 this->
POTRI( Matrix_->UPLO(), numRowCols_, AF_, LDAF_, &INFO_);
817 if (Matrix_->upper())
831template<
typename OrdinalType,
typename ScalarType>
834#ifdef HAVE_TEUCHOSNUMERICS_EIGEN
847 if (ierr!=0)
return(ierr);
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.
BLAS(void)
Default constructor.
CompObject()
Default constructor.
void GEMM(ETransp transa, ETransp transb, const OrdinalType &m, const OrdinalType &n, const OrdinalType &k, const alpha_type alpha, const A_type *A, const OrdinalType &lda, const B_type *B, const OrdinalType &ldb, const beta_type beta, ScalarType *C, const OrdinalType &ldc) const
General matrix-matrix multiply.
void PORFS(const char &UPLO, const OrdinalType &n, const OrdinalType &nrhs, const ScalarType *A, const OrdinalType &lda, const ScalarType *AF, const OrdinalType &ldaf, const ScalarType *B, const OrdinalType &ldb, ScalarType *X, const OrdinalType &ldx, ScalarType *FERR, ScalarType *BERR, ScalarType *WORK, OrdinalType *IWORK, OrdinalType *info) const
Improves the computed solution to a system of linear equations when the coefficient matrix is symmetr...
void POCON(const char &UPLO, const OrdinalType &n, const ScalarType *A, const OrdinalType &lda, const ScalarType &anorm, ScalarType *rcond, ScalarType *WORK, OrdinalType *IWORK, OrdinalType *info) const
Estimates the reciprocal of the condition number (1-norm) of a real symmetric positive definite matri...
void POTRS(const char &UPLO, const OrdinalType &n, const OrdinalType &nrhs, const ScalarType *A, const OrdinalType &lda, ScalarType *B, const OrdinalType &ldb, OrdinalType *info) const
Solves a system of linear equations A*X=B, where A is a symmetric positive definite matrix factored b...
void POEQU(const OrdinalType &n, const ScalarType *A, const OrdinalType &lda, MagnitudeType *S, MagnitudeType *scond, MagnitudeType *amax, OrdinalType *info) const
Computes row and column scalings intended to equilibrate a symmetric positive definite matrix A and r...
void POTRI(const char &UPLO, const OrdinalType &n, ScalarType *A, const OrdinalType &lda, OrdinalType *info) const
Computes the inverse of a real symmetric positive definite matrix A using the Cholesky factorization ...
LAPACK(void)
Default Constructor.
void POTRF(const char &UPLO, const OrdinalType &n, ScalarType *A, const OrdinalType &lda, OrdinalType *info) const
Computes Cholesky factorization of a real symmetric positive definite matrix A.
Object(int tracebackModeIn=-1)
Default Constructor.
Ptr< T > ptr(T *p)
Create a pointer to an object from a raw pointer.
Smart reference counting pointer class for automatic garbage collection.
This class creates and provides basic support for dense rectangular matrix of templated type.
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()).
This class creates and provides basic support for symmetric, positive-definite dense matrices of temp...
#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_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.
This structure defines some basic traits for a scalar field type.
static magnitudeType rmax()
Overflow theshold - (base^emax)*(1-eps).
static T one()
Returns representation of one for this scalar type.
T magnitudeType
Mandatory typedef for result of magnitude.
static T zero()
Returns representation of zero for this scalar type.
static magnitudeType rmin()
Returns the underflow threshold - base^(emin-1).