mirror of
https://github.com/boostorg/histogram.git
synced 2025-05-09 23:04:07 +00:00
regular and variable axis are closed intervals if overflow bin is absent (#344)
This commit is contained in:
parent
b482598597
commit
bf7712f0d7
@ -31,7 +31,33 @@ using DStore = boost::histogram::adaptive_storage<>;
|
||||
#endif
|
||||
|
||||
using namespace boost::histogram;
|
||||
namespace op = boost::histogram::axis::option;
|
||||
using reg = axis::regular<>;
|
||||
using reg_closed =
|
||||
axis::regular<double, boost::use_default, boost::use_default, op::none_t>;
|
||||
|
||||
class reg_closed_unsafe {
|
||||
public:
|
||||
reg_closed_unsafe(axis::index_type n, double start, double stop)
|
||||
: min_{start}, delta_{stop - start}, size_{n} {}
|
||||
|
||||
axis::index_type index(double x) const noexcept {
|
||||
// Runs in hot loop, please measure impact of changes
|
||||
auto z = (x - min_) / delta_;
|
||||
// assume that z < 0 and z > 1 never happens, promised by inclusive()
|
||||
if (z == 1) return size() - 1;
|
||||
return static_cast<axis::index_type>(z * size());
|
||||
}
|
||||
|
||||
axis::index_type size() const noexcept { return size_; }
|
||||
|
||||
static constexpr bool inclusive() { return true; }
|
||||
|
||||
private:
|
||||
double min_;
|
||||
double delta_;
|
||||
axis::index_type size_;
|
||||
};
|
||||
|
||||
template <class Distribution, class Tag, class Storage = SStore>
|
||||
static void fill_1d(benchmark::State& state) {
|
||||
@ -41,6 +67,22 @@ static void fill_1d(benchmark::State& state) {
|
||||
state.SetItemsProcessed(state.iterations());
|
||||
}
|
||||
|
||||
template <class Distribution, class Tag, class Storage = SStore>
|
||||
static void fill_1d_closed(benchmark::State& state) {
|
||||
auto h = make_s(Tag(), Storage(), reg_closed(100, 0, 1));
|
||||
auto gen = generator<Distribution>();
|
||||
for (auto _ : state) benchmark::DoNotOptimize(h(gen()));
|
||||
state.SetItemsProcessed(state.iterations());
|
||||
}
|
||||
|
||||
template <class Distribution, class Tag, class Storage = SStore>
|
||||
static void fill_1d_closed_unsafe(benchmark::State& state) {
|
||||
auto h = make_s(Tag(), Storage(), reg_closed_unsafe(100, 0, 1));
|
||||
auto gen = generator<Distribution>();
|
||||
for (auto _ : state) benchmark::DoNotOptimize(h(gen()));
|
||||
state.SetItemsProcessed(state.iterations());
|
||||
}
|
||||
|
||||
template <class Distribution, class Tag, class Storage = SStore>
|
||||
static void fill_n_1d(benchmark::State& state) {
|
||||
auto h = make_s(Tag(), Storage(), reg(100, 0, 1));
|
||||
@ -49,6 +91,22 @@ static void fill_n_1d(benchmark::State& state) {
|
||||
state.SetItemsProcessed(state.iterations() * gen.size());
|
||||
}
|
||||
|
||||
template <class Distribution, class Tag, class Storage = SStore>
|
||||
static void fill_n_1d_closed(benchmark::State& state) {
|
||||
auto h = make_s(Tag(), Storage(), reg_closed(100, 0, 1));
|
||||
auto gen = generator<Distribution>();
|
||||
for (auto _ : state) h.fill(gen);
|
||||
state.SetItemsProcessed(state.iterations() * gen.size());
|
||||
}
|
||||
|
||||
template <class Distribution, class Tag, class Storage = SStore>
|
||||
static void fill_n_1d_closed_unsafe(benchmark::State& state) {
|
||||
auto h = make_s(Tag(), Storage(), reg_closed_unsafe(100, 0, 1));
|
||||
auto gen = generator<Distribution>();
|
||||
for (auto _ : state) h.fill(gen);
|
||||
state.SetItemsProcessed(state.iterations() * gen.size());
|
||||
}
|
||||
|
||||
template <class Distribution, class Tag, class Storage = SStore>
|
||||
static void fill_2d(benchmark::State& state) {
|
||||
auto h = make_s(Tag(), Storage(), reg(100, 0, 1), reg(100, 0, 1));
|
||||
@ -111,6 +169,8 @@ BENCHMARK_TEMPLATE(fill_1d, uniform, dynamic_tag);
|
||||
// BENCHMARK_TEMPLATE(fill_1d, uniform, dynamic_tag, DStore);
|
||||
BENCHMARK_TEMPLATE(fill_1d, normal, dynamic_tag);
|
||||
// BENCHMARK_TEMPLATE(fill_1d, normal, dynamic_tag, DStore);
|
||||
BENCHMARK_TEMPLATE(fill_1d_closed, uniform, static_tag);
|
||||
BENCHMARK_TEMPLATE(fill_1d_closed_unsafe, uniform, static_tag);
|
||||
|
||||
BENCHMARK_TEMPLATE(fill_n_1d, uniform, static_tag);
|
||||
// BENCHMARK_TEMPLATE(fill_n_1d, uniform, static_tag, DStore);
|
||||
@ -120,6 +180,8 @@ BENCHMARK_TEMPLATE(fill_n_1d, uniform, dynamic_tag);
|
||||
// BENCHMARK_TEMPLATE(fill_n_1d, uniform, dynamic_tag, DStore);
|
||||
BENCHMARK_TEMPLATE(fill_n_1d, normal, dynamic_tag);
|
||||
// BENCHMARK_TEMPLATE(fill_n_1d, normal, dynamic_tag, DStore);
|
||||
BENCHMARK_TEMPLATE(fill_n_1d_closed, uniform, static_tag);
|
||||
BENCHMARK_TEMPLATE(fill_n_1d_closed_unsafe, uniform, static_tag);
|
||||
|
||||
BENCHMARK_TEMPLATE(fill_2d, uniform, static_tag);
|
||||
// BENCHMARK_TEMPLATE(fill_2d, uniform, static_tag, DStore);
|
||||
|
@ -26,22 +26,21 @@ namespace boost {
|
||||
namespace histogram {
|
||||
namespace axis {
|
||||
|
||||
/**
|
||||
Maps at a set of unique values to bin indices.
|
||||
/** Maps at a set of unique values to bin indices.
|
||||
|
||||
The axis maps a set of values to bins, following the order of arguments in the
|
||||
constructor. The optional overflow bin for this axis counts input values that
|
||||
are not part of the set. Binning has O(N) complexity, but with a very small
|
||||
factor. For small N (the typical use case) it beats other kinds of lookup.
|
||||
The axis maps a set of values to bins, following the order of arguments in the
|
||||
constructor. The optional overflow bin for this axis counts input values that
|
||||
are not part of the set. Binning has O(N) complexity, but with a very small
|
||||
factor. For small N (the typical use case) it beats other kinds of lookup.
|
||||
|
||||
@tparam Value input value type, must be equal-comparable.
|
||||
@tparam MetaData type to store meta data.
|
||||
@tparam Options see boost::histogram::axis::option.
|
||||
@tparam Allocator allocator to use for dynamic memory management.
|
||||
@tparam Value input value type, must be equal-comparable.
|
||||
@tparam MetaData type to store meta data.
|
||||
@tparam Options see boost::histogram::axis::option.
|
||||
@tparam Allocator allocator to use for dynamic memory management.
|
||||
|
||||
The options `underflow` and `circular` are not allowed. The options `growth`
|
||||
and `overflow` are mutually exclusive.
|
||||
*/
|
||||
The options `underflow` and `circular` are not allowed. The options `growth`
|
||||
and `overflow` are mutually exclusive.
|
||||
*/
|
||||
template <class Value, class MetaData, class Options, class Allocator>
|
||||
class category : public iterator_mixin<category<Value, MetaData, Options, Allocator>>,
|
||||
public metadata_base_t<MetaData> {
|
||||
@ -66,12 +65,12 @@ public:
|
||||
explicit category(allocator_type alloc) : vec_(alloc) {}
|
||||
|
||||
/** Construct from iterator range of unique values.
|
||||
*
|
||||
* @param begin begin of category range of unique values.
|
||||
* @param end end of category range of unique values.
|
||||
* @param meta description of the axis (optional).
|
||||
* @param options see boost::histogram::axis::option (optional).
|
||||
* @param alloc allocator instance to use (optional).
|
||||
|
||||
@param begin begin of category range of unique values.
|
||||
@param end end of category range of unique values.
|
||||
@param meta description of the axis (optional).
|
||||
@param options see boost::histogram::axis::option (optional).
|
||||
@param alloc allocator instance to use (optional).
|
||||
*/
|
||||
template <class It, class = detail::requires_iterator<It>>
|
||||
category(It begin, It end, metadata_type meta = {}, options_type options = {},
|
||||
@ -91,11 +90,11 @@ public:
|
||||
: category(begin, end, std::move(meta), {}, std::move(alloc)) {}
|
||||
|
||||
/** Construct axis from iterable sequence of unique values.
|
||||
*
|
||||
* @param iterable sequence of unique values.
|
||||
* @param meta description of the axis.
|
||||
* @param options see boost::histogram::axis::option (optional).
|
||||
* @param alloc allocator instance to use.
|
||||
|
||||
@param iterable sequence of unique values.
|
||||
@param meta description of the axis.
|
||||
@param options see boost::histogram::axis::option (optional).
|
||||
@param alloc allocator instance to use.
|
||||
*/
|
||||
template <class C, class = detail::requires_iterable<C>>
|
||||
category(const C& iterable, metadata_type meta = {}, options_type options = {},
|
||||
@ -110,11 +109,11 @@ public:
|
||||
std::move(alloc)) {}
|
||||
|
||||
/** Construct axis from an initializer list of unique values.
|
||||
*
|
||||
* @param list `std::initializer_list` of unique values.
|
||||
* @param meta description of the axis.
|
||||
* @param options see boost::histogram::axis::option (optional).
|
||||
* @param alloc allocator instance to use.
|
||||
|
||||
@param list `std::initializer_list` of unique values.
|
||||
@param meta description of the axis.
|
||||
@param options see boost::histogram::axis::option (optional).
|
||||
@param alloc allocator instance to use.
|
||||
*/
|
||||
template <class U>
|
||||
category(std::initializer_list<U> list, metadata_type meta = {},
|
||||
|
@ -29,14 +29,13 @@ namespace boost {
|
||||
namespace histogram {
|
||||
namespace axis {
|
||||
|
||||
/**
|
||||
Axis for an interval of integer values with unit steps.
|
||||
/** Axis for an interval of integer values with unit steps.
|
||||
|
||||
Binning is a O(1) operation. This axis bins faster than a regular axis.
|
||||
Binning is a O(1) operation. This axis bins faster than a regular axis.
|
||||
|
||||
@tparam Value input value type. Must be integer or floating point.
|
||||
@tparam MetaData type to store meta data.
|
||||
@tparam Options see boost::histogram::axis::option.
|
||||
@tparam Value input value type. Must be integer or floating point.
|
||||
@tparam MetaData type to store meta data.
|
||||
@tparam Options see boost::histogram::axis::option.
|
||||
*/
|
||||
template <class Value, class MetaData, class Options>
|
||||
class integer : public iterator_mixin<integer<Value, MetaData, Options>>,
|
||||
@ -72,11 +71,11 @@ public:
|
||||
constexpr integer() = default;
|
||||
|
||||
/** Construct over semi-open integer interval [start, stop).
|
||||
*
|
||||
* @param start first integer of covered range.
|
||||
* @param stop one past last integer of covered range.
|
||||
* @param meta description of the axis (optional).
|
||||
* @param options see boost::histogram::axis::option (optional).
|
||||
|
||||
@param start first integer of covered range.
|
||||
@param stop one past last integer of covered range.
|
||||
@param meta description of the axis (optional).
|
||||
@param options see boost::histogram::axis::option (optional).
|
||||
*/
|
||||
integer(value_type start, value_type stop, metadata_type meta = {},
|
||||
options_type options = {})
|
||||
|
@ -165,15 +165,22 @@ step_type<T> step(T t) {
|
||||
return step_type<T>{t};
|
||||
}
|
||||
|
||||
/**
|
||||
Axis for equidistant intervals on the real line.
|
||||
/** Axis for equidistant intervals on the real line.
|
||||
|
||||
The most common binning strategy. Very fast. Binning is a O(1) operation.
|
||||
The most common binning strategy. Very fast. Binning is a O(1) operation.
|
||||
|
||||
@tparam Value input value type, must be floating point.
|
||||
@tparam Transform builtin or user-defined transform type.
|
||||
@tparam MetaData type to store meta data.
|
||||
@tparam Options see boost::histogram::axis::option.
|
||||
If the axis has an overflow bin (the default), a value on the upper edge of the last
|
||||
bin is put in the overflow bin. The axis range represents a semi-open interval.
|
||||
|
||||
If the overflow bin is deactivated, then a value on the upper edge of the last bin is
|
||||
still counted towards the last bin. The axis range represents a closed interval. This
|
||||
is the desired behavior for random numbers drawn from a bounded interval, which is
|
||||
usually closed.
|
||||
|
||||
@tparam Value input value type, must be floating point.
|
||||
@tparam Transform builtin or user-defined transform type.
|
||||
@tparam MetaData type to store meta data.
|
||||
@tparam Options see boost::histogram::axis::option.
|
||||
*/
|
||||
template <class Value, class Transform, class MetaData, class Options>
|
||||
class regular : public iterator_mixin<regular<Value, Transform, MetaData, Options>>,
|
||||
@ -207,13 +214,13 @@ public:
|
||||
constexpr regular() = default;
|
||||
|
||||
/** Construct n bins over real transformed range [start, stop).
|
||||
*
|
||||
* @param trans transform instance to use.
|
||||
* @param n number of bins.
|
||||
* @param start low edge of first bin.
|
||||
* @param stop high edge of last bin.
|
||||
* @param meta description of the axis (optional).
|
||||
* @param options see boost::histogram::axis::option (optional).
|
||||
|
||||
@param trans transform instance to use.
|
||||
@param n number of bins.
|
||||
@param start low edge of first bin.
|
||||
@param stop high edge of last bin.
|
||||
@param meta description of the axis (optional).
|
||||
@param options see boost::histogram::axis::option (optional).
|
||||
*/
|
||||
regular(transform_type trans, unsigned n, value_type start, value_type stop,
|
||||
metadata_type meta = {}, options_type options = {})
|
||||
@ -232,30 +239,30 @@ public:
|
||||
}
|
||||
|
||||
/** Construct n bins over real range [start, stop).
|
||||
*
|
||||
* @param n number of bins.
|
||||
* @param start low edge of first bin.
|
||||
* @param stop high edge of last bin.
|
||||
* @param meta description of the axis (optional).
|
||||
* @param options see boost::histogram::axis::option (optional).
|
||||
|
||||
@param n number of bins.
|
||||
@param start low edge of first bin.
|
||||
@param stop high edge of last bin.
|
||||
@param meta description of the axis (optional).
|
||||
@param options see boost::histogram::axis::option (optional).
|
||||
*/
|
||||
regular(unsigned n, value_type start, value_type stop, metadata_type meta = {},
|
||||
options_type options = {})
|
||||
: regular({}, n, start, stop, std::move(meta), options) {}
|
||||
|
||||
/** Construct bins with the given step size over real transformed range
|
||||
* [start, stop).
|
||||
*
|
||||
* @param trans transform instance to use.
|
||||
* @param step width of a single bin.
|
||||
* @param start low edge of first bin.
|
||||
* @param stop upper limit of high edge of last bin (see below).
|
||||
* @param meta description of the axis (optional).
|
||||
* @param options see boost::histogram::axis::option (optional).
|
||||
*
|
||||
* The axis computes the number of bins as n = abs(stop - start) / step,
|
||||
* rounded down. This means that stop is an upper limit to the actual value
|
||||
* (start + n * step).
|
||||
[start, stop).
|
||||
|
||||
@param trans transform instance to use.
|
||||
@param step width of a single bin.
|
||||
@param start low edge of first bin.
|
||||
@param stop upper limit of high edge of last bin (see below).
|
||||
@param meta description of the axis (optional).
|
||||
@param options see boost::histogram::axis::option (optional).
|
||||
|
||||
The axis computes the number of bins as n = abs(stop - start) / step,
|
||||
rounded down. This means that stop is an upper limit to the actual value
|
||||
(start + n * step).
|
||||
*/
|
||||
template <class T>
|
||||
regular(transform_type trans, step_type<T> step, value_type start, value_type stop,
|
||||
@ -267,16 +274,16 @@ public:
|
||||
std::move(meta), options) {}
|
||||
|
||||
/** Construct bins with the given step size over real range [start, stop).
|
||||
*
|
||||
* @param step width of a single bin.
|
||||
* @param start low edge of first bin.
|
||||
* @param stop upper limit of high edge of last bin (see below).
|
||||
* @param meta description of the axis (optional).
|
||||
* @param options see boost::histogram::axis::option (optional).
|
||||
*
|
||||
* The axis computes the number of bins as n = abs(stop - start) / step,
|
||||
* rounded down. This means that stop is an upper limit to the actual value
|
||||
* (start + n * step).
|
||||
|
||||
@param step width of a single bin.
|
||||
@param start low edge of first bin.
|
||||
@param stop upper limit of high edge of last bin (see below).
|
||||
@param meta description of the axis (optional).
|
||||
@param options see boost::histogram::axis::option (optional).
|
||||
|
||||
The axis computes the number of bins as n = abs(stop - start) / step,
|
||||
rounded down. This means that stop is an upper limit to the actual value
|
||||
(start + n * step).
|
||||
*/
|
||||
template <class T>
|
||||
regular(step_type<T> step, value_type start, value_type stop, metadata_type meta = {},
|
||||
@ -311,6 +318,8 @@ public:
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
// upper edge of last bin is inclusive if overflow bin is not present
|
||||
if (!options_type::test(option::overflow) && z == 1) return size() - 1;
|
||||
}
|
||||
return size(); // also returned if x is NaN
|
||||
}
|
||||
|
@ -34,17 +34,24 @@ namespace boost {
|
||||
namespace histogram {
|
||||
namespace axis {
|
||||
|
||||
/**
|
||||
Axis for non-equidistant bins on the real line.
|
||||
/** Axis for non-equidistant bins on the real line.
|
||||
|
||||
Binning is a O(log(N)) operation. If speed matters and the problem domain
|
||||
allows it, prefer a regular axis, possibly with a transform.
|
||||
|
||||
If the axis has an overflow bin (the default), a value on the upper edge of the last
|
||||
bin is put in the overflow bin. The axis range represents a semi-open interval.
|
||||
|
||||
If the overflow bin is deactivated, then a value on the upper edge of the last bin is
|
||||
still counted towards the last bin. The axis range represents a closed interval. This
|
||||
is the desired behavior for random numbers drawn from a bounded interval, which is
|
||||
usually closed.
|
||||
|
||||
@tparam Value input value type, must be floating point.
|
||||
@tparam MetaData type to store meta data.
|
||||
@tparam Options see boost::histogram::axis::option.
|
||||
@tparam Allocator allocator to use for dynamic memory management.
|
||||
*/
|
||||
*/
|
||||
template <class Value, class MetaData, class Options, class Allocator>
|
||||
class variable : public iterator_mixin<variable<Value, MetaData, Options, Allocator>>,
|
||||
public metadata_base_t<MetaData> {
|
||||
@ -72,12 +79,12 @@ public:
|
||||
explicit variable(allocator_type alloc) : vec_(alloc) {}
|
||||
|
||||
/** Construct from iterator range of bin edges.
|
||||
*
|
||||
* @param begin begin of edge sequence.
|
||||
* @param end end of edge sequence.
|
||||
* @param meta description of the axis (optional).
|
||||
* @param options see boost::histogram::axis::option (optional).
|
||||
* @param alloc allocator instance to use (optional).
|
||||
|
||||
@param begin begin of edge sequence.
|
||||
@param end end of edge sequence.
|
||||
@param meta description of the axis (optional).
|
||||
@param options see boost::histogram::axis::option (optional).
|
||||
@param alloc allocator instance to use (optional).
|
||||
*/
|
||||
template <class It, class = detail::requires_iterator<It>>
|
||||
variable(It begin, It end, metadata_type meta = {}, options_type options = {},
|
||||
@ -106,11 +113,11 @@ public:
|
||||
: variable(begin, end, std::move(meta), {}, std::move(alloc)) {}
|
||||
|
||||
/** Construct variable axis from iterable range of bin edges.
|
||||
*
|
||||
* @param iterable iterable range of bin edges.
|
||||
* @param meta description of the axis (optional).
|
||||
* @param options see boost::histogram::axis::option (optional).
|
||||
* @param alloc allocator instance to use (optional).
|
||||
|
||||
@param iterable iterable range of bin edges.
|
||||
@param meta description of the axis (optional).
|
||||
@param options see boost::histogram::axis::option (optional).
|
||||
@param alloc allocator instance to use (optional).
|
||||
*/
|
||||
template <class U, class = detail::requires_iterable<U>>
|
||||
variable(const U& iterable, metadata_type meta = {}, options_type options = {},
|
||||
@ -125,11 +132,11 @@ public:
|
||||
std::move(alloc)) {}
|
||||
|
||||
/** Construct variable axis from initializer list of bin edges.
|
||||
*
|
||||
* @param list `std::initializer_list` of bin edges.
|
||||
* @param meta description of the axis (optional).
|
||||
* @param options see boost::histogram::axis::option (optional).
|
||||
* @param alloc allocator instance to use (optional).
|
||||
|
||||
@param list `std::initializer_list` of bin edges.
|
||||
@param meta description of the axis (optional).
|
||||
@param options see boost::histogram::axis::option (optional).
|
||||
@param alloc allocator instance to use (optional).
|
||||
*/
|
||||
template <class U>
|
||||
variable(std::initializer_list<U> list, metadata_type meta = {},
|
||||
@ -159,6 +166,8 @@ public:
|
||||
const auto b = vec_[size()];
|
||||
x -= std::floor((x - a) / (b - a)) * (b - a);
|
||||
}
|
||||
// upper edge of last bin is inclusive if overflow bin is not present
|
||||
if (!options_type::test(option::overflow) && x == vec_.back()) return size() - 1;
|
||||
return static_cast<index_type>(std::upper_bound(vec_.begin(), vec_.end(), x) -
|
||||
vec_.begin() - 1);
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ int main() {
|
||||
using namespace boost::histogram;
|
||||
using def = use_default;
|
||||
namespace tr = axis::transform;
|
||||
namespace op = axis::option;
|
||||
|
||||
BOOST_TEST(std::is_nothrow_move_assignable<axis::regular<>>::value);
|
||||
BOOST_TEST(std::is_nothrow_move_constructible<axis::regular<>>::value);
|
||||
@ -202,7 +203,7 @@ int main() {
|
||||
// with growth
|
||||
{
|
||||
using pii_t = std::pair<axis::index_type, axis::index_type>;
|
||||
axis::regular<double, def, def, axis::option::growth_t> a{1, 0, 1};
|
||||
axis::regular<double, def, def, op::growth_t> a{1, 0, 1};
|
||||
BOOST_TEST_EQ(a.size(), 1);
|
||||
BOOST_TEST_EQ(a.update(0), pii_t(0, 0));
|
||||
BOOST_TEST_EQ(a.size(), 1);
|
||||
@ -223,11 +224,32 @@ int main() {
|
||||
BOOST_TEST_EQ(a.update(-std::numeric_limits<double>::infinity()), pii_t(-1, 0));
|
||||
}
|
||||
|
||||
// axis with overflow bin represents open interval
|
||||
{
|
||||
axis::regular<double, def, def, op::overflow_t> a{2, 0, 1};
|
||||
BOOST_TEST_EQ(a.index(0), 0);
|
||||
BOOST_TEST_EQ(a.index(0.49), 0);
|
||||
BOOST_TEST_EQ(a.index(0.50), 1);
|
||||
BOOST_TEST_EQ(a.index(0.99), 1);
|
||||
BOOST_TEST_EQ(a.index(1), 2); // overflow bin
|
||||
BOOST_TEST_EQ(a.index(1.1), 2); // overflow bin
|
||||
}
|
||||
|
||||
// axis without overflow bin represents a closed interval
|
||||
{
|
||||
axis::regular<double, def, def, op::none_t> a{2, 0, 1};
|
||||
BOOST_TEST_EQ(a.index(0), 0);
|
||||
BOOST_TEST_EQ(a.index(0.49), 0);
|
||||
BOOST_TEST_EQ(a.index(0.50), 1);
|
||||
BOOST_TEST_EQ(a.index(0.99), 1);
|
||||
BOOST_TEST_EQ(a.index(1), 1); // last ordinary bin
|
||||
BOOST_TEST_EQ(a.index(1.1), 2); // out of range
|
||||
}
|
||||
|
||||
// iterators
|
||||
{
|
||||
test_axis_iterator(axis::regular<>(5, 0, 1), 0, 5);
|
||||
test_axis_iterator(axis::regular<double, def, def, axis::option::none_t>(5, 0, 1), 0,
|
||||
5);
|
||||
test_axis_iterator(axis::regular<double, def, def, op::none_t>(5, 0, 1), 0, 5);
|
||||
test_axis_iterator(axis::circular<>(5, 0, 1), 0, 5);
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "utility_str.hpp"
|
||||
|
||||
using namespace boost::histogram;
|
||||
namespace op = boost::histogram::axis::option;
|
||||
|
||||
int main() {
|
||||
constexpr auto inf = std::numeric_limits<double>::infinity();
|
||||
@ -104,7 +105,7 @@ int main() {
|
||||
|
||||
// axis::variable circular
|
||||
{
|
||||
axis::variable<double, axis::null_type, axis::option::circular_t> a{-1, 1, 2};
|
||||
axis::variable<double, axis::null_type, op::circular_t> a{-1, 1, 2};
|
||||
BOOST_TEST_EQ(a.value(-2), -4);
|
||||
BOOST_TEST_EQ(a.value(-1), -2);
|
||||
BOOST_TEST_EQ(a.value(0), -1);
|
||||
@ -125,7 +126,7 @@ int main() {
|
||||
// axis::regular with growth
|
||||
{
|
||||
using pii_t = std::pair<axis::index_type, axis::index_type>;
|
||||
axis::variable<double, axis::null_type, axis::option::growth_t> a{0, 1};
|
||||
axis::variable<double, axis::null_type, op::growth_t> a{0, 1};
|
||||
BOOST_TEST_EQ(a.size(), 1);
|
||||
BOOST_TEST_EQ(a.update(0), pii_t(0, 0));
|
||||
BOOST_TEST_EQ(a.size(), 1);
|
||||
@ -149,11 +150,33 @@ int main() {
|
||||
BOOST_TEST_EQ(a.update(nan), pii_t(a.size(), 0));
|
||||
}
|
||||
|
||||
// axis with overflow bin represents open interval
|
||||
{
|
||||
axis::variable<double, boost::use_default, op::overflow_t> a{0.0, 0.5, 1.0};
|
||||
BOOST_TEST_EQ(a.index(0), 0);
|
||||
BOOST_TEST_EQ(a.index(0.49), 0);
|
||||
BOOST_TEST_EQ(a.index(0.50), 1);
|
||||
BOOST_TEST_EQ(a.index(0.99), 1);
|
||||
BOOST_TEST_EQ(a.index(1), 2); // overflow bin
|
||||
BOOST_TEST_EQ(a.index(1.1), 2); // overflow bin
|
||||
}
|
||||
|
||||
// axis without overflow bin represents a closed interval
|
||||
{
|
||||
axis::variable<double, boost::use_default, op::none_t> a{0.0, 0.5, 1.0};
|
||||
BOOST_TEST_EQ(a.index(0), 0);
|
||||
BOOST_TEST_EQ(a.index(0.49), 0);
|
||||
BOOST_TEST_EQ(a.index(0.50), 1);
|
||||
BOOST_TEST_EQ(a.index(0.99), 1);
|
||||
BOOST_TEST_EQ(a.index(1), 1); // last ordinary bin
|
||||
BOOST_TEST_EQ(a.index(1.1), 2); // out of range
|
||||
}
|
||||
|
||||
// iterators
|
||||
{
|
||||
test_axis_iterator(axis::variable<>{1, 2, 3}, 0, 2);
|
||||
test_axis_iterator(
|
||||
axis::variable<double, axis::null_type, axis::option::circular_t>{1, 2, 3}, 0, 2);
|
||||
test_axis_iterator(axis::variable<double, axis::null_type, op::circular_t>{1, 2, 3},
|
||||
0, 2);
|
||||
}
|
||||
|
||||
// shrink and rebin
|
||||
@ -176,7 +199,7 @@ int main() {
|
||||
|
||||
// shrink and rebin with circular option
|
||||
{
|
||||
using A = axis::variable<double, axis::null_type, axis::option::circular_t>;
|
||||
using A = axis::variable<double, axis::null_type, op::circular_t>;
|
||||
auto a = A({1, 2, 3, 4, 5});
|
||||
BOOST_TEST_THROWS(A(a, 1, 4, 1), std::invalid_argument);
|
||||
BOOST_TEST_THROWS(A(a, 0, 3, 1), std::invalid_argument);
|
||||
|
Loading…
x
Reference in New Issue
Block a user