diff --git a/ApplicationCode/Application/Tools/CMakeLists_files.cmake b/ApplicationCode/Application/Tools/CMakeLists_files.cmake index 31b73e05b8..7de31c36b1 100644 --- a/ApplicationCode/Application/Tools/CMakeLists_files.cmake +++ b/ApplicationCode/Application/Tools/CMakeLists_files.cmake @@ -34,6 +34,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiaArcCurveCalculator.h ${CMAKE_CURRENT_LIST_DIR}/RiaJCurveCalculator.h ${CMAKE_CURRENT_LIST_DIR}/RiaOffshoreSphericalCoords.h ${CMAKE_CURRENT_LIST_DIR}/RiaWeightedAverageCalculator.h +${CMAKE_CURRENT_LIST_DIR}/RiaWeightedGeometricMeanCalculator.h ) 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}/RiaJCurveCalculator.cpp ${CMAKE_CURRENT_LIST_DIR}/RiaWeightedAverageCalculator.cpp +${CMAKE_CURRENT_LIST_DIR}/RiaWeightedGeometricMeanCalculator.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/Application/Tools/RiaWeightedGeometricMeanCalculator.cpp b/ApplicationCode/Application/Tools/RiaWeightedGeometricMeanCalculator.cpp new file mode 100644 index 0000000000..cf522e28b7 --- /dev/null +++ b/ApplicationCode/Application/Tools/RiaWeightedGeometricMeanCalculator.cpp @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiaWeightedGeometricMeanCalculator.h" + +#include "cvfAssert.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +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; +} diff --git a/ApplicationCode/Application/Tools/RiaWeightedGeometricMeanCalculator.h b/ApplicationCode/Application/Tools/RiaWeightedGeometricMeanCalculator.h new file mode 100644 index 0000000000..e21253b463 --- /dev/null +++ b/ApplicationCode/Application/Tools/RiaWeightedGeometricMeanCalculator.h @@ -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 +// 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; +}; diff --git a/ApplicationCode/UnitTests/CMakeLists_files.cmake b/ApplicationCode/UnitTests/CMakeLists_files.cmake index 6d5ce9480a..ff8c0b9108 100644 --- a/ApplicationCode/UnitTests/CMakeLists_files.cmake +++ b/ApplicationCode/UnitTests/CMakeLists_files.cmake @@ -48,6 +48,7 @@ ${CMAKE_CURRENT_LIST_DIR}/SolveSpaceSolver-Test.cpp ${CMAKE_CURRENT_LIST_DIR}/RiaPolyArcLineSampler-Test.cpp ${CMAKE_CURRENT_LIST_DIR}/RifEclipseDataTableFormatter-Test.cpp ${CMAKE_CURRENT_LIST_DIR}/RiaWeightedAverage-Test.cpp +${CMAKE_CURRENT_LIST_DIR}/RiaWeightedGeometricMeanCalculator-Test.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/UnitTests/RiaWeightedGeometricMeanCalculator-Test.cpp b/ApplicationCode/UnitTests/RiaWeightedGeometricMeanCalculator-Test.cpp new file mode 100644 index 0000000000..6a3d48aee6 --- /dev/null +++ b/ApplicationCode/UnitTests/RiaWeightedGeometricMeanCalculator-Test.cpp @@ -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 values {30.0, 60.0}; + std::vector 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()); + } +}