43 if (
p.is_exact())
throw std::invalid_argument(
"quadrature requires finite precision");
48 requires(!has_runtime_precision_v<R>)
78template <
class R>
struct quadrature_sum
83 R
const adjusted =
value - correction, next =
sum + adjusted;
84 correction = (next -
sum) - adjusted;
99template <Real R, std::
size_t N,
class F>
105 throw std::invalid_argument(
"quadrature requires matching finite precision");
106 auto number = [
p](
auto x) {
return scalar_at_precision<R>(x,
p); };
107 R
const zero = number(0), one = number(1), two = number(2);
110 throw std::invalid_argument(
"invalid quadrature interval, tolerance or endpoint power");
114 throw std::invalid_argument(
"quadrature requires nonnegative tolerances, with a positive target per component");
119 out.value.fill(zero);
120 out.error.fill(infinity);
121 out.absolute_integral.fill(zero);
122 out.endpoint_indicator.fill(infinity);
125 out.error.fill(zero);
126 out.endpoint_indicator.fill(zero);
138 std::array<R, N> previous = out.value;
139 unsigned stable = 0, endpoint_stable = 0;
141 for (std::size_t level = 0; level < options.
max_levels; ++level)
143 std::array<detail::quadrature_sum<R>, N>
sum, absolute;
144 for (std::size_t j = 0; j < N; ++j)
145 sum[j] = absolute[j] = {zero, zero};
146 std::array<R, N> edge;
147 std::array<std::size_t, N> nonzero_samples{};
149 auto sample = [&](R
const& x, R
const& lower, R
const& upper, R
const& unscaled_weight,
bool endpoint) {
155 R
const weight = unscaled_weight * h;
156 if (!(lower > zero) || !(upper > zero) || !(weight > zero) || !
isfinite(weight))
163 for (std::size_t j = 0; j < N; ++j)
165 if (
precision_of(y[j]) !=
p)
throw std::invalid_argument(
"quadrature integrand changed working precision");
171 R
const term = weight * y[j];
172 if (y[j] != zero) ++nonzero_samples[j];
177 if (endpoint) edge[j] +=
math::abs(unscaled_weight * y[j]);
186 R
const half =
width / two;
187 if (!sample(lo + half, half, half,
width * (pi_value / number(4)),
false))
return out;
189 while (argument <= limit)
191 R
const next = t + h;
197 R
const next_argument = pi_value *
math::sinh(next);
198 bool const endpoint = next_argument > limit;
199 R
const z =
math::exp(-argument), denominator = one + z;
200 R
const distance =
width * (z / denominator), far =
width / denominator;
201 R
const unscaled_weight = distance * (pi_value *
math::cosh(t) / denominator);
202 if (!sample(lo + distance, distance, far, unscaled_weight, endpoint) ||
203 !sample(hi - distance, far, distance, unscaled_weight, endpoint))
206 argument = next_argument;
208 bool mesh_ok = level >= 2, endpoints_ok =
true, tail_limited_mesh = level >= 2;
209 for (std::size_t j = 0; j < N; ++j)
211 out.value[j] =
sum[j].sum;
212 out.absolute_integral[j] = absolute[j].sum;
213 out.endpoint_indicator[j] = edge[j];
217 R
const roundoff = number(8) * (eps * out.absolute_integral[j] + minimum * number(nonzero_samples[j]));
218 R
const mesh_error = level == 0 ? infinity : std::max(
math::abs(out.value[j] - previous[j]), roundoff);
219 out.error[j] = std::max(mesh_error, edge[j]);
221 mesh_ok = mesh_ok && mesh_error <= target;
222 tail_limited_mesh = tail_limited_mesh && mesh_error <= std::max(target, edge[j]);
223 endpoints_ok = endpoints_ok && edge[j] <= target;
226 stable = mesh_ok ? stable + 1 : 0;
230 endpoint_stable = tail_limited_mesh && !endpoints_ok ? endpoint_stable + 1 : 0;
236 if (endpoint_stable == 2)
241 previous = out.value;
Exact arithmetic or an explicit binary working precision.
Definition core/precision.hpp:13
locale_t value
Definition data_table.cpp:49
std::size_t width
Definition display.cpp:142
constexpr bool isfinite(I const &x) noexcept
Returns whether an integer scalar is finite.
Definition math.hpp:121
Scalar math helper utilities.
constexpr detail::scalar_math::exp_fn exp
Natural exponential with scalar-specific precision handling.
Definition math.hpp:465
constexpr detail::scalar_math::cosh_fn cosh
Hyperbolic cosine.
Definition math.hpp:491
constexpr detail::scalar_math::sinh_fn sinh
Hyperbolic sine.
Definition math.hpp:489
constexpr detail::scalar_math::next_up_fn next_up
Adjacent value toward positive infinity.
Definition math.hpp:551
constexpr detail::scalar_math::abs_fn abs
Absolute value or complex magnitude, preserving the selected scalar implementation.
Definition math.hpp:459
constexpr detail::scalar_math::log_fn log
Natural logarithm with scalar-specific precision handling.
Definition math.hpp:467
Definition data_table.cpp:8
Definition async/async.hpp:26
quadrature_status
Termination of finite-interval tanh-sinh integration.
Definition finite_quadrature.hpp:25
void sum(BackendSelector selector, async::Async< OutputTensor > &output, async::Async< InputTensor > const &input)
Schedule a full sum into an explicit async scalar tensor.
Definition linalg/async/reductions.hpp:309
constexpr Precision precision_of(T const &value)
Read scalar precision without changing any scalar or provider state.
Definition runtime_precision.hpp:53
constexpr S scalar_at_precision(V const &value, Precision p)
Construct or convert a scalar at one explicit precision.
Definition runtime_precision.hpp:76
int add(int a, int b)
Definition dummy.cpp:6
constexpr Precision native_precision()
Concrete precision of a fixed scalar family, including complex components.
Definition runtime_precision.hpp:41
quadrature_result< R, N > tanh_sinh_integrate(F const &f, R const &lo, R const &hi, tanh_sinh_options< R, N > const &options)
Integrate N real components over lo<=hi using successive tanh-sinh meshes.
Definition finite_quadrature.hpp:100
Project-level numeric limits customization point.
Definition numeric_limits.hpp:16
An abscissa and independently evaluated distances to its finite endpoints.
Definition finite_quadrature.hpp:17
R upper_distance
Definition finite_quadrature.hpp:20
R value
Definition finite_quadrature.hpp:18
R lower_distance
Definition finite_quadrature.hpp:19
Last complete mesh, its diagnostic estimates and total work, including an interrupted mesh.
Definition finite_quadrature.hpp:66
std::size_t levels
Definition finite_quadrature.hpp:72
std::array< R, N > endpoint_indicator
Definition finite_quadrature.hpp:70
std::array< R, N > absolute_integral
Definition finite_quadrature.hpp:69
quadrature_status status
Definition finite_quadrature.hpp:73
std::array< R, N > error
Definition finite_quadrature.hpp:68
std::size_t evaluations
Definition finite_quadrature.hpp:71
std::array< R, N > value
Definition finite_quadrature.hpp:67
Explicit precision, component tolerances and work limits for tanh-sinh quadrature.
Definition finite_quadrature.hpp:39
unsigned endpoint_power
Definition finite_quadrature.hpp:56
std::size_t max_evaluations
Definition finite_quadrature.hpp:54
tanh_sinh_options(Precision p)
Definition finite_quadrature.hpp:41
tanh_sinh_options()
Definition finite_quadrature.hpp:47
R relative_tolerance
Definition finite_quadrature.hpp:52
std::array< R, N > absolute_tolerance
Definition finite_quadrature.hpp:53
std::size_t max_levels
Definition finite_quadrature.hpp:55