 OGS
MathLib::PiecewiseLinearInterpolation Class Reference

## Detailed Description

This class implements a one dimensional piecewise linear interpolation algorithm.

Definition at line 25 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)

double getValue (double pnt_to_interpolate) const
Calculates the interpolation value. More...

double getDerivative (double const pnt_to_interpolate) const
Calculates derivative using quadratic interpolation and central difference quotient. More...

double getSupportMax () const

double getSupportMin () const

## Protected Attributes

std::vector< double > supp_pnts_

std::vector< double > values_at_supp_pnts_

## ◆ PiecewiseLinearInterpolation()

 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_points vector of supporting points values_at_supp_pnts vector of values at the supporting points supp_pnts_sorted false (default), if it is sure the supporting points are sorted one can set the switch to true

Definition at line 25 of file PiecewiseLinearInterpolation.cpp.

30 : supp_pnts_(std::move(supporting_points)),
31 values_at_supp_pnts_(std::move(values_at_supp_pnts))
32{
33 if (!supp_pnts_sorted)
34 {
35 BaseLib::quicksort<double, double>(
36 supp_pnts_, static_cast<std::size_t>(0), supp_pnts_.size(),
38 }
39
40 const auto it = std::adjacent_find(supp_pnts_.begin(), supp_pnts_.end());
41 if (it != supp_pnts_.end())
42 {
43 const std::size_t i = std::distance(supp_pnts_.begin(), it);
45 "Variable {:d} and variable {:d} are the same. Piecewise linear "
46 "interpolation is not possible\n",
47 i, i + 1);
48 }
49}
#define OGS_FATAL(...)
Definition: Error.h:26

References OGS_FATAL, supp_pnts_, and values_at_supp_pnts_.

## ◆ getDerivative()

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

Calculates derivative using quadratic interpolation and central difference quotient.

Parameters
 pnt_to_interpolate The 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 82 of file PiecewiseLinearInterpolation.cpp.

84{
85 if (pnt_to_interpolate < supp_pnts_.front() ||
86 supp_pnts_.back() < pnt_to_interpolate)
87 {
88 return 0;
89 }
90
91 auto const& it(std::lower_bound(supp_pnts_.begin(), supp_pnts_.end(),
92 pnt_to_interpolate));
93 std::size_t interval_idx = std::distance(supp_pnts_.begin(), it);
94
95 if (pnt_to_interpolate == supp_pnts_.front())
96 {
97 interval_idx = 1;
98 }
99
100 if (interval_idx > 1 && interval_idx < supp_pnts_.size() - 2)
101 {
102 // left and right support points.
103 double const x_ll = supp_pnts_[interval_idx - 2];
104 double const x_l = supp_pnts_[interval_idx - 1];
105 double const x = supp_pnts_[interval_idx];
106 double const x_r = supp_pnts_[interval_idx + 1];
107
108 // left and right values.
109 double const f_ll = values_at_supp_pnts_[interval_idx - 2];
110 double const f_l = values_at_supp_pnts_[interval_idx - 1];
111 double const f = values_at_supp_pnts_[interval_idx];
112 double const f_r = values_at_supp_pnts_[interval_idx + 1];
113
114 double const tangent_right = (f_l - f_r) / (x_l - x_r);
115 double const tangent_left = (f_ll - f) / (x_ll - x);
116 double const w = (pnt_to_interpolate - x) / (x_l - x);
117 return (1. - w) * tangent_right + w * tangent_left;
118 }
119
120 return (values_at_supp_pnts_[interval_idx] -
121 values_at_supp_pnts_[interval_idx - 1]) /
122 (supp_pnts_[interval_idx] - supp_pnts_[interval_idx - 1]);
123}

References supp_pnts_, and values_at_supp_pnts_.

## ◆ getSupportMax()

 double MathLib::PiecewiseLinearInterpolation::getSupportMax ( ) const

Definition at line 125 of file PiecewiseLinearInterpolation.cpp.

126{
127 assert(!supp_pnts_.empty());
128 return supp_pnts_.back();
129}

References supp_pnts_.

## ◆ getSupportMin()

 double MathLib::PiecewiseLinearInterpolation::getSupportMin ( ) const

Definition at line 130 of file PiecewiseLinearInterpolation.cpp.

131{
132 assert(!supp_pnts_.empty());
133 return supp_pnts_.front();
134}

References supp_pnts_.

## ◆ getValue()

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

Calculates the interpolation value.

Parameters
 pnt_to_interpolate The 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 51 of file PiecewiseLinearInterpolation.cpp.

52{
53 // search interval that has the point inside
54 if (pnt_to_interpolate <= supp_pnts_.front())
55 {
56 return values_at_supp_pnts_;
57 }
58
59 if (supp_pnts_.back() <= pnt_to_interpolate)
60 {
61 return values_at_supp_pnts_[supp_pnts_.size() - 1];
62 }
63
64 auto const& it(std::lower_bound(supp_pnts_.begin(), supp_pnts_.end(),
65 pnt_to_interpolate));
66 std::size_t const interval_idx = std::distance(supp_pnts_.begin(), it) - 1;
67
68 // support points.
69 double const x = supp_pnts_[interval_idx];
70 double const x_r = supp_pnts_[interval_idx + 1];
71
72 // values.
73 double const f = values_at_supp_pnts_[interval_idx];
74 double const f_r = values_at_supp_pnts_[interval_idx + 1];
75
76 // compute linear interpolation polynom: y = m * (x - support[i]) + value[i]
77 const double m = (f_r - f) / (x_r - x);
78
79 return m * (pnt_to_interpolate - x) + f;
80}

References supp_pnts_, and values_at_supp_pnts_.

## ◆ supp_pnts_

 std::vector MathLib::PiecewiseLinearInterpolation::supp_pnts_
protected

Definition at line 79 of file PiecewiseLinearInterpolation.h.

## ◆ values_at_supp_pnts_

 std::vector MathLib::PiecewiseLinearInterpolation::values_at_supp_pnts_
protected

Definition at line 80 of file PiecewiseLinearInterpolation.h.

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