From a79af2f3c9a13375119ebee26501b8b3b9ba866a Mon Sep 17 00:00:00 2001 From: Yonghui <huangyh56@gmail.com> Date: Mon, 10 Oct 2016 18:17:58 +0200 Subject: [PATCH] update the getDerivative function and update g-test --- .../PiecewiseLinearInterpolation.cpp | 37 +++++++++++++------ .../PiecewiseLinearInterpolation.h | 2 + .../TestPiecewiseLinearInterpolation.cpp | 7 +++- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/MathLib/InterpolationAlgorithms/PiecewiseLinearInterpolation.cpp b/MathLib/InterpolationAlgorithms/PiecewiseLinearInterpolation.cpp index a314121459a..cf984006af5 100644 --- a/MathLib/InterpolationAlgorithms/PiecewiseLinearInterpolation.cpp +++ b/MathLib/InterpolationAlgorithms/PiecewiseLinearInterpolation.cpp @@ -72,29 +72,44 @@ double PiecewiseLinearInterpolation::getDerivative( auto const& it(std::lower_bound(_supp_pnts.begin(), _supp_pnts.end(), pnt_to_interpolate)); - std::size_t const interval_idx = std::distance(_supp_pnts.begin(), it) - 1; + std::size_t interval_idx = std::distance(_supp_pnts.begin(), it); + + if (pnt_to_interpolate == _supp_pnts.front()) + { + interval_idx = 1; + } - // interval_idx = interval_max - 1 - interval_idx; - if (interval_idx > 1 && interval_idx < _supp_pnts.size() - 2) + if (interval_idx > 2 && interval_idx < _supp_pnts.size() - 1) { double const tangent_right = - (_values_at_supp_pnts[interval_idx] - - _values_at_supp_pnts[interval_idx + 2]) / - (_supp_pnts[interval_idx] - _supp_pnts[interval_idx + 2]); - double const tangent_left = (_values_at_supp_pnts[interval_idx - 1] - _values_at_supp_pnts[interval_idx + 1]) / (_supp_pnts[interval_idx - 1] - _supp_pnts[interval_idx + 1]); + double const tangent_left = + (_values_at_supp_pnts[interval_idx - 2] - + _values_at_supp_pnts[interval_idx]) / + (_supp_pnts[interval_idx - 2] - _supp_pnts[interval_idx]); double const w = - (pnt_to_interpolate - _supp_pnts[interval_idx + 1]) / - (_supp_pnts[interval_idx] - _supp_pnts[interval_idx + 1]); + (pnt_to_interpolate - _supp_pnts[interval_idx]) / + (_supp_pnts[interval_idx - 1] - _supp_pnts[interval_idx]); return (1. - w) * tangent_right + w * tangent_left; } else { return (_values_at_supp_pnts[interval_idx] - - _values_at_supp_pnts[interval_idx + 1]) / - (_supp_pnts[interval_idx] - _supp_pnts[interval_idx + 1]); + _values_at_supp_pnts[interval_idx - 1]) / + (_supp_pnts[interval_idx] - _supp_pnts[interval_idx - 1]); } } + +double PiecewiseLinearInterpolation::getSupportMax() const +{ + assert(!_supp_pnts.empty()); + return _supp_pnts.back(); +} +double PiecewiseLinearInterpolation::getSupportMin() const +{ + assert(!_supp_pnts.empty()); + return _supp_pnts.front(); +} } // end MathLib diff --git a/MathLib/InterpolationAlgorithms/PiecewiseLinearInterpolation.h b/MathLib/InterpolationAlgorithms/PiecewiseLinearInterpolation.h index 7a38a80a5af..1a66e4d7c3a 100644 --- a/MathLib/InterpolationAlgorithms/PiecewiseLinearInterpolation.h +++ b/MathLib/InterpolationAlgorithms/PiecewiseLinearInterpolation.h @@ -75,6 +75,8 @@ public: * using linear interpolation. */ double getDerivative(double const pnt_to_interpolate) const; + double getSupportMax() const; + double getSupportMin() const; private: std::vector<double> _supp_pnts; diff --git a/Tests/MathLib/TestPiecewiseLinearInterpolation.cpp b/Tests/MathLib/TestPiecewiseLinearInterpolation.cpp index e29fc0e0fc7..914d781e83d 100644 --- a/Tests/MathLib/TestPiecewiseLinearInterpolation.cpp +++ b/Tests/MathLib/TestPiecewiseLinearInterpolation.cpp @@ -131,7 +131,7 @@ TEST(MathLibInterpolationAlgorithms, PiecewiseLinearInterpolationDerivative) for (std::size_t k(0); k < size; ++k) { supp_pnts.push_back(static_cast<double>(k)); - values.push_back(k * k); + values.push_back(static_cast<double>(k * k)); } MathLib::PiecewiseLinearInterpolation interpolation{std::move(supp_pnts), @@ -142,6 +142,11 @@ TEST(MathLibInterpolationAlgorithms, PiecewiseLinearInterpolationDerivative) ASSERT_NEAR(1 + 2 * k, interpolation.getDerivative(k + 0.5), std::numeric_limits<double>::epsilon()); } + // max and min value test + ASSERT_NEAR(1, interpolation.getDerivative(0), + std::numeric_limits<double>::epsilon()); + ASSERT_NEAR(1997, interpolation.getDerivative(999), + std::numeric_limits<double>::epsilon()); // Extrapolation ASSERT_NEAR(0, interpolation.getDerivative(-1), -- GitLab