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_;
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_;
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>
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>
536 "SerialSpdDenseSolver<T>::factor: Cannot factor an inverted matrix!");
538 ANORM_ = Matrix_->normOne();
545 if (refineSolution_ ) {
547 AF_ = Factor_->values();
548 LDAF_ = Factor_->stride();
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>
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_);
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_);
646 std::cout <<
"WARNING! SerialSpdDenseSolver<T>::solve: System should be equilibrated!" << std::endl;
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);
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);
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 846 this->
POTRI( Matrix_->UPLO(), numRowCols_, AF_, LDAF_, &INFO_);
849 if (Matrix_->upper())
863 template<
typename OrdinalType,
typename ScalarType>
866 #ifdef HAVE_TEUCHOSNUMERICS_EIGEN 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;
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 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.
OrdinalType numCols() const
Returns column dimension of system.
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...
Templated serial dense matrix class.
MagnitudeType AMAX() const
Returns the absolute value of the largest entry of the this matrix (returns -1 if not yet computed)...
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.
MagnitudeType RCOND() const
Returns the reciprocal of the condition number of the this matrix (returns -1 if not yet computed)...
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getRHS() const
Returns pointer to current RHS.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
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...
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...
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getLHS() const
Returns pointer to current LHS.
RCP< SerialSymDenseMatrix< OrdinalType, ScalarType > > getFactoredMatrix() const
Returns pointer to factored matrix (assuming factorization has been performed).
std::vector< MagnitudeType > R() const
Returns a pointer to the row scaling vector used for equilibration.
This structure defines some basic traits for a scalar field type.
int equilibrateMatrix()
Equilibrates the this matrix.
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.
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...
int setMatrix(const RCP< SerialSymDenseMatrix< OrdinalType, ScalarType > > &A_in)
Sets the pointers for coefficient matrix.
virtual ~SerialSpdDenseSolver()
SerialSpdDenseSolver destructor.
Teuchos implementation details.
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).
void Print(std::ostream &os) const
Print service methods; defines behavior of ostream << operator.
OrdinalType numRows() const
Returns row dimension of system.
int applyRefinement()
Apply Iterative Refinement.
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.
The Templated LAPACK Wrapper Class.
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...
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.
RCP< SerialSymDenseMatrix< OrdinalType, ScalarType > > getMatrix() const
Returns pointer to current matrix.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos, as well as a number of utility routines.
MagnitudeType ANORM() const
Returns the 1-Norm of the this matrix (returns -1 if not yet computed).
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()).
Smart reference counting pointer class for automatic garbage collection.
std::vector< MagnitudeType > BERR() const
Returns a pointer to the backward error estimates computed by LAPACK.
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.
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...
std::vector< MagnitudeType > FERR() const
Returns a pointer to the forward error estimates computed by LAPACK.
bool solutionRefined()
Returns true if the current set of vectors has been refined.
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.
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 ...
This class creates and provides basic support for dense rectangular matrix of templated type...