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;
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;
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>
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>
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. ...
std::vector< MagnitudeType > BERR_
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.
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.
SerialSpdDenseSolver & operator=(const SerialSpdDenseSolver< OrdinalType, ScalarType > &Source)
bool solutionErrorsEstimated_
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
bool estimateSolutionErrors_
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.
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > LHS_
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.
std::vector< int > IWORK_
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getLHS() const
Returns pointer to current LHS.
RCP< SerialSymDenseMatrix< OrdinalType, ScalarType > > Matrix_
Templated class for solving dense linear problems.
Functionality and data that is common to all computational classes.
RCP< SerialSymDenseMatrix< OrdinalType, ScalarType > > Factor_
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.
std::vector< ScalarType > WORK_
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...
Teuchos::ScalarTraits< ScalarType >::magnitudeType MagnitudeType
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 reciprocalConditionEstimated_
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.
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > RHS_
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()...
std::vector< MagnitudeType > R_
std::vector< MagnitudeType > FERR_
int equilibrateRHS()
Equilibrates the current RHS.
This class creates and provides basic support for dense rectangular matrix of templated type...