ReFRACtor
linear_interpolate.h
Go to the documentation of this file.
1 #ifndef LINEAR_INTERPOLATE_H
2 #define LINEAR_INTERPOLATE_H
3 #include "printable.h"
4 #include "fp_exception.h"
5 #include "auto_derivative.h"
6 #include <map>
7 #include <boost/shared_ptr.hpp>
8 
9 namespace FullPhysics {
10 
11 template<class TX, class TY> class InterpolatePoint;
12 template<> class InterpolatePoint<AutoDerivative<double>,
13  AutoDerivative<double> >;
14 
15 /****************************************************************/
19 template<class TX, class TY> class InterpolatePoint {
20 public:
21  virtual const TX& x_min() const = 0;
22  virtual const TX& x_max() const = 0;
23  virtual TY operator()(const TX& x) const = 0;
24 };
25 
26 /****************************************************************/
30 template<class TX, class TY> class Return1Point;
31 template<> class Return1Point<AutoDerivative<double>, AutoDerivative<double> >;
32 
33 template<class TX, class TY> class Return1Point :
34  public InterpolatePoint<TX, TY>,
35  public Printable<Return1Point<TX, TY> > {
36 public:
37  Return1Point(const TX& x0, const TY& y0)
38  : x0_(x0), y0_(y0)
39  {}
40  const TX& x_min() const {return x0_; }
41  const TX& x_max() const {return x0_; }
42  TY operator()(const TX& x) const { return y0_; }
43  void print(std::ostream& Os) const { Os << "Return1Point"; }
44 private:
45  TX x0_;
46  TY y0_;
47 };
48 
49 
50 template<class TX, class TY> class LinearInterpolate2Point;
51 template<> class LinearInterpolate2Point<AutoDerivative<double>,
52  AutoDerivative<double> >;
53 
54 /****************************************************************/
58 template<class TX, class TY> class LinearInterpolate2Point :
59  public InterpolatePoint<TX, TY>,
60  public Printable<LinearInterpolate2Point<TX, TY> > {
61 public:
62  LinearInterpolate2Point(const TX& x0, const TY& y0, const TX& x1,
63  const TY& y1)
64  : x0_(x0), x1_(x1), y0_(y0), delta_y0_((y1 - y0) / (x1 - x0))
65  {
66  range_max_check(x0, x1);
67  }
68  const TX& x_min() const {return x0_; }
69  const TX& x_max() const {return x1_; }
70  TY operator()(const TX& x) const { return TY(y0_ + delta_y0_ * (x - x0_)); }
71  void print(std::ostream& Os) const { Os << "LinearInterpolate2Point"; }
72 private:
73  TX x0_;
74  TX x1_;
75  TY y0_;
76  TY delta_y0_;
77 };
78 
79 template<class TX, class TY> class LinearInterpolate;
80 template<> class LinearInterpolate<AutoDerivative<double>, AutoDerivative<double> >;
81 /****************************************************************/
96 template<class TX, class TY> class LinearInterpolate :
97  public Printable<LinearInterpolate<TX, TY> > {
98 public:
99  enum BehaviorOutOfRange
100  {OUT_OF_RANGE_EXTRAPOLATE = 0, OUT_OF_RANGE_CLIP, OUT_OF_RANGE_ERROR};
102 
103 //-----------------------------------------------------------------------
106 //-----------------------------------------------------------------------
107 
108  template<class I1, class I2> LinearInterpolate(I1 xstart, I1 xend,
109  I2 ystart, BehaviorOutOfRange Out_of_range = OUT_OF_RANGE_EXTRAPOLATE)
110  : out_of_range(Out_of_range)
111  {
112  if(std::distance(xstart, xend) == 0) {
113  // If no values then we can not do any interpolation,
114  // error in operator if attempted
115  return;
116  } else if(std::distance(xstart, xend) == 1) {
117  // If only one value available then just return that one point
118  // no need for interpolation
119  const TX& x0 = *xstart;
120  const TY& y0 = *ystart;
121 
123  (new Return1Point<TX, TY>(x0, y0));
124 
125  } else while(xstart != xend) {
126  // For two more points we can use linear interpolation
127  const TX& x0 = *xstart++;
128  const TY& y0 = *ystart++;
129  if(xstart == xend)
130  break;
131  const TX& x1 = *xstart;
132  const TY& y1 = *ystart;
133  if(x1 <= x0)
134  throw Exception("X needs to be sorted");
135 
137  (new LinearInterpolate2Point<TX, TY>(x0, y0, x1, y1));
138  }
139  }
140  TY operator()(const TX& x) const
141  {
142  if(inter.empty()) {
143  throw Exception("Can not interpolate since interpolation map is empty.");
144  }
145 
146  typedef typename
147  std::map<TX, boost::shared_ptr<InterpolatePoint<TX, TY> > >::
148  const_iterator Itype;
149  Itype i = inter.lower_bound(x);
150  if(i == inter.end()) { // Are we past the end?
151  switch(out_of_range) {
152  case OUT_OF_RANGE_ERROR:
153  {
154  std::stringstream err_msg;
155  err_msg << "Linear interpolation point "
156  << x << " is past the end of interpolation range: "
157  << "[" << inter.begin()->first
158  << ", " << inter.rbegin()->first << "]";
159  throw Exception(err_msg.str());
160  }
161  case OUT_OF_RANGE_EXTRAPOLATE:
162  return (*inter.rbegin()->second)(x);
163  case OUT_OF_RANGE_CLIP:
164  return (*inter.rbegin()->second)(inter.rbegin()->second->x_max());
165  default:
166  throw Exception("Unknown out_of_range value");
167  }
168  } else {
169  if(x >= i->second->x_min())
170  return (*i->second)(x);
171  switch(out_of_range) {
172  case OUT_OF_RANGE_ERROR:
173  {
174  std::stringstream err_msg;
175  err_msg << "Linear interpolation point "
176  << x << " is outside of interpolation range: "
177  << "[" << inter.begin()->first
178  << ", " << inter.rbegin()->first << "]";
179  throw Exception(err_msg.str());
180  }
181  case OUT_OF_RANGE_EXTRAPOLATE:
182  return (*i->second)(x);
183  case OUT_OF_RANGE_CLIP:
184  return (*i->second)(i->second->x_min());
185  default:
186  throw Exception("Unknown out_of_range value");
187  }
188  }
189  }
190  void print(std::ostream& Os) const { Os << "LinearInterpolate"; }
191 private:
192  std::map<TX, boost::shared_ptr<InterpolatePoint<TX, TY> > > inter;
193  BehaviorOutOfRange out_of_range;
194 };
195 
196 }
197 // Specialization for autoderivative
198 #include "linear_interpolate_ad.h"
199 #endif
200 
#define range_max_check(V, Max)
Range check.
Definition: fp_exception.h:194
This just returns the same y value, always.
virtual TY operator()(const TX &x) const =0
This class takes a set of points and values, and linearly interpolates between those values...
This is the base of the exception hierarchy for Full Physics code.
Definition: fp_exception.h:16
void print(std::ostream &Os) const
This is a Mixin for classes that can be printed.
Definition: printable.h:24
Interface for interpolating values.
LinearInterpolate(I1 xstart, I1 xend, I2 ystart, BehaviorOutOfRange Out_of_range=OUT_OF_RANGE_EXTRAPOLATE)
Constructor.
void print(std::ostream &Os) const
This does linear interpolate between two points.
There are a number of tools that can be used to do "Automatic Differentiation" (see for example http:...
LinearInterpolate2Point(const TX &x0, const TY &y0, const TX &x1, const TY &y1)
TY operator()(const TX &x) const
virtual const TX & x_min() const =0
Contains classes to abstract away details in various Spurr Radiative Transfer software.
Definition: doxygen_python.h:1
void print(std::ostream &Os) const
TY operator()(const TX &x) const
virtual const TX & x_max() const =0
Return1Point(const TX &x0, const TY &y0)

Copyright © 2017, California Institute of Technology.
ALL RIGHTS RESERVED.
U.S. Government Sponsorship acknowledged.
Generated Fri Aug 24 2018 15:44:11