29 #ifndef EIGEN_BICGSTABL_H
30 #define EIGEN_BICGSTABL_H
46 template <
typename MatrixType,
typename Rhs,
typename Dest,
typename Preconditioner>
48 typename Dest::RealScalar &tol_error,
Index L) {
51 typedef typename Dest::RealScalar RealScalar;
52 typedef typename Dest::Scalar Scalar;
53 const Index N = rhs.size();
54 L =
L <
x.rows() ?
L :
x.rows();
58 const RealScalar tol = tol_error;
59 const Index maxIters = iters;
64 DenseMatrixType rHat(N,
L + 1);
65 DenseMatrixType uHat(N,
L + 1);
70 rHat.col(0) = rhs -
mat * x0;
74 VectorType rShadow = VectorType::Random(N);
76 VectorType x_prime =
x;
80 VectorType b_prime = rHat.col(0);
87 uHat.col(0).setZero();
89 bool bicg_convergence =
false;
91 const RealScalar normb = rhs.stableNorm();
97 RealScalar normr = rHat.col(0).stableNorm();
98 RealScalar Mx = normr;
99 RealScalar Mr = normr;
102 RealScalar normr_min = normr;
103 VectorType x_min = x_prime +
x;
106 const RealScalar delta = 0.01;
108 bool compute_res =
false;
109 bool update_app =
false;
111 while (normr > tol * normb && k < maxIters) {
115 const Scalar rho1 = rShadow.dot(rHat.col(
j));
122 normr = (rhs -
mat * (precond.solve(
x) + x0)).stableNorm();
129 tol_error = normr / normb;
132 x = precond.solve(
x);
134 return (normr < tol * normb);
137 const Scalar beta = alpha * (rho1 / rho0);
140 uHat.leftCols(
j + 1) = rHat.leftCols(
j + 1) - beta * uHat.leftCols(
j + 1);
141 uHat.col(
j + 1) =
mat * precond.solve(uHat.col(
j));
142 const Scalar sigma = rShadow.dot(uHat.col(
j + 1));
143 alpha = rho1 / sigma;
145 rHat.leftCols(
j + 1) -= alpha * uHat.middleCols(1,
j + 1);
146 rHat.col(
j + 1) =
mat * precond.solve(rHat.col(
j));
148 x += alpha * uHat.col(0);
149 normr = rHat.col(0).stableNorm();
151 if (normr < tol * normb) {
158 bicg_convergence =
true;
160 }
else if (normr < normr_min) {
166 if (!bicg_convergence) {
175 const VectorType gamma = rHat.rightCols(
L).householderQr().solve(rHat.col(0));
176 x += rHat.leftCols(
L) * gamma;
177 rHat.col(0) -= rHat.rightCols(
L) * gamma;
178 uHat.col(0) -= uHat.rightCols(
L) * gamma;
179 normr = rHat.col(0).stableNorm();
182 if (normr < normr_min) {
206 if (normr < delta * normb && normb <= Mx) {
210 if (update_app || (normr < delta * Mr && normb <= Mr)) {
214 if (bicg_convergence) {
217 bicg_convergence =
false;
225 rHat.col(0) = b_prime -
mat * precond.solve(
x);
226 normr = rHat.col(0).stableNorm();
234 b_prime = rHat.col(0);
238 if (normr < normr_min) {
251 normr = (rhs -
mat * (precond.solve(
x) + x0)).stableNorm();
257 tol_error = normr / normb;
261 x = precond.solve(
x);
268 template <
typename MatrixType_,
typename Preconditioner_ = DiagonalPreconditioner<
typename MatrixType_::Scalar>>
273 template <
typename MatrixType_,
typename Preconditioner_>
274 struct traits<
Eigen::BiCGSTABL<MatrixType_, Preconditioner_>> {
276 typedef Preconditioner_ Preconditioner;
281 template <
typename MatrixType_,
typename Preconditioner_>
293 typedef typename MatrixType::Scalar
Scalar;
311 template <
typename MatrixDerived>
319 template <
typename Rhs,
typename Dest>
SparseMatrix< double > A(n, n)
Matrix< float, 1, Dynamic > MatrixType
const ActualMatrixType & matrix() const
BiCGSTABL(const EigenBase< MatrixDerived > &A)
Preconditioner_ Preconditioner
IterativeSolverBase< BiCGSTABL > Base
MatrixType::RealScalar RealScalar
void _solve_vector_with_guess_impl(const Rhs &b, Dest &x) const
MatrixType::Scalar Scalar
Index maxIterations() const
Preconditioner m_preconditioner
const ActualMatrixType & matrix() const
bool bicgstabl(const MatrixType &mat, const Rhs &rhs, Dest &x, const Preconditioner &precond, Index &iters, typename Dest::RealScalar &tol_error, Index L)
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 T maxi(const T &x, const T &y)
EIGEN_ALWAYS_INLINE bool() isfinite(const Eigen::bfloat16 &h)
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