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;
112 typedef typename Eigen::Map<EigenVector,0,EigenInnerStride >
EigenVectorMap;
114 typedef typename Eigen::Map<EigenMatrix,0,EigenOuterStride >
EigenMatrixMap;
116 typedef typename Eigen::PermutationMatrix<Eigen::Dynamic,Eigen::Dynamic,OrdinalType>
EigenPermutationMatrix;
119 typedef typename Eigen::Array<ScalarType,Eigen::Dynamic,1>
EigenScalarArray;
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_;
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>
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>
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();
526#ifdef HAVE_TEUCHOSNUMERICS_EIGEN
529 if (Matrix_->upper())
535 this->POTRF(Matrix_->UPLO(), numRowCols_, AF_, LDAF_, &INFO_);
545template<
typename OrdinalType,
typename ScalarType>
559 ierr = equilibrateRHS();
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
598 if (Matrix_->upper())
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();
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
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);
687 if (R_.size()==0)
ierr = computeEquilibrateScaling();
689 if (Matrix_->upper()) {
692 for (
j=0;
j<numRowCols_;
j++) {
695 for (
i=0;
i<=
j;
i++) {
704 for (
j=0;
j<numRowCols_;
j++) {
706 ptr1 = AF_ +
j*LDAF_;
708 for (
i=0;
i<=
j;
i++) {
720 for (
j=0;
j<numRowCols_;
j++) {
721 ptr = A_ +
j +
j*LDA_;
723 for (
i=
j;
i<numRowCols_;
i++) {
732 for (
j=0;
j<numRowCols_;
j++) {
733 ptr = A_ +
j +
j*LDA_;
736 for (
i=
j;
i<numRowCols_;
i++) {
746 equilibratedA_ =
true;
753template<
typename OrdinalType,
typename ScalarType>
759 if (equilibratedB_)
return(0);
760 if (R_.size()==0)
ierr = computeEquilibrateScaling();
768 for (
i=0;
i<numRowCols_;
i++) {
774 equilibratedB_ =
true;
781template<
typename OrdinalType,
typename ScalarType>
786 if (!equilibratedB_)
return(0);
793 for (
i=0;
i<numRowCols_;
i++) {
804template<
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())
831template<
typename OrdinalType,
typename ScalarType>
834#ifdef HAVE_TEUCHOSNUMERICS_EIGEN
838 if (reciprocalConditionEstimated()) {
846 if (!factored())
ierr = factor();
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.
Functionality and data that is common to all computational classes.
The Templated LAPACK Wrapper Class.
Smart reference counting pointer class for automatic garbage collection.
RCP< T > rcp(const boost::shared_ptr< T > &sptr)
Conversion function that takes in a boost::shared_ptr object and spits out a Teuchos::RCP object.
Ptr< T > ptr() const
Get a safer wrapper raw C++ pointer to the underlying object.
A class for constructing and using Hermitian positive definite dense matrices.
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()).
#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 implementation details.
This structure defines some basic traits for a scalar field type.
static T one()
Returns representation of one for this scalar type.
T magnitudeType
Mandatory typedef for result of magnitude.