CMS 3D CMS Logo

HcalPiecewiseLinearFunctor.cc
Go to the documentation of this file.
1 #include <algorithm>
3 
5 
6 inline static double interpolateSimple(
7  const double x0, const double x1, const double y0, const double y1, const double x) {
8  return y0 + (y1 - y0) * ((x - x0) / (x1 - x0));
9 }
10 
12  : leftExtrapolationLinear_(false), rightExtrapolationLinear_(false) {}
13 
14 HcalPiecewiseLinearFunctor::HcalPiecewiseLinearFunctor(const std::vector<std::pair<double, double> >& points,
15  const bool leftExtrapolationLinear,
16  const bool rightExtrapolationLinear)
17  : leftExtrapolationLinear_(leftExtrapolationLinear), rightExtrapolationLinear_(rightExtrapolationLinear) {
18  const std::size_t sz = points.size();
19  if (sz) {
20  std::vector<std::pair<double, double> > tmp(points);
21  std::sort(tmp.begin(), tmp.end());
22  abscissae_.reserve(sz);
23  values_.reserve(sz);
24  for (std::size_t i = 0; i < sz; ++i) {
25  abscissae_.push_back(tmp[i].first);
26  values_.push_back(tmp[i].second);
27  }
28  if (!isStrictlyIncreasing(abscissae_.begin(), abscissae_.end()))
29  throw cms::Exception(
30  "In HcalPiecewiseLinearFunctor constructor:"
31  " abscissae must not coincide");
32  }
33 }
34 
35 double HcalPiecewiseLinearFunctor::operator()(const double x) const {
36  double result = 0.0;
37  const std::size_t sz = abscissae_.size();
38  if (sz) {
39  if (sz > 1) {
40  const std::size_t szm1 = sz - 1;
41  if (x >= abscissae_[szm1]) {
43  result = interpolateSimple(abscissae_[sz - 2], abscissae_[szm1], values_[sz - 2], values_[szm1], x);
44  else
45  result = values_[szm1];
46  } else if (x <= abscissae_[0]) {
49  else
50  result = values_[0];
51  } else {
52  const std::size_t cell = std::upper_bound(abscissae_.begin(), abscissae_.end(), x) - abscissae_.begin() - 1;
53  result = interpolateSimple(abscissae_[cell], abscissae_[cell + 1], values_[cell], values_[cell + 1], x);
54  }
55  } else
56  result = values_[0];
57  }
58  return result;
59 }
60 
62  return isStrictlyIncreasing(values_.begin(), values_.end()) || isStrictlyDecreasing(values_.begin(), values_.end());
63 }
64 
66  if (!isStrictlyMonotonous())
67  throw cms::Exception(
68  "In HcalPiecewiseLinearFunctor::inverse:"
69  " can't invert non-monotonous functor");
70  const std::size_t sz = abscissae_.size();
71  std::vector<std::pair<double, double> > points;
72  points.reserve(sz);
73  for (std::size_t i = 0; i < sz; ++i)
74  points.push_back(std::make_pair(values_[i], abscissae_[i]));
77  if (values_[0] > values_[sz - 1])
78  std::swap(l, r);
79  return HcalPiecewiseLinearFunctor(points, l, r);
80 }
81 
83  double result = 0.0;
84  if (!abscissae_.empty())
85  result = abscissae_[0];
86  return result;
87 }
88 
90  double result = 0.0;
91  if (!abscissae_.empty())
92  result = abscissae_.back();
93  return result;
94 }
95 
96 BOOST_CLASS_EXPORT_IMPLEMENT(HcalPiecewiseLinearFunctor)
double operator()(double x) const override
HcalPiecewiseLinearFunctor inverse() const
static bool isStrictlyIncreasing(Iter begin, Iter const end)
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:112
U second(std::pair< T, U > const &p)
static bool isStrictlyDecreasing(Iter begin, Iter const end)
static double interpolateSimple(const double x0, const double x1, const double y0, const double y1, const double x)
float x
tmp
align.sh
Definition: createJobs.py:716