CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/RecoJets/FFTJetAlgorithms/src/LinInterpolatedTable1D.cc

Go to the documentation of this file.
00001 #include "RecoJets/FFTJetAlgorithms/interface/LinInterpolatedTable1D.h"
00002 
00003 namespace fftjetcms {
00004     LinInterpolatedTable1D::LinInterpolatedTable1D(const double c)
00005         : data_(2, c),
00006           xmin_(0.0),
00007           xmax_(1.0),
00008           binwidth_(1.0),
00009           npoints_(2U),
00010           leftExtrapolationLinear_(false),
00011           rightExtrapolationLinear_(false),
00012           monotonous_(false),
00013           monotonicityKnown_(true)
00014     {
00015     }
00016 
00017     bool LinInterpolatedTable1D::operator==(
00018         const LinInterpolatedTable1D& r) const
00019     {
00020         return xmin_ == r.xmin_ &&
00021                xmax_ == r.xmax_ &&
00022                binwidth_ == r.binwidth_ &&
00023                npoints_ == r.npoints_ &&
00024                leftExtrapolationLinear_ == r.leftExtrapolationLinear_ &&
00025                rightExtrapolationLinear_ == r.rightExtrapolationLinear_ &&
00026                data_ == r.data_;
00027     }
00028 
00029     bool LinInterpolatedTable1D::isMonotonous() const
00030     {
00031         if (!monotonicityKnown_)
00032         {
00033             monotonous_ = true;
00034             const double delta = data_[npoints_ - 1U] - data_[0];
00035             if (delta == 0.0)
00036                 monotonous_ = false;
00037             const double sg = delta > 0.0 ? 1.0 : -1.0;
00038             for (unsigned i=1; i<npoints_ && monotonous_; ++i)
00039                 if ((data_[i] - data_[i-1])*sg <= 0.0)
00040                     monotonous_ = false;
00041             monotonicityKnown_ = true;
00042         }
00043         return monotonous_;
00044     }
00045 
00046     std::auto_ptr<LinInterpolatedTable1D> LinInterpolatedTable1D::inverse(
00047         const unsigned npoints, const bool leftExtrapolationLinear,
00048         const bool rightExtrapolationLinear) const
00049     {
00050         if (!isMonotonous())
00051             return std::auto_ptr<LinInterpolatedTable1D>(NULL);
00052 
00053         std::vector<std::pair<double,double> > points;
00054         points.reserve(npoints_);
00055 
00056         if (data_[npoints_ - 1U] > data_[0])
00057         {
00058             points.push_back(std::pair<double,double>(data_[0], xmin_));
00059             for (unsigned i=1; i<npoints_ - 1U; ++i)
00060                 points.push_back(std::pair<double,double>(data_[i], xmin_+i*binwidth_));
00061             points.push_back(std::pair<double,double>(data_[npoints_ - 1U], xmax_));
00062         }
00063         else
00064         {
00065             points.push_back(std::pair<double,double>(data_[npoints_ - 1U], xmax_));
00066             for (unsigned i=npoints_ - 2U; i>0; --i)
00067                 points.push_back(std::pair<double,double>(data_[i], xmin_+i*binwidth_));
00068             points.push_back(std::pair<double,double>(data_[0], xmin_));
00069         }
00070 
00071         return std::auto_ptr<LinInterpolatedTable1D>(
00072             new LinInterpolatedTable1D(points, npoints,
00073                                        leftExtrapolationLinear,
00074                                        rightExtrapolationLinear));
00075     }
00076 
00077     double LinInterpolatedTable1D::operator()(const double& x) const
00078     {
00079         if (x <= xmin_)
00080         {
00081             if (leftExtrapolationLinear_)
00082                 return data_[0] + (data_[1]-data_[0])*((x-xmin_)/binwidth_);
00083             else
00084                 return data_[0];
00085         }
00086         else if (x >= xmax_)
00087         {
00088             if (rightExtrapolationLinear_)
00089                 return data_[npoints_ - 1U] - (
00090                   data_[npoints_-2U]-data_[npoints_-1U])*((x-xmax_)/binwidth_);
00091             else
00092                 return data_[npoints_ - 1U];
00093         }
00094         else
00095         {
00096             const unsigned ux = static_cast<unsigned>((x - xmin_)/binwidth_);
00097             if (ux >= npoints_ - 1U)
00098                 return data_[npoints_ - 1U];
00099             const double delta = x - (ux*binwidth_ + xmin_);
00100             return data_[ux] + (data_[ux+1U]-data_[ux])*delta/binwidth_;
00101         }
00102     }
00103 }