Commit d653e557 authored by Hahn, Steven's avatar Hahn, Steven
Browse files

Use boost::accumulator_set.

parent 8fe893ec
...@@ -11,6 +11,15 @@ ...@@ -11,6 +11,15 @@
#include <stdexcept> #include <stdexcept>
#include <functional> #include <functional>
#include <functional>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/median.hpp>
#include <boost/accumulators/statistics/min.hpp>
#include <boost/accumulators/statistics/max.hpp>
#include <boost/accumulators/statistics/variance.hpp>
namespace Mantid { namespace Mantid {
namespace Kernel { namespace Kernel {
...@@ -44,7 +53,7 @@ double getMedian(const vector<TYPE> &data, const size_t num_data, ...@@ -44,7 +53,7 @@ double getMedian(const vector<TYPE> &data, const size_t num_data,
if (num_data == 1) if (num_data == 1)
return static_cast<double>(*(data.begin())); return static_cast<double>(*(data.begin()));
bool is_even = ((num_data % 2) == 0); bool is_even = ((num_data & 1) == 0);
if (is_even) { if (is_even) {
double left = 0.0; double left = 0.0;
double right = 0.0; double right = 0.0;
...@@ -80,7 +89,8 @@ double getMedian(const vector<TYPE> &data, const size_t num_data, ...@@ -80,7 +89,8 @@ double getMedian(const vector<TYPE> &data, const size_t num_data,
return static_cast<double>(*(temp.begin() + num_data / 2)); return static_cast<double>(*(temp.begin() + num_data / 2));
} }
} }
} }
/** /**
* There are enough special cases in determining the Z score where it useful to * There are enough special cases in determining the Z score where it useful to
* put it in a single function. * put it in a single function.
...@@ -150,36 +160,41 @@ Statistics getStatistics(const vector<TYPE> &data, const unsigned int flags) { ...@@ -150,36 +160,41 @@ Statistics getStatistics(const vector<TYPE> &data, const unsigned int flags) {
if (num_data == 0) { // don't do anything if (num_data == 0) { // don't do anything
return stats; return stats;
} }
// calculate the mean if this or the stddev is requested // calculate the mean if this or the stddev is requested
const bool stddev = ((flags & StatOptions::UncorrectedStdDev) || const bool stddev = ((flags & StatOptions::UncorrectedStdDev) ||
(flags & StatOptions::CorrectedStdDev)); (flags & StatOptions::CorrectedStdDev));
if ((flags & StatOptions::Mean) || stddev) { if (stddev) {
const TYPE sum = std::accumulate(data.begin(), data.end(), using namespace boost::accumulators;
static_cast<TYPE>(0), std::plus<TYPE>()); accumulator_set<TYPE,
stats.mean = static_cast<double>(sum) / (static_cast<double>(num_data)); features<tag::min, tag::max, tag::mean, tag::variance>> acc;
if (stddev) { for (auto &value : data) {
// calculate the standard deviation, min, max acc(value);
stats.minimum = stats.mean; }
stats.maximum = stats.mean; stats.minimum = min(acc);
double stddev = 0.; stats.maximum = max(acc);
for (auto it = data.cbegin(); it != data.cend(); ++it) { stats.mean = mean(acc);
double temp = static_cast<double>(*it); double var = variance(acc);
stddev += ((temp - stats.mean) * (temp - stats.mean));
if (temp > stats.maximum) if (flags & StatOptions::CorrectedStdDev) {
stats.maximum = temp; double ndofs = static_cast<double>(data.size());
if (temp < stats.minimum) var *= ndofs / (ndofs - 1.0);
stats.minimum = temp; }
} stats.standard_deviation = std::sqrt(var);
size_t ndofs =
(flags & StatOptions::CorrectedStdDev) ? num_data - 1 : num_data; } else if (flags & StatOptions::Mean) {
stats.standard_deviation = sqrt(stddev / (static_cast<double>(ndofs))); using namespace boost::accumulators;
accumulator_set<TYPE, features<tag::mean>> acc;
for (auto &value : data) {
acc(value);
} }
stats.mean = mean(acc);
} }
// calculate the median if requested // calculate the median if requested
if (flags & StatOptions::Median) { if (flags & StatOptions::Median) {
stats.median = getMedian(data, num_data, flags & StatOptions::SortedData); stats.median = getMedian(data, num_data, flags & StatOptions::SortedData);
} }
return stats; return stats;
} }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment