1010// constants --------------------------------------------------------------------------
1111
1212constexpr auto INF = std::numeric_limits<double >::infinity();
13- constexpr auto EPS = std::numeric_limits<double >::epsilon();
13+
14+ template <typename Numeric>
15+ constexpr auto EPS (Numeric x) -> Numeric {
16+ return 8 * x * std::numeric_limits<Numeric>::epsilon ();
17+ }
1418
1519// literals ---------------------------------------------------------------------------
1620
@@ -37,6 +41,7 @@ constexpr R_xlen_t operator""_rz(unsigned long long n) {
3741// [[Rcpp::export(rng = false)]]
3842Rcpp::IntegerVector wilkinson_bin_to_right_ (const Rcpp::NumericVector& x, const double width) {
3943 const auto n = x.size ();
44+ const auto eps = EPS (width);
4045
4146 auto bins = Rcpp::IntegerVector (n);
4247 auto current_bin = 1_rz;
@@ -46,7 +51,7 @@ Rcpp::IntegerVector wilkinson_bin_to_right_(const Rcpp::NumericVector& x, const
4651 for (auto i = 1_rz; i < n; ++i) {
4752 // This is equivalent to x[i] - first_x >= width but it accounts for machine precision.
4853 // If we instead used `>=` directly some things that should be symmetric will not be
49- if (x[i] - first_x - width >= -EPS ) {
54+ if (x[i] - first_x - width >= -eps ) {
5055 current_bin = current_bin + 1_rz;
5156 first_x = x[i];
5257 }
@@ -74,7 +79,7 @@ inline auto place_candidate(
7479 std::vector<std::multiset<double >>& rows,
7580 const std::ptrdiff_t target_row_i
7681) -> bool {
77- const auto eps = 8 * EPS * xsize;
82+ const auto eps = EPS ( xsize) ;
7883
7984 auto & target_row = rows[target_row_i];
8085 auto insert_loc = target_row.begin ();
0 commit comments