#3281 Add weighted geometric mean calculator

This commit is contained in:
Bjørn Erik Jensen 2018-08-31 09:11:44 +02:00
parent f8045826c7
commit 130828416d
5 changed files with 143 additions and 0 deletions

View File

@ -34,6 +34,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiaArcCurveCalculator.h
${CMAKE_CURRENT_LIST_DIR}/RiaJCurveCalculator.h ${CMAKE_CURRENT_LIST_DIR}/RiaJCurveCalculator.h
${CMAKE_CURRENT_LIST_DIR}/RiaOffshoreSphericalCoords.h ${CMAKE_CURRENT_LIST_DIR}/RiaOffshoreSphericalCoords.h
${CMAKE_CURRENT_LIST_DIR}/RiaWeightedAverageCalculator.h ${CMAKE_CURRENT_LIST_DIR}/RiaWeightedAverageCalculator.h
${CMAKE_CURRENT_LIST_DIR}/RiaWeightedGeometricMeanCalculator.h
) )
set (SOURCE_GROUP_SOURCE_FILES set (SOURCE_GROUP_SOURCE_FILES
@ -70,6 +71,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiaSCurveCalculator.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaArcCurveCalculator.cpp ${CMAKE_CURRENT_LIST_DIR}/RiaArcCurveCalculator.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaJCurveCalculator.cpp ${CMAKE_CURRENT_LIST_DIR}/RiaJCurveCalculator.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaWeightedAverageCalculator.cpp ${CMAKE_CURRENT_LIST_DIR}/RiaWeightedAverageCalculator.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaWeightedGeometricMeanCalculator.cpp
) )
list(APPEND CODE_HEADER_FILES list(APPEND CODE_HEADER_FILES

View File

@ -0,0 +1,65 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight 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.
//
// ResInsight 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 "RiaWeightedGeometricMeanCalculator.h"
#include "cvfAssert.h"
#include <cmath>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaWeightedGeometricMeanCalculator::RiaWeightedGeometricMeanCalculator()
: m_aggregatedWeightedValue(1.0)
, m_aggregatedWeight(0.0)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaWeightedGeometricMeanCalculator::addValueAndWeight(double value, double weight)
{
CVF_ASSERT(weight >= 0.0);
// This can be a very big number, consider other algorithms if that becomes a problem
m_aggregatedWeightedValue *= std::pow(value, weight);
m_aggregatedWeight += weight;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RiaWeightedGeometricMeanCalculator::weightedMean() const
{
if (m_aggregatedWeight > 1e-7)
{
return std::pow(m_aggregatedWeightedValue, 1 / m_aggregatedWeight);
}
return 0.0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RiaWeightedGeometricMeanCalculator::aggregatedWeight() const
{
return m_aggregatedWeight;
}

View File

@ -0,0 +1,37 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil ASA
//
// ResInsight 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.
//
// ResInsight 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RiaWeightedGeometricMeanCalculator
{
public:
RiaWeightedGeometricMeanCalculator();
void addValueAndWeight(double value, double weight);
double weightedMean() const;
double aggregatedWeight() const;
private:
double m_aggregatedWeightedValue;
double m_aggregatedWeight;
};

View File

@ -48,6 +48,7 @@ ${CMAKE_CURRENT_LIST_DIR}/SolveSpaceSolver-Test.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaPolyArcLineSampler-Test.cpp ${CMAKE_CURRENT_LIST_DIR}/RiaPolyArcLineSampler-Test.cpp
${CMAKE_CURRENT_LIST_DIR}/RifEclipseDataTableFormatter-Test.cpp ${CMAKE_CURRENT_LIST_DIR}/RifEclipseDataTableFormatter-Test.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaWeightedAverage-Test.cpp ${CMAKE_CURRENT_LIST_DIR}/RiaWeightedAverage-Test.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaWeightedGeometricMeanCalculator-Test.cpp
) )
list(APPEND CODE_HEADER_FILES list(APPEND CODE_HEADER_FILES

View File

@ -0,0 +1,38 @@
#include "gtest/gtest.h"
#include "RiaWeightedGeometricMeanCalculator.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST(RiaWeightedGeometricMeanCalculator, BasicUsage)
{
{
RiaWeightedGeometricMeanCalculator calc;
EXPECT_DOUBLE_EQ(0.0, calc.aggregatedWeight());
EXPECT_DOUBLE_EQ(0.0, calc.weightedMean());
}
{
RiaWeightedGeometricMeanCalculator calc;
std::vector<double> values {30.0, 60.0};
std::vector<double> weights {1.5, 3.5};
for (size_t i = 0; i< values.size(); i++)
{
calc.addValueAndWeight(values[i], weights[i]);
}
double expectedValue = std::pow(
std::pow(30.0, 1.5) * std::pow(60.0, 3.5),
1 / (1.5 + 3.5)
);
EXPECT_DOUBLE_EQ(5.0, calc.aggregatedWeight());
EXPECT_DOUBLE_EQ(expectedValue, calc.weightedMean());
}
}