CMS 3D CMS Logo

LinInterpolatedTable1D.h
Go to the documentation of this file.
1 //=========================================================================
2 // LinInterpolatedTable1D.h
3 //
4 // This class can be used to linearly interpolate data in one dimension.
5 // It differs from similar facilities in the fftjet package by its handling
6 // of the extrapolation beyound the grid limits.
7 //
8 // I. Volobouev
9 // April 2011
10 //=========================================================================
11 
12 #ifndef RecoJets_FFTJetAlgorithms_LinInterpolatedTable1D_h
13 #define RecoJets_FFTJetAlgorithms_LinInterpolatedTable1D_h
14 
15 #include <utility>
16 #include <vector>
17 #include <memory>
18 #include <algorithm>
19 
20 #include "fftjet/SimpleFunctors.hh"
22 
23 namespace fftjetcms {
24  class LinInterpolatedTable1D : public fftjet::Functor1<double, double> {
25  public:
26  // Constructor from a regularly spaced data. Extrapolation
27  // from the edge to infinity can be either linear or constant.
28  // "npoints" must be larger than 1.
29  template <typename RealN>
30  LinInterpolatedTable1D(const RealN* data,
31  unsigned npoints,
32  double x_min,
33  double x_max,
36 
37  // Constructor from a list of points, not necessarily regularly
38  // spaced (but must be sorted in the increasing order). The first
39  // member of the pair is the x coordinate, the second is the
40  // tabulated function value. The input list will be interpolated
41  // to "npoints" internal points linearly.
42  template <typename RealN>
43  LinInterpolatedTable1D(const std::vector<std::pair<RealN, RealN> >& v,
44  unsigned npoints,
47 
48  // Constructor which builds a function returning the given constant
49  explicit LinInterpolatedTable1D(double c);
50 
51  inline ~LinInterpolatedTable1D() override {}
52 
53  // Main calculations are performed inside the following operator
54  double operator()(const double& x) const override;
55 
56  // Comparisons (useful for testing)
57  bool operator==(const LinInterpolatedTable1D& r) const;
58  inline bool operator!=(const LinInterpolatedTable1D& r) const { return !(*this == r); }
59 
60  // Various simple inspectors
61  inline double xmin() const { return xmin_; }
62  inline double xmax() const { return xmax_; }
63  inline unsigned npoints() const { return npoints_; }
64  inline bool leftExtrapolationLinear() const { return leftExtrapolationLinear_; }
65  inline bool rightExtrapolationLinear() const { return rightExtrapolationLinear_; }
66  inline const double* data() const { return &data_[0]; }
67 
68  // The following checks whether the table is monotonous
69  // (and, therefore, can be inverted). Possible flat regions
70  // at the edges are not taken into account.
71  bool isMonotonous() const;
72 
73  // Generate the inverse lookup table. Note that it is only
74  // possible if the original table is monotonous (not taking
75  // into account possible flat regions at the edges). If the
76  // inversion is not possible, NULL pointer will be returned.
77  //
78  // The new table will have "npoints" points. The parameters
79  // "leftExtrapolationLinear" and "rightExtrapolationLinear"
80  // refer to the inverted table (note that left and right will
81  // exchange places if the original table is decreasing).
82  //
83  std::unique_ptr<LinInterpolatedTable1D> inverse(unsigned npoints,
85  bool rightExtrapolationLinear) const;
86 
87  private:
88  static inline double interpolateSimple(
89  const double x0, const double x1, const double y0, const double y1, const double x) {
90  return y0 + (y1 - y0) * ((x - x0) / (x1 - x0));
91  }
92 
93  std::vector<double> data_;
94  double xmin_;
95  double xmax_;
96  double binwidth_;
97  unsigned npoints_;
100  mutable bool monotonous_;
101  mutable bool monotonicityKnown_;
102  };
103 } // namespace fftjetcms
104 
105 // Implementation of the templated constructors
106 namespace fftjetcms {
107  template <typename RealN>
109  const unsigned npoints,
110  const double x_min,
111  const double x_max,
112  const bool leftExtrapolationLinear,
113  const bool rightExtrapolationLinear)
114  : data_(data, data + npoints),
115  xmin_(x_min),
116  xmax_(x_max),
117  binwidth_((x_max - x_min) / (npoints - 1U)),
118  npoints_(npoints),
119  leftExtrapolationLinear_(leftExtrapolationLinear),
120  rightExtrapolationLinear_(rightExtrapolationLinear),
121  monotonous_(false),
122  monotonicityKnown_(false) {
123  if (!data)
124  throw cms::Exception("FFTJetBadConfig") << "No data configured" << std::endl;
125  if (npoints <= 1U)
126  throw cms::Exception("FFTJetBadConfig") << "Not enough data points" << std::endl;
127  }
128 
129  template <typename RealN>
131  const unsigned npoints,
132  const bool leftExtrapolationLinear,
133  const bool rightExtrapolationLinear)
134  : xmin_(v[0].first),
135  xmax_(v[v.size() - 1U].first),
136  binwidth_((xmax_ - xmin_) / (npoints - 1U)),
137  npoints_(npoints),
138  leftExtrapolationLinear_(leftExtrapolationLinear),
139  rightExtrapolationLinear_(rightExtrapolationLinear),
140  monotonous_(false),
141  monotonicityKnown_(false) {
142  const unsigned len = v.size();
143  if (len <= 1U)
144  throw cms::Exception("FFTJetBadConfig") << "Not enough data for interpolation" << std::endl;
145 
146  if (npoints <= 1U)
147  throw cms::Exception("FFTJetBadConfig") << "Not enough interpolation table entries" << std::endl;
148 
149  const std::pair<RealN, RealN>* vdata = &v[0];
150  for (unsigned i = 1; i < len; ++i)
151  if (vdata[i - 1U].first >= vdata[i].first)
152  throw cms::Exception("FFTJetBadConfig") << "Input data is not sorted properly" << std::endl;
153 
154  unsigned shift = 0U;
156  ++npoints_;
157  xmin_ -= binwidth_;
158  shift = 1U;
159  }
161  ++npoints_;
162  xmax_ += binwidth_;
163  }
164 
165  data_.resize(npoints_);
166 
168  data_[0] = interpolateSimple(vdata[0].first, vdata[1].first, vdata[0].second, vdata[1].second, xmin_);
169  }
172  vdata[len - 2U].first, vdata[len - 1U].first, vdata[len - 2U].second, vdata[len - 1U].second, xmax_);
173  }
174 
175  data_[shift] = vdata[0].second;
176  data_[npoints - 1U + shift] = vdata[len - 1U].second;
177  unsigned ibelow = 0, iabove = 1;
178  for (unsigned i = 1; i < npoints - 1; ++i) {
179  const double x = xmin_ + (i + shift) * binwidth_;
180  while (static_cast<double>(v[iabove].first) <= x) {
181  ++ibelow;
182  ++iabove;
183  }
184  if (v[ibelow].first == v[iabove].first)
185  data_[i + shift] = (v[ibelow].second + v[iabove].second) / 2.0;
186  else
187  data_[i + shift] = interpolateSimple(v[ibelow].first, v[iabove].first, v[ibelow].second, v[iabove].second, x);
188  }
189  }
190 } // namespace fftjetcms
191 
192 #endif // RecoJets_FFTJetAlgorithms_LinInterpolatedTable1D_h
size
Write out results.
bool operator==(const LinInterpolatedTable1D &r) const
U second(std::pair< T, U > const &p)
static double interpolateSimple(const double x0, const double x1, const double y0, const double y1, const double x)
static const int npoints
std::unique_ptr< LinInterpolatedTable1D > inverse(unsigned npoints, bool leftExtrapolationLinear, bool rightExtrapolationLinear) const
double operator()(const double &x) const override
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:79
static unsigned int const shift
float x
LinInterpolatedTable1D(const RealN *data, unsigned npoints, double x_min, double x_max, bool leftExtrapolationLinear, bool rightExtrapolationLinear)
bool operator!=(const LinInterpolatedTable1D &r) const