guide_axis_with_transform.cpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. // Copyright 2019 Hans Dembinski
  2. //
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt
  5. // or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //[ guide_axis_with_transform
  7. #include <boost/histogram/axis/regular.hpp>
  8. #include <limits>
  9. int main() {
  10. using namespace boost::histogram;
  11. // make a regular axis with a log transform over [10, 100), [100, 1000), [1000, 10000)
  12. axis::regular<double, axis::transform::log> r_log{3, 10., 10000.};
  13. // log transform:
  14. // - useful when values vary dramatically in magnitude, like brightness of stars
  15. // - edges are not exactly at 10, 100, 1000, because of finite floating point precision
  16. // - values >= 0 but smaller than the starting value of the axis are mapped to -1
  17. // - values < 0 are mapped to `size()`, because the result of std::log(value) is NaN
  18. assert(r_log.index(10.1) == 0);
  19. assert(r_log.index(100.1) == 1);
  20. assert(r_log.index(1000.1) == 2);
  21. assert(r_log.index(1) == -1);
  22. assert(r_log.index(0) == -1);
  23. assert(r_log.index(-1) == 3);
  24. // make a regular axis with a sqrt transform over [4, 9), [9, 16), [16, 25)
  25. axis::regular<double, axis::transform::sqrt> r_sqrt{3, 4., 25.};
  26. // sqrt transform:
  27. // - bin widths are more mildly increasing compared to log transform
  28. // - axis starting at value == 0 is ok, sqrt(0) == 0 unlike log transform
  29. // - values < 0 are mapped to `size()`, because the result of std::sqrt(value) is NaN
  30. assert(r_sqrt.index(0) == -1);
  31. assert(r_sqrt.index(4.1) == 0);
  32. assert(r_sqrt.index(9.1) == 1);
  33. assert(r_sqrt.index(16.1) == 2);
  34. assert(r_sqrt.index(25.1) == 3);
  35. assert(r_sqrt.index(-1) == 3);
  36. // make a regular axis with a power transform x^1/3 over [1, 8), [8, 27), [27, 64)
  37. using pow_trans = axis::transform::pow;
  38. axis::regular<double, pow_trans> r_pow(pow_trans{1. / 3.}, 3, 1., 64.);
  39. // pow transform:
  40. // - generalization of the sqrt transform
  41. // - starting the axis at value == 0 is ok for power p > 0, 0^p == 0 for p > 0
  42. // - values < 0 are mapped to `size()` if power p is not a positive integer
  43. assert(r_pow.index(0) == -1);
  44. assert(r_pow.index(1.1) == 0);
  45. assert(r_pow.index(8.1) == 1);
  46. assert(r_pow.index(27.1) == 2);
  47. assert(r_pow.index(64.1) == 3);
  48. assert(r_pow.index(-1) == 3);
  49. }
  50. //]