10#ifndef _TEUCHOS_SERIALDENSESOLVER_HPP_
11#define _TEUCHOS_SERIALDENSESOLVER_HPP_
24#ifdef HAVE_TEUCHOSNUMERICS_EIGEN
104 template<
typename OrdinalType,
typename ScalarType>
106 public LAPACK<OrdinalType, ScalarType>
112#ifdef HAVE_TEUCHOSNUMERICS_EIGEN
113 typedef typename Eigen::Matrix<ScalarType,Eigen::Dynamic,Eigen::Dynamic,Eigen::ColMajor>
EigenMatrix;
114 typedef typename Eigen::Matrix<ScalarType,Eigen::Dynamic,1>
EigenVector;
117 typedef typename Eigen::Map<EigenVector,0,EigenInnerStride >
EigenVectorMap;
119 typedef typename Eigen::Map<EigenMatrix,0,EigenOuterStride >
EigenMatrixMap;
121 typedef typename Eigen::PermutationMatrix<Eigen::Dynamic,Eigen::Dynamic,OrdinalType>
EigenPermutationMatrix;
124 typedef typename Eigen::Array<ScalarType,Eigen::Dynamic,1>
EigenScalarArray;
303 std::vector<OrdinalType>
IPIV()
const {
return(IPIV_);}
306 MagnitudeType
ANORM()
const {
return(ANORM_);}
309 MagnitudeType
RCOND()
const {
return(RCOND_);}
314 MagnitudeType
ROWCND()
const {
return(ROWCND_);}
319 MagnitudeType
COLCND()
const {
return(COLCND_);}
322 MagnitudeType
AMAX()
const {
return(AMAX_);}
325 std::vector<MagnitudeType>
FERR()
const {
return(FERR_);}
328 std::vector<MagnitudeType>
BERR()
const {
return(BERR_);}
331 std::vector<MagnitudeType>
R()
const {
return(R_);}
334 std::vector<MagnitudeType>
C()
const {
return(C_);}
340 void Print(std::ostream& os)
const;
344 void allocateWORK() { LWORK_ = 4*N_; WORK_.resize( LWORK_ );
return;}
350 bool shouldEquilibrate_;
355 bool estimateSolutionErrors_;
356 bool solutionErrorsEstimated_;
359 bool reciprocalConditionEstimated_;
360 bool refineSolution_;
361 bool solutionRefined_;
373 std::vector<OrdinalType> IPIV_;
375 MagnitudeType ANORM_;
376 MagnitudeType RCOND_;
377 MagnitudeType ROWCND_;
378 MagnitudeType COLCND_;
381 RCP<SerialDenseMatrix<OrdinalType, ScalarType> > Matrix_;
382 RCP<SerialDenseMatrix<OrdinalType, ScalarType> > LHS_;
383 RCP<SerialDenseMatrix<OrdinalType, ScalarType> > RHS_;
384 RCP<SerialDenseMatrix<OrdinalType, ScalarType> > Factor_;
388 std::vector<MagnitudeType> FERR_;
389 std::vector<MagnitudeType> BERR_;
390 std::vector<ScalarType> WORK_;
391 std::vector<MagnitudeType> R_;
392 std::vector<MagnitudeType> C_;
393#ifdef HAVE_TEUCHOSNUMERICS_EIGEN
394 Eigen::PartialPivLU<EigenMatrix> lu_;
401 SerialDenseSolver & operator=(
const SerialDenseSolver<OrdinalType, ScalarType>& Source);
409 struct lapack_traits {
410 typedef int iwork_type;
415 struct lapack_traits<std::complex<T> > {
423template<
typename OrdinalType,
typename ScalarType>
427 shouldEquilibrate_(
false),
428 equilibratedA_(
false),
429 equilibratedB_(
false),
432 estimateSolutionErrors_(
false),
433 solutionErrorsEstimated_(
false),
436 reciprocalConditionEstimated_(
false),
437 refineSolution_(
false),
438 solutionRefined_(
false),
459template<
typename OrdinalType,
typename ScalarType>
465template<
typename OrdinalType,
typename ScalarType>
468 LHS_ = Teuchos::null;
469 RHS_ = Teuchos::null;
470 reciprocalConditionEstimated_ =
false;
471 solutionRefined_ =
false;
473 solutionErrorsEstimated_ =
false;
474 equilibratedB_ =
false;
478template<
typename OrdinalType,
typename ScalarType>
479void SerialDenseSolver<OrdinalType,ScalarType>::resetMatrix()
482 equilibratedA_ =
false;
504template<
typename OrdinalType,
typename ScalarType>
512 Min_MN_ = TEUCHOS_MIN(M_,N_);
521template<
typename OrdinalType,
typename ScalarType>
527 "SerialDenseSolver<T>::setVectors: X and B are not the same size!");
529 "SerialDenseSolver<T>::setVectors: B is an empty SerialDenseMatrix<T>!");
531 "SerialDenseSolver<T>::setVectors: X is an empty SerialDenseMatrix<T>!");
533 "SerialDenseSolver<T>::setVectors: B has an invalid stride!");
535 "SerialDenseSolver<T>::setVectors: X has an invalid stride!");
544template<
typename OrdinalType,
typename ScalarType>
547 estimateSolutionErrors_ =
flag;
550 refineSolution_ = refineSolution_ ||
flag;
554template<
typename OrdinalType,
typename ScalarType>
557 if (factored())
return(0);
560 "SerialDenseSolver<T>::factor: Cannot factor an inverted matrix!");
562 ANORM_ = Matrix_->normOne();
569 if (refineSolution_ ) {
571 AF_ = Factor_->values();
572 LDAF_ = Factor_->stride();
576 if (equilibrate_)
ierr = equilibrateMatrix();
580 if ((
int)IPIV_.size()!=Min_MN_) IPIV_.resize( Min_MN_ );
584#ifdef HAVE_TEUCHOSNUMERICS_EIGEN
591 p =
lu_.permutationP();
604 this->GETRF(M_, N_, AF_, LDAF_, &IPIV_[0], &INFO_);
614template<
typename OrdinalType,
typename ScalarType>
628 ierr = equilibrateRHS();
633 "SerialDenseSolver<T>::solve: No right-hand side vector (RHS) has been set for the linear system!");
635 "SerialDenseSolver<T>::solve: No solution vector (LHS) has been set for the linear system!");
640 "SerialDenseSolver<T>::solve: X and B must be different vectors if matrix is inverted.");
642 std::logic_error,
"SerialDenseSolver<T>::solve: Matrix and vectors must be similarly scaled!");
646 RHS_->values(), RHS_->stride(), 0.0, LHS_->values(), LHS_->stride());
647 if (INFO_!=0)
return(INFO_);
652 if (!factored()) factor();
655 std::logic_error,
"SerialDenseSolver<T>::solve: Matrix and vectors must be similarly scaled!");
657 if (RHS_->values()!=LHS_->values()) {
662#ifdef HAVE_TEUCHOSNUMERICS_EIGEN
679 this->GETRS(ETranspChar[TRANS_], N_, RHS_->numCols(), AF_, LDAF_, &IPIV_[0], LHS_->values(), LHS_->stride(), &INFO_);
682 if (INFO_!=0)
return(INFO_);
688 if (shouldEquilibrate() && !equilibratedA_)
689 std::cout <<
"WARNING! SerialDenseSolver<T>::solve: System should be equilibrated!" << std::endl;
692 if (refineSolution_ && !inverted())
ierr1 = applyRefinement();
696 if (equilibrate_)
ierr1 = unequilibrateLHS();
701template<
typename OrdinalType,
typename ScalarType>
705 "SerialDenseSolver<T>::applyRefinement: Must have an existing solution!");
707 "SerialDenseSolver<T>::applyRefinement: Cannot apply refinement if no original copy of A!");
709#ifdef HAVE_TEUCHOSNUMERICS_EIGEN
715 FERR_.resize(
NRHS );
716 BERR_.resize(
NRHS );
720 std::vector<typename details::lapack_traits<ScalarType>::iwork_type>
GERFS_WORK( N_ );
721 this->GERFS(ETranspChar[TRANS_], N_,
NRHS, A_, LDA_, AF_, LDAF_, &IPIV_[0],
722 RHS_->values(), RHS_->stride(), LHS_->values(), LHS_->stride(),
723 &FERR_[0], &BERR_[0], &WORK_[0], &
GERFS_WORK[0], &INFO_);
725 solutionErrorsEstimated_ =
true;
726 reciprocalConditionEstimated_ =
true;
727 solutionRefined_ =
true;
735template<
typename OrdinalType,
typename ScalarType>
738 if (R_.size()!=0)
return(0);
744 this->GEEQU (M_, N_, AF_, LDAF_, &R_[0], &C_[0], &ROWCND_, &COLCND_, &AMAX_, &INFO_);
749 shouldEquilibrate_ =
true;
756template<
typename OrdinalType,
typename ScalarType>
762 if (equilibratedA_)
return(0);
763 if (R_.size()==0)
ierr = computeEquilibrateScaling();
767 for (
j=0;
j<N_;
j++) {
770 for (
i=0;
i<M_;
i++) {
779 for (
j=0;
j<N_;
j++) {
781 ptr1 = AF_ +
j*LDAF_;
783 for (
i=0;
i<M_;
i++) {
792 equilibratedA_ =
true;
799template<
typename OrdinalType,
typename ScalarType>
805 if (equilibratedB_)
return(0);
806 if (R_.size()==0)
ierr = computeEquilibrateScaling();
809 MagnitudeType *
R_tmp = &R_[0];
810 if (transpose_)
R_tmp = &C_[0];
817 for (
i=0;
i<M_;
i++) {
823 equilibratedB_ =
true;
830template<
typename OrdinalType,
typename ScalarType>
835 if (!equilibratedB_)
return(0);
837 MagnitudeType *
C_tmp = &C_[0];
838 if (transpose_)
C_tmp = &R_[0];
845 for (
i=0;
i<N_;
i++) {
856template<
typename OrdinalType,
typename ScalarType>
860 if (!factored()) factor();
862#ifdef HAVE_TEUCHOSNUMERICS_EIGEN
887 this->GETRI( N_, AF_, LDAF_, &IPIV_[0], &WORK_[0], LWORK_, &INFO_);
899template<
typename OrdinalType,
typename ScalarType>
902#ifdef HAVE_TEUCHOSNUMERICS_EIGEN
906 if (reciprocalConditionEstimated()) {
914 if (!factored())
ierr = factor();
921 std::vector<typename details::lapack_traits<ScalarType>::iwork_type>
GECON_WORK( 2*N_ );
922 this->GECON(
'1', N_, AF_, LDAF_, ANORM_, &RCOND_, &WORK_[0], &
GECON_WORK[0], &INFO_);
924 reciprocalConditionEstimated_ =
true;
932template<
typename OrdinalType,
typename ScalarType>
935 if (Matrix_!=Teuchos::null) os <<
"Solver Matrix" << std::endl << *Matrix_ << std::endl;
936 if (Factor_!=Teuchos::null) os <<
"Solver Factored Matrix" << std::endl << *Factor_ << std::endl;
937 if (LHS_ !=Teuchos::null) os <<
"Solver LHS" << std::endl << *LHS_ << std::endl;
938 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.
Defines basic traits for the scalar field type.
Templated serial dense 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 solving dense linear problems.
std::vector< MagnitudeType > BERR() const
Returns a pointer to the backward error estimates computed by LAPACK.
MagnitudeType ROWCND() const
Ratio of smallest to largest row scale factors for the this matrix (returns -1 if not yet computed).
bool solutionRefined()
Returns true if the current set of vectors has been refined.
void factorWithEquilibration(bool flag)
Causes equilibration to be called just before the matrix factorization as part of the call to factor.
OrdinalType numRows() const
Returns row dimension of system.
bool factored()
Returns true if matrix is factored (factor available via getFactoredMatrix()).
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getRHS() const
Returns pointer to current RHS.
MagnitudeType RCOND() const
Returns the reciprocal of the condition number of the this matrix (returns -1 if not yet computed).
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getLHS() const
Returns pointer to current LHS.
std::vector< MagnitudeType > C() const
Returns a pointer to the column scale vector used for equilibration.
int setMatrix(const RCP< SerialDenseMatrix< OrdinalType, ScalarType > > &A)
Sets the pointers for coefficient matrix.
int computeEquilibrateScaling()
Computes the scaling vector S(i) = 1/sqrt(A(i,i)) of the this matrix.
int equilibrateRHS()
Equilibrates the current RHS.
bool inverted()
Returns true if matrix inverse has been computed (inverse available via getFactoredMatrix()).
bool equilibratedA()
Returns true if factor is equilibrated (factor available via getFactoredMatrix()).
MagnitudeType COLCND() const
Ratio of smallest to largest column scale factors for the this matrix (returns -1 if not yet computed...
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getMatrix() const
Returns pointer to current matrix.
bool shouldEquilibrate()
Returns true if the LAPACK general rules for equilibration suggest you should equilibrate the system.
bool solved()
Returns true if the current set of vectors has been solved.
std::vector< MagnitudeType > FERR() const
Returns a pointer to the forward error estimates computed by LAPACK.
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getFactoredMatrix() const
Returns pointer to factored matrix (assuming factorization has been performed).
void estimateSolutionErrors(bool flag)
Causes all solves to estimate the forward and backward solution error.
int invert()
Inverts the this matrix.
int factor()
Computes the in-place LU factorization of the matrix using the LAPACK routine _GETRF.
int equilibrateMatrix()
Equilibrates the this matrix.
void solveWithTransposeFlag(Teuchos::ETransp trans)
All subsequent function calls will work with the transpose-type set by this method (Teuchos::NO_TRANS...
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 Print(std::ostream &os) const
Print service methods; defines behavior of ostream << operator.
int applyRefinement()
Apply Iterative Refinement.
int unequilibrateLHS()
Unscales the solution vectors if equilibration was used to solve the system.
MagnitudeType AMAX() const
Returns the absolute value of the largest entry 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.
void solveWithTranspose(bool flag)
If flag is true, causes all subsequent function calls to work with the transpose of this matrix,...
virtual ~SerialDenseSolver()
SerialDenseSolver destructor.
SerialDenseSolver()
Default constructor; matrix should be set using setMatrix(), LHS and RHS set with 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).
OrdinalType numCols() const
Returns column dimension of system.
bool transpose()
Returns true if transpose of this matrix has and will be used.
std::vector< OrdinalType > IPIV() const
Returns pointer to pivot vector (if factorization has been computed), zero otherwise.
MagnitudeType ANORM() const
Returns the 1-Norm of the this matrix (returns -1 if not yet computed).
bool equilibratedB()
Returns true if RHS is equilibrated (RHS available via getRHS()).
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.
bool solutionErrorsEstimated()
Returns true if forward and backward error estimated have been computed (available via FERR() and BER...
#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.