19constexpr double epsilon = std::numeric_limits<double>::epsilon();
53 if (std::isnan(a) || std::isnan(b)) {
58 double diff = std::abs(a - b);
61 if (
diff <= abs_tol) {
66 double max_abs = std::max(std::abs(a), std::abs(b));
67 return diff <= rel_tol * max_abs;
79 return std::abs(x) <= tol;
90 return std::isfinite(x);
101template <
typename Iterator>
104 for (
auto it = first; it != last; ++it) {
105 if (!std::isfinite(
static_cast<double>(*it))) {
125 return std::abs(x_new - x_old) <= tol;
141 double denominator = std::max(std::abs(x_old),
epsilon);
142 return std::abs(x_new - x_old) / denominator <= tol;
157 double abs_tol = 1e-8,
158 double rel_tol = 1e-6)
160 double threshold = abs_tol + rel_tol * std::abs(x_old);
161 return std::abs(x_new - x_old) <= threshold;
174 return std::log1p(x);
187 return std::expm1(x);
199inline double clamp(
double x,
double min_val,
double max_val)
201 if (min_val > max_val) {
202 throw std::invalid_argument(
"statcpp::clamp: min_val must be <= max_val");
204 return std::max(min_val, std::min(x, max_val));
215inline bool in_range(
double x,
double min_val,
double max_val)
217 return x >= min_val && x <= max_val;
231 double denominator = std::max(std::abs(x_ref),
epsilon);
232 return std::abs(x - x_ref) / denominator;
244 double default_value = std::numeric_limits<double>::quiet_NaN())
247 return default_value;
249 return numerator / denominator;
263template <
typename Iterator>
267 double compensation = 0.0;
269 for (
auto it = first; it != last; ++it) {
270 double value =
static_cast<double>(*it);
271 double y = value - compensation;
273 compensation = (t -
sum) - y;
283template <
typename Iterator,
typename Proj>
284double kahan_sum(Iterator first, Iterator last, Proj proj)
287 double compensation = 0.0;
289 for (
auto it = first; it != last; ++it) {
290 double value =
static_cast<double>(proj(*it));
291 double y = value - compensation;
293 compensation = (t -
sum) - y;
313template <
typename Iterator1,
typename Iterator2>
315 Iterator2 first2, Iterator2 last2,
319 auto n1 = std::distance(first1, last1);
320 auto n2 = std::distance(first2, last2);
329 while (it1 != last1) {
330 double v1 =
static_cast<double>(*it1);
331 double v2 =
static_cast<double>(*it2);
constexpr double default_abs_tol
Default absolute tolerance for floating-point comparisons.
bool has_converged_abs(double x_new, double x_old, double tol=1e-6)
Check for convergence based on absolute change.
bool approx_equal_range(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, double rel_tol=default_rel_tol, double abs_tol=default_abs_tol)
Check if two ranges are approximately equal element-wise.
double safe_divide(double numerator, double denominator, double default_value=std::numeric_limits< double >::quiet_NaN())
Safe division with check for division by zero.
double relative_error(double x, double x_ref)
Compute the relative error between two values.
double kahan_sum(Iterator first, Iterator last)
Compute sum with Kahan summation algorithm.
auto sum(Iterator first, Iterator last)
Sum.
double log1p_safe(double x)
Safely compute log(1 + x) for small x.
constexpr double epsilon
Machine epsilon for double precision.
bool all_finite(Iterator first, Iterator last)
Check if all values in a range are finite.
bool in_range(double x, double min_val, double max_val)
Check if a value is in range [min_val, max_val].
bool has_converged_rel(double x_new, double x_old, double tol=1e-6)
Check for convergence based on relative change.
bool is_finite(double x)
Check if a value is finite (not infinity or NaN)
bool has_converged(double x_new, double x_old, double abs_tol=1e-8, double rel_tol=1e-6)
Check for convergence using combined absolute and relative criteria.
std::vector< double > diff(Iterator first, Iterator last, std::size_t order=1)
Difference series (first-order or d-th order differencing)
double clamp(double x, double min_val, double max_val)
Clamp a value to a range [min_val, max_val].
bool approx_equal(double a, double b, double rel_tol=default_rel_tol, double abs_tol=default_abs_tol)
Check if two floating-point numbers are approximately equal.
bool is_zero(double x, double tol=default_abs_tol)
Check if a value is close to zero.
double expm1_safe(double x)
Safely compute exp(x) - 1 for small x.
constexpr double default_rel_tol
Default relative tolerance for floating-point comparisons.