From 4e0cda386d12f6075354dc393111cbe6e59474e3 Mon Sep 17 00:00:00 2001 From: Jacob Odle Date: Fri, 20 Jan 2023 16:06:54 -0500 Subject: [PATCH 1/5] Added overload for derivative and dderivative * In TensionSpline::derivative and TensionSpline::dderivative I created an overloaded function that takes in a starting index and outputs the last index. If there are many points in your spline, this improves performance greatly, assuming you know where to start your index. Without this we were seeing large time increases as the spline length increased. --- .../include/ecl/geometry/tension_spline.hpp | 5 +++++ ecl_geometry/src/lib/tension_spline.cpp | 20 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/ecl_geometry/include/ecl/geometry/tension_spline.hpp b/ecl_geometry/include/ecl/geometry/tension_spline.hpp index 325565d..f595fa8 100644 --- a/ecl_geometry/include/ecl/geometry/tension_spline.hpp +++ b/ecl_geometry/include/ecl/geometry/tension_spline.hpp @@ -25,6 +25,7 @@ #include #include #include "macros.hpp" +#include /***************************************************************************** ** Namespaces @@ -167,6 +168,8 @@ class ecl_geometry_PUBLIC TensionSpline : public BluePrintFactory< TensionSpline * @exception : StandardException : throws if x is outside the spline range [debug mode only]. */ double derivative(const double &x) const; + + std::map derivative(const int &last_index, const double &x) const; /** * @brief Spline second derivative. * @@ -177,6 +180,8 @@ class ecl_geometry_PUBLIC TensionSpline : public BluePrintFactory< TensionSpline */ double dderivative(const double &x) const; + std::map dderivative(const int &last_index, const double &x) const; + /** * @brief The discretised domain for this spline. * diff --git a/ecl_geometry/src/lib/tension_spline.cpp b/ecl_geometry/src/lib/tension_spline.cpp index 388872f..9cd229c 100644 --- a/ecl_geometry/src/lib/tension_spline.cpp +++ b/ecl_geometry/src/lib/tension_spline.cpp @@ -44,6 +44,16 @@ double TensionSpline::derivative(const double &x) const { return functions[index].derivative(tension,x); } + std::map TensionSpline::derivative(const int &last_index, const double &x) const { + ecl_assert_throw( ( ( x >= discretised_domain.front() ) && ( x <= discretised_domain.back() ) ), StandardException(LOC,OutOfRangeError) ); + int index = last_index; + while ( x > discretised_domain[index+1] ) { + ++index; + } + std::map m = {{index, functions[index].derivative(tension,x)}}; + return m; + } + double TensionSpline::dderivative(const double &x) const { ecl_assert_throw( ( ( x >= discretised_domain.front() ) && ( x <= discretised_domain.back() ) ), StandardException(LOC,OutOfRangeError) ); int index = 0; @@ -53,4 +63,14 @@ double TensionSpline::dderivative(const double &x) const { return functions[index].dderivative(tension,x); } +std::map TensionSpline::dderivative(const int &last_index, const double &x) const { + ecl_assert_throw( ( ( x >= discretised_domain.front() ) && ( x <= discretised_domain.back() ) ), StandardException(LOC,OutOfRangeError) ); + int index = last_index; + while ( x > discretised_domain[index+1] ) { + ++index; + } + std::map m = {{index, functions[index].dderivative(tension, x)}}; + return m; +} + } // namespace ecl From 9eeea93609cb94582ab12d3a24a457bf9ef0289e Mon Sep 17 00:00:00 2001 From: Joshua Beck Date: Fri, 3 Mar 2023 12:00:51 -0500 Subject: [PATCH 2/5] Added efficiency change to cubic splines as well. --- .../include/ecl/geometry/cubic_spline.hpp | 3 ++- ecl_geometry/src/lib/cubic_spline.cpp | 21 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/ecl_geometry/include/ecl/geometry/cubic_spline.hpp b/ecl_geometry/include/ecl/geometry/cubic_spline.hpp index aac50db..4d84b69 100644 --- a/ecl_geometry/include/ecl/geometry/cubic_spline.hpp +++ b/ecl_geometry/include/ecl/geometry/cubic_spline.hpp @@ -186,6 +186,7 @@ class ECL_PUBLIC CubicSpline : public BluePrintFactory< CubicSpline > { * @exception : StandardException : throws if input x value is outside the spline range [debug mode only]. */ double derivative(double x) const; + std::map derivative(const int &last_index, const double &x) const; /** * @brief Spline second derivative. * @@ -195,7 +196,7 @@ class ECL_PUBLIC CubicSpline : public BluePrintFactory< CubicSpline > { * @exception : StandardException : throws if input x value is outside the spline range [debug mode only]. */ double dderivative(double x) const; - + std::map dderivative(const int &last_index, const double &x) const; /** * @brief The discretised domain for this spline. * diff --git a/ecl_geometry/src/lib/cubic_spline.cpp b/ecl_geometry/src/lib/cubic_spline.cpp index 33e66b8..9f132c8 100644 --- a/ecl_geometry/src/lib/cubic_spline.cpp +++ b/ecl_geometry/src/lib/cubic_spline.cpp @@ -44,6 +44,16 @@ double CubicSpline::derivative(double x) const { return cubic_polynomials[index].derivative()(x); } +std::map CubicSpline::derivative(const int &last_index, const double &x) const { + ecl_assert_throw( ( ( x >= discretised_domain.front() ) && ( x <= discretised_domain.back() ) ), StandardException(LOC,OutOfRangeError) ); + int index = last_index; + while ( x > discretised_domain[index+1] ) { + ++index; + } + std::map m = {{index, cubic_polynomials[index].derivative()(x)}}; + return m; +} + double CubicSpline::dderivative(double x) const { ecl_assert_throw( ( ( x >= discretised_domain.front() ) && ( x <= discretised_domain.back() ) ), StandardException(LOC,OutOfRangeError) ); int index = 0; @@ -53,4 +63,15 @@ double CubicSpline::dderivative(double x) const { return cubic_polynomials[index].derivative().derivative()(x); } +std::map CubicSpline::dderivative(const int &last_index, const double &x) const { + ecl_assert_throw( ( ( x >= discretised_domain.front() ) && ( x <= discretised_domain.back() ) ), StandardException(LOC,OutOfRangeError) ); + int index = last_index; + while ( x > discretised_domain[index+1] ) { + ++index; + } + std::map m = {{index, cubic_polynomials[index].derivative().derivative()(x)}}; + return m; +} + + } // namespace ecl From adebf2d7146226b03b80d293bd606fedb00cbfba Mon Sep 17 00:00:00 2001 From: Joshua Beck Date: Wed, 26 Apr 2023 11:19:06 -0400 Subject: [PATCH 3/5] added more indexed evaluations --- .../ecl/geometry/smooth_linear_spline.hpp | 3 ++ .../include/ecl/geometry/tension_spline.hpp | 4 ++- ecl_geometry/src/lib/smooth_linear_spline.cpp | 34 +++++++++++++++++++ ecl_geometry/src/lib/tension_spline.cpp | 10 ++++++ 4 files changed, 50 insertions(+), 1 deletion(-) diff --git a/ecl_geometry/include/ecl/geometry/smooth_linear_spline.hpp b/ecl_geometry/include/ecl/geometry/smooth_linear_spline.hpp index 9804cc1..2f5988f 100644 --- a/ecl_geometry/include/ecl/geometry/smooth_linear_spline.hpp +++ b/ecl_geometry/include/ecl/geometry/smooth_linear_spline.hpp @@ -99,6 +99,8 @@ class ecl_geometry_PUBLIC SmoothLinearSpline { * @exception : StandardException : throws if x is outside the spline range [debug mode only]. */ double derivative(const double &x) const; + std::map derivative(const int &last_index, const double &x) const; + /** * @brief Spline second derivative. * @@ -108,6 +110,7 @@ class ecl_geometry_PUBLIC SmoothLinearSpline { * @exception : StandardException : throws if x is outside the spline range [debug mode only]. */ double dderivative(const double &x) const; + std::map dderivative(const int &last_index, const double &x) const; /** * @brief The discretised domain for this spline. diff --git a/ecl_geometry/include/ecl/geometry/tension_spline.hpp b/ecl_geometry/include/ecl/geometry/tension_spline.hpp index f595fa8..09064b7 100644 --- a/ecl_geometry/include/ecl/geometry/tension_spline.hpp +++ b/ecl_geometry/include/ecl/geometry/tension_spline.hpp @@ -157,6 +157,8 @@ class ecl_geometry_PUBLIC TensionSpline : public BluePrintFactory< TensionSpline * @exception : StandardException : throws if x is outside the spline range [debug mode only]. */ double operator()(const double &x) const; + + std::map operator()(const int &last_index, const double &x) const; /** * @brief Spline derivative. * @@ -169,7 +171,7 @@ class ecl_geometry_PUBLIC TensionSpline : public BluePrintFactory< TensionSpline */ double derivative(const double &x) const; - std::map derivative(const int &last_index, const double &x) const; + std::map derivative(const int &last_index, const double &x) const; /** * @brief Spline second derivative. * diff --git a/ecl_geometry/src/lib/smooth_linear_spline.cpp b/ecl_geometry/src/lib/smooth_linear_spline.cpp index fec1839..8922e20 100644 --- a/ecl_geometry/src/lib/smooth_linear_spline.cpp +++ b/ecl_geometry/src/lib/smooth_linear_spline.cpp @@ -135,6 +135,23 @@ double SmoothLinearSpline::derivative(const double &x) const { } } +std::map SmoothLinearSpline::derivative(const int &last_index, const double &x) const { + ecl_assert_throw( ( ( x >= discretised_domain.front() ) && ( x <= discretised_domain.back() ) ), StandardException(LOC,OutOfRangeError) ); + int index = last_index; + while ( x > discretised_domain[index+1] ) { + ++index; + } + std::map m; + if ( index % 2 == 0 ) + { // linear + std::map m = {{index,segments[index/2].derivative(x)}}; + return m; + } else { // quintic + std::map m = {{index,corners[(index-1)/2].derivative(x)}}; + return m; + } +} + double SmoothLinearSpline::dderivative(const double &x) const { ecl_assert_throw( ( ( x >= discretised_domain.front() ) && ( x <= discretised_domain.back() ) ), StandardException(LOC,OutOfRangeError) ); int index = 0; @@ -148,6 +165,23 @@ double SmoothLinearSpline::dderivative(const double &x) const { } } +std::map SmoothLinearSpline::dderivative(const int &last_index, const double &x) const { + ecl_assert_throw( ( ( x >= discretised_domain.front() ) && ( x <= discretised_domain.back() ) ), StandardException(LOC,OutOfRangeError) ); + int index = last_index; + while ( x > discretised_domain[index+1] ) { + ++index; + } + std::map m; + if ( index % 2 == 0 ) + { // linear + std::map m = {{index,segments[index/2].dderivative(x)}}; + return m; + } else { // quintic + std::map m = {{index,corners[(index-1)/2].dderivative(x)}}; + return m; + } +} + } // namespace ecl diff --git a/ecl_geometry/src/lib/tension_spline.cpp b/ecl_geometry/src/lib/tension_spline.cpp index 9cd229c..6d520d3 100644 --- a/ecl_geometry/src/lib/tension_spline.cpp +++ b/ecl_geometry/src/lib/tension_spline.cpp @@ -35,6 +35,16 @@ double TensionSpline::operator()(const double &x) const { return functions[index](tension,x); } +std::map TensionSpline::operator()(const int &last_index, const double &x) const { + ecl_assert_throw( ( ( x >= discretised_domain.front() ) && ( x <= discretised_domain.back() ) ), StandardException(LOC,OutOfRangeError) ); + int index = last_index; + while ( x > discretised_domain[index+1] ) { + ++index; + } + std::map m = {{index, functions[index](tension,x)}}; + return m; +} + double TensionSpline::derivative(const double &x) const { ecl_assert_throw( ( ( x >= discretised_domain.front() ) && ( x <= discretised_domain.back() ) ), StandardException(LOC,OutOfRangeError) ); int index = 0; From 2d788e089d4f5f682b37422eb298704a4cb8746e Mon Sep 17 00:00:00 2001 From: jodle001 Date: Thu, 4 May 2023 16:42:19 -0400 Subject: [PATCH 4/5] added indexing for CubicSpline --- ecl_geometry/include/ecl/geometry/cubic_spline.hpp | 1 + ecl_geometry/src/lib/cubic_spline.cpp | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/ecl_geometry/include/ecl/geometry/cubic_spline.hpp b/ecl_geometry/include/ecl/geometry/cubic_spline.hpp index 4d84b69..e093957 100644 --- a/ecl_geometry/include/ecl/geometry/cubic_spline.hpp +++ b/ecl_geometry/include/ecl/geometry/cubic_spline.hpp @@ -177,6 +177,7 @@ class ECL_PUBLIC CubicSpline : public BluePrintFactory< CubicSpline > { * @exception : StandardException : throws if input x value is outside the spline range [debug mode only]. */ double operator()(const double &x) const; + std::map operator()(int last_index, const double &x); /** * @brief Spline derivative. * diff --git a/ecl_geometry/src/lib/cubic_spline.cpp b/ecl_geometry/src/lib/cubic_spline.cpp index 9f132c8..0f76a96 100644 --- a/ecl_geometry/src/lib/cubic_spline.cpp +++ b/ecl_geometry/src/lib/cubic_spline.cpp @@ -35,6 +35,16 @@ double CubicSpline::operator()(const double &x) const { return cubic_polynomials[index](x); } +std::map CubicSpline::operator()(int last_index, const double &x) { + ecl_assert_throw( ( ( x >= discretised_domain.front() ) && ( x <= discretised_domain.back() ) ), StandardException(LOC,OutOfRangeError) ); + int index = last_index; + while ( x > discretised_domain[index+1] ) { + ++index; + } + std::map m = {{index, cubic_polynomials[index](x)}}; + return m; +} + double CubicSpline::derivative(double x) const { ecl_assert_throw( ( ( x >= discretised_domain.front() ) && ( x <= discretised_domain.back() ) ), StandardException(LOC,OutOfRangeError) ); int index = 0; From 43b8106c453a961d099e21862558c631a0c885a3 Mon Sep 17 00:00:00 2001 From: Joshua Beck Date: Sat, 6 May 2023 13:35:21 -0400 Subject: [PATCH 5/5] added overloaded operator () to smoothLinearspline --- .../include/ecl/geometry/smooth_linear_spline.hpp | 4 +++- ecl_geometry/src/lib/smooth_linear_spline.cpp | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/ecl_geometry/include/ecl/geometry/smooth_linear_spline.hpp b/ecl_geometry/include/ecl/geometry/smooth_linear_spline.hpp index 2f5988f..bb4473d 100644 --- a/ecl_geometry/include/ecl/geometry/smooth_linear_spline.hpp +++ b/ecl_geometry/include/ecl/geometry/smooth_linear_spline.hpp @@ -88,6 +88,8 @@ class ecl_geometry_PUBLIC SmoothLinearSpline { * @exception : StandardException : throws if x is outside the spline range [debug mode only]. */ double operator()(const double &x) const; + std::map operator()(const int &last_index,const double &x) const; + /** * @brief Spline derivative. * @@ -153,7 +155,7 @@ class ecl_geometry_PUBLIC SmoothLinearSpline { * @brief Streaming output insertion operator for smoothed linear splines. * * Streaming output insertion operator for smoothed linear splines. This - * simply lists the spline segments and corners (linear functions and + * simply lists the spline segments and corners (linear functions andTensionSpline * quintic polynomials) in algebraic form. * * @tparam OutputStream : the type of stream being used. diff --git a/ecl_geometry/src/lib/smooth_linear_spline.cpp b/ecl_geometry/src/lib/smooth_linear_spline.cpp index 8922e20..9bdc857 100644 --- a/ecl_geometry/src/lib/smooth_linear_spline.cpp +++ b/ecl_geometry/src/lib/smooth_linear_spline.cpp @@ -122,6 +122,21 @@ double SmoothLinearSpline::operator()(const double &x) const { } } +std::map SmoothLinearSpline::operator()(const int &last_index, const double &x) const { + ecl_assert_throw( ( ( x >= discretised_domain.front() ) && ( x <= discretised_domain.back() ) ), StandardException(LOC,OutOfRangeError) ); + int index = last_index; + while ( x > discretised_domain[index+1] ) { + ++index; + } + if ( index % 2 == 0 ) { // linear + std::map m = {{index,segments[index/2](x)}}; + return m; + } else { // quintic + std::map m = {{index, corners[(index-1)/2](x)}}; + return m; + } +} + double SmoothLinearSpline::derivative(const double &x) const { ecl_assert_throw( ( ( x >= discretised_domain.front() ) && ( x <= discretised_domain.back() ) ), StandardException(LOC,OutOfRangeError) ); int index = 0;