mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
hist: use more C++ constructs
This commit is contained in:
parent
7a65f5ff41
commit
a7b7727047
3 changed files with 46 additions and 67 deletions
|
@ -23,8 +23,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#include <jansson.h>
|
||||
|
||||
|
@ -38,13 +37,11 @@ class Hist {
|
|||
|
||||
public:
|
||||
using cnt_t = uintmax_t;
|
||||
using idx_t = std::vector<cnt_t>::difference_type;
|
||||
|
||||
/** Initialize struct hist with supplied values and allocate memory for buckets. */
|
||||
Hist(int buckets = 0, cnt_t warmup = 0);
|
||||
|
||||
/** Free the dynamically allocated memory. */
|
||||
~Hist();
|
||||
|
||||
/** Reset all counters and values back to zero. */
|
||||
void reset();
|
||||
|
||||
|
@ -121,8 +118,6 @@ protected:
|
|||
double lowest; /**< The lowest value observed (may be lower than #low). */
|
||||
double last; /**< The last value which has been put into the buckets */
|
||||
|
||||
int length; /**< The number of buckets in #data. */
|
||||
|
||||
cnt_t total; /**< Total number of counted values. */
|
||||
cnt_t warmup; /**< Number of values which are used during warmup phase. */
|
||||
|
||||
|
@ -130,7 +125,7 @@ protected:
|
|||
cnt_t lower; /**< The number of values which are lower than #low. */
|
||||
|
||||
|
||||
cnt_t *data; /**< Pointer to dynamically allocated array of size length. */
|
||||
std::vector<cnt_t> data; /**< Bucket counters. */
|
||||
|
||||
double _m[2], _s[2]; /**< Private variables for online variance calculation */
|
||||
};
|
||||
|
|
|
@ -20,12 +20,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <float.h>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
#include <algorithm>
|
||||
|
||||
#include <villas/utils.hpp>
|
||||
#include <villas/hist.hpp>
|
||||
|
@ -36,21 +32,10 @@ using namespace villas::utils;
|
|||
|
||||
namespace villas {
|
||||
|
||||
Hist::Hist(int buckets, Hist::cnt_t wu)
|
||||
{
|
||||
length = buckets;
|
||||
warmup = wu;
|
||||
|
||||
data = (Hist::cnt_t *) (buckets ? alloc(length * sizeof(Hist::cnt_t)) : nullptr);
|
||||
|
||||
Hist::reset();
|
||||
}
|
||||
|
||||
Hist::~Hist()
|
||||
{
|
||||
if (data)
|
||||
free(data);
|
||||
}
|
||||
Hist::Hist(int buckets, Hist::cnt_t wu) :
|
||||
warmup(wu),
|
||||
data(buckets)
|
||||
{ }
|
||||
|
||||
void Hist::put(double value)
|
||||
{
|
||||
|
@ -62,24 +47,26 @@ void Hist::put(double value)
|
|||
if (value < lowest)
|
||||
lowest = value;
|
||||
|
||||
if (total < warmup) {
|
||||
if (data.size()) {
|
||||
if (total < warmup) {
|
||||
/* We are still in warmup phase... Waiting for more samples... */
|
||||
}
|
||||
else if (data.size() && total == warmup) {
|
||||
low = getMean() - 3 * getStddev();
|
||||
high = getMean() + 3 * getStddev();
|
||||
resolution = (high - low) / data.size();
|
||||
}
|
||||
else {
|
||||
idx_t idx = std::round((value - low) / resolution);
|
||||
|
||||
}
|
||||
else if (total == warmup) {
|
||||
low = getMean() - 3 * getStddev();
|
||||
high = getMean() + 3 * getStddev();
|
||||
resolution = (high - low) / length;
|
||||
}
|
||||
else {
|
||||
int idx = round((value - low) / resolution);
|
||||
|
||||
/* Check bounds and increment */
|
||||
if (idx >= length)
|
||||
higher++;
|
||||
else if (idx < 0)
|
||||
lower++;
|
||||
else if (data != nullptr)
|
||||
data[idx]++;
|
||||
/* Check bounds and increment */
|
||||
if (idx >= (idx_t) data.size())
|
||||
higher++;
|
||||
else if (idx < 0)
|
||||
lower++;
|
||||
else
|
||||
data[idx]++;
|
||||
}
|
||||
}
|
||||
|
||||
total++;
|
||||
|
@ -107,21 +94,21 @@ void Hist::reset()
|
|||
higher = 0;
|
||||
lower = 0;
|
||||
|
||||
highest = -DBL_MAX;
|
||||
lowest = DBL_MAX;
|
||||
highest = std::numeric_limits<double>::min();
|
||||
lowest = std::numeric_limits<double>::max();
|
||||
|
||||
if (data)
|
||||
memset(data, 0, length * sizeof(unsigned));
|
||||
for (auto &elm : data)
|
||||
elm = 0;
|
||||
}
|
||||
|
||||
double Hist::getMean() const
|
||||
{
|
||||
return (total > 0) ? _m[0] : NAN;
|
||||
return total > 0 ? _m[0] : std::numeric_limits<double>::quiet_NaN();
|
||||
}
|
||||
|
||||
double Hist::getVar() const
|
||||
{
|
||||
return (total > 1) ? _s[0] / (total - 1) : NAN;
|
||||
return total > 1 ? _s[0] / (total - 1) : std::numeric_limits<double>::quiet_NaN();
|
||||
}
|
||||
|
||||
double Hist::getStddev() const
|
||||
|
@ -156,13 +143,8 @@ void Hist::print(bool details) const
|
|||
|
||||
void Hist::plot() const
|
||||
{
|
||||
Hist::cnt_t max = 1;
|
||||
|
||||
/* Get highest bar */
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (data[i] > max)
|
||||
max = data[i];
|
||||
}
|
||||
Hist::cnt_t max = *std::max_element(data.begin(), data.end());
|
||||
|
||||
std::vector<TableColumn> cols = {
|
||||
{ -9, TableColumn::Alignment::RIGHT, "Value", "%+9.3g" },
|
||||
|
@ -175,7 +157,7 @@ void Hist::plot() const
|
|||
/* Print plot */
|
||||
table.header();
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
for (size_t i = 0; i < data.size(); i++) {
|
||||
double value = low + (i) * resolution;
|
||||
Hist::cnt_t cnt = data[i];
|
||||
int bar = cols[2].getWidth() * ((double) cnt / max);
|
||||
|
@ -196,8 +178,8 @@ char * Hist::dump() const
|
|||
|
||||
strcatf(&buf, "[ ");
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
strcatf(&buf, "%ju ", data[i]);
|
||||
for (auto elm : data)
|
||||
strcatf(&buf, "%ju ", elm);
|
||||
|
||||
strcatf(&buf, "]");
|
||||
|
||||
|
@ -229,8 +211,8 @@ json_t * Hist::toJson() const
|
|||
if (total - lower - higher > 0) {
|
||||
json_buckets = json_array();
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
json_array_append(json_buckets, json_integer(data[i]));
|
||||
for (auto elm : data)
|
||||
json_array_append(json_buckets, json_integer(elm));
|
||||
|
||||
json_object_set(json_hist, "buckets", json_buckets);
|
||||
}
|
||||
|
@ -269,7 +251,7 @@ int Hist::dumpMatlab(FILE *f) const
|
|||
free(buf);
|
||||
}
|
||||
else
|
||||
fprintf(f, "'buckets', zeros(1, %d)", length);
|
||||
fprintf(f, "'buckets', zeros(1, %zu)", data.size());
|
||||
|
||||
fprintf(f, ")");
|
||||
|
||||
|
|
|
@ -20,12 +20,14 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <array>
|
||||
|
||||
#include <criterion/criterion.h>
|
||||
|
||||
#include <villas/hist.hpp>
|
||||
#include <villas/utils.hpp>
|
||||
|
||||
const double test_data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
const std::array<double, 10> test_data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
|
||||
using namespace villas;
|
||||
|
||||
|
@ -35,10 +37,10 @@ Test(hist, simple) {
|
|||
|
||||
Hist h;
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_LEN(test_data); i++)
|
||||
h.put(test_data[i]);
|
||||
for (auto td : test_data)
|
||||
h.put(td);
|
||||
|
||||
cr_assert_float_eq(h.getMean(), 5.5, 1e-6);
|
||||
cr_assert_float_eq(h.getMean(), 5.5, 1e-6, "Mean is %lf", h.getMean());
|
||||
cr_assert_float_eq(h.getVar(), 9.1666, 1e-3,);
|
||||
cr_assert_float_eq(h.getStddev(), 3.027650, 1e-6);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue