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);
44  OGS_FATAL(
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_[0];
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: