BubbleProfiler  0.3.0
by Peter Athron, Csaba Balazs, Michael Bardsley, Andrew Fowlie, Dylan Harries & Graham White
univariate_interpolation.hpp
Go to the documentation of this file.
1 /*
2  * This file is part of BubbleProfiler.
3  *
4  * BubbleProfiler is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * BubbleProfiler is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with BubbleProfiler. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef BUBBLEPROFILER_UNIVARIATE_INTERPOLATION_HPP_INCLUDED
19 #define BUBBLEPROFILER_UNIVARIATE_INTERPOLATION_HPP_INCLUDED
20 
21 #include <algorithm>
22 
23 namespace BubbleProfiler {
24 
28 template <typename Scalar, typename Data>
29 Scalar linear_lagrange_interpolation_at_point(Scalar x, const Data& xdata,
30  const Data& ydata)
31 {
32  using index_type = typename Data::size_type;
33 
34  const auto num_x_points = xdata.size();
35 
36  const Scalar xmin = xdata[0];
37  const Scalar xmax = xdata[num_x_points - 1];
38 
39  index_type upper_index;
40  if (x <= xmin) {
41  upper_index = 1;
42  } else if (x >= xmax) {
43  upper_index = num_x_points - 1;
44  } else {
45  const auto upper_it = std::upper_bound(std::begin(xdata),
46  std::end(xdata), x);
47  upper_index = std::distance(std::begin(xdata), upper_it);
48  }
49 
50  index_type lower_index = upper_index - 1;
51 
52  const Scalar x_lower = (x - xdata[upper_index])
53  / (xdata[lower_index] - xdata[upper_index]);
54  const Scalar x_upper = (x - xdata[lower_index])
55  / (xdata[upper_index] - xdata[lower_index]);
56 
57  return ydata[lower_index] * x_lower + ydata[upper_index] * x_upper;
58 }
59 
60 template <typename Scalar, typename Data>
61 Scalar quadratic_lagrange_interpolation_at_point(Scalar x, const Data& xdata,
62  const Data& ydata)
63 {
64  using index_type = typename Data::size_type;
65 
66  const auto num_x_points = xdata.size();
67 
68  index_type upper_index;
69  if (x <= xdata[1]) {
70  upper_index = 2;
71  } else if (x >= xdata[num_x_points - 1]) {
72  upper_index = num_x_points - 1;
73  } else {
74  const auto upper_it = std::upper_bound(std::begin(xdata),
75  std::end(xdata), x);
76  upper_index = std::distance(std::begin(xdata), upper_it);
77  }
78 
79  index_type center_index = upper_index - 1;
80  index_type lower_index = upper_index - 2;
81 
82  const Scalar xdata_lower = xdata[lower_index];
83  const Scalar xdata_center = xdata[center_index];
84  const Scalar xdata_upper = xdata[upper_index];
85 
86  const Scalar x_lower = (x - xdata_center) * (x - xdata_upper)
87  / ((xdata_lower - xdata_center) * (xdata_lower - xdata_upper));
88  const Scalar x_center = (x - xdata_lower) * (x - xdata_upper)
89  / ((xdata_center - xdata_lower) * (xdata_center - xdata_upper));
90  const Scalar x_upper = (x - xdata_lower) * (x - xdata_center)
91  / ((xdata_upper - xdata_lower) * (xdata_upper - xdata_center));
92 
93  return ydata[lower_index] * x_lower + ydata[center_index] * x_center
94  + ydata[upper_index] * x_upper;
95 }
96 
97 } // namespace BubbleProfiler
98 
99 #endif
Scalar linear_lagrange_interpolation_at_point(Scalar x, const Data &xdata, const Data &ydata)
Scalar quadratic_lagrange_interpolation_at_point(Scalar x, const Data &xdata, const Data &ydata)