mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-24 22:27:55 -05:00
Add RimSummaryEnsemble-Test.cpp with tests verifying that: - a realization whose calculated summary vector value is NaN or Inf at the selected timestep is excluded from the Pearson correlation result instead of corrupting it - extremely large but finite parameter/result magnitudes, which overflow the sum-of-squares in RigStatisticsTools::pearsonCorrelation() and RigEnsembleParameter::stdDeviation(), do not surface a NaN/Inf correlation value and are not silently dropped from the result Add RigStatisticsTools.OverflowProducesNan reproducing the pearsonCorrelation() overflow directly. Verified each new test fails without its corresponding production fix and passes with it.
132 lines
4.5 KiB
C++
132 lines
4.5 KiB
C++
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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 "gtest/gtest.h"
|
|
|
|
#include "RigStatisticsTools.h"
|
|
|
|
#include <QDebug>
|
|
|
|
#include <cmath>
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
TEST( RigStatisticsTools, NoCorrelation )
|
|
{
|
|
const int N = 1000;
|
|
std::vector<double> a, b;
|
|
a.reserve( N );
|
|
b.reserve( N );
|
|
for ( int i = 0; i < N; ++i )
|
|
{
|
|
a.push_back( (double)i );
|
|
}
|
|
for ( int i = 0; i < N; ++i )
|
|
{
|
|
b.push_back( (double)std::rand() );
|
|
}
|
|
double correlation = RigStatisticsTools::pearsonCorrelation( a, b );
|
|
EXPECT_LE( correlation, 0.25 );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
TEST( RigStatisticsTools, FullCorrelation )
|
|
{
|
|
const int N = 1000;
|
|
std::vector<double> a, b;
|
|
a.reserve( N );
|
|
b.reserve( N );
|
|
for ( int i = 0; i < N; ++i )
|
|
{
|
|
a.push_back( (double)i );
|
|
}
|
|
for ( int i = 0; i < N; ++i )
|
|
{
|
|
b.push_back( i * 2.0 + 1.0 );
|
|
}
|
|
double correlation = RigStatisticsTools::pearsonCorrelation( a, b );
|
|
EXPECT_NEAR( correlation, 1.0, 1.0e-2 );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
TEST( RigStatisticsTools, NegativeCorrelation )
|
|
{
|
|
const int N = 1000;
|
|
std::vector<double> a, b;
|
|
a.reserve( N );
|
|
b.reserve( N );
|
|
for ( int i = 0; i < N; ++i )
|
|
{
|
|
a.push_back( (double)i );
|
|
}
|
|
for ( int i = 0; i < N; ++i )
|
|
{
|
|
b.push_back( i * -2.0 + 1.0 );
|
|
}
|
|
double correlation = RigStatisticsTools::pearsonCorrelation( a, b );
|
|
EXPECT_NEAR( correlation, -1.0, 1.0e-2 );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Extremely large but finite magnitudes can overflow the sum-of-squares to +Inf, and the final
|
|
/// Inf/Inf division then yields NaN even though every individual input value is finite. Callers of
|
|
/// pearsonCorrelation() (e.g. RimSummaryEnsemble::parameterCorrelations()) must guard against this.
|
|
//--------------------------------------------------------------------------------------------------
|
|
TEST( RigStatisticsTools, OverflowProducesNan )
|
|
{
|
|
std::vector<double> a = { 1.0e200, 2.0e200, 3.0e200 };
|
|
std::vector<double> b = { 1.0e200, 2.0e200, 3.0e200 };
|
|
|
|
double correlation = RigStatisticsTools::pearsonCorrelation( a, b );
|
|
EXPECT_TRUE( std::isnan( correlation ) );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
TEST( RigStatisticsTools, MinValue )
|
|
{
|
|
const int N = 1000;
|
|
std::vector<double> a;
|
|
for ( int i = 10; i < N; ++i )
|
|
{
|
|
a.push_back( static_cast<double>( i ) );
|
|
}
|
|
double minValue = RigStatisticsTools::minimumValue( a );
|
|
EXPECT_EQ( minValue, 10.0 );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
TEST( RigStatisticsTools, MaxValue )
|
|
{
|
|
const int N = 1000;
|
|
std::vector<double> a;
|
|
for ( int i = 10; i < N; ++i )
|
|
{
|
|
a.push_back( static_cast<double>( i ) );
|
|
}
|
|
double maxValue = RigStatisticsTools::maximumValue( a );
|
|
EXPECT_EQ( maxValue, 999.0 );
|
|
}
|