11 #ifndef TEUCHOS_SERIALSPDDENSESOLVER_H
12 #define TEUCHOS_SERIALSPDDENSESOLVER_H
27 #ifdef HAVE_TEUCHOSNUMERICS_EIGEN
28 #include "Eigen/Dense"
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;
298 std::vector<MagnitudeType>
FERR()
const {
return(
FERR_);}
301 std::vector<MagnitudeType>
BERR()
const {
return(
BERR_);}
304 std::vector<MagnitudeType>
R()
const {
return(
R_);}
310 void Print(std::ostream& os)
const;
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;
377 template<
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),
409 template<
typename OrdinalType,
typename ScalarType>
415 template<
typename OrdinalType,
typename ScalarType>
420 reciprocalConditionEstimated_ =
false;
421 solutionRefined_ =
false;
423 solutionErrorsEstimated_ =
false;
424 equilibratedB_ =
false;
428 template<
typename OrdinalType,
typename ScalarType>
432 equilibratedA_ =
false;
450 template<
typename OrdinalType,
typename ScalarType>
456 numRowCols_ =
A->numRows();
465 template<
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!");
488 template<
typename OrdinalType,
typename ScalarType>
491 estimateSolutionErrors_ = flag;
494 refineSolution_ = refineSolution_ || flag;
498 template<
typename OrdinalType,
typename ScalarType>
501 if (factored())
return(0);
504 "SerialSpdDenseSolver<T>::factor: Cannot factor an inverted matrix!");
506 ANORM_ = Matrix_->normOne();
513 if (refineSolution_ ) {
515 AF_ = Factor_->values();
516 LDAF_ = Factor_->stride();
520 if (equilibrate_) ierr = equilibrateMatrix();
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_);
545 template<
typename OrdinalType,
typename ScalarType>
559 ierr = equilibrateRHS();
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_);
584 if (!factored()) factor();
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_);
613 if (shouldEquilibrate() && !equilibratedA_)
614 std::cout <<
"WARNING! SerialSpdDenseSolver<T>::solve: System should be equilibrated!" << std::endl;
617 if (refineSolution_ && !inverted()) ierr1 = applyRefinement();
621 if (equilibrate_) ierr1 = unequilibrateLHS();
626 template<
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;
661 template<
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;
680 template<
typename OrdinalType,
typename ScalarType>
686 if (equilibratedA_)
return(0);
687 if (R_.size()==0) ierr = computeEquilibrateScaling();
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++) {
696 *ptr = *ptr*s1*R_[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++) {
709 *ptr = *ptr*s1*R_[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++) {
724 *ptr = *ptr*s1*R_[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++) {
737 *ptr = *ptr*s1*R_[i];
739 *ptr1 = *ptr1*s1*R_[i];
746 equilibratedA_ =
true;
753 template<
typename OrdinalType,
typename ScalarType>
759 if (equilibratedB_)
return(0);
760 if (R_.size()==0) ierr = computeEquilibrateScaling();
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;
781 template<
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++) {
804 template<
typename OrdinalType,
typename ScalarType>
807 #ifdef HAVE_TEUCHOSNUMERICS_EIGEN
811 if (!factored()) factor();
814 this->POTRI( Matrix_->UPLO(), numRowCols_, AF_, LDAF_, &INFO_);
817 if (Matrix_->upper())
831 template<
typename OrdinalType,
typename ScalarType>
834 #ifdef HAVE_TEUCHOSNUMERICS_EIGEN
838 if (reciprocalConditionEstimated()) {
846 if (!factored()) ierr = factor();
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;
864 template<
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;
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.
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.
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...