#2659 Ensemble statistics. New and more precise way to calculate statistics

This commit is contained in:
Bjørn Erik Jensen 2018-06-14 08:37:56 +02:00
parent 4c25ba8c7d
commit 9c06df11d5
2 changed files with 66 additions and 14 deletions

View File

@ -26,6 +26,8 @@
#include "RimEnsembleCurveSet.h" #include "RimEnsembleCurveSet.h"
#include <vector>
#include <set>
#include <limits> #include <limits>
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -156,25 +158,16 @@ void RimEnsembleStatisticsCase::calculate(const std::vector<RimSummaryCase*> sum
for (int t = 0; t < (int)allTimeSteps.size(); t++) for (int t = 0; t < (int)allTimeSteps.size(); t++)
{ {
std::vector<double> valuesForTimeSteps; std::vector<double> valuesAtTimeStep;
valuesForTimeSteps.reserve(sumCases.size()); valuesAtTimeStep.reserve(sumCases.size());
for (int c = 0; c < sumCases.size(); c++) for (int c = 0; c < sumCases.size(); c++)
{ {
valuesForTimeSteps.push_back(allValues[c][t]); valuesAtTimeStep.push_back(allValues[c][t]);
} }
double min, max, range, mean, stdev; double p10, p50, p90, mean;
RigStatisticsMath::calculateBasicStatistics(valuesForTimeSteps, &min, &max, nullptr, &range, &mean, &stdev); calculateStatistics(valuesAtTimeStep, &p10, &p50, &p90, &mean);
std::vector<size_t> histogram;
RigHistogramCalculator histCalc(min, max, 100, &histogram);
histCalc.addData(valuesForTimeSteps);
double p10, p50, p90;
p10 = histCalc.calculatePercentil(0.1);
p50 = histCalc.calculatePercentil(0.5);
p90 = histCalc.calculatePercentil(0.9);
m_p10Data.push_back(p10); m_p10Data.push_back(p10);
m_p50Data.push_back(p50); m_p50Data.push_back(p50);
@ -239,3 +232,61 @@ std::vector<RimSummaryCase*> RimEnsembleStatisticsCase::validSummaryCases(const
} }
return validCases; return validCases;
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEnsembleStatisticsCase::calculateStatistics(const std::vector<double>& values, double* p10, double* p50, double* p90, double* mean)
{
CVF_ASSERT(p10 && p50 && p90 && mean);
std::multiset<double> vSet(values.begin(), values.end());
int count = 0;
double total = 0;
double p10Count = (double)vSet.size() * 0.1;
double p50Count = (double)vSet.size() * 0.5;
double p90Count = (double)vSet.size() * 0.9;
int p10CountFloor = std::floor(p10Count);
int p50CountFloor = std::floor(p50Count);
int p90CountFloor = std::floor(p90Count);
enum State { P10, P50, P90, DONE } state = P10;
for (double val : vSet)
{
count++;
total += val;
switch (state)
{
case DONE:
break;
case P10:
if (count >= p10CountFloor)
{
*p10 = val;
state = P50;
}
break;
case P50:
if (count >= p50CountFloor)
{
*p50 = val;
state = P90;
}
break;
case P90:
if (count >= p90CountFloor)
{
*p90 = val;
state = DONE;
}
break;
}
}
*mean = total / vSet.size();
}

View File

@ -55,6 +55,7 @@ private:
void calculate(const std::vector<RimSummaryCase*> sumCases, const RifEclipseSummaryAddress& inputAddress); void calculate(const std::vector<RimSummaryCase*> sumCases, const RifEclipseSummaryAddress& inputAddress);
void clearData(); void clearData();
std::vector<RimSummaryCase*> validSummaryCases(const std::vector<RimSummaryCase*> allSumCases, const RifEclipseSummaryAddress& inputAddress); std::vector<RimSummaryCase*> validSummaryCases(const std::vector<RimSummaryCase*> allSumCases, const RifEclipseSummaryAddress& inputAddress);
void calculateStatistics(const std::vector<double>& values, double* p10, double* p50, double* p90, double* mean);
private: private:
std::unique_ptr<RifEnsembleStatisticsReader> m_statisticsReader; std::unique_ptr<RifEnsembleStatisticsReader> m_statisticsReader;