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;
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_);}
310 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;
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>
418 LHS_ = Teuchos::null;
419 RHS_ = Teuchos::null;
420 reciprocalConditionEstimated_ =
false;
421 solutionRefined_ =
false;
423 solutionErrorsEstimated_ =
false;
424 equilibratedB_ =
false;
428 template<
typename OrdinalType,
typename ScalarType>
429 void SerialSpdDenseSolver<OrdinalType,ScalarType>::resetMatrix()
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. ...
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.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
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...
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.
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getLHS() const
Returns pointer to current LHS.
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.
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.
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...
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()).
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.
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()...
int equilibrateRHS()
Equilibrates the current RHS.
This class creates and provides basic support for dense rectangular matrix of templated type...