38 #ifndef EIGEN_IDRSTABL_H
39 #define EIGEN_IDRSTABL_H
45 template <
typename MatrixType,
typename Rhs,
typename Dest,
typename Preconditioner>
47 typename Dest::RealScalar &tol_error,
Index L,
Index S) {
53 typedef typename Dest::Scalar Scalar;
54 typedef typename Dest::RealScalar RealScalar;
61 const Index maxIters = iters;
63 const RealScalar rhs_norm = rhs.stableNorm();
64 const RealScalar tol = tol_error * rhs_norm;
78 if (S >= N ||
L >= N) {
85 tol_error = (rhs -
mat *
x).stableNorm() / rhs_norm;
90 DenseMatrixType u(N,
L + 1);
91 DenseMatrixType r(N,
L + 1);
93 DenseMatrixType
V(N * (
L + 1), S);
104 r.col(0) = rhs -
mat *
x;
107 tol_error = r.col(0).stableNorm();
110 DenseMatrixType h_FOM = DenseMatrixType::Zero(S, S - 1);
113 DenseMatrixType U(N * (
L + 1), S);
114 for (
Index col_index = 0; col_index < S; ++col_index) {
119 if (col_index != 0) {
123 VectorType
w =
mat * precond.solve(u.col(0));
124 for (
Index i = 0;
i < col_index; ++
i) {
125 auto v = U.col(
i).head(N);
126 h_FOM(
i, col_index - 1) =
v.dot(
w);
127 w -= h_FOM(
i, col_index - 1) *
v;
130 h_FOM(col_index, col_index - 1) = u.col(0).stableNorm();
132 if (
abs(h_FOM(col_index, col_index - 1)) != RealScalar(0)) {
157 u.col(0) /= h_FOM(col_index, col_index - 1);
161 u.col(0).normalize();
164 U.col(col_index).head(N) = u.col(0);
169 Scalar beta = r.col(0).stableNorm();
170 VectorType e1 = VectorType::Zero(S - 1);
172 lu_solver.
compute(h_FOM.topLeftCorner(S - 1, S - 1));
173 VectorType
y = lu_solver.
solve(e1);
174 VectorType x2 =
x + U.topLeftCorner(N, S - 1) *
y;
178 RealScalar FOM_residual = (h_FOM(S - 1, S - 2) *
y(S - 2) * U.col(S - 1).head(N)).stableNorm();
180 if (FOM_residual < tol) {
184 x = precond.solve(x2);
187 tol_error = FOM_residual / rhs_norm;
205 DenseMatrixType R_T = (
qr.householderQ() * DenseMatrixType::Identity(N, S)).adjoint();
206 DenseMatrixType AR_T = DenseMatrixType(R_T *
mat);
209 DenseMatrixType sigma(S, S);
211 bool reset_while =
false;
213 while (k < maxIters) {
220 sigma.col(
i).noalias() = AR_T * precond.solve(U.block(N * (
j - 1),
i, N, 1));
227 alpha.noalias() = lu_solver.
solve(R_T * r.col(0));
230 alpha.noalias() = lu_solver.
solve(AR_T * precond.solve(r.col(
j - 2)));
234 update.noalias() = U.topRows(N) * alpha;
235 r.col(0) -=
mat * precond.solve(update);
240 r.col(
i) -= U.block(N * (
i + 1), 0, N, S) * alpha;
244 r.col(
j - 1).noalias() =
mat * precond.solve(r.col(
j - 2));
246 tol_error = r.col(0).stableNorm();
248 if (tol_error < tol) {
254 bool break_normalization =
false;
258 u.leftCols(
j + 1) = r.leftCols(
j + 1);
261 u.leftCols(
j) = u.middleCols(1,
j);
266 u.reshaped().head(u.rows() *
j) -= U.topRows(N *
j) * lu_solver.
solve(AR_T * precond.solve(u.col(
j - 1)));
269 u.col(
j).noalias() =
mat * precond.solve(u.col(
j - 1));
281 auto v =
V.col(
i).segment(N *
j, N);
282 Scalar h =
v.squaredNorm();
283 h =
v.dot(u.col(
j)) / h;
284 u.reshaped().head(u.rows() * (
j + 1)) -= h *
V.block(0,
i, N * (
j + 1), 1);
288 Scalar normalization_constant = u.col(
j).stableNorm();
291 if (normalization_constant == RealScalar(0.0)) {
292 break_normalization =
true;
295 u.leftCols(
j + 1) /= normalization_constant;
298 V.block(0,
q - 1, N * (
j + 1), 1).noalias() = u.reshaped().head(u.rows() * (
j + 1));
301 if (break_normalization ==
false) {
310 r.col(
L).noalias() =
mat * precond.solve(r.col(
L - 1));
316 gamma.noalias() = qr_solver.
solve(r.col(0));
319 update.noalias() = r.leftCols(
L) * gamma;
321 r.col(0) -=
mat * precond.solve(update);
325 tol_error = r.col(0).stableNorm();
327 if (tol_error < tol) {
341 U.topRows(N) -= U.block(N *
i, 0, N, S) * gamma(
i - 1);
350 x = precond.solve(
x);
353 tol_error = tol_error / rhs_norm;
359 template <
typename MatrixType_,
typename Preconditioner_ = DiagonalPreconditioner<
typename MatrixType_::Scalar>>
364 template <
typename MatrixType_,
typename Preconditioner_>
365 struct traits<IDRSTABL<MatrixType_, Preconditioner_>> {
367 typedef Preconditioner_ Preconditioner;
411 template <
typename MatrixType_,
typename Preconditioner_>
424 typedef typename MatrixType::Scalar
Scalar;
442 template <
typename MatrixDerived>
451 template <
typename Rhs,
typename Dest>
Array< int, Dynamic, 1 > v
SparseMatrix< double > A(n, n)
HouseholderQR< MatrixXf > qr(A)
Matrix< float, 1, Dynamic > MatrixType
const Solve< ColPivHouseholderQR, Rhs > solve(const MatrixBase< Rhs > &b) const
FullPivLU & compute(const EigenBase< InputType > &matrix)
const Solve< FullPivLU, Rhs > solve(const MatrixBase< Rhs > &b) const
The IDR(s)STAB(l) is a combination of IDR(s) and BiCGSTAB(l). It is a short-recurrences Krylov method...
Preconditioner_ Preconditioner
MatrixType::Scalar Scalar
const ActualMatrixType & matrix() const
IDRSTABL(const EigenBase< MatrixDerived > &A)
IterativeSolverBase< IDRSTABL > Base
MatrixType::RealScalar RealScalar
void _solve_vector_with_guess_impl(const Rhs &b, Dest &x) const
Index maxIterations() const
Preconditioner m_preconditioner
const ActualMatrixType & matrix() const
bool idrstabl(const MatrixType &mat, const Rhs &rhs, Dest &x, const Preconditioner &precond, Index &iters, typename Dest::RealScalar &tol_error, Index L, Index S)
EIGEN_ALWAYS_INLINE double sqrt(const double &x)
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)