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