mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-09 23:16:00 -06:00
Added interpolation of observed values to statistics computation
p4#: 21492
This commit is contained in:
parent
d84d69ffc2
commit
6ef5205343
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,8 @@ public:
|
||||
enum PercentileCalcType
|
||||
{
|
||||
NEAREST_OBSERVATION,
|
||||
HISTOGRAM_ESTIMATED
|
||||
HISTOGRAM_ESTIMATED,
|
||||
INTERPOLATED_OBSERVATION
|
||||
};
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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]);
|
||||
*/
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
|
Loading…
Reference in New Issue
Block a user