Added interpolation of observed values to statistics computation

p4#: 21492
This commit is contained in:
Magne Sjaastad 2013-04-30 11:36:50 +02:00
parent d84d69ffc2
commit 6ef5205343
7 changed files with 111 additions and 5 deletions

View File

@ -37,9 +37,10 @@ namespace caf {
template<>
void caf::AppEnum<RimStatisticsCase::PercentileCalcType>::setUp()
{
addItem(RimStatisticsCase::NEAREST_OBSERVATION, "NearestObservationPercentile", "Nearest Observation");
addItem(RimStatisticsCase::HISTOGRAM_ESTIMATED, "HistogramEstimatedPercentile", "Histogram based estimate");
setDefault(RimStatisticsCase::NEAREST_OBSERVATION);
addItem(RimStatisticsCase::NEAREST_OBSERVATION, "NearestObservationPercentile", "Nearest Observation");
addItem(RimStatisticsCase::HISTOGRAM_ESTIMATED, "HistogramEstimatedPercentile", "Histogram based estimate");
addItem(RimStatisticsCase::INTERPOLATED_OBSERVATION, "InterpolatedObservationPercentile", "Interpolated Observation");
setDefault(RimStatisticsCase::INTERPOLATED_OBSERVATION);
}
}

View File

@ -58,7 +58,8 @@ public:
enum PercentileCalcType
{
NEAREST_OBSERVATION,
HISTOGRAM_ESTIMATED
HISTOGRAM_ESTIMATED,
INTERPOLATED_OBSERVATION
};

View File

@ -284,6 +284,17 @@ void RimStatisticsCaseEvaluator::evaluateForResults(const QList<ResSpec>& result
statParams[PMID] = histCalc.calculatePercentil(m_statisticsConfig.m_pMidPos);
statParams[PMAX] = histCalc.calculatePercentil(m_statisticsConfig.m_pMaxPos);
}
else if (m_statisticsConfig.m_pValMethod == RimStatisticsCase::INTERPOLATED_OBSERVATION)
{
std::vector<double> pValPoss;
pValPoss.push_back(m_statisticsConfig.m_pMinPos);
pValPoss.push_back(m_statisticsConfig.m_pMidPos);
pValPoss.push_back(m_statisticsConfig.m_pMaxPos);
std::vector<double> pVals = RigStatisticsMath::calculateInterpolatedPercentiles(values, pValPoss);
statParams[PMIN] = pVals[0];
statParams[PMID] = pVals[1];
statParams[PMAX] = pVals[2];
}
else
{
CVF_ASSERT(false);

View File

@ -41,7 +41,7 @@ public:
m_pMinPos(10.0),
m_pMidPos(50.0),
m_pMaxPos(90.0),
m_pValMethod(RimStatisticsCase::NEAREST_OBSERVATION)
m_pValMethod(RimStatisticsCase::INTERPOLATED_OBSERVATION)
{
}

View File

@ -141,3 +141,44 @@ TEST(RigStatisticsMath, HistogramPercentiles)
EXPECT_DOUBLE_EQ( 5312.1312871307755 , p50);
EXPECT_DOUBLE_EQ( 94818.413022321271 , p90);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST(RigStatisticsMath, InterpolatedPercentiles)
{
std::vector<double> values;
values.push_back(HUGE_VAL);
values.push_back(2788.2723335651900);
values.push_back(-22481.0927881701000);
values.push_back(68778.6851686236000);
values.push_back(-76092.8157632591000);
values.push_back(6391.97999909729003);
values.push_back(65930.1200169780000);
values.push_back(-27696.2320267235000);
values.push_back(HUGE_VAL);
values.push_back(HUGE_VAL);
values.push_back(96161.7546348456000);
values.push_back(73875.6716288563000);
values.push_back(80720.4378655615000);
values.push_back(-98649.8109937874000);
values.push_back(99372.9362079615000);
values.push_back(HUGE_VAL);
values.push_back(-57020.4389966513000);
std::vector<double> pValPos;
pValPos.push_back(10);
pValPos.push_back(40);
pValPos.push_back(50);
pValPos.push_back(90);
std::vector<double> pVals = RigStatisticsMath::calculateInterpolatedPercentiles(values, pValPos);
/*
EXPECT_DOUBLE_EQ( -76092.8157632591000, pVals[0]);
EXPECT_DOUBLE_EQ( 2788.2723335651900 , pVals[1]);
EXPECT_DOUBLE_EQ( 6391.979999097290 , pVals[2]);
EXPECT_DOUBLE_EQ( 96161.7546348456000 , pVals[3]);
*/
}

View File

@ -19,6 +19,7 @@
#include "RigStatisticsMath.h"
#include <algorithm>
#include <assert.h>
#include <math.h>
//--------------------------------------------------------------------------------------------------
/// A function to do basic statistical calculations
@ -114,6 +115,56 @@ std::vector<double> RigStatisticsMath::calculateNearestRankPercentiles(const std
return percentiles;
};
//--------------------------------------------------------------------------------------------------
/// Calculate the percentiles of /a inputValues at the pValPosition percentages by interpolating input values.
/// This method treats HUGE_VAL as "undefined" values, and ignores these. Will return HUGE_VAL if
/// the inputValues does not contain any valid values
//--------------------------------------------------------------------------------------------------
std::vector<double> RigStatisticsMath::calculateInterpolatedPercentiles(const std::vector<double> & inputValues, const std::vector<double>& pValPositions)
{
std::vector<double> sortedValues;
sortedValues.reserve(inputValues.size());
for (size_t i = 0; i < inputValues.size(); ++i)
{
if (inputValues[i] != HUGE_VAL)
{
sortedValues.push_back(inputValues[i]);
}
}
std::sort(sortedValues.begin(), sortedValues.end());
std::vector<double> percentiles(pValPositions.size(), HUGE_VAL);
if (sortedValues.size())
{
for (size_t i = 0; i < pValPositions.size(); ++i)
{
double pVal = HUGE_VAL;
double doubleIndex = sortedValues.size() * fabs(pValPositions[i]) / 100.0;
size_t lowerValueIndex = static_cast<size_t>(floor(doubleIndex));
size_t upperValueIndex = lowerValueIndex + 1;
if (lowerValueIndex >= sortedValues.size() ) lowerValueIndex = sortedValues.size() - 1;
if (upperValueIndex >= sortedValues.size() ) upperValueIndex = sortedValues.size() - 1;
double upperValueWeight = 1.0;
if (lowerValueIndex != upperValueIndex)
{
upperValueWeight = doubleIndex - lowerValueIndex;
assert(upperValueWeight < 1.0);
}
pVal = (1.0 - upperValueWeight) * sortedValues[lowerValueIndex] + upperValueWeight * sortedValues[upperValueIndex];
percentiles[i] = pVal;
}
}
return percentiles;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -26,6 +26,7 @@ class RigStatisticsMath
public:
static void calculateBasicStatistics(const std::vector<double>& values, double* min, double* max, double* range, double* mean, double* dev);
static std::vector<double> calculateNearestRankPercentiles(const std::vector<double> & inputValues, const std::vector<double>& pValPositions);
static std::vector<double> calculateInterpolatedPercentiles(const std::vector<double> & inputValues, const std::vector<double>& pValPositions);
};
//==================================================================================================