| 406 | } |
| 407 | |
| 408 | std::vector<double> histogram::integers_rule(const std::vector<double> &x, |
| 409 | double minx, double maxx, |
| 410 | bool hard_limits) { |
| 411 | constexpr size_t max_num_of_bins = 65536; |
| 412 | double xrange = maxx - minx; |
| 413 | double binwidth = 1.0; |
| 414 | if (!x.empty()) { |
| 415 | std::vector abs_x = |
| 416 | transform(x, [](double x) { return std::abs(x); }); |
| 417 | double xscale = *std::max_element(abs_x.begin(), abs_x.end()); |
| 418 | xrange = *std::max_element(x.begin(), x.end()) - |
| 419 | *std::min_element(x.begin(), x.end()); |
| 420 | if (xrange > max_num_of_bins) { |
| 421 | binwidth = pow(10, ceil(log10(xrange / max_num_of_bins))); |
| 422 | } else if (nextafter(xscale, xscale + 1) - xscale > 1.) { |
| 423 | binwidth = pow( |
| 424 | 10, ceil(log10(nextafter(xscale, xscale + 1) - xscale))); |
| 425 | } else { |
| 426 | binwidth = 1.; |
| 427 | } |
| 428 | if (!hard_limits) { |
| 429 | minx = binwidth * round(minx / binwidth); |
| 430 | maxx = binwidth * round(maxx / binwidth); |
| 431 | return iota(floor(minx) - .5 * binwidth, binwidth, |
| 432 | ceil(maxx) + .5 * binwidth); |
| 433 | } else { |
| 434 | double minxi = binwidth * ceil(minx / binwidth) + 0.5; |
| 435 | double maxxi = binwidth * floor(maxx / binwidth) - 0.5; |
| 436 | std::vector<double> edges = {minx}; |
| 437 | auto mid = iota(minxi, binwidth, maxxi); |
| 438 | edges.insert(edges.end(), mid.begin(), mid.end()); |
| 439 | edges.emplace_back(maxx); |
| 440 | return edges; |
| 441 | } |
| 442 | } else { |
| 443 | if (!hard_limits) { |
| 444 | return std::vector<double>{-0.5, 0.5}; |
| 445 | } else { |
| 446 | double minxi = ceil(minx) + 0.5; |
| 447 | double maxxi = floor(maxx) - 0.5; |
| 448 | std::vector<double> edges = {minx}; |
| 449 | std::vector<double> mid = iota(minxi, maxxi); |
| 450 | edges.insert(edges.end(), mid.begin(), mid.end()); |
| 451 | edges.emplace_back(maxx); |
| 452 | return edges; |
| 453 | } |
| 454 | } |
| 455 | } |
| 456 | |
| 457 | std::vector<double> histogram::sqrt_rule(const std::vector<double> &x, |
| 458 | double minx, double maxx, |