#6007 Add utility for linear interpolation.

This commit is contained in:
Kristian Bendiksen 2020-05-29 14:38:18 +02:00 committed by Magne Sjaastad
parent 79af3d7379
commit 2ef822e491
5 changed files with 178 additions and 0 deletions

View File

@ -16,6 +16,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiaQDateTimeTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaSummaryTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaWellNameComparer.h
${CMAKE_CURRENT_LIST_DIR}/RiaStdStringTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaInterpolationTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaSummaryCurveAnalyzer.h
${CMAKE_CURRENT_LIST_DIR}/RiaSimWellBranchTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaProjectFileVersionTools.h
@ -62,6 +63,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiaQDateTimeTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaSummaryTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaWellNameComparer.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaStdStringTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaInterpolationTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaSummaryCurveAnalyzer.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaSimWellBranchTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaProjectFileVersionTools.cpp

View File

@ -0,0 +1,66 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020 Equinor 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 "RiaInterpolationTools.h"
#include <cassert>
#include <limits>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RiaInterpolationTools::linear( const std::vector<double>& x, const std::vector<double>& y, double value )
{
assert( x.size() == y.size() );
// Handle cases with only one data point.
if ( x.size() == 1 )
{
return std::numeric_limits<double>::infinity();
}
// Find the lower boundary
bool found = false;
int lowerIndex = 0;
for ( int i = 0; i < static_cast<int>( x.size() - 1 ); i++ )
{
if ( x[i] < value && x[i + 1] > value )
{
lowerIndex = i;
found = true;
}
}
// Value is outside of the defined range
if ( !found )
{
return std::numeric_limits<double>::infinity();
}
int upperIndex = lowerIndex + 1;
double lowerX = x[lowerIndex];
double lowerY = y[lowerIndex];
double upperX = x[upperIndex];
double upperY = y[upperIndex];
double deltaY = upperY - lowerY;
double deltaX = upperX - lowerX;
return lowerY + ( ( value - lowerX ) / deltaX ) * deltaY;
}

View File

@ -0,0 +1,30 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020 Equinor 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
#include <vector>
//==================================================================================================
//
//==================================================================================================
class RiaInterpolationTools
{
public:
static double linear( const std::vector<double>& x, const std::vector<double>& y, double value );
};

View File

@ -62,6 +62,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RifActiveCellsReader-Test.cpp
${CMAKE_CURRENT_LIST_DIR}/RifCsvDataTableFormatter-Test.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaSummaryCurveAnalyzer-Test.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaStdStringTools-Test.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaInterpolationTools-Test.cpp
${CMAKE_CURRENT_LIST_DIR}/RifWellMeasurementReader-Test.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaDateStringParser-Test.cpp
${CMAKE_CURRENT_LIST_DIR}/RigHexGradientTools-Test.cpp

View File

@ -0,0 +1,79 @@
#include "gtest/gtest.h"
#include "RiaInterpolationTools.h"
#include <limits>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST( RiaInterpolationToolsTest, LinearEmptyData )
{
std::vector<double> x;
std::vector<double> y;
double res = RiaInterpolationTools::linear( x, y, 99.9 );
EXPECT_EQ( std::numeric_limits<double>::infinity(), res );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST( RiaInterpolationToolsTest, SingleValue )
{
std::vector<double> x = { 1.0 };
std::vector<double> y = { 3.0 };
double res = RiaInterpolationTools::linear( x, y, 2.0 );
EXPECT_EQ( std::numeric_limits<double>::infinity(), res );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST( RiaInterpolationToolsTest, ValidInterval )
{
std::vector<double> x = { 0.0, 1.0 };
std::vector<double> y = { 0.0, 2.0 };
double res = RiaInterpolationTools::linear( x, y, 0.5 );
EXPECT_DOUBLE_EQ( 1.0, res );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST( RiaInterpolationToolsTest, ValidIntervalLastBin )
{
std::vector<double> x = { 0.0, 1.0, 100.0, 1100.0 };
std::vector<double> y = { 0.0, 2.0, 0.0, 2000.0 };
double res = RiaInterpolationTools::linear( x, y, 600.0 );
EXPECT_DOUBLE_EQ( 1000.0, res );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST( RiaInterpolationToolsTest, ValidIntervalValueTooLow )
{
std::vector<double> x = { 0.0, 1.0 };
std::vector<double> y = { 0.0, 2.0 };
// Outside interval on low side
double res = RiaInterpolationTools::linear( x, y, -1.0 );
EXPECT_DOUBLE_EQ( std::numeric_limits<double>::infinity(), res );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST( RiaInterpolationToolsTest, ValidIntervalValueTooHigh )
{
std::vector<double> x = { 0.0, 1.0 };
std::vector<double> y = { 0.0, 2.0 };
// Outside interval on high side
double res = RiaInterpolationTools::linear( x, y, 100.0 );
EXPECT_DOUBLE_EQ( std::numeric_limits<double>::infinity(), res );
}