Skip to content
Permalink
Browse files

core: utils: Avoid heap allocations when updating Histogram

  • Loading branch information...
fweik committed Mar 14, 2019
1 parent e0477bf commit a78430f107cda86d1bf80f5153e3d818d8c7a8d9
@@ -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();
@@ -28,6 +28,7 @@

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

namespace Utils {

@@ -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,7 @@ 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 +137,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 +151,13 @@ 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 a78430f

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.