CMS 3D CMS Logo

HcalInterpolatedTableFunctor.cc
Go to the documentation of this file.
1 #include <algorithm>
3 
5 
6 inline static double interpolateStep(
7  const double x0, const double step,
8  const double y0, const double y1,
9  const double x)
10 {
11  return y0 + (y1 - y0)*((x - x0)/step);
12 }
13 
15  : xmin_(0.), xmax_(0.),
16  leftExtrapolationLinear_(false), rightExtrapolationLinear_(false)
17 {
18 }
19 
21  const std::vector<double>& values,
22  const double ixmin, const double ixmax,
23  const bool leftExtrapolationLinear,
24  const bool rightExtrapolationLinear)
25  : values_(values),
26  xmin_(ixmin),
27  xmax_(ixmax),
28  leftExtrapolationLinear_(leftExtrapolationLinear),
29  rightExtrapolationLinear_(rightExtrapolationLinear)
30 {
31  if (values_.size() < 2)
32  throw cms::Exception("In HcalInterpolatedTableFunctor constructor:"
33  " insufficient number of points");
34  if (xmin_ >= xmax_)
35  throw cms::Exception("In HcalInterpolatedTableFunctor constructor:"
36  " invalid min and/or max coordinates");
37 }
38 
39 double HcalInterpolatedTableFunctor::operator()(const double x) const
40 {
41  double result = 0.0;
42  const std::size_t sz = values_.size();
43  const std::size_t szm1 = sz - 1;
44  const double step = (xmax_ - xmin_)/szm1;
45 
46  if (x >= xmax_)
47  {
49  result = interpolateStep(xmax_ - step, step,
50  values_[sz-2], values_[szm1], x);
51  else
52  result = values_[szm1];
53  }
54  else if (x <= xmin_)
55  {
57  result = interpolateStep(xmin_, step, values_[0], values_[1], x);
58  else
59  result = values_[0];
60  }
61  else
62  {
63  const std::size_t ux = static_cast<std::size_t>((x - xmin_)/step);
64  if (ux >= szm1)
65  return values_[szm1];
66  result = interpolateStep(ux*step + xmin_, step,
67  values_[ux], values_[ux+1], x);
68  }
69 
70  return result;
71 }
72 
74 {
75  return isStrictlyIncreasing(values_.begin(), values_.end()) ||
76  isStrictlyDecreasing(values_.begin(), values_.end());
77 }
78 
80 {
81  if (!isStrictlyMonotonous())
82  throw cms::Exception("In HcalInterpolatedTableFunctor::inverse:"
83  " can't invert non-monotonous functor");
84  const std::size_t sz = values_.size();
85  const std::size_t szm1 = sz - 1;
86  const double step = (xmax_ - xmin_)/szm1;
87  std::vector<std::pair<double, double> > points;
88  points.reserve(sz);
89  for (std::size_t i=0; i<sz; ++i)
90  {
91  const double x = (i == szm1 ? xmax_ : xmin_ + step*i);
92  points.push_back(std::make_pair(values_[i], x));
93  }
96  if (values_[0] > values_[sz - 1])
97  std::swap(l, r);
98  return HcalPiecewiseLinearFunctor(points, l, r);
99 }
100 
101 BOOST_CLASS_EXPORT_IMPLEMENT(HcalInterpolatedTableFunctor)
static double interpolateStep(const double x0, const double step, const double y0, const double y1, const double x)
HcalPiecewiseLinearFunctor inverse() const
static bool isStrictlyIncreasing(Iter begin, Iter const end)
static bool isStrictlyDecreasing(Iter begin, Iter const end)
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
double operator()(double x) const override
step