26template <
class WorkingSpace,
class InnerSpace,
class ResidualSpace,
class InnerOp,
class ResidualOp,
27 class Preconditioner,
class Transfer>
69 std::optional<GmresErrorEstimates<R>>
errors = {};
86template <
class WSpace,
class ISpace,
class RSpace,
class IOp,
class ROp,
class P,
class Transfer>
89 typename RSpace::vector_type
const& b,
92 using W =
typename WSpace::scalar_type;
93 using I =
typename ISpace::scalar_type;
94 using R =
typename RSpace::scalar_type;
99 "GMRES refinement spaces must be all real or all complex");
101 auto& is = context.
inner;
109 auto n = ws.ops.problem_dimension();
110 if (is.ops.problem_dimension() != n || rs.ops.problem_dimension() != n || ws.ops.vector_dimension(x) != n ||
111 rs.ops.vector_dimension(b) != n)
112 throw std::invalid_argument(
"GMRES refinement spaces have incompatible dimensions");
113 if ((options.relative_tolerance &&
114 (!
uni20::isfinite(*options.relative_tolerance) || *options.relative_tolerance < 0)) ||
115 !
uni20::isfinite(options.absolute_tolerance) || options.absolute_tolerance < 0)
116 throw std::invalid_argument(
"GMRES refinement requires finite nonnegative tolerances");
117 RR relative = options.relative_tolerance
118 ? scalar_at_precision<RR>(*options.relative_tolerance, rs.precision)
120 RR absolute = scalar_at_precision<RR>(options.absolute_tolerance, rs.precision);
122 throw std::invalid_argument(
"GMRES refinement tolerance is not representable at residual precision");
123 auto rone = scalar_at_precision<R>(1, rs.precision);
124 auto wone = scalar_at_precision<W>(1, ws.precision);
125 GmresRefinementInfo<IR, RR> info;
127 info.status = status;
130 auto rnorm = [&](
auto const& v) {
return gmres_detail::norm<R>(rs.ops, v, rs.precision); };
131 auto wnorm = [&](
auto const& v) {
return gmres_detail::norm<W>(ws.ops, v, ws.precision); };
134 auto rhs = rs.ops.allocate_like(rs.prototype);
135 context.
transfer(rhs, b, rs.precision);
136 auto bnorm = rnorm(rhs);
138 auto residual = rs.ops.allocate_like(rs.prototype);
139 auto rx = rs.ops.allocate_like(rs.prototype);
140 auto applied = rs.ops.allocate_like(rs.prototype);
141 std::optional<RR> candidate_norm;
142 auto evaluate = [&](
auto const& candidate) {
143 context.
transfer(rx, candidate, rs.precision);
144 candidate_norm = rnorm(rx);
145 if (!candidate_norm)
return std::optional<RR>{};
146 ++
info.residual_operator_applications;
148 rs.ops.copy(residual, rhs);
149 rs.ops.axpy(residual, -rone, applied);
150 return rnorm(residual);
152 auto beta = evaluate(x);
154 auto diagnose = [&](RR
const& residual_norm) {
155 info.residual = GmresResidual<RR>{residual_norm, *bnorm, *candidate_norm};
161 if (options.max_corrections == 0)
return info;
163 auto ib = is.ops.allocate_like(is.prototype);
164 auto correction = is.ops.allocate_like(is.prototype);
165 auto update = ws.ops.allocate_like(ws.prototype);
166 auto candidate = ws.ops.allocate_like(ws.prototype);
167 auto difference = ws.ops.allocate_like(ws.prototype);
168 while (
info.corrections < options.max_corrections)
172 gmres_detail::normalize<R>(rs.ops, residual, *
beta, rs.
precision);
173 context.
transfer(ib, residual, is.precision);
175 is.ops.set_zero(correction);
178 options.inner, is.precision);
179 info.inner_iterations +=
info.last_inner->iterations;
181 context.
transfer(rx, correction, rs.precision);
182 rs.ops.scal(rx, scalar_at_precision<R>(*
beta, rs.
precision));
184 context.
transfer(update, rx, ws.precision);
186 ws.ops.copy(candidate, x);
187 ws.ops.axpy(candidate, wone, update);
189 ws.ops.copy(difference, candidate);
190 ws.ops.axpy(difference, -wone, x);
191 auto change = wnorm(difference);
193 beta = evaluate(candidate);
195 ws.ops.copy(x, candidate);
Precision precision() const
Return exact state or the working precision stored by MPFR.
Definition mpreal.hpp:178
Concept for complex scalar types.
Definition scalar_concepts.hpp:75
locale_t value
Definition data_table.cpp:49
Restarted right-preconditioned GMRES over opaque vector operations.
typename make_real< T >::type make_real_t
Alias for the underlying real-valued type of T.
Definition scalar_traits.hpp:168
constexpr bool isfinite(I const &x) noexcept
Returns whether an integer scalar is finite.
Definition math.hpp:121
void info(checked_format_string< Args... > format, Args &&... args)
Emit an informational display message.
Definition display.hpp:393
bool reached(R const &residual, R const &rhs, R const &relative, R const &absolute)
Definition gmres.hpp:156
std::optional< GmresErrorEstimates< R > > error_estimates(GmresResidual< R > const &residual, GmresOperatorEstimates< R > const &properties)
Definition gmres_diagnostics.hpp:132
Tolerances< R > tolerances(GmresOptions< R > const &options, Precision precision)
Definition gmres.hpp:77
GmresOperatorEstimates< R > operator_estimates_at_precision(GmresOperatorEstimates< R > const &input, Precision p)
Definition gmres_diagnostics.hpp:73
Definition block_tensor_vector.hpp:23
GmresRefinementStatus
Outer termination, distinct from convergence of an inner correction.
Definition gmres_refinement.hpp:52
auto gmres_refine_with_info(GmresRefinementContext< WSpace, ISpace, RSpace, IOp, ROp, P, Transfer > &context, typename WSpace::vector_type &x, typename RSpace::vector_type const &b, GmresRefinementOptions< typename ISpace::real_type, typename RSpace::real_type > const &options={})
Refine a supplied iterate using matrix-free GMRES correction solves.
Definition gmres_refinement.hpp:87
std::optional< DenseMatrix< W > > correction(Backend &backend, LuFactorization< F > const &factor, DenseMatrix< R > const &rhs, LuRefinementPrecision< F, W, R > p, std::vector< bool > const &active, std::int64_t target_exponent, SolveInfo &info)
Definition lu_refine.hpp:93
mpreal epsilon(Precision precision)
Spacing above one for a specified binary working precision.
Definition mpreal.hpp:805
mpreal beta(mpreal const &a, mpreal const &x)
Real Beta function; positive rational/integer pairs retain exact values.
Definition mpreal_special.hpp:164
Optional properties of the original operator in the vector space's 2-norm.
Definition gmres_diagnostics.hpp:38
Residual stopping policy and storage/iteration limits.
Definition gmres.hpp:27
Bind precision roles and application operations for GMRES refinement.
Definition gmres_refinement.hpp:29
InnerOp & inner_operator
Definition gmres_refinement.hpp:33
InnerSpace inner
Definition gmres_refinement.hpp:31
ResidualSpace residual
Definition gmres_refinement.hpp:32
ResidualOp & residual_operator
Definition gmres_refinement.hpp:34
Transfer & transfer
Definition gmres_refinement.hpp:36
WorkingSpace working
Definition gmres_refinement.hpp:30
Preconditioner & preconditioner
Definition gmres_refinement.hpp:35
Refinement diagnostics for the last finite published working iterate.
Definition gmres_refinement.hpp:63
std::size_t inner_iterations
Definition gmres_refinement.hpp:66
std::size_t corrections
Definition gmres_refinement.hpp:65
bool succeeded() const noexcept
Definition gmres_refinement.hpp:71
std::size_t residual_operator_applications
Definition gmres_refinement.hpp:67
GmresRefinementStatus status
Definition gmres_refinement.hpp:64
std::optional< GmresResidual< R > > residual
Definition gmres_refinement.hpp:68
std::optional< GmresErrorEstimates< R > > errors
Definition gmres_refinement.hpp:69
std::optional< GmresInfo< I > > last_inner
Definition gmres_refinement.hpp:70
Outer residual targets and independently configured inner solves.
Definition gmres_refinement.hpp:41
std::size_t max_corrections
Definition gmres_refinement.hpp:45
GmresOptions< InnerReal > inner
Definition gmres_refinement.hpp:46
std::optional< ResidualReal > relative_tolerance
Absent means working-precision epsilon, converted to residual precision.
Definition gmres_refinement.hpp:43
ResidualReal absolute_tolerance
Definition gmres_refinement.hpp:44
GmresOperatorEstimates< ResidualReal > operator_estimates
Definition gmres_refinement.hpp:47
Project-level numeric limits customization point.
Definition numeric_limits.hpp:16