24 #include "marley/Error.hh"
35 template <
typename FirstNumericType,
typename SecondNumericType
40 using OrderedPair = std::pair<FirstNumericType, SecondNumericType>;
41 using Grid = std::vector<OrderedPair>;
42 using GridConstIterator
43 =
typename std::vector<OrderedPair>::const_iterator;
64 LinearLinear = 2, LinearLog = 3, LogLinear = 4,
102 = ExtrapolationMethod::Zero)
103 : interpolation_method_(interp_method),
104 extrapolation_method_(extrap_method)
112 : interpolation_method_(interp_method),
113 extrapolation_method_(extrap_method), ordered_pairs_(grid)
120 const std::vector<SecondNumericType>& ys,
123 : interpolation_method_(interp_method),
124 extrapolation_method_(extrap_method)
127 std::string(
"Vectors of x and y values passed to the constructor")
128 +
" of marley::InterpolationGrid have unequal sizes.");
130 double old_x = marley_utils::minus_infinity;
131 for (
size_t j = 0; j < xs.size(); ++j) {
132 double new_x = xs.at(j);
133 if (new_x <= old_x)
throw marley::Error(std::string(
"The grid")
134 +
" point x-values defined for a marley::InterpolationGrid object"
135 +
" are not strictly increasing");
136 ordered_pairs_.push_back(OrderedPair(xs.at(j), ys.at(j)));
144 void insert(FirstNumericType x, SecondNumericType y);
147 inline size_t size()
const {
return ordered_pairs_.size(); }
150 inline void clear() { ordered_pairs_.clear(); }
153 inline OrderedPair&
at(
size_t j) {
return ordered_pairs_.at(j); }
157 inline std::function<SecondNumericType(FirstNumericType)>
160 return [
this](FirstNumericType x)
161 -> SecondNumericType {
return this->
interpolate(x); };
169 GridConstIterator& begin,
170 const GridConstIterator& end, FirstNumericType x)
const
172 return std::lower_bound(begin, end, x,
173 [](
const OrderedPair& pair,
const FirstNumericType& f)
174 ->
bool {
return pair.first < f; });
180 GridConstIterator& begin,
181 const GridConstIterator& end, FirstNumericType x)
const
183 return std::upper_bound(begin, end, x,
184 [](
const FirstNumericType& f,
const OrderedPair& pair)
185 ->
bool {
return f < pair.first; });
189 inline const OrderedPair&
front()
const {
return ordered_pairs_.front(); }
192 inline const OrderedPair&
back()
const {
return ordered_pairs_.back(); }
196 {
return interpolation_method_; }
200 { interpolation_method_ = method; }
204 {
return extrapolation_method_; }
208 { extrapolation_method_ = method; }
226 inline void check_grid()
const {
228 if (ordered_pairs_.size() < 2)
throw marley::Error(std::string(
"A")
229 +
" class method was called for an InterpolationGrid object"
230 +
" that contains less than two grid points.");
236 inline bool find_bin_limits(FirstNumericType x,
237 GridConstIterator& lower_point, GridConstIterator& upper_point)
const
243 bool extrapolate =
false;
244 GridConstIterator begin = ordered_pairs_.begin();
245 GridConstIterator end = ordered_pairs_.end();
246 GridConstIterator not_less_point =
lower_bound(begin, end, x);
249 if (not_less_point == begin) {
251 upper_point = begin + 1;
253 if (begin->first != x) extrapolate =
true;
255 else if (not_less_point == end) {
258 lower_point = end - 2;
259 upper_point = end - 1;
263 lower_point = not_less_point - 1;
264 upper_point = not_less_point;
271 template <
typename FirstNumericType,
typename SecondNumericType>
272 SecondNumericType InterpolationGrid<FirstNumericType,
273 SecondNumericType>::interpolate(FirstNumericType x)
const
276 InterpolationGrid::GridConstIterator lower_point, upper_point;
278 bool extrapolate = find_bin_limits(x, lower_point, upper_point);
283 if (extrapolation_method_ == ExtrapolationMethod::Zero)
284 return static_cast<SecondNumericType
>(0.);
285 else if (extrapolation_method_ == ExtrapolationMethod::Endpoint) {
286 if (lower_point->first > x)
return lower_point->second;
287 else return upper_point->second;
289 else if (extrapolation_method_ == ExtrapolationMethod::Throw) {
291 +
" lies outside of the current interpolation grid object"
292 +
" (which extends from x_min = "
293 + std::to_string(ordered_pairs_.front().first)
294 +
" and x_max = " + std::to_string(ordered_pairs_.back().first)
295 +
") and extrapolation is disabled.");
308 if (interpolation_method_ == InterpolationMethod::Constant) {
309 if (!extrapolate)
return lower_point->second;
310 else if (lower_point->first > x)
return lower_point->second;
311 else return upper_point->second;
316 FirstNumericType x1 = lower_point->first;
317 FirstNumericType x2 = upper_point->first;
318 SecondNumericType y1 = lower_point->second;
319 SecondNumericType y2 = upper_point->second;
321 bool log_x =
false, log_y =
false;
322 FirstNumericType x_to_use = x;
323 if (interpolation_method_ == InterpolationMethod::LinearLog)
325 else if (interpolation_method_ == InterpolationMethod::LogLinear)
327 else if (interpolation_method_ == InterpolationMethod::LogLog) {
334 x_to_use = std::log(x);
341 FirstNumericType y_interp = y1 + ((y2 - y1)/(x2 - x1))*(x_to_use - x1);
342 if (log_y) y_interp = std::exp(y_interp);
346 template <
typename FirstNumericType,
typename SecondNumericType>
348 FirstNumericType x, SecondNumericType y)
354 GridConstIterator insert_point = upper_bound(ordered_pairs_.begin(),
355 ordered_pairs_.end(), x);
358 ordered_pairs_.insert(insert_point, OrderedPair(x, y));
Base class for all exceptions thrown by MARLEY functions.
Definition: Error.hh:32
One-dimensional function y(x) defined using a grid of ordered pairs (x,y) and an interpolation rule.
Definition: InterpolationGrid.hh:37
ExtrapolationMethod
Method to use for computing y(x) when the x value lies beyond the grid boundaries.
Definition: InterpolationGrid.hh:96
void insert(FirstNumericType x, SecondNumericType y)
Add a new ordered pair (x, y) to the grid.
Definition: InterpolationGrid.hh:347
GridConstIterator lower_bound(const GridConstIterator &begin, const GridConstIterator &end, FirstNumericType x) const
Returns a const_iterator to the first element of the grid for which the x value is not less than (i....
Definition: InterpolationGrid.hh:168
InterpolationGrid(const Grid &grid, InterpolationMethod interp_method=InterpolationMethod::LinearLinear, ExtrapolationMethod extrap_method=ExtrapolationMethod::Zero)
Create an InterpolationGrid from a vector of ordered pairs.
Definition: InterpolationGrid.hh:109
void clear()
Delete all ordered pairs from the grid.
Definition: InterpolationGrid.hh:150
InterpolationGrid(const std::vector< FirstNumericType > &xs, const std::vector< SecondNumericType > &ys, InterpolationMethod interp_method=InterpolationMethod::LinearLinear, ExtrapolationMethod extrap_method=ExtrapolationMethod::Zero)
Create an InterpolationGrid from vectors of x and y values.
Definition: InterpolationGrid.hh:119
OrderedPair & at(size_t j)
Get a reference to the jth ordered pair from the grid.
Definition: InterpolationGrid.hh:153
const OrderedPair & back() const
Returns a reference to the last ordered pair.
Definition: InterpolationGrid.hh:192
size_t size() const
Get the number of ordered pairs on the grid.
Definition: InterpolationGrid.hh:147
void set_interpolationMethod(InterpolationMethod method)
Set the InterpolationMethod to use.
Definition: InterpolationGrid.hh:199
SecondNumericType interpolate(FirstNumericType x) const
Compute y(x) using the current InterpolationMethod.
Definition: InterpolationGrid.hh:273
ExtrapolationMethod extrapolation_method() const
Get the ExtrapolationMethod used by this InterpolationGrid.
Definition: InterpolationGrid.hh:203
InterpolationGrid(InterpolationMethod interp_method=InterpolationMethod::LinearLinear, ExtrapolationMethod extrap_method=ExtrapolationMethod::Zero)
Create an InterpolationGrid without any grid points.
Definition: InterpolationGrid.hh:100
std::function< SecondNumericType(FirstNumericType)> get_interpolating_function()
Get a std::function object that represents y(x) for this InterpolationGrid.
Definition: InterpolationGrid.hh:158
void set_interpolationMethod(ExtrapolationMethod method)
Set the ExtrapolationMethod to use.
Definition: InterpolationGrid.hh:207
InterpolationMethod interpolation_method() const
Get the InterpolationMethod used by this InterpolationGrid.
Definition: InterpolationGrid.hh:195
InterpolationMethod
Method to use for interpolating between (x,y) grid points.
Definition: InterpolationGrid.hh:63
const OrderedPair & front() const
Returns a reference to the first ordered pair.
Definition: InterpolationGrid.hh:189
GridConstIterator upper_bound(const GridConstIterator &begin, const GridConstIterator &end, FirstNumericType x) const
Returns a const_iterator to the first element of the grid for which the x value is greater than x.
Definition: InterpolationGrid.hh:179