Moved the statistical calculation algorithm code into a separate file.

Added unit test to these calculations, and fixed a calculation error.
p4#: 21140
This commit is contained in:
Jacob Støren
2013-04-05 10:49:39 +02:00
parent db62f01e0a
commit 0fed66deb2
11 changed files with 404 additions and 187 deletions

View File

@@ -116,86 +116,3 @@ private:
RigMainGrid* m_ownerMainGrid;
};
class RigHistogramCalculator
{
public:
RigHistogramCalculator(double min, double max, size_t nBins, std::vector<size_t>* histogram)
{
CVF_ASSERT(histogram);
CVF_ASSERT(nBins > 0);
if (max == min) { nBins = 1; } // Avoid dividing on 0 range
m_histogram = histogram;
m_min = min;
m_observationCount = 0;
// Initialize bins
m_histogram->resize(nBins);
for (size_t i = 0; i < m_histogram->size(); ++i) (*m_histogram)[i] = 0;
m_range = max - min;
maxIndex = nBins-1;
}
void addData(const std::vector<double>& data)
{
CVF_ASSERT(m_histogram);
for (size_t i = 0; i < data.size(); ++i)
{
if (data[i] == HUGE_VAL)
{
continue;
}
size_t index = 0;
if (maxIndex > 0) index = (size_t)(maxIndex*(data[i] - m_min)/m_range);
if(index < m_histogram->size()) // Just clip to the max min range (-index will overflow to positive )
{
(*m_histogram)[index]++;
m_observationCount++;
}
}
}
/// Calculates the estimated percentile from the histogram.
/// the percentile is the domain value at which pVal of the observations are below it.
/// Will only consider observed values between min and max, as all other values are discarded from the histogram
double calculatePercentil(double pVal)
{
CVF_ASSERT(m_histogram);
CVF_ASSERT(m_histogram->size());
CVF_ASSERT( 0.0 <= pVal && pVal <= 1.0);
double pValObservationCount = pVal*m_observationCount;
if (pValObservationCount == 0.0) return m_min;
size_t accObsCount = 0;
double binWidth = m_range/m_histogram->size();
for (size_t binIdx = 0; binIdx < m_histogram->size(); ++binIdx)
{
size_t binObsCount = (*m_histogram)[binIdx];
accObsCount += binObsCount;
if (accObsCount >= pValObservationCount)
{
double domainValueAtEndOfBin = m_min + (binIdx+1) * binWidth;
double unusedFractionOfLastBin = (double)(accObsCount - pValObservationCount)/binObsCount;
return domainValueAtEndOfBin - unusedFractionOfLastBin*binWidth;
}
}
CVF_ASSERT(false);
return HUGE_VAL;
}
private:
size_t maxIndex;
double m_range;
double m_min;
size_t m_observationCount;
std::vector<size_t>* m_histogram;
};