mirror of
https://github.com/OPM/ResInsight.git
synced 2025-01-20 21:43:20 -06:00
#7116 Add extrapolation options for linear interpolation tool.
This commit is contained in:
parent
c1f7f0f66f
commit
f3fe51ef65
@ -40,7 +40,10 @@ bool almostEqual( double a, double b, double maxRelDiff = std::numeric_limits<do
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
double RiaInterpolationTools::linear( const std::vector<double>& x, const std::vector<double>& y, double value )
|
double RiaInterpolationTools::linear( const std::vector<double>& x,
|
||||||
|
const std::vector<double>& y,
|
||||||
|
double value,
|
||||||
|
ExtrapolationMode extrapolationMode )
|
||||||
{
|
{
|
||||||
assert( x.size() == y.size() );
|
assert( x.size() == y.size() );
|
||||||
|
|
||||||
@ -70,6 +73,17 @@ double RiaInterpolationTools::linear( const std::vector<double>& x, const std::v
|
|||||||
return y[0];
|
return y[0];
|
||||||
else if ( almostEqual( value, x[x.size() - 1] ) )
|
else if ( almostEqual( value, x[x.size() - 1] ) )
|
||||||
return y[x.size() - 1];
|
return y[x.size() - 1];
|
||||||
|
|
||||||
|
if ( extrapolationMode == ExtrapolationMode::CLOSEST )
|
||||||
|
{
|
||||||
|
return extrapolateClosestValue( x, y, value );
|
||||||
|
}
|
||||||
|
else if ( extrapolationMode == ExtrapolationMode::TREND )
|
||||||
|
{
|
||||||
|
return extrapolate( x, y, value );
|
||||||
|
}
|
||||||
|
|
||||||
|
assert( extrapolationMode == ExtrapolationMode::NONE );
|
||||||
return std::numeric_limits<double>::infinity();
|
return std::numeric_limits<double>::infinity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,6 +108,17 @@ double RiaInterpolationTools::extrapolate( const std::vector<double>& x, const s
|
|||||||
return y[0] + ( value - x[0] ) / ( x[1] - x[0] ) * ( y[1] - y[0] );
|
return y[0] + ( value - x[0] ) / ( x[1] - x[0] ) * ( y[1] - y[0] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
double RiaInterpolationTools::extrapolateClosestValue( const std::vector<double>& x, const std::vector<double>& y, double value )
|
||||||
|
{
|
||||||
|
if ( value <= x[0] )
|
||||||
|
return y[0];
|
||||||
|
else
|
||||||
|
return y[x.size() - 1];
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
@ -26,7 +26,17 @@
|
|||||||
class RiaInterpolationTools
|
class RiaInterpolationTools
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static double linear( const std::vector<double>& x, const std::vector<double>& y, double value );
|
enum class ExtrapolationMode
|
||||||
|
{
|
||||||
|
NONE,
|
||||||
|
CLOSEST,
|
||||||
|
TREND
|
||||||
|
};
|
||||||
|
|
||||||
|
static double linear( const std::vector<double>& x,
|
||||||
|
const std::vector<double>& y,
|
||||||
|
double value,
|
||||||
|
ExtrapolationMode extrapolationMode = ExtrapolationMode::NONE );
|
||||||
|
|
||||||
// Interpolate/extrapolate away inf values in y vector.
|
// Interpolate/extrapolate away inf values in y vector.
|
||||||
static void interpolateMissingValues( const std::vector<double>& x, std::vector<double>& y );
|
static void interpolateMissingValues( const std::vector<double>& x, std::vector<double>& y );
|
||||||
@ -47,4 +57,5 @@ private:
|
|||||||
static int findNextDataPoint( const std::vector<double>& values, int index );
|
static int findNextDataPoint( const std::vector<double>& values, int index );
|
||||||
static int findPreviousDataPoint( const std::vector<double>& values, int index );
|
static int findPreviousDataPoint( const std::vector<double>& values, int index );
|
||||||
static double extrapolate( const std::vector<double>& x, const std::vector<double>& y, double value );
|
static double extrapolate( const std::vector<double>& x, const std::vector<double>& y, double value );
|
||||||
|
static double extrapolateClosestValue( const std::vector<double>& x, const std::vector<double>& y, double value );
|
||||||
};
|
};
|
||||||
|
@ -81,7 +81,46 @@ TEST( RiaInterpolationToolsTest, ValidIntervalValueTooHigh )
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
TEST( RiaInterpolationToolsTest, InterpolateMisssingValuesStraightLine )
|
TEST( RiaInterpolationToolsTest, ValidIntervalValueTooHighExtrapolationClosest )
|
||||||
|
{
|
||||||
|
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, RiaInterpolationTools::ExtrapolationMode::CLOSEST );
|
||||||
|
EXPECT_DOUBLE_EQ( 2.0, res );
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
TEST( RiaInterpolationToolsTest, ValidIntervalValueTooLowExtrapolationClosest )
|
||||||
|
{
|
||||||
|
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, RiaInterpolationTools::ExtrapolationMode::CLOSEST );
|
||||||
|
EXPECT_DOUBLE_EQ( 0.0, res );
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
TEST( RiaInterpolationToolsTest, ValidIntervalValueTooLowExtrapolationTrend )
|
||||||
|
{
|
||||||
|
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, RiaInterpolationTools::ExtrapolationMode::TREND );
|
||||||
|
EXPECT_DOUBLE_EQ( -2.0, res );
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
TEST( RiaInterpolationToolsTest, InterpolateMissingValuesStraightLine )
|
||||||
{
|
{
|
||||||
double inf = std::numeric_limits<double>::infinity();
|
double inf = std::numeric_limits<double>::infinity();
|
||||||
std::vector<double> x = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 };
|
std::vector<double> x = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 };
|
||||||
|
Loading…
Reference in New Issue
Block a user