mirror of
https://github.com/boostorg/histogram.git
synced 2025-05-10 07:14:05 +00:00
clang-format everything
This commit is contained in:
parent
47d4d85301
commit
d4dbae92f5
@ -11,9 +11,7 @@ int main(int, char**) {
|
||||
create a static 1d-histogram with an axis that has 6 equidistant
|
||||
bins on the real line from -1.0 to 2.0, and label it as "x"
|
||||
*/
|
||||
auto h = bh::make_static_histogram(
|
||||
bh::axis::regular<>(6, -1.0, 2.0, "x")
|
||||
);
|
||||
auto h = bh::make_static_histogram(bh::axis::regular<>(6, -1.0, 2.0, "x"));
|
||||
|
||||
// fill histogram with data, typically this happens in a loop
|
||||
// STL algorithms are supported
|
||||
@ -56,13 +54,10 @@ int main(int, char**) {
|
||||
std::cout.setf(std::ios_base::fixed);
|
||||
for (auto it = h.begin(); it != h.end(); ++it) {
|
||||
const auto bin = it.bin(0_c);
|
||||
std::cout << "bin " << it.idx(0) << " x in ["
|
||||
<< std::setprecision(1)
|
||||
<< std::setw(4) << bin.lower() << ", "
|
||||
<< std::setw(4) << bin.upper() << "): "
|
||||
<< std::setprecision(1)
|
||||
<< it->value() << " +/- "
|
||||
<< std::setprecision(3) << std::sqrt(it->variance())
|
||||
std::cout << "bin " << it.idx(0) << " x in [" << std::setprecision(1)
|
||||
<< std::setw(4) << bin.lower() << ", " << std::setw(4)
|
||||
<< bin.upper() << "): " << std::setprecision(1) << it->value()
|
||||
<< " +/- " << std::setprecision(3) << std::sqrt(it->variance())
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
|
@ -8,10 +8,8 @@ namespace bh = boost::histogram;
|
||||
|
||||
int main() {
|
||||
// make histogram with 2 x 2 = 4 bins (not counting under-/overflow bins)
|
||||
auto h = bh::make_static_histogram(
|
||||
bh::axis::regular<>(2, -1, 1),
|
||||
bh::axis::regular<>(2, 2, 4)
|
||||
);
|
||||
auto h = bh::make_static_histogram(bh::axis::regular<>(2, -1, 1),
|
||||
bh::axis::regular<>(2, 2, 4));
|
||||
|
||||
h(bh::weight(1), -0.5, 2.5); // bin index 0, 0
|
||||
h(bh::weight(2), -0.5, 3.5); // bin index 0, 1
|
||||
@ -19,19 +17,14 @@ int main() {
|
||||
h(bh::weight(4), 0.5, 3.5); // bin index 1, 1
|
||||
|
||||
// access count value, number of indices must match number of axes
|
||||
std::cout << h.at(0, 0).value() << " "
|
||||
<< h.at(0, 1).value() << " "
|
||||
<< h.at(1, 0).value() << " "
|
||||
<< h.at(1, 1).value()
|
||||
<< std::endl;
|
||||
std::cout << h.at(0, 0).value() << " " << h.at(0, 1).value() << " "
|
||||
<< h.at(1, 0).value() << " " << h.at(1, 1).value() << std::endl;
|
||||
|
||||
// prints: 1 2 3 4
|
||||
|
||||
// access count variance, number of indices must match number of axes
|
||||
std::cout << h.at(0, 0).variance() << " "
|
||||
<< h.at(0, 1).variance() << " "
|
||||
<< h.at(1, 0).variance() << " "
|
||||
<< h.at(1, 1).variance()
|
||||
std::cout << h.at(0, 0).variance() << " " << h.at(0, 1).variance() << " "
|
||||
<< h.at(1, 0).variance() << " " << h.at(1, 1).variance()
|
||||
<< std::endl;
|
||||
// prints: 1 4 9 16
|
||||
|
||||
|
@ -8,8 +8,7 @@ int main() {
|
||||
// create a 2d-histogram with an "age" and an "income" axis
|
||||
auto h = bh::make_static_histogram(
|
||||
bh::axis::regular<>(20, 0, 100, "age in years"),
|
||||
bh::axis::regular<>(20, 0, 100, "yearly income in $1000")
|
||||
);
|
||||
bh::axis::regular<>(20, 0, 100, "yearly income in $1000"));
|
||||
|
||||
// do something with h
|
||||
}
|
||||
|
@ -6,7 +6,8 @@ namespace bh = boost::histogram;
|
||||
|
||||
int main() {
|
||||
// create a 1d-histogram for dice throws with integer values from 1 to 6
|
||||
auto h = bh::make_static_histogram(bh::axis::integer<>(1, 7, "eyes", bh::axis::uoflow::off));
|
||||
auto h = bh::make_static_histogram(
|
||||
bh::axis::integer<>(1, 7, "eyes", bh::axis::uoflow::off));
|
||||
|
||||
// do something with h
|
||||
}
|
||||
|
@ -14,9 +14,7 @@ struct custom_axis : public bh::axis::integer<> {
|
||||
// the customization point
|
||||
// - accept const char* and convert to int
|
||||
// - then call index method of base class
|
||||
int index(value_type s) const {
|
||||
return integer::index(std::atoi(s));
|
||||
}
|
||||
int index(value_type s) const { return integer::index(std::atoi(s)); }
|
||||
};
|
||||
|
||||
int main() {
|
||||
@ -28,8 +26,7 @@ int main() {
|
||||
|
||||
for (auto xi : h.axis()) {
|
||||
std::cout << "bin " << xi.idx() << " [" << xi.lower() << ", "
|
||||
<< xi.upper() << ") " << h.at(xi).value()
|
||||
<< std::endl;
|
||||
<< xi.upper() << ") " << h.at(xi).value() << std::endl;
|
||||
}
|
||||
|
||||
/* prints:
|
||||
|
@ -8,8 +8,7 @@ namespace bh = boost::histogram;
|
||||
int main() {
|
||||
// create static histogram with array_storage, using int as counter type
|
||||
auto h = bh::make_static_histogram_with<bh::array_storage<int>>(
|
||||
bh::axis::regular<>(10, 0, 1)
|
||||
);
|
||||
bh::axis::regular<>(10, 0, 1));
|
||||
|
||||
// do something with h
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
//[ guide_fill_histogram
|
||||
|
||||
#include <boost/histogram.hpp>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace bh = boost::histogram;
|
||||
|
||||
@ -23,14 +23,13 @@ int main() {
|
||||
|
||||
// functional-style processing is also supported
|
||||
std::vector<std::pair<int, double>> input_data{
|
||||
{0, 1.2}, {2, 3.4}, {4, 5.6}
|
||||
};
|
||||
{0, 1.2}, {2, 3.4}, {4, 5.6}};
|
||||
// Note that std::for_each takes the functor by value, thus it makes a
|
||||
// potentially expensive copy of your histogram. Passing freshly created
|
||||
// histograms is ok, though, because of return-value-optimization
|
||||
auto h2 = std::for_each(input_data.begin(), input_data.end(),
|
||||
bh::make_static_histogram(
|
||||
bh::axis::integer<>(0, 4),
|
||||
auto h2 =
|
||||
std::for_each(input_data.begin(), input_data.end(),
|
||||
bh::make_static_histogram(bh::axis::integer<>(0, 4),
|
||||
bh::axis::regular<>(10, 0, 5)));
|
||||
// h is filled
|
||||
}
|
||||
|
@ -41,10 +41,10 @@ int main() {
|
||||
// note: special effect of multiplication on counter variance
|
||||
auto h = bh::make_static_histogram(bh::axis::regular<>(2, -1, 1));
|
||||
h(-0.5); // counts are: 1 0
|
||||
std::cout << "value " << (2 * h).at(0).value()
|
||||
<< " " << (h + h).at(0).value() << "\n"
|
||||
<< "variance " << (2 * h).at(0).variance()
|
||||
<< " " << (h + h).at(0).variance() << std::endl;
|
||||
std::cout << "value " << (2 * h).at(0).value() << " "
|
||||
<< (h + h).at(0).value() << "\n"
|
||||
<< "variance " << (2 * h).at(0).variance() << " "
|
||||
<< (h + h).at(0).variance() << std::endl;
|
||||
// equality operator also checks variances, so the statement is false
|
||||
std::cout << (h + h == 2 * h) << std::endl;
|
||||
/* prints:
|
||||
|
@ -7,10 +7,10 @@ namespace bh = boost::histogram;
|
||||
|
||||
// example of a generic function for histograms, this one sums all entries
|
||||
template <typename... Ts>
|
||||
typename bh::histogram<Ts...>::element_type sum(const bh::histogram<Ts...>& h) {
|
||||
typename bh::histogram<Ts...>::element_type sum(
|
||||
const bh::histogram<Ts...>& h) {
|
||||
auto result = typename bh::histogram<Ts...>::element_type(0);
|
||||
for (auto x : h)
|
||||
result += x;
|
||||
for (auto x : h) result += x;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -32,15 +32,12 @@ int main() {
|
||||
reduce does not remove counts; returned histograms are summed over
|
||||
the removed axes, so h, hr0, and hr1 have same number of total counts
|
||||
*/
|
||||
std::cout << sum(h).value() << " "
|
||||
<< sum(hr0).value() << " "
|
||||
std::cout << sum(h).value() << " " << sum(hr0).value() << " "
|
||||
<< sum(hr1).value() << std::endl;
|
||||
// prints: 3 3 3
|
||||
|
||||
for (auto yi : h.axis(1_c)) {
|
||||
for (auto xi : h.axis(0_c)) {
|
||||
std::cout << h.at(xi, yi).value() << " ";
|
||||
}
|
||||
for (auto xi : h.axis(0_c)) { std::cout << h.at(xi, yi).value() << " "; }
|
||||
std::cout << std::endl;
|
||||
}
|
||||
// prints: 1 0 0
|
||||
@ -48,13 +45,11 @@ int main() {
|
||||
// 0 1 0
|
||||
// 0 0 1
|
||||
|
||||
for (auto xi : hr0.axis())
|
||||
std::cout << hr0.at(xi).value() << " ";
|
||||
for (auto xi : hr0.axis()) std::cout << hr0.at(xi).value() << " ";
|
||||
std::cout << std::endl;
|
||||
// prints: 1 1 1
|
||||
|
||||
for (auto yi : hr1.axis())
|
||||
std::cout << hr1.at(yi).value() << " ";
|
||||
for (auto yi : hr1.axis()) std::cout << hr1.at(yi).value() << " ";
|
||||
std::cout << std::endl;
|
||||
// prints: 1 0 1 1
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
//[ guide_histogram_serialization
|
||||
|
||||
#include <boost/histogram.hpp>
|
||||
#include <boost/histogram/serialization.hpp> // includes serialization code
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
#include <boost/histogram.hpp>
|
||||
#include <boost/histogram/serialization.hpp> // includes serialization code
|
||||
#include <sstream>
|
||||
|
||||
namespace bh = boost::histogram;
|
||||
|
@ -17,8 +17,7 @@ int main() {
|
||||
axis::circular<>(4, 0.1, 1.0, "polar"),
|
||||
axis::variable<>({-1, 0, 1}, "variable", axis::uoflow::off),
|
||||
axis::category<>({A, B, C}, "category"),
|
||||
axis::integer<>(-1, 1, "integer", axis::uoflow::off)
|
||||
);
|
||||
axis::integer<>(-1, 1, "integer", axis::uoflow::off));
|
||||
|
||||
std::cout << h << std::endl;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
//[ guide_mixed_cpp_python_part_cpp
|
||||
|
||||
#include <boost/python.hpp>
|
||||
#include <boost/histogram.hpp>
|
||||
#include <boost/python.hpp>
|
||||
|
||||
namespace bh = boost::histogram;
|
||||
namespace bp = boost::python;
|
||||
@ -9,13 +9,10 @@ namespace bp = boost::python;
|
||||
// function that runs in C++ and accepts reference to dynamic histogram
|
||||
void process(bh::dynamic_histogram<>& h) {
|
||||
// fill histogram, in reality this would be arbitrarily complex code
|
||||
for (int i = 0; i < 4; ++i)
|
||||
h(0.25 * i, i);
|
||||
for (int i = 0; i < 4; ++i) h(0.25 * i, i);
|
||||
}
|
||||
|
||||
// a minimal Python module, which exposes the process function to Python
|
||||
BOOST_PYTHON_MODULE(cpp_filler) {
|
||||
bp::def("process", process);
|
||||
}
|
||||
BOOST_PYTHON_MODULE(cpp_filler) { bp::def("process", process); }
|
||||
|
||||
//]
|
||||
|
@ -20,7 +20,8 @@ histogram<T, A, S>&& operator+(histogram<T, A, S>&& a,
|
||||
}
|
||||
|
||||
template <typename T, typename A, typename S>
|
||||
histogram<T, A, S>&& operator+(histogram<T, A, S>&& a, histogram<T, A, S>&& b) {
|
||||
histogram<T, A, S>&& operator+(histogram<T, A, S>&& a,
|
||||
histogram<T, A, S>&& b) {
|
||||
a += b;
|
||||
return std::move(a);
|
||||
}
|
||||
|
@ -45,9 +45,7 @@ class base {
|
||||
: size_(size),
|
||||
shape_(size + static_cast<int>(uo)),
|
||||
label_(label.begin(), label.end()) {
|
||||
if (size_ == 0) {
|
||||
throw std::invalid_argument("bins > 0 required");
|
||||
}
|
||||
if (size_ == 0) { throw std::invalid_argument("bins > 0 required"); }
|
||||
}
|
||||
|
||||
base() = default;
|
||||
|
@ -32,7 +32,9 @@ class interval_view {
|
||||
auto upper() const noexcept -> decltype(std::declval<Axis&>().lower(0)) {
|
||||
return axis_.lower(idx_ + 1);
|
||||
}
|
||||
typename Axis::value_type width() const noexcept { return upper() - lower(); }
|
||||
typename Axis::value_type width() const noexcept {
|
||||
return upper() - lower();
|
||||
}
|
||||
|
||||
bool operator==(const interval_view& rhs) const noexcept {
|
||||
return idx_ == rhs.idx_ && axis_ == rhs.axis_;
|
||||
|
@ -14,12 +14,13 @@ namespace histogram {
|
||||
namespace axis {
|
||||
|
||||
template <typename Axis>
|
||||
class iterator_over : public iterator_facade<iterator_over<Axis>,
|
||||
typename Axis::bin_type,
|
||||
class iterator_over
|
||||
: public iterator_facade<iterator_over<Axis>, typename Axis::bin_type,
|
||||
random_access_traversal_tag,
|
||||
typename Axis::bin_type> {
|
||||
public:
|
||||
explicit iterator_over(const Axis& axis, int idx) : axis_(axis), idx_(idx) {}
|
||||
explicit iterator_over(const Axis& axis, int idx)
|
||||
: axis_(axis), idx_(idx) {}
|
||||
|
||||
iterator_over(const iterator_over&) = default;
|
||||
iterator_over& operator=(const iterator_over&) = default;
|
||||
@ -43,10 +44,9 @@ class iterator_over : public iterator_facade<iterator_over<Axis>,
|
||||
|
||||
template <typename Axis>
|
||||
class reverse_iterator_over
|
||||
: public iterator_facade<reverse_iterator_over<Axis>,
|
||||
typename Axis::bin_type,
|
||||
random_access_traversal_tag,
|
||||
typename Axis::bin_type> {
|
||||
: public iterator_facade<
|
||||
reverse_iterator_over<Axis>, typename Axis::bin_type,
|
||||
random_access_traversal_tag, typename Axis::bin_type> {
|
||||
public:
|
||||
explicit reverse_iterator_over(const Axis& axis, int idx)
|
||||
: axis_(axis), idx_(idx) {}
|
||||
|
@ -20,15 +20,9 @@ namespace histogram {
|
||||
namespace axis {
|
||||
|
||||
namespace detail {
|
||||
inline string_view to_string(const transform::identity&) {
|
||||
return {};
|
||||
}
|
||||
inline string_view to_string(const transform::log&) {
|
||||
return {"_log", 4};
|
||||
}
|
||||
inline string_view to_string(const transform::sqrt&) {
|
||||
return {"_sqrt", 5};
|
||||
}
|
||||
inline string_view to_string(const transform::identity&) { return {}; }
|
||||
inline string_view to_string(const transform::log&) { return {"_log", 4}; }
|
||||
inline string_view to_string(const transform::sqrt&) { return {"_sqrt", 5}; }
|
||||
} // namespace detail
|
||||
|
||||
template <typename T>
|
||||
@ -52,36 +46,30 @@ inline std::ostream& operator<<(std::ostream& os,
|
||||
os << ", label=";
|
||||
::boost::histogram::detail::escape(os, a.label());
|
||||
}
|
||||
if (!a.uoflow()) {
|
||||
os << ", uoflow=False";
|
||||
}
|
||||
if (!a.uoflow()) { os << ", uoflow=False"; }
|
||||
os << ")";
|
||||
return os;
|
||||
}
|
||||
|
||||
template <typename RealType>
|
||||
inline std::ostream& operator<<(
|
||||
std::ostream& os,
|
||||
const regular<RealType, axis::transform::pow>& a) {
|
||||
std::ostream& os, const regular<RealType, axis::transform::pow>& a) {
|
||||
os << "regular_pow(" << a.size() << ", " << a[0].lower() << ", "
|
||||
<< a[a.size()].lower() << ", " << a.transform().power;
|
||||
if (!a.label().empty()) {
|
||||
os << ", label=";
|
||||
::boost::histogram::detail::escape(os, a.label());
|
||||
}
|
||||
if (!a.uoflow()) {
|
||||
os << ", uoflow=False";
|
||||
}
|
||||
if (!a.uoflow()) { os << ", uoflow=False"; }
|
||||
os << ")";
|
||||
return os;
|
||||
}
|
||||
|
||||
template <typename RealType>
|
||||
inline std::ostream& operator<<(std::ostream& os, const circular<RealType>& a) {
|
||||
inline std::ostream& operator<<(std::ostream& os,
|
||||
const circular<RealType>& a) {
|
||||
os << "circular(" << a.size();
|
||||
if (a.phase() != 0.0) {
|
||||
os << ", phase=" << a.phase();
|
||||
}
|
||||
if (a.phase() != 0.0) { os << ", phase=" << a.phase(); }
|
||||
if (a.perimeter() != RealType(::boost::histogram::detail::two_pi)) {
|
||||
os << ", perimeter=" << a.perimeter();
|
||||
}
|
||||
@ -94,18 +82,15 @@ inline std::ostream& operator<<(std::ostream& os, const circular<RealType>& a) {
|
||||
}
|
||||
|
||||
template <typename RealType>
|
||||
inline std::ostream& operator<<(std::ostream& os, const variable<RealType>& a) {
|
||||
inline std::ostream& operator<<(std::ostream& os,
|
||||
const variable<RealType>& a) {
|
||||
os << "variable(" << a[0].lower();
|
||||
for (int i = 1; i <= a.size(); ++i) {
|
||||
os << ", " << a[i].lower();
|
||||
}
|
||||
for (int i = 1; i <= a.size(); ++i) { os << ", " << a[i].lower(); }
|
||||
if (!a.label().empty()) {
|
||||
os << ", label=";
|
||||
::boost::histogram::detail::escape(os, a.label());
|
||||
}
|
||||
if (!a.uoflow()) {
|
||||
os << ", uoflow=False";
|
||||
}
|
||||
if (!a.uoflow()) { os << ", uoflow=False"; }
|
||||
os << ")";
|
||||
return os;
|
||||
}
|
||||
@ -117,9 +102,7 @@ inline std::ostream& operator<<(std::ostream& os, const integer<IntType>& a) {
|
||||
os << ", label=";
|
||||
::boost::histogram::detail::escape(os, a.label());
|
||||
}
|
||||
if (!a.uoflow()) {
|
||||
os << ", uoflow=False";
|
||||
}
|
||||
if (!a.uoflow()) { os << ", uoflow=False"; }
|
||||
os << ")";
|
||||
return os;
|
||||
}
|
||||
|
@ -127,11 +127,8 @@ class regular : public base,
|
||||
* \param uoflow whether to add under-/overflow bins.
|
||||
* \param trans arguments passed to the transform.
|
||||
*/
|
||||
regular(unsigned n,
|
||||
value_type lower,
|
||||
value_type upper,
|
||||
string_view label = {},
|
||||
axis::uoflow uo = axis::uoflow::on,
|
||||
regular(unsigned n, value_type lower, value_type upper,
|
||||
string_view label = {}, axis::uoflow uo = axis::uoflow::on,
|
||||
Transform trans = Transform())
|
||||
: base(n, label, uo),
|
||||
Transform(trans),
|
||||
@ -177,8 +174,8 @@ class regular : public base,
|
||||
bin_type operator[](int idx) const noexcept { return bin_type(idx, *this); }
|
||||
|
||||
bool operator==(const regular& o) const noexcept {
|
||||
return base::operator==(o) && Transform::operator==(o) && min_ == o.min_ &&
|
||||
delta_ == o.delta_;
|
||||
return base::operator==(o) && Transform::operator==(o) &&
|
||||
min_ == o.min_ && delta_ == o.delta_;
|
||||
}
|
||||
|
||||
/// Access properties of the transform.
|
||||
@ -213,8 +210,7 @@ class circular : public base, public iterator_mixin<circular<RealType>> {
|
||||
* \param perimeter range after which value wraps around.
|
||||
* \param label description of the axis.
|
||||
*/
|
||||
explicit circular(unsigned n,
|
||||
value_type phase = 0.0,
|
||||
explicit circular(unsigned n, value_type phase = 0.0,
|
||||
value_type perimeter = boost::histogram::detail::two_pi,
|
||||
string_view label = {})
|
||||
: base(n, label, axis::uoflow::off),
|
||||
@ -230,7 +226,8 @@ class circular : public base, public iterator_mixin<circular<RealType>> {
|
||||
/// Returns the bin index for the passed argument.
|
||||
int index(value_type x) const noexcept {
|
||||
const value_type z = (x - phase_) / perimeter_;
|
||||
const int i = static_cast<int>(std::floor(z * base::size())) % base::size();
|
||||
const int i =
|
||||
static_cast<int>(std::floor(z * base::size())) % base::size();
|
||||
return i + (i < 0) * base::size();
|
||||
}
|
||||
|
||||
@ -275,8 +272,7 @@ class variable : public base, public iterator_mixin<variable<RealType>> {
|
||||
* \param label description of the axis.
|
||||
* \param uoflow whether to add under-/overflow bins.
|
||||
*/
|
||||
variable(std::initializer_list<value_type> x,
|
||||
string_view label = {},
|
||||
variable(std::initializer_list<value_type> x, string_view label = {},
|
||||
axis::uoflow uo = axis::uoflow::on)
|
||||
: base(x.size() - 1, label, uo), x_(new value_type[x.size()]) {
|
||||
if (x.size() >= 2) {
|
||||
@ -288,9 +284,7 @@ class variable : public base, public iterator_mixin<variable<RealType>> {
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
variable(Iterator begin,
|
||||
Iterator end,
|
||||
string_view label = {},
|
||||
variable(Iterator begin, Iterator end, string_view label = {},
|
||||
axis::uoflow uo = axis::uoflow::on)
|
||||
: base(std::distance(begin, end) - 1, label, uo),
|
||||
x_(new value_type[std::distance(begin, end)]) {
|
||||
@ -299,7 +293,8 @@ class variable : public base, public iterator_mixin<variable<RealType>> {
|
||||
}
|
||||
|
||||
variable() = default;
|
||||
variable(const variable& o) : base(o), x_(new value_type[base::size() + 1]) {
|
||||
variable(const variable& o)
|
||||
: base(o), x_(new value_type[base::size() + 1]) {
|
||||
std::copy(o.x_.get(), o.x_.get() + base::size() + 1, x_.get());
|
||||
}
|
||||
variable& operator=(const variable& o) {
|
||||
@ -321,9 +316,7 @@ class variable : public base, public iterator_mixin<variable<RealType>> {
|
||||
|
||||
/// Returns the starting edge of the bin.
|
||||
value_type lower(int i) const noexcept {
|
||||
if (i < 0) {
|
||||
return -std::numeric_limits<value_type>::infinity();
|
||||
}
|
||||
if (i < 0) { return -std::numeric_limits<value_type>::infinity(); }
|
||||
if (i > base::size()) {
|
||||
return std::numeric_limits<value_type>::infinity();
|
||||
}
|
||||
@ -333,9 +326,7 @@ class variable : public base, public iterator_mixin<variable<RealType>> {
|
||||
bin_type operator[](int idx) const noexcept { return bin_type(idx, *this); }
|
||||
|
||||
bool operator==(const variable& o) const noexcept {
|
||||
if (!base::operator==(o)) {
|
||||
return false;
|
||||
}
|
||||
if (!base::operator==(o)) { return false; }
|
||||
return std::equal(x_.get(), x_.get() + base::size() + 1, o.x_.get());
|
||||
}
|
||||
|
||||
@ -365,9 +356,7 @@ class integer : public base, public iterator_mixin<integer<IntType>> {
|
||||
* \param label description of the axis.
|
||||
* \param uoflow whether to add under-/overflow bins.
|
||||
*/
|
||||
integer(value_type lower,
|
||||
value_type upper,
|
||||
string_view label = {},
|
||||
integer(value_type lower, value_type upper, string_view label = {},
|
||||
axis::uoflow uo = axis::uoflow::on)
|
||||
: base(upper - lower, label, uo), min_(lower) {
|
||||
if (!(lower < upper)) {
|
||||
@ -389,12 +378,8 @@ class integer : public base, public iterator_mixin<integer<IntType>> {
|
||||
|
||||
/// Returns lower edge of the integral bin.
|
||||
value_type lower(int i) const noexcept {
|
||||
if (i < 0) {
|
||||
return -std::numeric_limits<value_type>::max();
|
||||
}
|
||||
if (i > base::size()) {
|
||||
return std::numeric_limits<value_type>::max();
|
||||
}
|
||||
if (i < 0) { return -std::numeric_limits<value_type>::max(); }
|
||||
if (i > base::size()) { return std::numeric_limits<value_type>::max(); }
|
||||
return min_ + i;
|
||||
}
|
||||
|
||||
@ -446,10 +431,8 @@ class category : public base, public iterator_mixin<category<T>> {
|
||||
category(std::initializer_list<value_type> seq, string_view label = {})
|
||||
: base(seq.size(), label, axis::uoflow::off), map_(new map_type()) {
|
||||
int index = 0;
|
||||
for (const auto& x : seq)
|
||||
map_->insert({x, index++});
|
||||
if (index == 0)
|
||||
throw std::invalid_argument("sequence is empty");
|
||||
for (const auto& x : seq) map_->insert({x, index++});
|
||||
if (index == 0) throw std::invalid_argument("sequence is empty");
|
||||
}
|
||||
|
||||
template <typename Iterator,
|
||||
@ -458,17 +441,14 @@ class category : public base, public iterator_mixin<category<T>> {
|
||||
: base(std::distance(begin, end), label, axis::uoflow::off),
|
||||
map_(new map_type()) {
|
||||
int index = 0;
|
||||
while (begin != end)
|
||||
map_->insert({*begin++, index++});
|
||||
if (index == 0)
|
||||
throw std::invalid_argument("iterator range is empty");
|
||||
while (begin != end) map_->insert({*begin++, index++});
|
||||
if (index == 0) throw std::invalid_argument("iterator range is empty");
|
||||
}
|
||||
|
||||
/// Returns the bin index for the passed argument.
|
||||
int index(const value_type& x) const noexcept {
|
||||
auto it = map_->left.find(x);
|
||||
if (it == map_->left.end())
|
||||
return base::size();
|
||||
if (it == map_->left.end()) return base::size();
|
||||
return it->second;
|
||||
}
|
||||
|
||||
|
@ -59,15 +59,13 @@ struct axes_assign_vecvar_tuple {
|
||||
};
|
||||
|
||||
template <typename... Ts>
|
||||
inline bool axes_equal_impl(mp11::mp_true,
|
||||
const std::tuple<Ts...>& t,
|
||||
inline bool axes_equal_impl(mp11::mp_true, const std::tuple<Ts...>& t,
|
||||
const std::tuple<Ts...>& u) {
|
||||
return t == u;
|
||||
}
|
||||
|
||||
template <typename... Ts, typename... Us>
|
||||
inline bool axes_equal_impl(mp11::mp_false,
|
||||
const std::tuple<Ts...>&,
|
||||
inline bool axes_equal_impl(mp11::mp_false, const std::tuple<Ts...>&,
|
||||
const std::tuple<Us...>&) {
|
||||
return false;
|
||||
}
|
||||
@ -75,14 +73,16 @@ inline bool axes_equal_impl(mp11::mp_false,
|
||||
} // namespace
|
||||
|
||||
template <typename... Ts, typename... Us>
|
||||
inline bool axes_equal(const std::tuple<Ts...>& t, const std::tuple<Us...>& u) {
|
||||
inline bool axes_equal(const std::tuple<Ts...>& t,
|
||||
const std::tuple<Us...>& u) {
|
||||
return axes_equal_impl(
|
||||
mp11::mp_same<mp11::mp_list<Ts...>, mp11::mp_list<Us...>>(), t, u);
|
||||
}
|
||||
|
||||
template <typename... Ts, typename... Us>
|
||||
inline void axes_assign(std::tuple<Ts...>& t, const std::tuple<Us...>& u) {
|
||||
static_assert(std::is_same<mp11::mp_list<Ts...>, mp11::mp_list<Us...>>::value,
|
||||
static_assert(
|
||||
std::is_same<mp11::mp_list<Ts...>, mp11::mp_list<Us...>>::value,
|
||||
"cannot assign incompatible axes");
|
||||
t = u;
|
||||
}
|
||||
@ -90,12 +90,11 @@ inline void axes_assign(std::tuple<Ts...>& t, const std::tuple<Us...>& u) {
|
||||
template <typename... Ts, typename... Us>
|
||||
inline bool axes_equal(const std::tuple<Ts...>& t,
|
||||
const std::vector<axis::any<Us...>>& u) {
|
||||
if (sizeof...(Ts) != u.size())
|
||||
return false;
|
||||
if (sizeof...(Ts) != u.size()) return false;
|
||||
bool equal = true;
|
||||
auto fn =
|
||||
axes_equal_tuple_vecvar<std::tuple<Ts...>, std::vector<axis::any<Us...>>>(
|
||||
equal, t, u);
|
||||
axes_equal_tuple_vecvar<std::tuple<Ts...>,
|
||||
std::vector<axis::any<Us...>>>(equal, t, u);
|
||||
mp11::mp_for_each<mp11::mp_iota_c<sizeof...(Ts)>>(fn);
|
||||
return equal;
|
||||
}
|
||||
@ -126,11 +125,9 @@ inline void axes_assign(std::vector<axis::any<Ts...>>& t,
|
||||
template <typename... Ts, typename... Us>
|
||||
inline bool axes_equal(const std::vector<axis::any<Ts...>>& t,
|
||||
const std::vector<axis::any<Us...>>& u) {
|
||||
if (t.size() != u.size())
|
||||
return false;
|
||||
if (t.size() != u.size()) return false;
|
||||
for (std::size_t i = 0; i < t.size(); ++i) {
|
||||
if (t[i] != u[i])
|
||||
return false;
|
||||
if (t[i] != u[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -138,9 +135,7 @@ inline bool axes_equal(const std::vector<axis::any<Ts...>>& t,
|
||||
template <typename... Ts, typename... Us>
|
||||
inline void axes_assign(std::vector<axis::any<Ts...>>& t,
|
||||
const std::vector<axis::any<Us...>>& u) {
|
||||
for (std::size_t i = 0; i < t.size(); ++i) {
|
||||
t[i] = u[i];
|
||||
}
|
||||
for (std::size_t i = 0; i < t.size(); ++i) { t[i] = u[i]; }
|
||||
}
|
||||
|
||||
struct field_count_visitor : public static_visitor<void> {
|
||||
|
@ -7,8 +7,8 @@
|
||||
#ifndef _BOOST_HISTOGRAM_DETAIL_INDEX_CACHE_HPP_
|
||||
#define _BOOST_HISTOGRAM_DETAIL_INDEX_CACHE_HPP_
|
||||
|
||||
#include <memory>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
|
||||
namespace boost {
|
||||
namespace histogram {
|
||||
@ -62,8 +62,7 @@ struct index_cache {
|
||||
}
|
||||
|
||||
void operator()(std::size_t idx) {
|
||||
if (idx == idx_)
|
||||
return;
|
||||
if (idx == idx_) return;
|
||||
idx_ = idx;
|
||||
auto dim_ptr = dims_.get();
|
||||
auto dim = dim_;
|
||||
|
@ -32,8 +32,9 @@ struct index_mapper {
|
||||
s1 *= ni;
|
||||
++bi;
|
||||
}
|
||||
std::sort(dims.begin(), dims.end(),
|
||||
[](const dim& a, const dim& b) { return a.stride1 > b.stride1; });
|
||||
std::sort(dims.begin(), dims.end(), [](const dim& a, const dim& b) {
|
||||
return a.stride1 > b.stride1;
|
||||
});
|
||||
nfirst = s1;
|
||||
}
|
||||
|
||||
|
@ -55,14 +55,12 @@ struct no_container_tag {};
|
||||
|
||||
template <typename T>
|
||||
using classify_container = typename std::conditional<
|
||||
is_static_container<T>::value,
|
||||
static_container_tag,
|
||||
is_static_container<T>::value, static_container_tag,
|
||||
typename std::conditional<is_dynamic_container<T>::value,
|
||||
dynamic_container_tag,
|
||||
no_container_tag>::type>::type;
|
||||
|
||||
template <typename T,
|
||||
typename = decltype(std::declval<T&>().size(),
|
||||
template <typename T, typename = decltype(std::declval<T&>().size(),
|
||||
std::declval<T&>().increase(0),
|
||||
std::declval<T&>()[0])>
|
||||
struct requires_storage {};
|
||||
@ -72,10 +70,9 @@ template <typename T,
|
||||
struct requires_iterator {};
|
||||
|
||||
template <typename T>
|
||||
using requires_axis = decltype(std::declval<T&>().size(),
|
||||
std::declval<T&>().shape(),
|
||||
std::declval<T&>().uoflow(),
|
||||
std::declval<T&>().label(),
|
||||
using requires_axis =
|
||||
decltype(std::declval<T&>().size(), std::declval<T&>().shape(),
|
||||
std::declval<T&>().uoflow(), std::declval<T&>().label(),
|
||||
std::declval<T&>()[0]);
|
||||
|
||||
namespace {
|
||||
@ -108,13 +105,11 @@ using mp_at_c = mp11::mp_at_c<rm_cv_ref<T>, D>;
|
||||
|
||||
template <typename T1, typename T2>
|
||||
using copy_qualifiers = mp11::mp_if<
|
||||
std::is_rvalue_reference<T1>,
|
||||
T2&&,
|
||||
std::is_rvalue_reference<T1>, T2&&,
|
||||
mp11::mp_if<
|
||||
std::is_lvalue_reference<T1>,
|
||||
mp11::mp_if<std::is_const<typename std::remove_reference<T1>::type>,
|
||||
const T2&,
|
||||
T2&>,
|
||||
const T2&, T2&>,
|
||||
mp11::mp_if<std::is_const<T1>, const T2, T2>>>;
|
||||
|
||||
template <typename S, typename L>
|
||||
|
@ -41,11 +41,8 @@ inline void escape(std::ostream& os, const string_view s) {
|
||||
|
||||
// the following is highly optimized code that runs in a hot loop;
|
||||
// please measure the performance impact of changes
|
||||
inline void lin(std::size_t& out,
|
||||
std::size_t& stride,
|
||||
const int axis_size,
|
||||
const int axis_shape,
|
||||
int j) noexcept {
|
||||
inline void lin(std::size_t& out, std::size_t& stride, const int axis_size,
|
||||
const int axis_shape, int j) noexcept {
|
||||
BOOST_ASSERT_MSG(stride == 0 || (-1 <= j && j <= axis_size),
|
||||
"index must be in bounds for this algorithm");
|
||||
j += (j < 0) * (axis_size + 2); // wrap around if j < 0
|
||||
@ -53,7 +50,8 @@ inline void lin(std::size_t& out,
|
||||
#ifndef _MSC_VER
|
||||
#pragma GCC diagnostic ignored "-Wstrict-overflow"
|
||||
#endif
|
||||
stride *= (j < axis_shape) * axis_shape; // stride == 0 indicates out-of-range
|
||||
stride *=
|
||||
(j < axis_shape) * axis_shape; // stride == 0 indicates out-of-range
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -84,8 +82,7 @@ inline void fill_storage(S& s, std::size_t idx) {
|
||||
template <typename S>
|
||||
inline auto storage_get(const S& s, std::size_t idx, bool error) ->
|
||||
typename S::const_reference {
|
||||
if (error)
|
||||
throw std::out_of_range("bin index out of range");
|
||||
if (error) throw std::out_of_range("bin index out of range");
|
||||
return s[idx];
|
||||
}
|
||||
|
||||
|
@ -69,8 +69,7 @@ class histogram<dynamic_tag, Axes, Storage> {
|
||||
histogram& operator=(const histogram&) = default;
|
||||
histogram& operator=(histogram&&) = default;
|
||||
|
||||
template <typename Axis0,
|
||||
typename... Axis,
|
||||
template <typename Axis0, typename... Axis,
|
||||
typename = detail::requires_axis<Axis0>>
|
||||
explicit histogram(Axis0&& axis0, Axis&&... axis)
|
||||
: axes_({any_axis_type(std::forward<Axis0>(axis0)),
|
||||
@ -161,9 +160,7 @@ class histogram<dynamic_tag, Axes, Storage> {
|
||||
"(did you use weight() in the wrong place?)");
|
||||
std::size_t idx = 0, stride = 1;
|
||||
xlin<0>(idx, stride, std::forward<Ts>(ts)...);
|
||||
if (stride) {
|
||||
detail::fill_storage(storage_, idx);
|
||||
}
|
||||
if (stride) { detail::fill_storage(storage_, idx); }
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -183,9 +180,7 @@ class histogram<dynamic_tag, Axes, Storage> {
|
||||
"fill arguments does not match histogram dimension");
|
||||
std::size_t idx = 0, stride = 1;
|
||||
xlin<0>(idx, stride, std::forward<Ts>(ts)...);
|
||||
if (stride) {
|
||||
detail::fill_storage(storage_, idx, std::move(w));
|
||||
}
|
||||
if (stride) { detail::fill_storage(storage_, idx, std::move(w)); }
|
||||
}
|
||||
|
||||
template <typename W, typename T>
|
||||
@ -260,8 +255,7 @@ class histogram<dynamic_tag, Axes, Storage> {
|
||||
template <typename... Ts>
|
||||
histogram reduce_to(int n, Ts... ts) const {
|
||||
std::vector<bool> b(dim(), false);
|
||||
for (const auto& i : {n, int(ts)...})
|
||||
b[i] = true;
|
||||
for (const auto& i : {n, int(ts)...}) b[i] = true;
|
||||
return reduce_impl(b);
|
||||
}
|
||||
|
||||
@ -269,8 +263,7 @@ class histogram<dynamic_tag, Axes, Storage> {
|
||||
template <typename Iterator, typename = detail::requires_iterator<Iterator>>
|
||||
histogram reduce_to(Iterator begin, Iterator end) const {
|
||||
std::vector<bool> b(dim(), false);
|
||||
for (; begin != end; ++begin)
|
||||
b[*begin] = true;
|
||||
for (; begin != end; ++begin) b[*begin] = true;
|
||||
return reduce_impl(b);
|
||||
}
|
||||
|
||||
@ -402,9 +395,7 @@ class histogram<dynamic_tag, Axes, Storage> {
|
||||
noexcept {}
|
||||
|
||||
template <int N, typename T>
|
||||
void xlin_get(mp11::mp_int<N>,
|
||||
std::size_t& idx,
|
||||
std::size_t& stride,
|
||||
void xlin_get(mp11::mp_int<N>, std::size_t& idx, std::size_t& stride,
|
||||
T&& t) const {
|
||||
constexpr unsigned D = detail::mp_size<T>::value - N;
|
||||
apply_visitor(
|
||||
@ -434,7 +425,8 @@ class histogram<dynamic_tag, Axes, Storage> {
|
||||
const auto a_size = a.size();
|
||||
const auto a_shape = a.shape();
|
||||
const auto j = detail::indirect_int_cast(*iter++);
|
||||
stride *= (-1 <= j && j <= a_size); // set stride to zero, if j is invalid
|
||||
stride *=
|
||||
(-1 <= j && j <= a_size); // set stride to zero, if j is invalid
|
||||
detail::lin(idx, stride, a_size, a_shape, j);
|
||||
}
|
||||
}
|
||||
@ -444,9 +436,7 @@ class histogram<dynamic_tag, Axes, Storage> {
|
||||
noexcept {}
|
||||
|
||||
template <long unsigned int N, typename T>
|
||||
void lin_get(mp11::mp_size_t<N>,
|
||||
std::size_t& idx,
|
||||
std::size_t& stride,
|
||||
void lin_get(mp11::mp_size_t<N>, std::size_t& idx, std::size_t& stride,
|
||||
const T& t) const noexcept {
|
||||
constexpr long unsigned int D = detail::mp_size<T>::value - N;
|
||||
const auto& a = axes_[D];
|
||||
@ -464,17 +454,14 @@ class histogram<dynamic_tag, Axes, Storage> {
|
||||
auto axes_iter = axes_.begin();
|
||||
auto n_iter = n.begin();
|
||||
for (const auto& bi : b) {
|
||||
if (bi)
|
||||
axes.emplace_back(*axes_iter);
|
||||
if (bi) axes.emplace_back(*axes_iter);
|
||||
*n_iter = axes_iter->shape();
|
||||
++axes_iter;
|
||||
++n_iter;
|
||||
}
|
||||
histogram h(std::move(axes));
|
||||
detail::index_mapper m(n, b);
|
||||
do {
|
||||
h.storage_.add(m.second, storage_[m.first]);
|
||||
} while (m.next());
|
||||
do { h.storage_.add(m.second, storage_[m.first]); } while (m.next());
|
||||
return h;
|
||||
}
|
||||
|
||||
@ -499,25 +486,22 @@ make_dynamic_histogram(Axis&&... axis) {
|
||||
|
||||
template <typename Storage, typename... Axis>
|
||||
dynamic_histogram<
|
||||
mp11::mp_set_push_back<axis::types, detail::rm_cv_ref<Axis>...>,
|
||||
Storage>
|
||||
mp11::mp_set_push_back<axis::types, detail::rm_cv_ref<Axis>...>, Storage>
|
||||
make_dynamic_histogram_with(Axis&&... axis) {
|
||||
return dynamic_histogram<
|
||||
mp11::mp_set_push_back<axis::types, detail::rm_cv_ref<Axis>...>, Storage>(
|
||||
std::forward<Axis>(axis)...);
|
||||
mp11::mp_set_push_back<axis::types, detail::rm_cv_ref<Axis>...>,
|
||||
Storage>(std::forward<Axis>(axis)...);
|
||||
}
|
||||
|
||||
template <typename Iterator, typename = detail::requires_iterator<Iterator>>
|
||||
dynamic_histogram<
|
||||
detail::mp_set_union<axis::types, typename Iterator::value_type::types>>
|
||||
make_dynamic_histogram(Iterator begin, Iterator end) {
|
||||
return dynamic_histogram<
|
||||
detail::mp_set_union<axis::types, typename Iterator::value_type::types>>(
|
||||
begin, end);
|
||||
return dynamic_histogram<detail::mp_set_union<
|
||||
axis::types, typename Iterator::value_type::types>>(begin, end);
|
||||
}
|
||||
|
||||
template <typename Storage,
|
||||
typename Iterator,
|
||||
template <typename Storage, typename Iterator,
|
||||
typename = detail::requires_iterator<Iterator>>
|
||||
dynamic_histogram<
|
||||
detail::mp_set_union<axis::types, typename Iterator::value_type::types>,
|
||||
|
@ -27,7 +27,8 @@ struct sqrt;
|
||||
struct pow;
|
||||
} // namespace transform
|
||||
|
||||
template <typename RealType = double, typename Transform = transform::identity>
|
||||
template <typename RealType = double,
|
||||
typename Transform = transform::identity>
|
||||
class regular;
|
||||
template <typename RealType = double>
|
||||
class circular;
|
||||
@ -42,10 +43,8 @@ using types = mp11::mp_list<axis::regular<double, axis::transform::identity>,
|
||||
axis::regular<double, axis::transform::log>,
|
||||
axis::regular<double, axis::transform::sqrt>,
|
||||
axis::regular<double, axis::transform::pow>,
|
||||
axis::circular<double>,
|
||||
axis::variable<double>,
|
||||
axis::integer<int>,
|
||||
axis::category<int>,
|
||||
axis::circular<double>, axis::variable<double>,
|
||||
axis::integer<int>, axis::category<int>,
|
||||
axis::category<std::string>>;
|
||||
|
||||
template <typename... Ts>
|
||||
|
@ -21,10 +21,9 @@ namespace histogram {
|
||||
|
||||
template <typename Histogram>
|
||||
class iterator_over
|
||||
: public iterator_facade<iterator_over<Histogram>,
|
||||
typename Histogram::element_type,
|
||||
random_access_traversal_tag,
|
||||
typename Histogram::const_reference> {
|
||||
: public iterator_facade<
|
||||
iterator_over<Histogram>, typename Histogram::element_type,
|
||||
random_access_traversal_tag, typename Histogram::const_reference> {
|
||||
public:
|
||||
iterator_over(const Histogram& h, std::size_t idx)
|
||||
: histogram_(h), idx_(idx) {}
|
||||
|
@ -34,7 +34,8 @@ inline std::ostream& operator<<(std::ostream& os, const histogram<Ts...>& h) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::ostream& operator<<(std::ostream& os, const weight_counter<T>& x) {
|
||||
inline std::ostream& operator<<(std::ostream& os,
|
||||
const weight_counter<T>& x) {
|
||||
os << "weight_counter(" << x.value() << ", " << x.variance() << ")";
|
||||
return os;
|
||||
}
|
||||
|
@ -41,14 +41,14 @@ struct serialize_helper {
|
||||
|
||||
template <typename RealType>
|
||||
template <class Archive>
|
||||
void weight_counter<RealType>::serialize(Archive& ar, unsigned /* version */) {
|
||||
void weight_counter<RealType>::serialize(Archive& ar,
|
||||
unsigned /* version */) {
|
||||
ar& w;
|
||||
ar& w2;
|
||||
}
|
||||
|
||||
template <class Archive, typename Container>
|
||||
void serialize(Archive& ar,
|
||||
array_storage<Container>& store,
|
||||
void serialize(Archive& ar, array_storage<Container>& store,
|
||||
unsigned /* version */) {
|
||||
ar& store.array_;
|
||||
}
|
||||
|
@ -52,8 +52,7 @@ class histogram<static_tag, Axes, Storage> {
|
||||
histogram& operator=(const histogram& rhs) = default;
|
||||
histogram& operator=(histogram&& rhs) = default;
|
||||
|
||||
template <typename Axis0,
|
||||
typename... Axis,
|
||||
template <typename Axis0, typename... Axis,
|
||||
typename = detail::requires_axis<Axis0>>
|
||||
explicit histogram(Axis0&& axis0, Axis&&... axis)
|
||||
: axes_(std::forward<Axis0>(axis0), std::forward<Axis>(axis)...) {
|
||||
@ -154,8 +153,7 @@ class histogram<static_tag, Axes, Storage> {
|
||||
"fill arguments do not match histogram dimension");
|
||||
std::size_t idx = 0, stride = 1;
|
||||
xlin<0>(idx, stride, ts...);
|
||||
if (stride)
|
||||
detail::fill_storage(storage_, idx);
|
||||
if (stride) detail::fill_storage(storage_, idx);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -172,8 +170,7 @@ class histogram<static_tag, Axes, Storage> {
|
||||
// case with one argument is ambiguous, is specialized below
|
||||
std::size_t idx = 0, stride = 1;
|
||||
xlin<0>(idx, stride, ts...);
|
||||
if (stride)
|
||||
detail::fill_storage(storage_, idx, std::move(w));
|
||||
if (stride) detail::fill_storage(storage_, idx, std::move(w));
|
||||
}
|
||||
|
||||
// TODO: remove as obsolete
|
||||
@ -253,7 +250,8 @@ class histogram<static_tag, Axes, Storage> {
|
||||
auto reduce_to(mp11::mp_int<N>, Ns...) const
|
||||
-> static_histogram<detail::selection<Axes, mp11::mp_int<N>, Ns...>,
|
||||
Storage> {
|
||||
using HR = static_histogram<detail::selection<Axes, mp11::mp_int<N>, Ns...>,
|
||||
using HR =
|
||||
static_histogram<detail::selection<Axes, mp11::mp_int<N>, Ns...>,
|
||||
Storage>;
|
||||
auto hr =
|
||||
HR(detail::make_sub_tuple<axes_type, mp11::mp_int<N>, Ns...>(axes_));
|
||||
@ -264,7 +262,9 @@ class histogram<static_tag, Axes, Storage> {
|
||||
|
||||
const_iterator begin() const noexcept { return const_iterator(*this, 0); }
|
||||
|
||||
const_iterator end() const noexcept { return const_iterator(*this, size()); }
|
||||
const_iterator end() const noexcept {
|
||||
return const_iterator(*this, size());
|
||||
}
|
||||
|
||||
private:
|
||||
axes_type axes_;
|
||||
@ -350,13 +350,11 @@ class histogram<static_tag, Axes, Storage> {
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
void xlin_iter(mp11::mp_size_t<0>, std::size_t&, std::size_t&, Iterator) const
|
||||
noexcept {}
|
||||
void xlin_iter(mp11::mp_size_t<0>, std::size_t&, std::size_t&,
|
||||
Iterator) const noexcept {}
|
||||
|
||||
template <long unsigned int N, typename Iterator>
|
||||
void xlin_iter(mp11::mp_size_t<N>,
|
||||
std::size_t& idx,
|
||||
std::size_t& stride,
|
||||
void xlin_iter(mp11::mp_size_t<N>, std::size_t& idx, std::size_t& stride,
|
||||
Iterator iter) const {
|
||||
constexpr unsigned D = axes_size::value - N;
|
||||
const auto a_size = std::get<D>(axes_).size();
|
||||
@ -380,13 +378,11 @@ class histogram<static_tag, Axes, Storage> {
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
void lin_iter(mp11::mp_size_t<0>, std::size_t&, std::size_t&, Iterator) const
|
||||
noexcept {}
|
||||
void lin_iter(mp11::mp_size_t<0>, std::size_t&, std::size_t&,
|
||||
Iterator) const noexcept {}
|
||||
|
||||
template <long unsigned int N, typename Iterator>
|
||||
void lin_iter(mp11::mp_size_t<N>,
|
||||
std::size_t& idx,
|
||||
std::size_t& stride,
|
||||
void lin_iter(mp11::mp_size_t<N>, std::size_t& idx, std::size_t& stride,
|
||||
Iterator iter) const noexcept {
|
||||
constexpr unsigned D = axes_size::value - N;
|
||||
const auto a_size = std::get<D>(axes_).size();
|
||||
@ -402,9 +398,7 @@ class histogram<static_tag, Axes, Storage> {
|
||||
noexcept {}
|
||||
|
||||
template <long unsigned int N, typename T>
|
||||
void xlin_get(mp11::mp_size_t<N>,
|
||||
std::size_t& idx,
|
||||
std::size_t& stride,
|
||||
void xlin_get(mp11::mp_size_t<N>, std::size_t& idx, std::size_t& stride,
|
||||
T&& t) const {
|
||||
constexpr unsigned D = detail::mp_size<T>::value - N;
|
||||
const auto a_size = std::get<D>(axes_).size();
|
||||
@ -419,9 +413,7 @@ class histogram<static_tag, Axes, Storage> {
|
||||
noexcept {}
|
||||
|
||||
template <long unsigned int N, typename T>
|
||||
void lin_get(mp11::mp_size_t<N>,
|
||||
std::size_t& idx,
|
||||
std::size_t& stride,
|
||||
void lin_get(mp11::mp_size_t<N>, std::size_t& idx, std::size_t& stride,
|
||||
T&& t) const noexcept {
|
||||
constexpr unsigned D = detail::mp_size<T>::value - N;
|
||||
const auto a_size = std::get<D>(axes_).size();
|
||||
@ -437,9 +429,7 @@ class histogram<static_tag, Axes, Storage> {
|
||||
detail::shape_vector_visitor v(dim());
|
||||
for_each_axis(v);
|
||||
detail::index_mapper m(v.shapes, b);
|
||||
do {
|
||||
h.storage_.add(m.second, storage_[m.first]);
|
||||
} while (m.next());
|
||||
do { h.storage_.add(m.second, storage_[m.first]); } while (m.next());
|
||||
}
|
||||
|
||||
template <typename T, typename A, typename S>
|
||||
|
@ -128,13 +128,9 @@ class array<void> : public array_base {
|
||||
using array_base::array_base;
|
||||
};
|
||||
|
||||
using any_array = variant<array<void>,
|
||||
array<uint8_t>,
|
||||
array<uint16_t>,
|
||||
array<uint32_t>,
|
||||
array<uint64_t>,
|
||||
array<mp_int>,
|
||||
array<wcount>>;
|
||||
using any_array =
|
||||
variant<array<void>, array<uint8_t>, array<uint16_t>, array<uint32_t>,
|
||||
array<uint64_t>, array<mp_int>, array<wcount>>;
|
||||
|
||||
template <typename T>
|
||||
struct next_type;
|
||||
@ -159,8 +155,7 @@ using next = typename next_type<T>::type;
|
||||
|
||||
template <typename T>
|
||||
inline bool safe_increase(T& t) {
|
||||
if (t == std::numeric_limits<T>::max())
|
||||
return false;
|
||||
if (t == std::numeric_limits<T>::max()) return false;
|
||||
++t;
|
||||
return true;
|
||||
}
|
||||
@ -176,8 +171,7 @@ inline bool safe_assign(T& t, const U& u) {
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool safe_radd(T& t, const U& u) {
|
||||
if (static_cast<T>(std::numeric_limits<T>::max() - t) < u)
|
||||
return false;
|
||||
if (static_cast<T>(std::numeric_limits<T>::max() - t) < u) return false;
|
||||
t += static_cast<T>(u);
|
||||
return true;
|
||||
}
|
||||
@ -185,8 +179,7 @@ inline bool safe_radd(T& t, const U& u) {
|
||||
// float rounding is a mess, the equal sign is necessary here
|
||||
template <typename T>
|
||||
inline bool safe_radd(T& t, const double u) {
|
||||
if ((std::numeric_limits<T>::max() - t) <= u)
|
||||
return false;
|
||||
if ((std::numeric_limits<T>::max() - t) <= u) return false;
|
||||
t += u;
|
||||
return true;
|
||||
}
|
||||
@ -390,24 +383,22 @@ struct rmul_visitor : public static_visitor<void> {
|
||||
}
|
||||
void operator()(array<void>&) const {}
|
||||
void operator()(array<wcount>& lhs) const {
|
||||
for (std::size_t i = 0; i != lhs.size; ++i)
|
||||
lhs[i] *= x;
|
||||
for (std::size_t i = 0; i != lhs.size; ++i) lhs[i] *= x;
|
||||
}
|
||||
};
|
||||
|
||||
struct bicmp_visitor : public static_visitor<bool> {
|
||||
template <typename T, typename U>
|
||||
bool operator()(const array<T>& b1, const array<U>& b2) const {
|
||||
if (b1.size != b2.size)
|
||||
return false;
|
||||
if (b1.size != b2.size) return false;
|
||||
return std::equal(b1.begin(), b1.end(), b2.begin());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator()(const array<T>& b1, const array<void>& b2) const {
|
||||
if (b1.size != b2.size)
|
||||
return false;
|
||||
return std::all_of(b1.begin(), b1.end(), [](const T& t) { return t == 0; });
|
||||
if (b1.size != b2.size) return false;
|
||||
return std::all_of(b1.begin(), b1.end(),
|
||||
[](const T& t) { return t == 0; });
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -429,7 +420,8 @@ class adaptive_storage {
|
||||
using element_type = detail::wcount;
|
||||
using const_reference = element_type;
|
||||
|
||||
explicit adaptive_storage(std::size_t s) : buffer_(detail::array<void>(s)) {}
|
||||
explicit adaptive_storage(std::size_t s)
|
||||
: buffer_(detail::array<void>(s)) {}
|
||||
|
||||
adaptive_storage() = default;
|
||||
adaptive_storage(const adaptive_storage&) = default;
|
||||
@ -450,9 +442,7 @@ class adaptive_storage {
|
||||
adaptive_storage& operator=(const RHS& rhs) {
|
||||
// no check for self-assign needed, default operator above is better match
|
||||
const auto n = rhs.size();
|
||||
if (size() != n) {
|
||||
buffer_ = detail::array<void>(n);
|
||||
}
|
||||
if (size() != n) { buffer_ = detail::array<void>(n); }
|
||||
using T = typename RHS::element_type;
|
||||
for (std::size_t i = 0; i < n; ++i) {
|
||||
apply_visitor(detail::assign_visitor<T>(buffer_, i, rhs[i]), buffer_);
|
||||
@ -477,7 +467,8 @@ class adaptive_storage {
|
||||
apply_visitor(detail::radd_visitor<double>(buffer_, i, x.value()),
|
||||
buffer_);
|
||||
} else {
|
||||
apply_visitor(detail::radd_visitor<element_type>(buffer_, i, x), buffer_);
|
||||
apply_visitor(detail::radd_visitor<element_type>(buffer_, i, x),
|
||||
buffer_);
|
||||
}
|
||||
}
|
||||
|
||||
@ -517,8 +508,8 @@ class adaptive_storage {
|
||||
template <typename RHS>
|
||||
adaptive_storage& operator+=(const RHS& rhs) {
|
||||
for (std::size_t i = 0, n = size(); i < n; ++i)
|
||||
apply_visitor(
|
||||
detail::radd_visitor<typename RHS::element_type>(buffer_, i, rhs[i]),
|
||||
apply_visitor(detail::radd_visitor<typename RHS::element_type>(
|
||||
buffer_, i, rhs[i]),
|
||||
buffer_);
|
||||
return *this;
|
||||
}
|
||||
|
@ -81,26 +81,25 @@ class array_storage {
|
||||
array_[i] += x;
|
||||
}
|
||||
|
||||
const_reference operator[](std::size_t i) const noexcept { return array_[i]; }
|
||||
const_reference operator[](std::size_t i) const noexcept {
|
||||
return array_[i];
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
bool operator==(const array_storage<U>& rhs) const noexcept {
|
||||
if (size_ != rhs.size_)
|
||||
return false;
|
||||
if (size_ != rhs.size_) return false;
|
||||
return std::equal(array_.get(), array_.get() + size_, rhs.array_.get());
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
array_storage& operator+=(const S& rhs) noexcept {
|
||||
for (std::size_t i = 0; i < size_; ++i)
|
||||
add(i, rhs[i]);
|
||||
for (std::size_t i = 0; i < size_; ++i) add(i, rhs[i]);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
array_storage& operator*=(const U& x) noexcept {
|
||||
for (std::size_t i = 0; i < size_; ++i)
|
||||
array_[i] *= x;
|
||||
for (std::size_t i = 0; i < size_; ++i) array_[i] *= x;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -12,22 +12,16 @@
|
||||
namespace boost {
|
||||
namespace histogram {
|
||||
|
||||
template <typename S1,
|
||||
typename S2,
|
||||
typename = detail::requires_storage<S1>,
|
||||
template <typename S1, typename S2, typename = detail::requires_storage<S1>,
|
||||
typename = detail::requires_storage<S2>>
|
||||
bool operator==(const S1& s1, const S2& s2) noexcept {
|
||||
if (s1.size() != s2.size())
|
||||
return false;
|
||||
if (s1.size() != s2.size()) return false;
|
||||
for (std::size_t i = 0, n = s1.size(); i < n; ++i)
|
||||
if (!(s1[i] == s2[i]))
|
||||
return false;
|
||||
if (!(s1[i] == s2[i])) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename S1,
|
||||
typename S2,
|
||||
typename = detail::requires_storage<S1>,
|
||||
template <typename S1, typename S2, typename = detail::requires_storage<S1>,
|
||||
typename = detail::requires_storage<S2>>
|
||||
bool operator!=(const S1& s1, const S2& s2) noexcept {
|
||||
return !operator==(s1, s2);
|
||||
|
@ -4,33 +4,34 @@
|
||||
// (See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "utility.hpp"
|
||||
#include <boost/histogram/histogram_fwd.hpp>
|
||||
#include <boost/histogram/axis/types.hpp>
|
||||
#include <boost/histogram/axis/any.hpp>
|
||||
#include <boost/histogram/axis/ostream_operators.hpp>
|
||||
#include <boost/histogram/axis/types.hpp>
|
||||
#include <boost/histogram/detail/utility.hpp>
|
||||
#include <boost/histogram/histogram_fwd.hpp>
|
||||
#include <boost/python.hpp>
|
||||
#include <boost/python/def_visitor.hpp>
|
||||
#include <boost/python/raw_function.hpp>
|
||||
#include <boost/python/make_constructor.hpp>
|
||||
#include <boost/python/raw_function.hpp>
|
||||
#include <boost/python/to_python_converter.hpp>
|
||||
#include "utility.hpp"
|
||||
#ifdef HAVE_NUMPY
|
||||
#include <boost/python/numpy.hpp>
|
||||
namespace np = boost::python::numpy;
|
||||
#endif
|
||||
#include <sstream>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace bp = boost::python;
|
||||
namespace bh = boost::histogram;
|
||||
namespace bha = boost::histogram::axis;
|
||||
|
||||
template <typename T> bp::str generic_repr(const T &t) {
|
||||
template <typename T>
|
||||
bp::str generic_repr(const T& t) {
|
||||
std::ostringstream os;
|
||||
os << t;
|
||||
return os.str().c_str();
|
||||
@ -56,19 +57,15 @@ generic_iterator make_generic_iterator(bp::object self) {
|
||||
}
|
||||
|
||||
template <typename Axis>
|
||||
struct axis_value_view_to_python
|
||||
{
|
||||
static PyObject* convert(const bha::value_view<Axis> &i)
|
||||
{
|
||||
struct axis_value_view_to_python {
|
||||
static PyObject* convert(const bha::value_view<Axis>& i) {
|
||||
return bp::incref(bp::object(i.value()).ptr());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Axis>
|
||||
struct axis_interval_view_to_python
|
||||
{
|
||||
static PyObject* convert(const bha::interval_view<Axis> &i)
|
||||
{
|
||||
struct axis_interval_view_to_python {
|
||||
static PyObject* convert(const bha::interval_view<Axis>& i) {
|
||||
return bp::incref(bp::make_tuple(i.lower(), i.upper()).ptr());
|
||||
}
|
||||
};
|
||||
@ -96,10 +93,8 @@ bp::object variable_init(bp::tuple args, bp::dict kwargs) {
|
||||
if (k == "label")
|
||||
label = boost::string_view(bp::extract<const char*>(v), bp::len(v));
|
||||
else if (k == "uoflow") {
|
||||
if (!bp::extract<bool>(v))
|
||||
uo = bha::uoflow::off;
|
||||
}
|
||||
else {
|
||||
if (!bp::extract<bool>(v)) uo = bha::uoflow::off;
|
||||
} else {
|
||||
std::stringstream s;
|
||||
s << "keyword " << k << " not recognized";
|
||||
PyErr_SetString(PyExc_KeyError, s.str().c_str());
|
||||
@ -142,30 +137,34 @@ bp::object category_init(bp::tuple args, bp::dict kwargs) {
|
||||
return self.attr("__init__")(bha::category<>(c.begin(), c.end(), label));
|
||||
}
|
||||
|
||||
template <typename T> void axis_set_label(T& t, bp::str s) {
|
||||
t.label({bp::extract<const char*>(s)(),
|
||||
static_cast<std::size_t>(bp::len(s))});
|
||||
template <typename T>
|
||||
void axis_set_label(T& t, bp::str s) {
|
||||
t.label(
|
||||
{bp::extract<const char*>(s)(), static_cast<std::size_t>(bp::len(s))});
|
||||
}
|
||||
|
||||
template <typename T> bp::str axis_get_label(const T& t) {
|
||||
template <typename T>
|
||||
bp::str axis_get_label(const T& t) {
|
||||
auto s = t.label();
|
||||
return {s.data(), s.size()};
|
||||
}
|
||||
|
||||
template <typename A> bp::object axis_getitem(const A &a, int i) {
|
||||
template <typename A>
|
||||
bp::object axis_getitem(const A& a, int i) {
|
||||
if (i < -1 * a.uoflow() || i >= a.size() + 1 * a.uoflow())
|
||||
throw std::out_of_range("index out of bounds");
|
||||
return bp::make_tuple(a.lower(i), a.lower(i + 1));
|
||||
}
|
||||
|
||||
template <> bp::object axis_getitem<bha::category<>>(const bha::category<> &a, int i) {
|
||||
if (i < 0 || i >= a.size())
|
||||
throw std::out_of_range("index out of bounds");
|
||||
template <>
|
||||
bp::object axis_getitem<bha::category<>>(const bha::category<>& a, int i) {
|
||||
if (i < 0 || i >= a.size()) throw std::out_of_range("index out of bounds");
|
||||
return bp::object(a.value(i));
|
||||
}
|
||||
|
||||
#ifdef HAVE_NUMPY
|
||||
template <typename Axis> bp::object axis_array_interface(const Axis& axis) {
|
||||
template <typename Axis>
|
||||
bp::object axis_array_interface(const Axis& axis) {
|
||||
using T = typename std::decay<typename Axis::value_type>::type;
|
||||
bp::dict d;
|
||||
auto shape = bp::make_tuple(axis.size() + 1);
|
||||
@ -174,14 +173,15 @@ template <typename Axis> bp::object axis_array_interface(const Axis& axis) {
|
||||
// make new array, and pass it to Python
|
||||
auto a = np::empty(shape, np::dtype::get_builtin<T>());
|
||||
auto buf = reinterpret_cast<T*>(a.get_data());
|
||||
for (auto i = 0; i < axis.size()+1; ++i)
|
||||
buf[i] = axis.lower(i);
|
||||
for (auto i = 0; i < axis.size() + 1; ++i) buf[i] = axis.lower(i);
|
||||
d["data"] = a;
|
||||
d["version"] = 3;
|
||||
return d;
|
||||
}
|
||||
|
||||
template <> bp::object axis_array_interface<bha::category<>>(const bha::category<>& axis) {
|
||||
template <>
|
||||
bp::object axis_array_interface<bha::category<>>(
|
||||
const bha::category<>& axis) {
|
||||
bp::dict d;
|
||||
auto shape = bp::make_tuple(axis.size());
|
||||
d["shape"] = shape;
|
||||
@ -189,8 +189,7 @@ template <> bp::object axis_array_interface<bha::category<>>(const bha::category
|
||||
// make new array, and pass it to Python
|
||||
auto a = np::empty(shape, np::dtype::get_builtin<int>());
|
||||
auto buf = reinterpret_cast<int*>(a.get_data());
|
||||
for (auto i = 0; i < axis.size(); ++i)
|
||||
buf[i] = axis.value(i);
|
||||
for (auto i = 0; i < axis.size(); ++i) buf[i] = axis.value(i);
|
||||
d["data"] = a;
|
||||
d["version"] = 3;
|
||||
return d;
|
||||
@ -199,14 +198,15 @@ template <> bp::object axis_array_interface<bha::category<>>(const bha::category
|
||||
|
||||
template <class T>
|
||||
struct axis_suite : public bp::def_visitor<axis_suite<T>> {
|
||||
template <class Class> static void visit(Class &cl) {
|
||||
cl.add_property(
|
||||
"shape", &T::shape,
|
||||
"Number of bins, including over-/underflow bins if they are present.");
|
||||
cl.add_property(
|
||||
"label", axis_get_label<T>, axis_set_label<T>,
|
||||
template <class Class>
|
||||
static void visit(Class& cl) {
|
||||
cl.add_property("shape", &T::shape,
|
||||
"Number of bins, including over-/underflow bins if they "
|
||||
"are present.");
|
||||
cl.add_property("label", axis_get_label<T>, axis_set_label<T>,
|
||||
"Name or description for the axis.");
|
||||
cl.def("index", &T::index, ":param float x: value"
|
||||
cl.def("index", &T::index,
|
||||
":param float x: value"
|
||||
"\n:returns: bin index for the passed value",
|
||||
bp::args("self", "x"));
|
||||
cl.def("__len__", &T::size,
|
||||
@ -227,33 +227,29 @@ struct axis_suite : public bp::def_visitor<axis_suite<T>> {
|
||||
};
|
||||
|
||||
template <typename Transform>
|
||||
bha::regular<double, Transform>* regular_init(
|
||||
unsigned bin, double lower, double upper,
|
||||
bp::str pylabel, bool with_uoflow)
|
||||
{
|
||||
bha::regular<double, Transform>* regular_init(unsigned bin, double lower,
|
||||
double upper, bp::str pylabel,
|
||||
bool with_uoflow) {
|
||||
const auto uo = with_uoflow ? bha::uoflow::on : bha::uoflow::off;
|
||||
return new bha::regular<double, Transform>(bin, lower, upper,
|
||||
{bp::extract<const char*>(pylabel)(),
|
||||
return new bha::regular<double, Transform>(
|
||||
bin, lower, upper, {bp::extract<const char*>(pylabel)(),
|
||||
static_cast<std::size_t>(bp::len(pylabel))},
|
||||
uo);
|
||||
}
|
||||
|
||||
bha::regular<double, bha::transform::pow>* regular_pow_init(
|
||||
unsigned bin, double lower, double upper, double power,
|
||||
bp::str pylabel, bool with_uoflow)
|
||||
{
|
||||
unsigned bin, double lower, double upper, double power, bp::str pylabel,
|
||||
bool with_uoflow) {
|
||||
using namespace ::boost::python;
|
||||
const auto uo = with_uoflow ? bha::uoflow::on : bha::uoflow::off;
|
||||
return new bha::regular<double, bha::transform::pow>(
|
||||
bin, lower, upper,
|
||||
{extract<const char*>(pylabel)(),
|
||||
bin, lower, upper, {extract<const char*>(pylabel)(),
|
||||
static_cast<std::size_t>(bp::len(pylabel))},
|
||||
uo, power);
|
||||
}
|
||||
|
||||
bha::integer<>* integer_init(int lower, int upper,
|
||||
bp::str pylabel, bool with_uoflow)
|
||||
{
|
||||
bha::integer<>* integer_init(int lower, int upper, bp::str pylabel,
|
||||
bool with_uoflow) {
|
||||
using namespace ::boost::python;
|
||||
const auto uo = with_uoflow ? bha::uoflow::on : bha::uoflow::off;
|
||||
return new bha::integer<>(lower, upper,
|
||||
@ -273,12 +269,12 @@ void register_axis_types() {
|
||||
.def("next", &generic_iterator::next) // Python2
|
||||
;
|
||||
|
||||
class_<bha::regular<>>(
|
||||
"regular",
|
||||
class_<bha::regular<>>("regular",
|
||||
"Axis for real-valued data and bins of equal width."
|
||||
"\nBinning is a O(1) operation.",
|
||||
no_init)
|
||||
.def("__init__", make_constructor(regular_init<bha::transform::identity>,
|
||||
.def("__init__",
|
||||
make_constructor(regular_init<bha::transform::identity>,
|
||||
default_call_policies(),
|
||||
(arg("bin"), arg("lower"), arg("upper"),
|
||||
arg("label") = "", arg("uoflow") = true)))
|
||||
@ -287,10 +283,12 @@ void register_axis_types() {
|
||||
#define BOOST_HISTOGRAM_PYTHON_REGULAR_CLASS(x) \
|
||||
class_<bha::regular<double, bha::transform::x>>( \
|
||||
"regular_" #x, \
|
||||
"Axis for real-valued data and bins of equal width in "#x"-space." \
|
||||
"Axis for real-valued data and bins of equal width in " #x \
|
||||
"-space." \
|
||||
"\nBinning is a O(1) operation.", \
|
||||
no_init) \
|
||||
.def("__init__", make_constructor(regular_init<bha::transform::x>, \
|
||||
.def("__init__", \
|
||||
make_constructor(regular_init<bha::transform::x>, \
|
||||
default_call_policies(), \
|
||||
(arg("bin"), arg("lower"), arg("upper"), \
|
||||
arg("label") = "", arg("uoflow") = true))) \
|
||||
@ -305,8 +303,9 @@ void register_axis_types() {
|
||||
"Axis for real-valued data and bins of equal width in power-space."
|
||||
"\nBinning is a O(1) operation.",
|
||||
no_init)
|
||||
.def("__init__", make_constructor(regular_pow_init,
|
||||
default_call_policies(),
|
||||
.def("__init__",
|
||||
make_constructor(
|
||||
regular_pow_init, default_call_policies(),
|
||||
(arg("bin"), arg("lower"), arg("upper"), arg("power"),
|
||||
arg("label") = "", arg("uoflow") = true)))
|
||||
.def(axis_suite<bha::regular<double, bha::transform::pow>>());
|
||||
@ -320,8 +319,7 @@ void register_axis_types() {
|
||||
no_init)
|
||||
.def(init<unsigned, double, double, const char*>(
|
||||
(arg("self"), arg("bin"), arg("phase") = 0.0,
|
||||
arg("perimeter") = bh::detail::two_pi,
|
||||
arg("label") = "")))
|
||||
arg("perimeter") = bh::detail::two_pi, arg("label") = "")))
|
||||
.def(axis_suite<bha::circular<>>());
|
||||
|
||||
class_<bha::variable<>>(
|
||||
@ -340,8 +338,8 @@ void register_axis_types() {
|
||||
"\nthat are one integer wide. Faster than a regular axis."
|
||||
"\nBinning is a O(1) operation.",
|
||||
no_init)
|
||||
.def("__init__", make_constructor(integer_init,
|
||||
default_call_policies(),
|
||||
.def("__init__",
|
||||
make_constructor(integer_init, default_call_policies(),
|
||||
(arg("lower"), arg("upper"), arg("label") = "",
|
||||
arg("uoflow") = true)))
|
||||
.def(axis_suite<bha::integer<>>());
|
||||
|
@ -4,18 +4,18 @@
|
||||
// (See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "serialization_suite.hpp"
|
||||
#include "utility.hpp"
|
||||
#include <boost/histogram/detail/cat.hpp>
|
||||
#include <boost/histogram/dynamic_histogram.hpp>
|
||||
#include <boost/histogram/storage/adaptive_storage.hpp>
|
||||
#include <boost/histogram/ostream_operators.hpp>
|
||||
#include <boost/histogram/serialization.hpp>
|
||||
#include <boost/histogram/detail/cat.hpp>
|
||||
#include <boost/histogram/storage/adaptive_storage.hpp>
|
||||
#include <boost/python.hpp>
|
||||
#include <boost/python/raw_function.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include "serialization_suite.hpp"
|
||||
#include "utility.hpp"
|
||||
#ifdef HAVE_NUMPY
|
||||
#include <boost/python/numpy.hpp>
|
||||
namespace np = boost::python::numpy;
|
||||
@ -85,10 +85,10 @@ public:
|
||||
// double array, fill it and pass it
|
||||
auto a = np::empty(tuple(shapes), np::dtype::get_builtin<double>());
|
||||
for (auto i = 0l, n = bp::len(shapes); i < n; ++i)
|
||||
const_cast<Py_intptr_t*>(a.get_strides())[i] = bp::extract<int>(strides[i]);
|
||||
const_cast<Py_intptr_t*>(a.get_strides())[i] =
|
||||
bp::extract<int>(strides[i]);
|
||||
auto* buf = (double*)a.get_data();
|
||||
for (auto i = 0ul; i < b.size; ++i)
|
||||
buf[i] = static_cast<double>(b[i]);
|
||||
for (auto i = 0ul; i < b.size; ++i) buf[i] = static_cast<double>(b[i]);
|
||||
return a;
|
||||
}
|
||||
};
|
||||
@ -103,8 +103,7 @@ public:
|
||||
if (i) strides.append(strides[-1] * shapes[-1]);
|
||||
shapes.append(self.axis(i).shape());
|
||||
}
|
||||
if (self.dim() == 0)
|
||||
shapes.append(0);
|
||||
if (self.dim() == 0) shapes.append(0);
|
||||
d["shape"] = tuple(shapes);
|
||||
d["strides"] = tuple(strides);
|
||||
d["data"] = boost::apply_visitor(data_visitor(shapes, strides), b);
|
||||
@ -117,7 +116,8 @@ public:
|
||||
} // namespace boost
|
||||
|
||||
struct axis_visitor : public boost::static_visitor<bp::object> {
|
||||
template <typename T> bp::object operator()(const T &t) const {
|
||||
template <typename T>
|
||||
bp::object operator()(const T& t) const {
|
||||
return bp::object(t);
|
||||
}
|
||||
};
|
||||
@ -126,9 +126,10 @@ struct axes_appender {
|
||||
bp::object obj;
|
||||
pyhistogram::axes_type& axes;
|
||||
bool& success;
|
||||
axes_appender(bp::object o, pyhistogram::axes_type& a,
|
||||
bool& s) : obj(o), axes(a), success(s) {}
|
||||
template <typename A> void operator()(const A&) const {
|
||||
axes_appender(bp::object o, pyhistogram::axes_type& a, bool& s)
|
||||
: obj(o), axes(a), success(s) {}
|
||||
template <typename A>
|
||||
void operator()(const A&) const {
|
||||
if (success) return;
|
||||
bp::extract<const A&> get_axis(obj);
|
||||
if (get_axis.check()) {
|
||||
@ -139,8 +140,7 @@ struct axes_appender {
|
||||
};
|
||||
|
||||
bp::object histogram_axis(const pyhistogram& self, int i) {
|
||||
if (i < 0)
|
||||
i += self.dim();
|
||||
if (i < 0) i += self.dim();
|
||||
if (i < 0 || i >= int(self.dim()))
|
||||
throw std::out_of_range("axis index out of range");
|
||||
return boost::apply_visitor(axis_visitor(), self.axis(i));
|
||||
@ -163,8 +163,7 @@ bp::object histogram_init(bp::tuple args, bp::dict kwargs) {
|
||||
bp::object pa = args[i + 1];
|
||||
bool success = false;
|
||||
boost::mp11::mp_for_each<pyhistogram::any_axis_type::types>(
|
||||
axes_appender(pa, axes, success)
|
||||
);
|
||||
axes_appender(pa, axes, success));
|
||||
if (!success) {
|
||||
std::string msg = "require an axis object, got ";
|
||||
msg += bp::extract<std::string>(pa.attr("__class__"))();
|
||||
@ -204,8 +203,7 @@ struct fetcher {
|
||||
}
|
||||
|
||||
const T& operator[](long i) const noexcept {
|
||||
if (n > 0)
|
||||
return carray[i];
|
||||
if (n > 0) return carray[i];
|
||||
return value;
|
||||
}
|
||||
};
|
||||
@ -224,14 +222,16 @@ bp::object histogram_fill(bp::tuple args, bp::dict kwargs) {
|
||||
|
||||
const unsigned dim = nargs - 1;
|
||||
if (dim != self.dim()) {
|
||||
PyErr_SetString(PyExc_ValueError, "number of arguments and dimension do not match");
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"number of arguments and dimension do not match");
|
||||
bp::throw_error_already_set();
|
||||
}
|
||||
|
||||
if (dim > BOOST_HISTOGRAM_AXIS_LIMIT) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
bh::detail::cat("too many arguments, maximum is ",
|
||||
BOOST_HISTOGRAM_AXIS_LIMIT).c_str());
|
||||
BOOST_HISTOGRAM_AXIS_LIMIT)
|
||||
.c_str());
|
||||
bp::throw_error_already_set();
|
||||
}
|
||||
|
||||
@ -241,7 +241,8 @@ bp::object histogram_fill(bp::tuple args, bp::dict kwargs) {
|
||||
fetch[d].assign(args[1 + d]);
|
||||
if (fetch[d].n > 0) {
|
||||
if (n > 0 && fetch[d].n != n) {
|
||||
PyErr_SetString(PyExc_ValueError, "lengths of sequences do not match");
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"lengths of sequences do not match");
|
||||
bp::throw_error_already_set();
|
||||
}
|
||||
n = fetch[d].n;
|
||||
@ -261,7 +262,8 @@ bp::object histogram_fill(bp::tuple args, bp::dict kwargs) {
|
||||
fetch_weight.assign(kwargs.get("weight"));
|
||||
if (fetch_weight.n > 0) {
|
||||
if (n > 0 && fetch_weight.n != n) {
|
||||
PyErr_SetString(PyExc_ValueError, "length of weight sequence does not match");
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"length of weight sequence does not match");
|
||||
bp::throw_error_already_set();
|
||||
}
|
||||
n = fetch_weight.n;
|
||||
@ -275,22 +277,18 @@ bp::object histogram_fill(bp::tuple args, bp::dict kwargs) {
|
||||
for (auto i = 0l; i < n; ++i)
|
||||
self(bh::weight(fetch_weight[i]), fetch[0][i]);
|
||||
} else {
|
||||
for (auto i = 0l; i < n; ++i)
|
||||
self(fetch[0][i]);
|
||||
for (auto i = 0l; i < n; ++i) self(fetch[0][i]);
|
||||
}
|
||||
} else {
|
||||
double v[BOOST_HISTOGRAM_AXIS_LIMIT];
|
||||
if (fetch_weight.n >= 0) {
|
||||
for (auto i = 0l; i < n; ++i) {
|
||||
for (auto d = 0u; d < dim; ++d)
|
||||
v[d] = fetch[d][i];
|
||||
for (auto d = 0u; d < dim; ++d) v[d] = fetch[d][i];
|
||||
self(bh::weight(fetch_weight[i]), span<double>{v, dim});
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
for (auto i = 0l; i < n; ++i) {
|
||||
for (auto d = 0u; d < dim; ++d)
|
||||
v[d] = fetch[d][i];
|
||||
for (auto d = 0u; d < dim; ++d) v[d] = fetch[d][i];
|
||||
self(span<double>{v, dim});
|
||||
}
|
||||
}
|
||||
@ -319,13 +317,13 @@ bp::object histogram_getitem(const pyhistogram& self, bp::object args) {
|
||||
if (dim > BOOST_HISTOGRAM_AXIS_LIMIT) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
bh::detail::cat("too many arguments, maximum is ",
|
||||
BOOST_HISTOGRAM_AXIS_LIMIT).c_str());
|
||||
BOOST_HISTOGRAM_AXIS_LIMIT)
|
||||
.c_str());
|
||||
bp::throw_error_already_set();
|
||||
}
|
||||
|
||||
int idx[BOOST_HISTOGRAM_AXIS_LIMIT];
|
||||
for (unsigned i = 0; i < dim; ++i)
|
||||
idx[i] = bp::extract<int>(args[i]);
|
||||
for (unsigned i = 0; i < dim; ++i) idx[i] = bp::extract<int>(args[i]);
|
||||
|
||||
return bp::object(self.at(span<int>{idx, self.dim()}));
|
||||
}
|
||||
@ -350,7 +348,8 @@ bp::object histogram_reduce_to(bp::tuple args, bp::dict kwargs) {
|
||||
if (nargs > BOOST_HISTOGRAM_AXIS_LIMIT) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
bh::detail::cat("too many arguments, maximum is ",
|
||||
BOOST_HISTOGRAM_AXIS_LIMIT).c_str());
|
||||
BOOST_HISTOGRAM_AXIS_LIMIT)
|
||||
.c_str());
|
||||
bp::throw_error_already_set();
|
||||
}
|
||||
|
||||
@ -360,8 +359,7 @@ bp::object histogram_reduce_to(bp::tuple args, bp::dict kwargs) {
|
||||
}
|
||||
|
||||
int idx[BOOST_HISTOGRAM_AXIS_LIMIT];
|
||||
for (auto i = 0u; i < nargs; ++i)
|
||||
idx[i] = bp::extract<int>(args[1 + i]);
|
||||
for (auto i = 0u; i < nargs; ++i) idx[i] = bp::extract<int>(args[1 + i]);
|
||||
|
||||
return bp::object(self.reduce_to(idx, idx + nargs));
|
||||
}
|
||||
@ -370,31 +368,31 @@ std::string histogram_repr(const pyhistogram &h) {
|
||||
return bh::detail::cat(h);
|
||||
}
|
||||
|
||||
double element_value(const pyhistogram::element_type& b) {
|
||||
return b.value();
|
||||
}
|
||||
double element_value(const pyhistogram::element_type& b) { return b.value(); }
|
||||
|
||||
double element_variance(const pyhistogram::element_type& b) {
|
||||
return b.variance();
|
||||
}
|
||||
|
||||
double element_getitem(const pyhistogram::element_type& e, int i) {
|
||||
if (i < 0 || i > 1)
|
||||
throw std::out_of_range("element_getitem");
|
||||
if (i < 0 || i > 1) throw std::out_of_range("element_getitem");
|
||||
return i == 0 ? e.value() : e.variance();
|
||||
}
|
||||
|
||||
int element_len(const pyhistogram::element_type&) { return 2; }
|
||||
|
||||
std::string element_repr(const pyhistogram::element_type& e) {
|
||||
return bh::detail::cat("histogram.element(", e.value(), ", ", e.variance(), ")");
|
||||
return bh::detail::cat("histogram.element(", e.value(), ", ", e.variance(),
|
||||
")");
|
||||
}
|
||||
|
||||
void register_histogram() {
|
||||
bp::docstring_options dopt(true, true, false);
|
||||
|
||||
bp::scope s = bp::class_<pyhistogram, boost::shared_ptr<pyhistogram>>(
|
||||
"histogram", "N-dimensional histogram for real-valued data.", bp::no_init)
|
||||
bp::scope s =
|
||||
bp::class_<pyhistogram, boost::shared_ptr<pyhistogram>>(
|
||||
"histogram", "N-dimensional histogram for real-valued data.",
|
||||
bp::no_init)
|
||||
.def("__init__", bp::raw_function(histogram_init),
|
||||
":param axis args: axis objects"
|
||||
"\nPass one or more axis objects to configure the histogram.")
|
||||
@ -408,20 +406,24 @@ void register_histogram() {
|
||||
.def("axis", histogram_axis, bp::arg("i") = 0,
|
||||
":param int i: axis index"
|
||||
"\n:return: corresponding axis object")
|
||||
.def("__call__", bp::raw_function(histogram_fill),
|
||||
.def(
|
||||
"__call__", bp::raw_function(histogram_fill),
|
||||
":param double args: values (number must match dimension)"
|
||||
"\n:keyword double weight: optional weight"
|
||||
"\n"
|
||||
"\nIf Numpy support is enabled, 1d-arrays can be passed instead of"
|
||||
"\nIf Numpy support is enabled, 1d-arrays can be passed "
|
||||
"instead of"
|
||||
"\nvalues, which must be equal in lenght. Arrays and values can"
|
||||
"\nbe mixed arbitrarily in the same call.")
|
||||
.def("__len__", &pyhistogram::size,
|
||||
":return: total number of bins, including under- and overflow")
|
||||
.def("at", bp::raw_function(histogram_at),
|
||||
":param int args: indices of the bin (number must match dimension)"
|
||||
":param int args: indices of the bin (number must match "
|
||||
"dimension)"
|
||||
"\n:return: bin content")
|
||||
.def("__getitem__", histogram_getitem,
|
||||
":param int args: indices of the bin (number must match dimension)"
|
||||
":param int args: indices of the bin (number must match "
|
||||
"dimension)"
|
||||
"\n:return: bin content")
|
||||
.def("reduce_to", bp::raw_function(histogram_reduce_to),
|
||||
":param int args: indices of the axes in the reduced histogram"
|
||||
@ -436,8 +438,7 @@ void register_histogram() {
|
||||
.def(bp::self * double())
|
||||
.def(double() * bp::self)
|
||||
.def(bp::self + bp::self)
|
||||
.def_pickle(bh::serialization_suite<pyhistogram>())
|
||||
;
|
||||
.def_pickle(bh::serialization_suite<pyhistogram>());
|
||||
|
||||
bp::class_<pyhistogram::element_type>(
|
||||
"element", "Holds value and variance of bin count.",
|
||||
@ -453,6 +454,5 @@ void register_histogram() {
|
||||
.def(bp::self + bp::self)
|
||||
.def(bp::self + double())
|
||||
.def(double() + bp::self)
|
||||
.def("__repr__", element_repr)
|
||||
;
|
||||
.def("__repr__", element_repr);
|
||||
}
|
||||
|
@ -5,8 +5,8 @@
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/scope.hpp>
|
||||
#include <boost/python/object.hpp>
|
||||
#include <boost/python/scope.hpp>
|
||||
#ifdef HAVE_NUMPY
|
||||
#include <boost/python/numpy.hpp>
|
||||
#endif
|
||||
@ -23,9 +23,7 @@ BOOST_PYTHON_MODULE(histogram) {
|
||||
#else
|
||||
current.attr("HAVE_NUMPY") = false;
|
||||
#endif
|
||||
object axis_module = object(
|
||||
borrowed(PyImport_AddModule("histogram.axis"))
|
||||
);
|
||||
object axis_module = object(borrowed(PyImport_AddModule("histogram.axis")));
|
||||
current.attr("axis") = axis_module;
|
||||
{
|
||||
scope current = axis_module;
|
||||
|
@ -60,7 +60,8 @@ private:
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
template <class T> struct serialization_suite : python::pickle_suite {
|
||||
template <class T>
|
||||
struct serialization_suite : python::pickle_suite {
|
||||
static python::tuple getstate(python::object obj) {
|
||||
PyObject* pobj = 0;
|
||||
iostreams::stream<detail::python_bytes_sink> os(&pobj);
|
||||
|
@ -8,8 +8,8 @@
|
||||
#define _BOOST_HISTOGRAM_PYTHON_UTILITY_HPP_
|
||||
|
||||
#include <boost/python/str.hpp>
|
||||
#include <type_traits>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace python {
|
||||
|
@ -190,8 +190,7 @@ void convert_array_storage_impl() {
|
||||
|
||||
array_storage<float> t(std::size_t(1));
|
||||
t.increase(0);
|
||||
while (t[0] < 1e20)
|
||||
t.add(0, t[0]);
|
||||
while (t[0] < 1e20) t.add(0, t[0]);
|
||||
auto d = aref;
|
||||
d = t;
|
||||
BOOST_TEST(d == t);
|
||||
|
@ -51,7 +51,8 @@ int main() {
|
||||
{
|
||||
axis::regular<> a{4, -2, 2};
|
||||
BOOST_TEST_EQ(a[-1].lower(), -std::numeric_limits<double>::infinity());
|
||||
BOOST_TEST_EQ(a[a.size()].upper(), std::numeric_limits<double>::infinity());
|
||||
BOOST_TEST_EQ(a[a.size()].upper(),
|
||||
std::numeric_limits<double>::infinity());
|
||||
axis::regular<> b;
|
||||
BOOST_TEST_NOT(a == b);
|
||||
b = a;
|
||||
@ -149,7 +150,8 @@ int main() {
|
||||
{
|
||||
axis::variable<> a{-1, 0, 1};
|
||||
BOOST_TEST_EQ(a[-1].lower(), -std::numeric_limits<double>::infinity());
|
||||
BOOST_TEST_EQ(a[a.size()].upper(), std::numeric_limits<double>::infinity());
|
||||
BOOST_TEST_EQ(a[a.size()].upper(),
|
||||
std::numeric_limits<double>::infinity());
|
||||
axis::variable<> b;
|
||||
BOOST_TEST_NOT(a == b);
|
||||
b = a;
|
||||
@ -258,7 +260,8 @@ int main() {
|
||||
a6 = a1;
|
||||
BOOST_TEST_EQ(a6, a1);
|
||||
axis::any<axis::regular<>, axis::integer<>> a7(axis::integer<>(0, 2));
|
||||
BOOST_TEST_THROWS(axis::any<axis::regular<>> a8(a7), std::invalid_argument);
|
||||
BOOST_TEST_THROWS(axis::any<axis::regular<>> a8(a7),
|
||||
std::invalid_argument);
|
||||
BOOST_TEST_THROWS(a4 = a7, std::invalid_argument);
|
||||
}
|
||||
|
||||
@ -288,14 +291,13 @@ int main() {
|
||||
axes.push_back(axis::regular<double, axis::transform::pow>(
|
||||
2, 1, 10, "regular4", axis::uoflow::off, -0.5));
|
||||
axes.push_back(axis::circular<>(4, 0.1, 1.0, "polar"));
|
||||
axes.push_back(axis::variable<>({-1, 0, 1}, "variable", axis::uoflow::off));
|
||||
axes.push_back(
|
||||
axis::variable<>({-1, 0, 1}, "variable", axis::uoflow::off));
|
||||
axes.push_back(axis::category<>({A, B, C}, "category"));
|
||||
axes.push_back(axis::category<std::string>({a, b}, "category2"));
|
||||
axes.push_back(axis::integer<>(-1, 1, "integer", axis::uoflow::off));
|
||||
std::ostringstream os;
|
||||
for (const auto& a : axes) {
|
||||
os << a << "\n";
|
||||
}
|
||||
for (const auto& a : axes) { os << a << "\n"; }
|
||||
const std::string ref =
|
||||
"regular(2, -1, 1, label='regular1')\n"
|
||||
"regular_log(2, 1, 10, label='regular2', uoflow=False)\n"
|
||||
@ -343,7 +345,8 @@ int main() {
|
||||
std_vector1 = {axis::regular<>{2, -1, 1}, axis::variable<>{-1, 0, 1},
|
||||
axis::category<>{A, B, C}};
|
||||
|
||||
std::vector<axis::any<axis::regular<>, axis::variable<>, axis::category<>>>
|
||||
std::vector<
|
||||
axis::any<axis::regular<>, axis::variable<>, axis::category<>>>
|
||||
std_vector2 = {axis::regular<>{2, -1, 1}, axis::variable<>{-1, 0, 1},
|
||||
axis::category<>{{A, B, C}}};
|
||||
|
||||
@ -365,8 +368,8 @@ int main() {
|
||||
std::make_tuple(axis::regular<>{2, -1, 1}, axis::variable<>{-1, 0, 1},
|
||||
axis::category<>{{A, B}});
|
||||
|
||||
auto tuple3 =
|
||||
std::make_tuple(axis::regular<>{2, -1, 1}, axis::variable<>{-1, 0, 1});
|
||||
auto tuple3 = std::make_tuple(axis::regular<>{2, -1, 1},
|
||||
axis::variable<>{-1, 0, 1});
|
||||
|
||||
BOOST_TEST(detail::axes_equal(std_vector1, tuple1));
|
||||
BOOST_TEST(detail::axes_equal(tuple1, std_vector1));
|
||||
@ -383,7 +386,8 @@ int main() {
|
||||
std_vector1 = {axis::regular<>{2, -1, 1}, axis::variable<>{-1, 0, 1},
|
||||
axis::category<>{A, B, C}};
|
||||
|
||||
std::vector<axis::any<axis::regular<>, axis::variable<>, axis::category<>>>
|
||||
std::vector<
|
||||
axis::any<axis::regular<>, axis::variable<>, axis::category<>>>
|
||||
std_vector2 = {axis::regular<>{2, -2, 2}, axis::variable<>{-2, 0, 2},
|
||||
axis::category<>{A, B}};
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
using namespace boost::histogram;
|
||||
int main() {
|
||||
auto h = make_dynamic_histogram(axis::integer<>(0, 2), axis::integer<>(0, 2));
|
||||
auto h =
|
||||
make_dynamic_histogram(axis::integer<>(0, 2), axis::integer<>(0, 2));
|
||||
h.at(std::make_pair(-2, 0));
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
using namespace boost::histogram;
|
||||
int main() {
|
||||
auto h = make_dynamic_histogram(axis::integer<>(0, 2), axis::integer<>(0, 2));
|
||||
auto h =
|
||||
make_dynamic_histogram(axis::integer<>(0, 2), axis::integer<>(0, 2));
|
||||
h.at(std::vector<int>({-2, 0}));
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
using namespace boost::histogram;
|
||||
int main() {
|
||||
auto h = make_static_histogram(axis::integer<>(0, 2), axis::integer<>(0, 2));
|
||||
auto h =
|
||||
make_static_histogram(axis::integer<>(0, 2), axis::integer<>(0, 2));
|
||||
h.at(std::vector<int>(-2, 0));
|
||||
}
|
||||
|
@ -76,8 +76,8 @@ void run_tests() {
|
||||
|
||||
// init_2
|
||||
{
|
||||
auto h = make_histogram<adaptive_storage>(Type(), axis::regular<>{3, -1, 1},
|
||||
axis::integer<>{-1, 2});
|
||||
auto h = make_histogram<adaptive_storage>(
|
||||
Type(), axis::regular<>{3, -1, 1}, axis::integer<>{-1, 2});
|
||||
BOOST_TEST_EQ(h.dim(), 2);
|
||||
BOOST_TEST_EQ(h.size(), 25);
|
||||
BOOST_TEST_EQ(h.axis(0_c).shape(), 5);
|
||||
@ -89,8 +89,8 @@ void run_tests() {
|
||||
|
||||
// init_3
|
||||
{
|
||||
auto h = make_histogram<adaptive_storage>(Type(), axis::regular<>{3, -1, 1},
|
||||
axis::integer<>{-1, 2},
|
||||
auto h = make_histogram<adaptive_storage>(
|
||||
Type(), axis::regular<>{3, -1, 1}, axis::integer<>{-1, 2},
|
||||
axis::circular<>{3});
|
||||
BOOST_TEST_EQ(h.dim(), 3);
|
||||
BOOST_TEST_EQ(h.size(), 75);
|
||||
@ -136,7 +136,8 @@ void run_tests() {
|
||||
h(0, 0);
|
||||
auto h2 = decltype(h)(h);
|
||||
BOOST_TEST(h2 == h);
|
||||
auto h3 = static_histogram<mp11::mp_list<axis::integer<>, axis::integer<>>,
|
||||
auto h3 =
|
||||
static_histogram<mp11::mp_list<axis::integer<>, axis::integer<>>,
|
||||
array_storage<unsigned>>(h);
|
||||
BOOST_TEST_EQ(h3, h);
|
||||
}
|
||||
@ -153,7 +154,8 @@ void run_tests() {
|
||||
// test self-assign
|
||||
h2 = h2;
|
||||
BOOST_TEST_EQ(h, h2);
|
||||
auto h3 = static_histogram<mp11::mp_list<axis::integer<>, axis::integer<>>,
|
||||
auto h3 =
|
||||
static_histogram<mp11::mp_list<axis::integer<>, axis::integer<>>,
|
||||
array_storage<unsigned>>();
|
||||
h3 = h;
|
||||
BOOST_TEST_EQ(h, h3);
|
||||
@ -183,8 +185,8 @@ void run_tests() {
|
||||
// axis methods
|
||||
{
|
||||
enum { A = 3, B = 5 };
|
||||
auto a = make_histogram<adaptive_storage>(Type(),
|
||||
axis::regular<>(1, 1, 2, "foo"));
|
||||
auto a = make_histogram<adaptive_storage>(
|
||||
Type(), axis::regular<>(1, 1, 2, "foo"));
|
||||
BOOST_TEST_EQ(a.axis().size(), 1);
|
||||
BOOST_TEST_EQ(a.axis().shape(), 3);
|
||||
BOOST_TEST_EQ(a.axis().index(1), 0);
|
||||
@ -203,7 +205,8 @@ void run_tests() {
|
||||
b.axis().label("foo");
|
||||
BOOST_TEST_EQ(b.axis().label(), "foo");
|
||||
|
||||
auto c = make_histogram<adaptive_storage>(Type(), axis::category<>({A, B}));
|
||||
auto c =
|
||||
make_histogram<adaptive_storage>(Type(), axis::category<>({A, B}));
|
||||
BOOST_TEST_EQ(c.axis().size(), 2);
|
||||
BOOST_TEST_EQ(c.axis().shape(), 2);
|
||||
BOOST_TEST_EQ(c.axis().index(A), 0);
|
||||
@ -227,7 +230,8 @@ void run_tests() {
|
||||
BOOST_TEST(c != b);
|
||||
BOOST_TEST(a == c);
|
||||
BOOST_TEST(c == a);
|
||||
auto d = make_histogram<adaptive_storage>(Type(), axis::regular<>(2, 0, 1));
|
||||
auto d =
|
||||
make_histogram<adaptive_storage>(Type(), axis::regular<>(2, 0, 1));
|
||||
BOOST_TEST(c != d);
|
||||
BOOST_TEST(d != c);
|
||||
c(0);
|
||||
@ -425,8 +429,8 @@ void run_tests() {
|
||||
// add_1
|
||||
{
|
||||
auto a = make_histogram<adaptive_storage>(Type(), axis::integer<>(0, 2));
|
||||
auto b =
|
||||
make_histogram<array_storage<unsigned>>(Type(), axis::integer<>(0, 2));
|
||||
auto b = make_histogram<array_storage<unsigned>>(Type(),
|
||||
axis::integer<>(0, 2));
|
||||
a(0); // 1 0
|
||||
b(1); // 0 1
|
||||
auto a2 = a;
|
||||
@ -477,8 +481,8 @@ void run_tests() {
|
||||
{
|
||||
auto a =
|
||||
make_histogram<array_storage<char>>(Type(), axis::integer<>(-1, 2));
|
||||
auto b =
|
||||
make_histogram<array_storage<unsigned>>(Type(), axis::integer<>(-1, 2));
|
||||
auto b = make_histogram<array_storage<unsigned>>(Type(),
|
||||
axis::integer<>(-1, 2));
|
||||
a(-1);
|
||||
b(1);
|
||||
auto c = a;
|
||||
@ -896,8 +900,8 @@ void run_mixed_tests() {
|
||||
{
|
||||
auto a = make_histogram<adaptive_storage>(T1{}, axis::regular<>{3, 0, 3},
|
||||
axis::integer<>(0, 2));
|
||||
auto b = make_histogram<array_storage<int>>(T2{}, axis::regular<>{3, 0, 3},
|
||||
axis::integer<>(0, 2));
|
||||
auto b = make_histogram<array_storage<int>>(
|
||||
T2{}, axis::regular<>{3, 0, 3}, axis::integer<>(0, 2));
|
||||
BOOST_TEST_EQ(a, b);
|
||||
auto b2 = make_histogram<adaptive_storage>(T2{}, axis::integer<>{0, 3},
|
||||
axis::integer<>(0, 2));
|
||||
@ -926,8 +930,8 @@ void run_mixed_tests() {
|
||||
{
|
||||
auto a = make_histogram<adaptive_storage>(T1{}, axis::regular<>{3, 0, 3},
|
||||
axis::integer<>(0, 2));
|
||||
auto b = make_histogram<array_storage<int>>(T2{}, axis::regular<>{3, 0, 3},
|
||||
axis::integer<>(0, 2));
|
||||
auto b = make_histogram<array_storage<int>>(
|
||||
T2{}, axis::regular<>{3, 0, 3}, axis::integer<>(0, 2));
|
||||
a(1, 1);
|
||||
BOOST_TEST_NE(a, b);
|
||||
b = a;
|
||||
|
@ -4,11 +4,11 @@
|
||||
// (See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "utility.hpp"
|
||||
#include <boost/histogram/detail/index_mapper.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <boost/histogram/detail/index_mapper.hpp>
|
||||
#include <vector>
|
||||
#include "utility.hpp"
|
||||
|
||||
using namespace boost::histogram::detail;
|
||||
|
||||
|
@ -135,7 +135,8 @@ int main() {
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<copy_qualifiers<int&, long>, long&>));
|
||||
BOOST_TEST_TRAIT_TRUE(
|
||||
(std::is_same<copy_qualifiers<const int&, long>, const long&>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<copy_qualifiers<int&&, long>, long&&>));
|
||||
BOOST_TEST_TRAIT_TRUE(
|
||||
(std::is_same<copy_qualifiers<int&&, long>, long&&>));
|
||||
}
|
||||
|
||||
// mp_set_union
|
||||
@ -153,8 +154,8 @@ int main() {
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<selection<T, i0>, std::tuple<char>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<selection<T, i1>, std::tuple<int>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<selection<T, i2>, std::tuple<long>>));
|
||||
BOOST_TEST_TRAIT_TRUE(
|
||||
(std::is_same<selection<T, i0, i1, i2>, std::tuple<char, int, long>>));
|
||||
BOOST_TEST_TRAIT_TRUE((
|
||||
std::is_same<selection<T, i0, i1, i2>, std::tuple<char, int, long>>));
|
||||
BOOST_TEST_TRAIT_TRUE(
|
||||
(std::is_same<selection<T, i0, i1>, std::tuple<char, int>>));
|
||||
BOOST_TEST_TRAIT_TRUE(
|
||||
|
@ -6,12 +6,12 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/histogram.hpp>
|
||||
#include <boost/mp11.hpp>
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
#include <limits>
|
||||
#include <random>
|
||||
#include <memory>
|
||||
#include <boost/mp11.hpp>
|
||||
#include <random>
|
||||
|
||||
using namespace boost::histogram;
|
||||
using boost::mp11::mp_list;
|
||||
@ -21,12 +21,10 @@ std::unique_ptr<double[]> random_array(unsigned n, int type) {
|
||||
std::default_random_engine gen(1);
|
||||
if (type) { // type == 1
|
||||
std::normal_distribution<> d(0.5, 0.3);
|
||||
for (unsigned i = 0; i < n; ++i)
|
||||
r[i] = d(gen);
|
||||
for (unsigned i = 0; i < n; ++i) r[i] = d(gen);
|
||||
} else { // type == 0
|
||||
std::uniform_real_distribution<> d(0.0, 1.0);
|
||||
for (unsigned i = 0; i < n; ++i)
|
||||
r[i] = d(gen);
|
||||
for (unsigned i = 0; i < n; ++i) r[i] = d(gen);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@ -58,8 +56,7 @@ double compare_1d(unsigned n, int distrib) {
|
||||
for (unsigned k = 0; k < 20; ++k) {
|
||||
auto h = Histogram(axis::regular<>(100, 0, 1));
|
||||
auto t = clock();
|
||||
for (unsigned i = 0; i < n; ++i)
|
||||
h(r[i]);
|
||||
for (unsigned i = 0; i < n; ++i) h(r[i]);
|
||||
t = clock() - t;
|
||||
best = std::min(best, double(t) / CLOCKS_PER_SEC);
|
||||
}
|
||||
@ -73,10 +70,10 @@ double compare_2d(unsigned n, int distrib) {
|
||||
|
||||
auto best = std::numeric_limits<double>::max();
|
||||
for (unsigned k = 0; k < 20; ++k) {
|
||||
auto h = Histogram(axis::regular<>(100, 0, 1), axis::regular<>(100, 0, 1));
|
||||
auto h =
|
||||
Histogram(axis::regular<>(100, 0, 1), axis::regular<>(100, 0, 1));
|
||||
auto t = clock();
|
||||
for (unsigned i = 0; i < n / 2; ++i)
|
||||
h(r[2 * i], r[2 * i + 1]);
|
||||
for (unsigned i = 0; i < n / 2; ++i) h(r[2 * i], r[2 * i + 1]);
|
||||
t = clock() - t;
|
||||
best = std::min(best, double(t) / CLOCKS_PER_SEC);
|
||||
}
|
||||
@ -136,9 +133,8 @@ int main() {
|
||||
else
|
||||
printf("normal distribution\n");
|
||||
printf("hs_ss %.3f\n",
|
||||
compare_1d<
|
||||
static_histogram<mp_list<axis::regular<>>, array_storage<int>>>(
|
||||
nfill, itype));
|
||||
compare_1d<static_histogram<mp_list<axis::regular<>>,
|
||||
array_storage<int>>>(nfill, itype));
|
||||
printf("hs_sd %.3f\n",
|
||||
compare_1d<
|
||||
static_histogram<mp_list<axis::regular<>>, adaptive_storage>>(
|
||||
@ -147,8 +143,8 @@ int main() {
|
||||
compare_1d<dynamic_histogram<axis::types, array_storage<int>>>(
|
||||
nfill, itype));
|
||||
printf("hd_sd %.3f\n",
|
||||
compare_1d<dynamic_histogram<axis::types, adaptive_storage>>(nfill,
|
||||
itype));
|
||||
compare_1d<dynamic_histogram<axis::types, adaptive_storage>>(
|
||||
nfill, itype));
|
||||
}
|
||||
|
||||
printf("2D\n");
|
||||
@ -169,8 +165,8 @@ int main() {
|
||||
compare_2d<dynamic_histogram<axis::types, array_storage<int>>>(
|
||||
nfill, itype));
|
||||
printf("hd_sd %.3f\n",
|
||||
compare_2d<dynamic_histogram<axis::types, adaptive_storage>>(nfill,
|
||||
itype));
|
||||
compare_2d<dynamic_histogram<axis::types, adaptive_storage>>(
|
||||
nfill, itype));
|
||||
}
|
||||
|
||||
printf("3D\n");
|
||||
@ -191,8 +187,8 @@ int main() {
|
||||
compare_3d<dynamic_histogram<axis::types, array_storage<int>>>(
|
||||
nfill, itype));
|
||||
printf("hd_sd %.3f\n",
|
||||
compare_3d<dynamic_histogram<axis::types, adaptive_storage>>(nfill,
|
||||
itype));
|
||||
compare_3d<dynamic_histogram<axis::types, adaptive_storage>>(
|
||||
nfill, itype));
|
||||
}
|
||||
|
||||
printf("6D\n");
|
||||
@ -215,7 +211,7 @@ int main() {
|
||||
compare_6d<dynamic_histogram<axis::types, array_storage<int>>>(
|
||||
nfill, itype));
|
||||
printf("hd_sd %.3f\n",
|
||||
compare_6d<dynamic_histogram<axis::types, adaptive_storage>>(nfill,
|
||||
itype));
|
||||
compare_6d<dynamic_histogram<axis::types, adaptive_storage>>(
|
||||
nfill, itype));
|
||||
}
|
||||
}
|
||||
|
@ -11,20 +11,18 @@
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
#include <limits>
|
||||
#include <random>
|
||||
#include <memory>
|
||||
#include <random>
|
||||
|
||||
std::unique_ptr<double[]> random_array(unsigned n, int type) {
|
||||
std::unique_ptr<double[]> r(new double[n]);
|
||||
std::default_random_engine gen(1);
|
||||
if (type) { // type == 1
|
||||
std::normal_distribution<> d(0.5, 0.3);
|
||||
for (unsigned i = 0; i < n; ++i)
|
||||
r[i] = d(gen);
|
||||
for (unsigned i = 0; i < n; ++i) r[i] = d(gen);
|
||||
} else { // type == 0
|
||||
std::uniform_real_distribution<> d(0.0, 1.0);
|
||||
for (unsigned i = 0; i < n; ++i)
|
||||
r[i] = d(gen);
|
||||
for (unsigned i = 0; i < n; ++i) r[i] = d(gen);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@ -37,8 +35,7 @@ void compare_1d(unsigned n, int distrib) {
|
||||
gsl_histogram* h = gsl_histogram_alloc(100);
|
||||
gsl_histogram_set_ranges_uniform(h, 0, 1);
|
||||
auto t = clock();
|
||||
for (unsigned i = 0; i < n; ++i)
|
||||
gsl_histogram_increment(h, r[i]);
|
||||
for (unsigned i = 0; i < n; ++i) gsl_histogram_increment(h, r[i]);
|
||||
t = clock() - t;
|
||||
best = std::min(best, double(t) / CLOCKS_PER_SEC);
|
||||
gsl_histogram_free(h);
|
||||
|
@ -13,20 +13,18 @@
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
#include <limits>
|
||||
#include <random>
|
||||
#include <memory>
|
||||
#include <random>
|
||||
|
||||
std::unique_ptr<double[]> random_array(unsigned n, int type) {
|
||||
std::unique_ptr<double[]> r(new double[n]);
|
||||
std::default_random_engine gen(1);
|
||||
if (type) { // type == 1
|
||||
std::normal_distribution<> d(0.5, 0.3);
|
||||
for (unsigned i = 0; i < n; ++i)
|
||||
r[i] = d(gen);
|
||||
for (unsigned i = 0; i < n; ++i) r[i] = d(gen);
|
||||
} else { // type == 0
|
||||
std::uniform_real_distribution<> d(0.0, 1.0);
|
||||
for (unsigned i = 0; i < n; ++i)
|
||||
r[i] = d(gen);
|
||||
for (unsigned i = 0; i < n; ++i) r[i] = d(gen);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@ -38,8 +36,7 @@ void compare_1d(unsigned n, int distrib) {
|
||||
for (unsigned k = 0; k < 20; ++k) {
|
||||
TH1I hroot("", "", 100, 0, 1);
|
||||
auto t = clock();
|
||||
for (unsigned i = 0; i < n; ++i)
|
||||
hroot.Fill(r[i]);
|
||||
for (unsigned i = 0; i < n; ++i) hroot.Fill(r[i]);
|
||||
t = clock() - t;
|
||||
best_root = std::min(best_root, double(t) / CLOCKS_PER_SEC);
|
||||
}
|
||||
@ -53,8 +50,7 @@ void compare_2d(unsigned n, int distrib) {
|
||||
for (unsigned k = 0; k < 20; ++k) {
|
||||
TH2I hroot("", "", 100, 0, 1, 100, 0, 1);
|
||||
auto t = clock();
|
||||
for (unsigned i = 0; i < n / 2; ++i)
|
||||
hroot.Fill(r[2 * i], r[2 * i + 1]);
|
||||
for (unsigned i = 0; i < n / 2; ++i) hroot.Fill(r[2 * i], r[2 * i + 1]);
|
||||
t = clock() - t;
|
||||
best_root = std::min(best_root, double(t) / CLOCKS_PER_SEC);
|
||||
}
|
||||
@ -87,9 +83,7 @@ void compare_6d(unsigned n, int distrib) {
|
||||
THnI hroot("", "", 6, &bin.front(), &min.front(), &max.front());
|
||||
|
||||
auto t = clock();
|
||||
for (unsigned i = 0; i < n / 6; ++i) {
|
||||
hroot.Fill(r.get() + 6 * i);
|
||||
}
|
||||
for (unsigned i = 0; i < n / 6; ++i) { hroot.Fill(r.get() + 6 * i); }
|
||||
t = clock() - t;
|
||||
best_root = std::min(best_root, double(t) / CLOCKS_PER_SEC);
|
||||
}
|
||||
|
@ -22,8 +22,7 @@ namespace std { // never add to std, we only do it to get ADL working
|
||||
template <typename T>
|
||||
ostream& operator<<(ostream& os, const vector<T>& v) {
|
||||
os << "[ ";
|
||||
for (const auto& x : v)
|
||||
os << x << " ";
|
||||
for (const auto& x : v) os << x << " ";
|
||||
os << "]";
|
||||
return os;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user