OGS
MathLib::PiecewiseLinearInterpolation Class Reference

Detailed Description

This class implements a one dimensional piecewise linear interpolation algorithm.

Definition at line 14 of file PiecewiseLinearInterpolation.h.

#include <PiecewiseLinearInterpolation.h>

Inheritance diagram for MathLib::PiecewiseLinearInterpolation:
[legend]

Public Member Functions

 PiecewiseLinearInterpolation (std::vector< double > supporting_points, std::vector< double > values_at_supp_pnts, bool supp_pnts_sorted=false)
 PiecewiseLinearInterpolation (std::vector< int > const &supporting_points, std::vector< double > const &values_at_supp_pnts, bool supp_pnts_sorted=false)
double getValue (double pnt_to_interpolate) const
 Calculates the interpolation value.
double getDerivative (double const pnt_to_interpolate) const
 Calculates derivative using quadratic interpolation and central difference quotient.
double getSupportMax () const
double getSupportMin () const

Protected Attributes

std::vector< double > supp_pnts_
std::vector< double > values_at_supp_pnts_

Constructor & Destructor Documentation

◆ PiecewiseLinearInterpolation() [1/2]

MathLib::PiecewiseLinearInterpolation::PiecewiseLinearInterpolation ( std::vector< double > supporting_points,
std::vector< double > values_at_supp_pnts,
bool supp_pnts_sorted = false )

The constructor copies the entries of the vector of supporting points \((x_0, x_1, \dots, x_n)\) and the entries of the vector of values at the supporting points \((y_0, y_1, \dots, y_n)\) where \(n\) is the number of entries of the vector. The number of supporting points must be the same like the number of values at the supporting points. It is assumed that \(x_j\) corresponds to \(y_j\) for all \(j \in [0, n]\).

It is not assumed that the supporting points are sorted, i.e. \(x_0 < x_1 < \dots < x_n\). It is assumed, that the supporting points are pairwise different. The user can set the flag supp_pnts_sorted to true, if the supporting points are sorted. This will save some setup time.

Parameters
supporting_pointsvector of supporting points
values_at_supp_pntsvector of values at the supporting points
supp_pnts_sortedfalse (default), if it is sure the supporting points are sorted one can set the switch to true

Definition at line 17 of file PiecewiseLinearInterpolation.cpp.

22 : supp_pnts_(std::move(supporting_points)),
23 values_at_supp_pnts_(std::move(values_at_supp_pnts))
24{
25 if (!supp_pnts_sorted)
26 {
28 supp_pnts_, static_cast<std::size_t>(0), supp_pnts_.size(),
30 }
31
32 const auto it = std::adjacent_find(supp_pnts_.begin(), supp_pnts_.end());
33 if (it != supp_pnts_.end())
34 {
35 const std::size_t i = std::distance(supp_pnts_.begin(), it);
37 "Variable {:d} and variable {:d} are the same. Piecewise linear "
38 "interpolation is not possible\n",
39 i, i + 1);
40 }
41}
#define OGS_FATAL(...)
Definition Error.h:19
void quicksort(It1 first1, It1 last1, It2 first2, Comparator compare)
Definition quicksort.h:17

References OGS_FATAL, BaseLib::quicksort(), supp_pnts_, and values_at_supp_pnts_.

Referenced by MathLib::PiecewiseLinearMonotonicCurve::PiecewiseLinearMonotonicCurve().

◆ PiecewiseLinearInterpolation() [2/2]

MathLib::PiecewiseLinearInterpolation::PiecewiseLinearInterpolation ( std::vector< int > const & supporting_points,
std::vector< double > const & values_at_supp_pnts,
bool supp_pnts_sorted = false )

Definition at line 43 of file PiecewiseLinearInterpolation.cpp.

47 : supp_pnts_(supporting_points | ranges::to<std::vector<double>>()),
48 values_at_supp_pnts_(values_at_supp_pnts)
49{
50 if (!supp_pnts_sorted)
51 {
53 supp_pnts_, static_cast<std::size_t>(0), supp_pnts_.size(),
55 }
56
57 const auto it = std::adjacent_find(supp_pnts_.begin(), supp_pnts_.end());
58 if (it != supp_pnts_.end())
59 {
60 const std::size_t i = std::distance(supp_pnts_.begin(), it);
62 "Variable {:d} and variable {:d} are the same. Piecewise linear "
63 "interpolation is not possible\n",
64 i, i + 1);
65 }
66}

References OGS_FATAL, BaseLib::quicksort(), supp_pnts_, and values_at_supp_pnts_.

Member Function Documentation

◆ getDerivative()

double MathLib::PiecewiseLinearInterpolation::getDerivative ( double const pnt_to_interpolate) const

Calculates derivative using quadratic interpolation and central difference quotient.

Parameters
pnt_to_interpolateThe point should be located within the range \([x_{\min}, x_{\max}]\), where \(x_{\min} = \min_{1 \le j \le n} x_j\) and \(x_{\max} = \max_{1 \le j \le n} x_j\). when points are located outside of this interval, the derivative is set to 0.
Attention
if a point is located between the first and second points (or last and second to last point), the derivative is calculated using linear interpolation.

Definition at line 98 of file PiecewiseLinearInterpolation.cpp.

100{
101 if (pnt_to_interpolate < supp_pnts_.front() ||
102 supp_pnts_.back() < pnt_to_interpolate)
103 {
104 return 0;
105 }
106
107 auto const& it(std::lower_bound(supp_pnts_.begin(), supp_pnts_.end(),
108 pnt_to_interpolate));
109 std::size_t interval_idx = std::distance(supp_pnts_.begin(), it);
110
111 if (pnt_to_interpolate == supp_pnts_.front())
112 {
113 interval_idx = 1;
114 }
115
116 if (interval_idx > 1 && interval_idx < supp_pnts_.size() - 2)
117 {
118 // left and right support points.
119 double const x_ll = supp_pnts_[interval_idx - 2];
120 double const x_l = supp_pnts_[interval_idx - 1];
121 double const x = supp_pnts_[interval_idx];
122 double const x_r = supp_pnts_[interval_idx + 1];
123
124 // left and right values.
125 double const f_ll = values_at_supp_pnts_[interval_idx - 2];
126 double const f_l = values_at_supp_pnts_[interval_idx - 1];
127 double const f = values_at_supp_pnts_[interval_idx];
128 double const f_r = values_at_supp_pnts_[interval_idx + 1];
129
130 double const tangent_right = (f_l - f_r) / (x_l - x_r);
131 double const tangent_left = (f_ll - f) / (x_ll - x);
132 double const w = (pnt_to_interpolate - x) / (x_l - x);
133 return (1. - w) * tangent_right + w * tangent_left;
134 }
135
136 return (values_at_supp_pnts_[interval_idx] -
137 values_at_supp_pnts_[interval_idx - 1]) /
138 (supp_pnts_[interval_idx] - supp_pnts_[interval_idx - 1]);
139}

References supp_pnts_, and values_at_supp_pnts_.

Referenced by MathLib::PiecewiseLinearMonotonicCurve::isStrongMonotonic().

◆ getSupportMax()

double MathLib::PiecewiseLinearInterpolation::getSupportMax ( ) const

Definition at line 141 of file PiecewiseLinearInterpolation.cpp.

142{
143 assert(!supp_pnts_.empty());
144 return supp_pnts_.back();
145}

References supp_pnts_.

◆ getSupportMin()

double MathLib::PiecewiseLinearInterpolation::getSupportMin ( ) const

Definition at line 146 of file PiecewiseLinearInterpolation.cpp.

147{
148 assert(!supp_pnts_.empty());
149 return supp_pnts_.front();
150}

References supp_pnts_.

◆ getValue()

double MathLib::PiecewiseLinearInterpolation::getValue ( double pnt_to_interpolate) const

Calculates the interpolation value.

Parameters
pnt_to_interpolateThe point should be located within the range \([x_{\min}, x_{\max}]\), where \(x_{\min} = \min_{1 \le j \le n} x_j\) and \(x_{\max} = \max_{1 \le j \le n} x_j\). Points outside of this interval are set to \(x_{\min}\) or \(x_{\max}\).
Returns
The interpolated value.

Definition at line 68 of file PiecewiseLinearInterpolation.cpp.

69{
70 // search interval that has the point inside
71 if (pnt_to_interpolate <= supp_pnts_.front())
72 {
73 return values_at_supp_pnts_[0];
74 }
75
76 if (supp_pnts_.back() <= pnt_to_interpolate)
77 {
78 return values_at_supp_pnts_[supp_pnts_.size() - 1];
79 }
80
81 auto const& it(std::lower_bound(supp_pnts_.begin(), supp_pnts_.end(),
82 pnt_to_interpolate));
83 std::size_t const interval_idx = std::distance(supp_pnts_.begin(), it) - 1;
84
85 // support points.
86 double const x = supp_pnts_[interval_idx];
87 double const x_r = supp_pnts_[interval_idx + 1];
88
89 // values.
90 double const f = values_at_supp_pnts_[interval_idx];
91 double const f_r = values_at_supp_pnts_[interval_idx + 1];
92
93 // compute linear interpolation polynom: y = m * (x - support[i]) + value[i]
94 const double t = (pnt_to_interpolate - x) / (x_r - x);
95 return std::lerp(f, f_r, t);
96}
static const double t

References supp_pnts_, MathLib::t, and values_at_supp_pnts_.

Member Data Documentation

◆ supp_pnts_

◆ values_at_supp_pnts_

std::vector<double> MathLib::PiecewiseLinearInterpolation::values_at_supp_pnts_
protected

The documentation for this class was generated from the following files: