/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
RecoJets/FFTJetAlgorithms/interface/LinInterpolatedTable1D.h
192 строки
8 KB
Cms Build
Clang-Format
31 май 2019, 13:15
31 май 2019, 13:15
eb1cff4
Код
Авторство
О чём код?
//========================================================================= // LinInterpolatedTable1D.h // // This class can be used to linearly interpolate data in one dimension. // It differs from similar facilities in the fftjet package by its handling // of the extrapolation beyound the grid limits. // // I. Volobouev // April 2011 //========================================================================= #ifndef RecoJets_FFTJetAlgorithms_LinInterpolatedTable1D_h #define RecoJets_FFTJetAlgorithms_LinInterpolatedTable1D_h #include <utility> #include <vector> #include <memory> #include <algorithm> #include "fftjet/SimpleFunctors.hh" #include "FWCore/Utilities/interface/Exception.h" namespace fftjetcms { class LinInterpolatedTable1D : public fftjet::Functor1<double, double> { public: // Constructor from a regularly spaced data. Extrapolation // from the edge to infinity can be either linear or constant. // "npoints" must be larger than 1. template <typename RealN> LinInterpolatedTable1D(const RealN* data, unsigned npoints, double x_min, double x_max, bool leftExtrapolationLinear, bool rightExtrapolationLinear); // Constructor from a list of points, not necessarily regularly // spaced (but must be sorted in the increasing order). The first // member of the pair is the x coordinate, the second is the // tabulated function value. The input list will be interpolated // to "npoints" internal points linearly. template <typename RealN> LinInterpolatedTable1D(const std::vector<std::pair<RealN, RealN> >& v, unsigned npoints, bool leftExtrapolationLinear, bool rightExtrapolationLinear); // Constructor which builds a function returning the given constant explicit LinInterpolatedTable1D(double c); inline ~LinInterpolatedTable1D() override {} // Main calculations are performed inside the following operator double operator()(const double& x) const override; // Comparisons (useful for testing) bool operator==(const LinInterpolatedTable1D& r) const; inline bool operator!=(const LinInterpolatedTable1D& r) const { return !(*this == r); } // Various simple inspectors inline double xmin() const { return xmin_; } inline double xmax() const { return xmax_; } inline unsigned npoints() const { return npoints_; } inline bool leftExtrapolationLinear() const { return leftExtrapolationLinear_; } inline bool rightExtrapolationLinear() const { return rightExtrapolationLinear_; } inline const double* data() const { return &data_[0]; } // The following checks whether the table is monotonous // (and, therefore, can be inverted). Possible flat regions // at the edges are not taken into account. bool isMonotonous() const; // Generate the inverse lookup table. Note that it is only // possible if the original table is monotonous (not taking // into account possible flat regions at the edges). If the // inversion is not possible, NULL pointer will be returned. // // The new table will have "npoints" points. The parameters // "leftExtrapolationLinear" and "rightExtrapolationLinear" // refer to the inverted table (note that left and right will // exchange places if the original table is decreasing). // std::unique_ptr<LinInterpolatedTable1D> inverse(unsigned npoints, bool leftExtrapolationLinear, bool rightExtrapolationLinear) const; private: static inline double interpolateSimple( const double x0, const double x1, const double y0, const double y1, const double x) { return y0 + (y1 - y0) * ((x - x0) / (x1 - x0)); } std::vector<double> data_; double xmin_; double xmax_; double binwidth_; unsigned npoints_; bool leftExtrapolationLinear_; bool rightExtrapolationLinear_; mutable bool monotonous_; mutable bool monotonicityKnown_; }; } // namespace fftjetcms // Implementation of the templated constructors namespace fftjetcms { template <typename RealN> inline LinInterpolatedTable1D::LinInterpolatedTable1D(const RealN* data, const unsigned npoints, const double x_min, const double x_max, const bool leftExtrapolationLinear, const bool rightExtrapolationLinear) : data_(data, data + npoints), xmin_(x_min), xmax_(x_max), binwidth_((x_max - x_min) / (npoints - 1U)), npoints_(npoints), leftExtrapolationLinear_(leftExtrapolationLinear), rightExtrapolationLinear_(rightExtrapolationLinear), monotonous_(false), monotonicityKnown_(false) { if (!data) throw cms::Exception("FFTJetBadConfig") << "No data configured" << std::endl; if (npoints <= 1U) throw cms::Exception("FFTJetBadConfig") << "Not enough data points" << std::endl; } template <typename RealN> LinInterpolatedTable1D::LinInterpolatedTable1D(const std::vector<std::pair<RealN, RealN> >& v, const unsigned npoints, const bool leftExtrapolationLinear, const bool rightExtrapolationLinear) : xmin_(v[0].first), xmax_(v[v.size() - 1U].first), binwidth_((xmax_ - xmin_) / (npoints - 1U)), npoints_(npoints), leftExtrapolationLinear_(leftExtrapolationLinear), rightExtrapolationLinear_(rightExtrapolationLinear), monotonous_(false), monotonicityKnown_(false) { const unsigned len = v.size(); if (len <= 1U) throw cms::Exception("FFTJetBadConfig") << "Not enough data for interpolation" << std::endl; if (npoints <= 1U) throw cms::Exception("FFTJetBadConfig") << "Not enough interpolation table entries" << std::endl; const std::pair<RealN, RealN>* vdata = &v[0]; for (unsigned i = 1; i < len; ++i) if (vdata[i - 1U].first >= vdata[i].first) throw cms::Exception("FFTJetBadConfig") << "Input data is not sorted properly" << std::endl; unsigned shift = 0U; if (leftExtrapolationLinear) { ++npoints_; xmin_ -= binwidth_; shift = 1U; } if (rightExtrapolationLinear) { ++npoints_; xmax_ += binwidth_; } data_.resize(npoints_); if (leftExtrapolationLinear) { data_[0] = interpolateSimple(vdata[0].first, vdata[1].first, vdata[0].second, vdata[1].second, xmin_); } if (rightExtrapolationLinear) { data_[npoints_ - 1U] = interpolateSimple( vdata[len - 2U].first, vdata[len - 1U].first, vdata[len - 2U].second, vdata[len - 1U].second, xmax_); } data_[shift] = vdata[0].second; data_[npoints - 1U + shift] = vdata[len - 1U].second; unsigned ibelow = 0, iabove = 1; for (unsigned i = 1; i < npoints - 1; ++i) { const double x = xmin_ + (i + shift) * binwidth_; while (static_cast<double>(v[iabove].first) <= x) { ++ibelow; ++iabove; } if (v[ibelow].first == v[iabove].first) data_[i + shift] = (v[ibelow].second + v[iabove].second) / 2.0; else data_[i + shift] = interpolateSimple(v[ibelow].first, v[iabove].first, v[ibelow].second, v[iabove].second, x); } } } // namespace fftjetcms #endif // RecoJets_FFTJetAlgorithms_LinInterpolatedTable1D_h