doc improvements

This commit is contained in:
Hans Dembinski
2019-02-07 22:57:08 +01:00
parent 02f0004863
commit a2dcbdccd9
16 changed files with 308 additions and 162 deletions

View File

@@ -79,24 +79,38 @@ inline auto rebin(unsigned iaxis, unsigned merge) {
std::numeric_limits<double>::quiet_NaN(), merge};
}
/// Convenience overload for single axis.
/// @copydoc shrink_and_rebin(unsigned, double, double, unsigned)
/**
Convenience overload for single axis.
@param lower lowest bound that should be kept.
@param upper highest bound that should be kept. If upper is inside bin interval, the
whole interval is removed.
@param merge how many adjacent bins to merge into one.
*/
inline auto shrink_and_rebin(double lower, double upper, unsigned merge) {
return shrink_and_rebin(0, lower, upper, merge);
}
/// Convenience overload for single axis.
/// @copydoc shrink(unsigned, double, double)
/**
Convenience overload for single axis.
@param lower lowest bound that should be kept.
@param upper highest bound that should be kept. If upper is inside bin interval, the
whole interval is removed.
*/
inline auto shrink(double lower, double upper) { return shrink(0, lower, upper); }
/// Convenience overload for single axis.
/// @copydoc rebin(unsigned, unsigned)
/**
Convenience overload for single axis.
@param merge how many adjacent bins to merge into one.
*/
inline auto rebin(unsigned merge) { return rebin(0, merge); }
/**
Shrink and/or rebin axes of a histogram.
Returns the modified copy.
Returns the reduced copy of the histogram.
@param hist original histogram.
@param options iterable sequence of reduce_options, generated by shrink_and_rebin(),

View File

@@ -41,15 +41,19 @@ public:
namespace axis {
/** 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. There is an optional overflow bin for this axis, which counts values that
* are not part of the set. Binning has a O(N) complexity, but with a very small factor.
* For small N (the typical use case) it beats other kinds of lookup.
*
* Value types must be equal-comparable.
*/
/**
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.
@tparam Value input value type, must be equal-comparable.
@tparam MetaData type to store meta data.
@tparam Options whether axis has an overflow bin or is growing.
@tparam Allocator allocator to use for dynamic memory management.
*/
template <class Value, class MetaData, option Options, class Allocator>
class category
: public iterator_mixin<category<Value, MetaData, Options, Allocator>>,

View File

@@ -57,10 +57,14 @@ public:
namespace axis {
/** Axis for an interval of integer values with unit steps.
*
* Binning is a O(1) operation. This axis operates
* faster than a regular axis.
/**
Axis for an interval of integer values with unit steps.
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 whether axis has an under- and/or overflow bin, is circular, or growing.
*/
template <class Value, class MetaData, option Options>
class integer : public iterator_mixin<integer<Value, MetaData, Options>>,

View File

@@ -0,0 +1,61 @@
// Copyright 2015-2019 Hans Dembinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_HISTOGRAM_AXIS_OPTION_HPP
#define BOOST_HISTOGRAM_AXIS_OPTION_HPP
namespace boost {
namespace histogram {
namespace axis {
/**
Options for builtin axis types.
Options should be combined with `operator|`.
*/
enum class option {
none = 0, ///< all options are off.
underflow = 0b1, ///< axis has underflow bin.
overflow = 0b10, ///< axis has overflow bin.
circular = 0b100, ///< axis is circular, mutually exclusive with underflow.
growth = 0b1000, ///< axis can grow, mutually exclusive with circular.
use_default = static_cast<int>(underflow) | static_cast<int>(overflow),
};
/// Invert options.
constexpr inline option operator~(option a) {
return static_cast<option>(~static_cast<int>(a));
}
/// Logical AND of options.
constexpr inline option operator&(option a, option b) {
return static_cast<option>(static_cast<int>(a) & static_cast<int>(b));
}
/// Logical OR or options.
constexpr inline option operator|(option a, option b) {
return static_cast<option>(static_cast<int>(a) | static_cast<int>(b));
}
/// Test whether the bits in b are also set in a.
constexpr inline bool test(option a, option b) {
return static_cast<int>(a) & static_cast<int>(b);
}
/// Logical OR of options and corrects for mutually exclusive options.
constexpr inline option join(option a, option b) {
// circular turns off underflow and vice versa
a = a | b;
if (test(b, option::underflow)) a = a & ~option::circular;
if (test(b, option::circular)) a = a & ~option::underflow;
return a;
}
} // namespace axis
} // namespace histogram
} // namespace boost
#endif

View File

@@ -17,6 +17,7 @@
#include <cmath>
#include <limits>
#include <stdexcept>
#include <type_traits>
#include <utility>
namespace boost {
@@ -157,9 +158,15 @@ auto step(T&& t) {
return step_type<T&&>{std::forward<T>(t)};
}
/** Axis for equidistant intervals on the real line.
*
* The most common binning strategy. Very fast. Binning is a O(1) operation.
/**
Axis for equidistant intervals on the real line.
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 whether axis has an under- and/or overflow bin, is circular, or growing.
*/
template <class Value, class Transform, class MetaData, option Options>
class regular : public iterator_mixin<regular<Value, Transform, MetaData, Options>>,
@@ -177,6 +184,8 @@ public:
private:
using unit_type = detail::get_unit_type<value_type>;
using internal_value_type = detail::get_scale_type<value_type>;
static_assert(std::is_floating_point<internal_value_type>::value,
"variable axis requires floating point type");
public:
regular() = default;

View File

@@ -60,10 +60,16 @@ public:
namespace axis {
/** 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.
/**
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.
@tparam Value input value type, must be floating point.
@tparam MetaData type to store meta data.
@tparam Options whether axis has an under- and/or overflow bin, is circular, or growing.
@tparam Allocator allocator to use for dynamic memory management.
*/
template <class Value, class MetaData, option Options, class Allocator>
class variable

View File

@@ -12,13 +12,13 @@
Forward declarations, basic typedefs, and default template arguments for main classes.
*/
#include <boost/histogram/axis/option.hpp>
#include <boost/histogram/detail/attribute.hpp> // BOOST_HISTOGRAM_DETAIL_NODISCARD
#include <string>
#include <vector>
namespace boost {
namespace histogram {
namespace axis {
/// Integral type for axis indices
@@ -33,39 +33,6 @@ struct null_type {};
/// default metadata type
using default_metadata = std::string;
enum class option {
none = 0,
underflow = 0b1,
overflow = 0b10,
circular = 0b100,
growth = 0b1000,
use_default = static_cast<int>(underflow) | static_cast<int>(overflow),
};
constexpr inline option operator~(option a) {
return static_cast<option>(~static_cast<int>(a));
}
constexpr inline option operator&(option a, option b) {
return static_cast<option>(static_cast<int>(a) & static_cast<int>(b));
}
constexpr inline option operator|(option a, option b) {
return static_cast<option>(static_cast<int>(a) | static_cast<int>(b));
}
constexpr inline bool test(option a, option b) {
return static_cast<int>(a) & static_cast<int>(b);
}
constexpr inline option join(option a, option b) {
// circular turns off underflow and vice versa
a = a | b;
if (test(b, option::underflow)) a = a & ~option::circular;
if (test(b, option::circular)) a = a & ~option::underflow;
return a;
}
namespace transform {
struct id;
struct log;

View File

@@ -13,10 +13,10 @@
*/
#include <boost/histogram/accumulators/weighted_sum.hpp>
#include <boost/histogram/unlimited_storage.hpp> // implements default_storage
#include <boost/histogram/detail/meta.hpp>
#include <boost/histogram/histogram.hpp>
#include <boost/histogram/storage_adaptor.hpp>
#include <boost/histogram/unlimited_storage.hpp> // = default_storage
#include <boost/mp11/utility.hpp>
#include <tuple>
#include <vector>
@@ -30,10 +30,9 @@ namespace histogram {
@param axis First axis instance.
@param axes Other axis instances.
*/
template <typename Storage, typename T, typename... Ts,
typename = detail::requires_axis<T>>
auto make_histogram_with(Storage&& storage, T&& axis, Ts&&... axes) {
auto a = std::make_tuple(std::forward<T>(axis), std::forward<Ts>(axes)...);
template <class Storage, class Axis, class... Axes, class = detail::requires_axis<Axis>>
auto make_histogram_with(Storage&& storage, Axis&& axis, Axes&&... axes) {
auto a = std::make_tuple(std::forward<Axis>(axis), std::forward<Axes>(axes)...);
using U = detail::naked<Storage>;
using S = mp11::mp_if<detail::is_storage<U>, U, storage_adaptor<U>>;
return histogram<decltype(a), S>(std::move(a), S(std::forward<Storage>(storage)));
@@ -44,10 +43,10 @@ auto make_histogram_with(Storage&& storage, T&& axis, Ts&&... axes) {
@param axis First axis instance.
@param axes Other axis instances.
*/
template <typename T, typename... Ts, typename = detail::requires_axis<T>>
auto make_histogram(T&& axis, Ts&&... axes) {
return make_histogram_with(default_storage(), std::forward<T>(axis),
std::forward<Ts>(axes)...);
template <class Axis, class... Axes, class = detail::requires_axis<Axis>>
auto make_histogram(Axis&& axis, Axes&&... axes) {
return make_histogram_with(default_storage(), std::forward<Axis>(axis),
std::forward<Axes>(axes)...);
}
/**
@@ -55,10 +54,10 @@ auto make_histogram(T&& axis, Ts&&... axes) {
@param axis First axis instance.
@param axes Other axis instances.
*/
template <typename T, typename... Ts, typename = detail::requires_axis<T>>
auto make_weighted_histogram(T&& axis, Ts&&... axes) {
return make_histogram_with(weight_storage(), std::forward<T>(axis),
std::forward<Ts>(axes)...);
template <class Axis, class... Axes, class = detail::requires_axis<Axis>>
auto make_weighted_histogram(Axis&& axis, Axes&&... axes) {
return make_histogram_with(weight_storage(), std::forward<Axis>(axis),
std::forward<Axes>(axes)...);
}
/**
@@ -66,8 +65,8 @@ auto make_weighted_histogram(T&& axis, Ts&&... axes) {
@param storage Storage or container with standard interface (any vector, array, or map).
@param iterable Iterable range of axis objects.
*/
template <typename Storage, typename Iterable,
typename = detail::requires_sequence_of_any_axis<Iterable>>
template <class Storage, class Iterable,
class = detail::requires_sequence_of_any_axis<Iterable>>
auto make_histogram_with(Storage&& storage, Iterable&& iterable) {
using U = detail::naked<Storage>;
using S = mp11::mp_if<detail::is_storage<U>, U, storage_adaptor<U>>;
@@ -82,7 +81,7 @@ auto make_histogram_with(Storage&& storage, Iterable&& iterable) {
Make histogram from iterable range and default storage.
@param iterable Iterable range of axis objects.
*/
template <typename Iterable, typename = detail::requires_sequence_of_any_axis<Iterable>>
template <class Iterable, class = detail::requires_sequence_of_any_axis<Iterable>>
auto make_histogram(Iterable&& iterable) {
return make_histogram_with(default_storage(), std::forward<Iterable>(iterable));
}
@@ -91,7 +90,7 @@ auto make_histogram(Iterable&& iterable) {
Make histogram from iterable range and weight-counting storage.
@param iterable Iterable range of axis objects.
*/
template <typename Iterable, typename = detail::requires_sequence_of_any_axis<Iterable>>
template <class Iterable, class = detail::requires_sequence_of_any_axis<Iterable>>
auto make_weighted_histogram(Iterable&& iterable) {
return make_histogram_with(weight_storage(), std::forward<Iterable>(iterable));
}
@@ -102,8 +101,7 @@ auto make_weighted_histogram(Iterable&& iterable) {
@param begin Iterator to range of axis objects.
@param end Iterator to range of axis objects.
*/
template <typename Storage, typename Iterator,
typename = detail::requires_iterator<Iterator>>
template <class Storage, class Iterator, class = detail::requires_iterator<Iterator>>
auto make_histogram_with(Storage&& storage, Iterator begin, Iterator end) {
using T = detail::naked<decltype(*begin)>;
return make_histogram_with(std::forward<Storage>(storage), std::vector<T>(begin, end));
@@ -114,7 +112,7 @@ auto make_histogram_with(Storage&& storage, Iterator begin, Iterator end) {
@param begin Iterator to range of axis objects.
@param end Iterator to range of axis objects.
*/
template <typename Iterator, typename = detail::requires_iterator<Iterator>>
template <class Iterator, class = detail::requires_iterator<Iterator>>
auto make_histogram(Iterator begin, Iterator end) {
return make_histogram_with(default_storage(), begin, end);
}
@@ -124,7 +122,7 @@ auto make_histogram(Iterator begin, Iterator end) {
@param begin Iterator to range of axis objects.
@param end Iterator to range of axis objects.
*/
template <typename Iterator, typename = detail::requires_iterator<Iterator>>
template <class Iterator, class = detail::requires_iterator<Iterator>>
auto make_weighted_histogram(Iterator begin, Iterator end) {
return make_histogram_with(weight_storage(), begin, end);
}

View File

@@ -24,17 +24,17 @@ namespace boost {
namespace histogram {
/// profile factory from compile-time axis configuration
template <typename T, typename... Ts, typename = detail::requires_axis<T>>
auto make_profile(T&& axis, Ts&&... axes) {
return make_histogram_with(profile_storage(), std::forward<T>(axis),
std::forward<Ts>(axes)...);
template <typename Axis, typename... Axes, typename = detail::requires_axis<Axis>>
auto make_profile(Axis&& axis, Axes&&... axes) {
return make_histogram_with(profile_storage(), std::forward<Axis>(axis),
std::forward<Axes>(axes)...);
}
/// profile factory from compile-time axis configuration with weighted mean
template <typename T, typename... Ts, typename = detail::requires_axis<T>>
auto make_weighted_profile(T&& axis, Ts&&... axes) {
return make_histogram_with(weighted_profile_storage(), std::forward<T>(axis),
std::forward<Ts>(axes)...);
template <typename Axis, typename... Axes, typename = detail::requires_axis<Axis>>
auto make_weighted_profile(Axis&& axis, Axes&&... axes) {
return make_histogram_with(weighted_profile_storage(), std::forward<Axis>(axis),
std::forward<Axes>(axes)...);
}
/// profile factory from vector-like

View File

@@ -15,46 +15,57 @@ namespace histogram {
/// Unsafe read/write access to classes that potentially break consistency
struct unsafe_access {
/// Get axes.
//@{
template <class T>
static auto& axes(T& t) {
return t.axes_;
/**
Get axes.
@param hist histogram.
*/
template <class Histogram>
static auto& axes(Histogram& hist) {
return hist.axes_;
}
template <class T>
static const auto& axes(const T& t) {
return t.axes_;
}
//@}
/// Get mutable axis reference with compile-time or run-time number.
//@{
template <class T>
static decltype(auto) axis(T& t, unsigned i) {
detail::axis_index_is_valid(t.axes_, i);
return detail::axis_get(t.axes_, i);
/// @copydoc axes()
template <class Histogram>
static const auto& axes(const Histogram& hist) {
return hist.axes_;
}
template <class T, unsigned N = 0>
static decltype(auto) axis(T& t, std::integral_constant<unsigned, N> = {}) {
detail::axis_index_is_valid(t.axes_, N);
return detail::axis_get<N>(t.axes_);
}
//@}
/// Get storage.
//@{
template <class T>
static auto& storage(T& t) {
return t.storage_;
/**
Get mutable axis reference with compile-time number.
@param hist histogram.
@tparam I axis index (optional, default: 0).
*/
template <class Histogram, unsigned I = 0>
static decltype(auto) axis(Histogram& hist, std::integral_constant<unsigned, I> = {}) {
detail::axis_index_is_valid(hist.axes_, I);
return detail::axis_get<I>(hist.axes_);
}
template <class T>
static const auto& storage(const T& t) {
return t.storage_;
/**
Get mutable axis reference with run-time number.
@param hist histogram.
@param i axis index.
*/
template <class Histogram>
static decltype(auto) axis(Histogram& hist, unsigned i) {
detail::axis_index_is_valid(hist.axes_, i);
return detail::axis_get(hist.axes_, i);
}
/**
Get storage.
@param hist histogram.
*/
template <class Histogram>
static auto& storage(Histogram& hist) {
return hist.storage_;
}
/// @copydoc storage()
template <class Histogram>
static const auto& storage(const Histogram& hist) {
return hist.storage_;
}
//@}
};
} // namespace histogram