Skip to content
Permalink
Browse files

Merge pull request #2592 from fweik/histogramm

core: utils: Avoid heap allocations when updating Histogram
  • Loading branch information...
fweik committed Mar 14, 2019
2 parents e0477bf + 04dfc97 commit 48f427366a7b2565c17ea34ec29a8dacb8bdf477
@@ -36,14 +36,12 @@ class DensityProfile : public PidProfileObservable {
std::make_pair(min_z, max_z)}};
Utils::Histogram<double, 3> histogram(n_bins, 1, limits);
for (auto const &id : ids()) {
auto const ppos = ::Vector3d(folded_position(partCfg[id]));
histogram.update(ppos);
histogram.update(folded_position(partCfg[id]));
}
histogram.normalize();
return histogram.get_histogram();
}
};

} // Namespace Observables

#endif
@@ -37,8 +37,7 @@ class FluxDensityProfile : public PidProfileObservable {
Utils::Histogram<double, 3> histogram(n_bins, 3, limits);
for (auto const &id : ids()) {
auto const ppos = ::Vector3d(folded_position(partCfg[id]));
histogram.update(ppos, ::Vector3d{{partCfg[id].m.v[0], partCfg[id].m.v[1],
partCfg[id].m.v[2]}});
histogram.update(ppos, partCfg[id].m.v);
}
histogram.normalize();
return histogram.get_histogram();
@@ -38,8 +38,7 @@ class ForceDensityProfile : public PidProfileObservable {
Utils::Histogram<double, 3> histogram(n_bins, 3, limits);
for (auto const &id : ids()) {
auto const ppos = ::Vector3d(folded_position(partCfg[id]));
histogram.update(ppos, ::Vector3d{{partCfg[id].f.f[0], partCfg[id].f.f[1],
partCfg[id].f.f[2]}});
histogram.update(ppos, partCfg[id].f.f);
}
histogram.normalize();
return histogram.get_histogram();
@@ -26,6 +26,7 @@
#include <numeric>
#include <vector>

#include "Span.hpp"
#include "constants.hpp"
#include "utils/index.hpp"

@@ -59,7 +60,7 @@ calc_bin_sizes(std::array<std::pair<T, T>, Dims> const &limits,
* \param limits: the min/max values.
*/
template <typename T, size_t Dims>
inline bool check_limits(std::vector<T> const &data,
inline bool check_limits(Span<const T> data,
std::array<std::pair<T, T>, Dims> limits) {
if (data.size() != limits.size()) {
throw std::invalid_argument("Dimension of data and limits not the same!");
@@ -81,8 +82,8 @@ template <typename T, size_t Dims> class Histogram {
std::vector<size_t> get_tot_count() const;
std::array<std::pair<T, T>, Dims> get_limits() const;
std::array<T, Dims> get_bin_sizes() const;
void update(std::vector<T> const &data);
void update(std::vector<T> const &data, std::vector<T> const &weights);
void update(Span<const T> data);
void update(Span<const T> data, Span<const T> weights);
void normalize();

private:
@@ -101,6 +102,7 @@ template <typename T, size_t Dims> class Histogram {
size_t m_n_dims_data;
// Track the number of total hits per bin entry.
std::vector<size_t> m_tot_count;
std::vector<T> m_ones;
};

/**
@@ -115,7 +117,8 @@ template <typename T, size_t Dims>
Histogram<T, Dims>::Histogram(std::array<size_t, Dims> n_bins,
size_t n_dims_data,
std::array<std::pair<T, T>, Dims> limits)
: m_n_bins(n_bins), m_limits(limits), m_n_dims_data(n_dims_data) {
: m_n_bins(n_bins), m_limits(limits), m_n_dims_data(n_dims_data),
m_ones(n_dims_data, T{1.}) {
if (n_bins.size() != limits.size()) {
throw std::invalid_argument("Argument for number of bins and limits do "
"not have same number of dimensions!");
@@ -135,10 +138,9 @@ Histogram<T, Dims>::Histogram(std::array<size_t, Dims> n_bins,
* of dimensions of the histogram.
*/
template <typename T, size_t Dims>
void Histogram<T, Dims>::update(std::vector<T> const &data) {
void Histogram<T, Dims>::update(Span<const T> data) {
if (check_limits(data, m_limits)) {
std::vector<T> weights(m_n_dims_data, static_cast<T>(1.0));
update(data, weights);
update(data, m_ones);
}
}

@@ -150,13 +152,12 @@ void Histogram<T, Dims>::update(std::vector<T> const &data) {
* \param weights: m_n_dims_data dimensional weights.
*/
template <typename T, size_t Dims>
void Histogram<T, Dims>::update(std::vector<T> const &data,
std::vector<T> const &weights) {
void Histogram<T, Dims>::update(Span<const T> data, Span<const T> weights) {
if (check_limits(data, m_limits)) {
std::vector<size_t> index;
Array<size_t, Dims> index;
for (size_t dim = 0; dim < m_n_bins.size(); ++dim) {
index.push_back(calculate_bin_index(data[dim], m_bin_sizes[dim],
m_limits[dim].first));
index[dim] =
calculate_bin_index(data[dim], m_bin_sizes[dim], m_limits[dim].first);
}
auto const flat_index =
m_n_dims_data * ::Utils::ravel_index(index, m_n_bins);
@@ -1,10 +1,8 @@
#ifndef UTILS_INDEX_HPP
#define UTILS_INDEX_HPP

#include <array>
#include <iterator>
#include <numeric>
#include <vector>

namespace Utils {

0 comments on commit 48f4273

Please sign in to comment.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.