34 template <
typename Vector,
typename RealScalar>
38 const RealScalar ns = s.stableNorm();
39 const RealScalar nt = t.stableNorm();
40 const Scalar ts = t.dot(s);
41 const RealScalar rho =
abs(ts / (nt * ns));
44 if (ts == Scalar(0)) {
51 return angle * (ns / nt) * (ts /
abs(ts));
53 return ts / (nt * nt);
56 template <
typename MatrixType,
typename Rhs,
typename Dest,
typename Preconditioner>
58 typename Dest::RealScalar& relres,
Index S,
bool smoothing,
typename Dest::RealScalar angle,
60 typedef typename Dest::RealScalar RealScalar;
61 typedef typename Dest::Scalar Scalar;
65 S = S <
x.rows() ? S :
x.rows();
66 const RealScalar tol = relres;
67 const Index maxit = iter;
76 P = (
qr.householderQ() * DenseMatrixType::Identity(N, S));
79 const RealScalar normb =
b.stableNorm();
101 const RealScalar tolb = tol * normb;
102 VectorType r =
b -
A *
x;
111 RealScalar normr = r.stableNorm();
116 relres = normr / normb;
120 DenseMatrixType
G = DenseMatrixType::Zero(N, S);
121 DenseMatrixType U = DenseMatrixType::Zero(N, S);
122 DenseMatrixType
M = DenseMatrixType::Identity(S, S);
123 VectorType t(N),
v(N);
129 while (normr > tolb && iter < maxit) {
131 VectorType f = (r.adjoint() *
P).adjoint();
133 for (
Index k = 0; k < S; ++k) {
136 lu_solver.
compute(
M.block(k, k, S - k, S - k));
137 VectorType
c = lu_solver.
solve(f.segment(k, S - k));
139 v = r -
G.rightCols(S - k) *
c;
141 v = precond.solve(
v);
144 U.col(k) = U.rightCols(S - k) *
c + om *
v;
145 G.col(k) =
A * U.col(k);
150 Scalar alpha =
P.col(
i).dot(
G.col(k)) /
M(
i,
i);
151 G.col(k) =
G.col(k) - alpha *
G.col(
i);
152 U.col(k) = U.col(k) - alpha * U.col(
i);
157 M.block(k, k, S - k, 1) = (
G.col(k).adjoint() *
P.rightCols(S - k)).adjoint();
164 Scalar beta = f(k) /
M(k, k);
165 r = r - beta *
G.col(k);
166 x =
x + beta * U.col(k);
167 normr = r.stableNorm();
169 if (replacement && normr > tolb / mp) {
177 Scalar gamma = t.dot(r_s) / t.stableNorm();
178 r_s = r_s - gamma * t;
179 x_s = x_s - gamma * (x_s -
x);
180 normr = r_s.stableNorm();
183 if (normr < tolb || iter == maxit) {
189 f.segment(k + 1, S - (k + 1)) = f.segment(k + 1, S - (k + 1)) - beta *
M.block(k + 1, k, S - (k + 1), 1);
193 if (normr < tolb || iter == maxit) {
201 v = precond.solve(
v);
209 if (om == RealScalar(0.0)) {
215 normr = r.stableNorm();
217 if (replacement && normr > tolb / mp) {
222 if (trueres && normr < normb) {
230 Scalar gamma = t.dot(r_s) / t.stableNorm();
231 r_s = r_s - gamma * t;
232 x_s = x_s - gamma * (x_s -
x);
233 normr = r_s.stableNorm();
243 relres = normr / normb;
249 template <
typename MatrixType_,
typename Preconditioner_ = DiagonalPreconditioner<
typename MatrixType_::Scalar> >
254 template <
typename MatrixType_,
typename Preconditioner_>
255 struct traits<
Eigen::IDRS<MatrixType_, Preconditioner_> > {
257 typedef Preconditioner_ Preconditioner;
303 template <
typename MatrixType_,
typename Preconditioner_>
307 typedef typename MatrixType::Scalar
Scalar;
337 template <
typename MatrixDerived>
346 template <
typename Rhs,
typename Dest>
Array< int, Dynamic, 1 > v
SparseMatrix< double > A(n, n)
Projective3d P(Matrix4d::Random())
HouseholderQR< MatrixXf > qr(A)
JacobiRotation< float > G
Matrix< float, 1, Dynamic > MatrixType
FullPivLU & compute(const EigenBase< InputType > &matrix)
const Solve< FullPivLU, Rhs > solve(const MatrixBase< Rhs > &b) const
The Induced Dimension Reduction method (IDR(s)) is a short-recurrences Krylov method for sparse squar...
void setResidualUpdate(bool update)
IDRS(const EigenBase< MatrixDerived > &A)
const ActualMatrixType & matrix() const
MatrixType::Scalar Scalar
Preconditioner_ Preconditioner
IterativeSolverBase< IDRS > Base
void _solve_vector_with_guess_impl(const Rhs &b, Dest &x) const
void setSmoothing(bool smoothing)
MatrixType::RealScalar RealScalar
void setAngle(RealScalar angle)
Index maxIterations() const
Preconditioner m_preconditioner
const ActualMatrixType & matrix() const
internal::traits< Derived >::Scalar Scalar
bool idrs(const MatrixType &A, const Rhs &b, Dest &x, const Preconditioner &precond, Index &iter, typename Dest::RealScalar &relres, Index S, bool smoothing, typename Dest::RealScalar angle, bool replacement)
bool isApprox(const Scalar &x, const Scalar &y, const typename NumTraits< Scalar >::Real &precision=NumTraits< Scalar >::dummy_precision())
Vector::Scalar omega(const Vector &t, const Vector &s, RealScalar angle)
EIGEN_ALWAYS_INLINE std::enable_if_t< NumTraits< T >::IsSigned||NumTraits< T >::IsComplex, typename NumTraits< T >::Real > abs(const T &x)
: TensorContractionSycl.h, provides various tensor contraction kernel for SYCL backend
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_abs_op< typename Derived::Scalar >, const Derived > abs(const Eigen::ArrayBase< Derived > &x)