Files
ResInsight/ThirdParty/Ert/lib/util/statistics.cpp
T
Magne Sjaastad 04091ad77d #4266 Update libecl
Use commit 0e1e780fd6f18ce93119061e36a4fca9711bc020

Excluded multibuild folder, as this caused git issues
2019-05-09 08:40:32 +02:00

144 lines
4.2 KiB
C++

/*
Copyright (C) 2011 Equinor ASA, Norway.
The file 'statistics.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <math.h>
#include <stdlib.h>
#include <ert/util/util.h>
#include <ert/util/double_vector.hpp>
#include <ert/util/statistics.hpp>
double statistics_mean( const double_vector_type * data_vector ) {
const double * data = double_vector_get_const_ptr( data_vector );
int size = double_vector_size( data_vector );
double sum = 0;
int i;
for (i=0; i < size; i++)
sum += data[i];
return sum / size;
}
double statistics_std( const double_vector_type * data_vector ) {
const double * data = double_vector_get_const_ptr( data_vector );
double std = 0;
double mean = statistics_mean( data_vector );
int size = double_vector_size( data_vector );
int i;
for (i=0; i < size; i++) {
double d = (data[i] - mean);
std += d*d;
}
return sqrt(std / size);
}
/**
Observe that the data vector will be sorted in place. If the vector is
already sorted, e.g. from a previous call to statistics_empirical_quantile(),
you can call statistics_empirical_quantile__() directly.
*/
double statistics_empirical_quantile( double_vector_type * data , double quantile ) {
double_vector_sort( data );
return statistics_empirical_quantile__( data , quantile );
}
/**
This assumes that data has already been sorted, either from a
previous call to statistics_empirical_quantile( ) or by sorting
data explicitly with double_vector_sort( data );
*/
double statistics_empirical_quantile__( const double_vector_type * data , double quantile ) {
if ((quantile < 0) || (quantile > 1.0))
util_abort("%s: quantile must be in [0,1] \n",__func__);
{
const int size = (double_vector_size( data ) - 1);
if (double_vector_iget( data , 0) == double_vector_iget( data , size))
/*
All elements are equal - and it is impossible to find a meaingful quantile,
we just return "the value".
*/
return double_vector_iget( data, 0 );
else {
double value;
double lower_value;
double upper_value;
double real_index;
double upper_quantile;
double lower_quantile;
int lower_index;
int upper_index;
real_index = quantile * size;
lower_index = floor( real_index );
upper_index = ceil( real_index );
upper_value = double_vector_iget( data , upper_index );
lower_value = double_vector_iget( data , lower_index );
/*
Will iterate in this loop until we have found upper_value !=
lower_value. As long as we know that now all elements are
equal (the first test), this is guaranteed to succeed, but of
course the estimate will not be very meaningful if the sample
consist of a significant number of equal values.
*/
while (true) {
/*1: Try to shift the upper index up. */
if (upper_value == lower_value) {
upper_index = util_int_min( size , upper_index + 1);
upper_value = double_vector_iget( data , upper_index );
} else
break;
/*2: Try to shift the lower index down. */
if (upper_value == lower_value) {
lower_index = util_int_max( 0 , lower_index - 1);
lower_value = double_vector_iget( data , lower_index );
} else
break;
}
upper_quantile = upper_index * 1.0 / size;
lower_quantile = lower_index * 1.0 / size;
/* Linear interpolation: */
{
double a = (upper_value - lower_value) / (upper_quantile - lower_quantile);
value = lower_value + a*(quantile - lower_quantile);
return value;
}
}
}
}