#ifndef GLTB_HISTOGRAM_H #define GLTB_HISTOGRAM_H #include #include #include #include "GLTB/referencedobject.h" namespace gltb { template class Histogram1D : public ReferencedObject { public: Histogram1D(std::vector data, size_t numBins) : lowCount(0), highCount(0) { counts.resize(numBins); resetCounts(); minValue = data[0]; maxValue = data[0]; for(scalarType value : data) { minValue = std::min(minValue, value); maxValue = std::max(maxValue, value); } processData(data); } Histogram1D(const std::vector &data, size_t numBins, scalarType minValue, scalarType maxValue) : minValue(minValue), maxValue(maxValue), lowCount(0), highCount(0) { counts.resize(numBins); resetCounts(); processData(data); } Histogram1D(size_t numBins, scalarType minValue, scalarType maxValue) : minValue(minValue), maxValue(maxValue), lowCount(0), highCount(0) { counts.resize(numBins); resetCounts(); } void resetCounts() { for(size_t i = 0; i < counts.size(); i++) { counts[i] = 0; } } void processData(const std::vector &data) { for(scalarType value : data) { processValue(value); } } void processValue(scalarType value) { if(value <= minValue) { lowCount++; } else if(value >= maxValue) { highCount++; } else { size_t bucketIndex = counts.size() * (value - minValue) / (maxValue - minValue); bucketIndex = std::max((size_t)0, std::min(bucketIndex, counts.size() -1)); counts[bucketIndex]++; } } scalarType getMinValue() const { return minValue; } scalarType getMaxValue() const { return maxValue; } std::uint32_t getLowCount() const { return lowCount; } std::uint32_t getHighCount() const { return highCount; } std::uint32_t getTotalCounts(bool includeLowAndHigh = true) const { std::uint32_t totalCounts = 0; if(includeLowAndHigh) { totalCounts += lowCount + highCount; } for(std::uint32_t count : counts) { totalCounts += count; } return totalCounts; } const std::vector &getHistogramCounts() const { return counts; } std::vector getNormalizedHistogram(bool includeLowAndHigh = true) const { std::uint32_t totalCounts = getTotalCounts(includeLowAndHigh); std::vector normalized(counts.size()); for(size_t i = 0; i < counts.size(); i++) { if(totalCounts > 0) { normalized[i] = (scalarType)counts[i] / scalarType(totalCounts); } else { normalized[i] = 0; } } return normalized; } private: scalarType minValue; scalarType maxValue; std::uint32_t lowCount; std::uint32_t highCount; std::vector counts; }; template class Histogram : public gltb::ReferencedObject { public: typedef typename vectorType::value_type scalarType; private: vectorType minValue; vectorType maxValue; std::vector outOfBoundsBins; // TODO how many low and high out of bounds bins are there? // 1D: 2 // 2D: 8 // 3D: 26? // nD: 3^n - 1 std::vector counts; }; } #endif