mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Iterative solvers: unify and fix handling of multiple rhs.
m_info was not properly computed and the logic was repeated in several places.
This commit is contained in:
@@ -109,6 +109,7 @@ class DGMRES : public IterativeSolverBase<DGMRES<_MatrixType,_Preconditioner> >
|
||||
using Base::m_tolerance;
|
||||
public:
|
||||
using Base::_solve_impl;
|
||||
using Base::_solve_with_guess_impl;
|
||||
typedef _MatrixType MatrixType;
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename MatrixType::StorageIndex StorageIndex;
|
||||
@@ -141,30 +142,16 @@ class DGMRES : public IterativeSolverBase<DGMRES<_MatrixType,_Preconditioner> >
|
||||
|
||||
/** \internal */
|
||||
template<typename Rhs,typename Dest>
|
||||
void _solve_with_guess_impl(const Rhs& b, Dest& x) const
|
||||
{
|
||||
bool failed = false;
|
||||
for(Index j=0; j<b.cols(); ++j)
|
||||
{
|
||||
m_iterations = Base::maxIterations();
|
||||
m_error = Base::m_tolerance;
|
||||
|
||||
typename Dest::ColXpr xj(x,j);
|
||||
dgmres(matrix(), b.col(j), xj, Base::m_preconditioner);
|
||||
}
|
||||
m_info = failed ? NumericalIssue
|
||||
: m_error <= Base::m_tolerance ? Success
|
||||
: NoConvergence;
|
||||
m_isInitialized = true;
|
||||
void _solve_vector_with_guess_impl(const Rhs& b, Dest& x) const
|
||||
{
|
||||
EIGEN_STATIC_ASSERT(Rhs::ColsAtCompileTime==1 || Dest::ColsAtCompileTime==1, YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX);
|
||||
|
||||
m_iterations = Base::maxIterations();
|
||||
m_error = Base::m_tolerance;
|
||||
|
||||
dgmres(matrix(), b, x, Base::m_preconditioner);
|
||||
}
|
||||
|
||||
/** \internal */
|
||||
template<typename Rhs,typename Dest>
|
||||
void _solve_impl(const Rhs& b, MatrixBase<Dest>& x) const
|
||||
{
|
||||
x = b;
|
||||
_solve_with_guess_impl(b,x.derived());
|
||||
}
|
||||
/**
|
||||
* Get the restart value
|
||||
*/
|
||||
|
||||
@@ -64,6 +64,15 @@ bool gmres(const MatrixType & mat, const Rhs & rhs, Dest & x, const Precondition
|
||||
typedef Matrix < Scalar, Dynamic, 1 > VectorType;
|
||||
typedef Matrix < Scalar, Dynamic, Dynamic, ColMajor> FMatrixType;
|
||||
|
||||
const RealScalar considerAsZero = (std::numeric_limits<RealScalar>::min)();
|
||||
|
||||
if(rhs.norm() <= considerAsZero)
|
||||
{
|
||||
x.setZero();
|
||||
tol_error = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
RealScalar tol = tol_error;
|
||||
const Index maxIters = iters;
|
||||
iters = 0;
|
||||
@@ -307,31 +316,14 @@ public:
|
||||
|
||||
/** \internal */
|
||||
template<typename Rhs,typename Dest>
|
||||
void _solve_with_guess_impl(const Rhs& b, Dest& x) const
|
||||
void _solve_vector_with_guess_impl(const Rhs& b, Dest& x) const
|
||||
{
|
||||
bool failed = false;
|
||||
for(Index j=0; j<b.cols(); ++j)
|
||||
{
|
||||
m_iterations = Base::maxIterations();
|
||||
m_error = Base::m_tolerance;
|
||||
|
||||
typename Dest::ColXpr xj(x,j);
|
||||
if(!internal::gmres(matrix(), b.col(j), xj, Base::m_preconditioner, m_iterations, m_restart, m_error))
|
||||
failed = true;
|
||||
}
|
||||
m_info = failed ? NumericalIssue
|
||||
m_iterations = Base::maxIterations();
|
||||
m_error = Base::m_tolerance;
|
||||
bool ret = internal::gmres(matrix(), b, x, Base::m_preconditioner, m_iterations, m_restart, m_error);
|
||||
m_info = (!ret) ? NumericalIssue
|
||||
: m_error <= Base::m_tolerance ? Success
|
||||
: NoConvergence;
|
||||
m_isInitialized = true;
|
||||
}
|
||||
|
||||
/** \internal */
|
||||
template<typename Rhs,typename Dest>
|
||||
void _solve_impl(const Rhs& b, MatrixBase<Dest> &x) const
|
||||
{
|
||||
x = b;
|
||||
if(x.squaredNorm() == 0) return; // Check Zero right hand side
|
||||
_solve_with_guess_impl(b,x.derived());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
@@ -233,7 +233,7 @@ namespace Eigen {
|
||||
|
||||
/** \internal */
|
||||
template<typename Rhs,typename Dest>
|
||||
void _solve_with_guess_impl(const Rhs& b, Dest& x) const
|
||||
void _solve_vector_with_guess_impl(const Rhs& b, Dest& x) const
|
||||
{
|
||||
typedef typename Base::MatrixWrapper MatrixWrapper;
|
||||
typedef typename Base::ActualMatrixType ActualMatrixType;
|
||||
@@ -253,28 +253,11 @@ namespace Eigen {
|
||||
m_iterations = Base::maxIterations();
|
||||
m_error = Base::m_tolerance;
|
||||
RowMajorWrapper row_mat(matrix());
|
||||
for(int j=0; j<b.cols(); ++j)
|
||||
{
|
||||
m_iterations = Base::maxIterations();
|
||||
m_error = Base::m_tolerance;
|
||||
|
||||
typename Dest::ColXpr xj(x,j);
|
||||
internal::minres(SelfAdjointWrapper(row_mat), b.col(j), xj,
|
||||
Base::m_preconditioner, m_iterations, m_error);
|
||||
}
|
||||
|
||||
m_isInitialized = true;
|
||||
internal::minres(SelfAdjointWrapper(row_mat), b, x,
|
||||
Base::m_preconditioner, m_iterations, m_error);
|
||||
m_info = m_error <= Base::m_tolerance ? Success : NoConvergence;
|
||||
}
|
||||
|
||||
/** \internal */
|
||||
template<typename Rhs,typename Dest>
|
||||
void _solve_impl(const Rhs& b, MatrixBase<Dest> &x) const
|
||||
{
|
||||
x.setZero();
|
||||
_solve_with_guess_impl(b,x.derived());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user