mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
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:
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user