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)
T x() const
Cartesian x coordinate.
static bool isStrictlyDecreasing(Iter begin, Iter const end)
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
virtual double operator()(double x) const override
step