CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_1/src/JetMETCorrections/InterpolationTables/interface/BoxND.h

Go to the documentation of this file.
00001 #ifndef NPSTAT_BOXND_HH_
00002 #define NPSTAT_BOXND_HH_
00003 
00014 #include <vector>
00015 
00016 #include "Alignment/Geners/interface/ClassId.hh"
00017 #include "JetMETCorrections/InterpolationTables/interface/Interval.h"
00018 
00019 namespace npstat {
00023     template <typename Numeric>
00024     struct BoxND : public std::vector<Interval<Numeric> >
00025     {
00027         inline BoxND() {}
00028 
00030         inline explicit BoxND(const unsigned long dim) :
00031             std::vector<Interval<Numeric> >(dim) {}
00032 
00034         inline BoxND(const unsigned long dim, const Interval<Numeric>& v) :
00035             std::vector<Interval<Numeric> >(dim, v) {}
00036 
00042         template <typename Num2>
00043         explicit BoxND(const std::vector<Num2>& limits);
00044 
00046         template <typename Num2>
00047         explicit BoxND(const BoxND<Num2>& r);
00048 
00053         template <typename Num2>
00054         BoxND& copyFrom(const BoxND<Num2>& r);
00055 
00057         inline unsigned long dim() const {return this->size();}
00058 
00060         Numeric volume() const;
00061 
00066         void getMidpoint(Numeric* coord, unsigned long coordLen) const;
00067 
00069 
00074         template <typename Num2>
00075         bool isInsideLower(const Num2* coord, unsigned long coordLen) const;
00076         template <typename Num2>
00077         bool isInsideUpper(const Num2* coord, unsigned long coordLen) const;
00078         template <typename Num2>
00079         bool isInsideWithBounds(const Num2* coord, unsigned long coordLen) const;
00080         template <typename Num2>
00081         bool isInside(const Num2* coord, unsigned long coordLen) const;
00083 
00085 
00086         BoxND& operator*=(double r);
00087         BoxND& operator/=(double r);
00089 
00091 
00092         BoxND& operator*=(const std::vector<double>& scales);
00093         BoxND& operator/=(const std::vector<double>& scales);
00095 
00100         BoxND& expand(double r);
00101 
00103 
00108         BoxND& expand(const std::vector<double>& scales);
00109         BoxND& expand(const double* scales, unsigned long lenScales);
00111 
00113 
00114         template <typename Num2>
00115         BoxND& operator+=(const std::vector<Num2>& shifts);
00116         template <typename Num2>
00117         BoxND& operator-=(const std::vector<Num2>& shifts);
00118         template <typename Num2>
00119         BoxND& shift(const Num2* shifts, unsigned long lenShifts);
00121 
00123         BoxND& moveToOrigin();
00124 
00126         Numeric overlapVolume(const BoxND& r) const;
00127 
00129         double overlapFraction(const BoxND& r) const;
00130 
00132         static BoxND unitBox(unsigned long ndim);
00133 
00139         static BoxND sizeTwoBox(unsigned long ndim);
00140 
00146         static BoxND allSpace(unsigned long ndim);
00147 
00149 
00150         inline gs::ClassId classId() const {return gs::ClassId(*this);}
00151         bool write(std::ostream& of) const;
00153 
00154         static const char* classname();
00155         static inline unsigned version() {return 1;}
00156         static void restore(const gs::ClassId& id, std::istream& in, BoxND* box);
00157     };
00158 }
00159 
00161 
00162 template <typename Numeric>
00163 bool operator==(const npstat::BoxND<Numeric>& l, const npstat::BoxND<Numeric>& r);
00164 
00165 template <typename Numeric>
00166 bool operator!=(const npstat::BoxND<Numeric>& l, const npstat::BoxND<Numeric>& r);
00168 
00169 #include <limits>
00170 #include <cassert>
00171 #include "JetMETCorrections/InterpolationTables/interface/NpstatException.h"
00172 
00173 #include "Alignment/Geners/interface/GenericIO.hh"
00174 
00175 namespace npstat {
00176     template <typename Numeric>
00177     template <typename Num2>
00178     BoxND<Numeric>::BoxND(const BoxND<Num2>& r)
00179     {
00180         const unsigned long dim = r.size();
00181         if (dim)
00182         {
00183             this->reserve(dim);
00184             for (unsigned long i=0; i<dim; ++i)
00185             {
00186                 const Interval<Num2>& ri(r[i]);
00187                 this->push_back(Interval<Numeric>(ri.min(), ri.max()));
00188             }
00189         }
00190     }
00191 
00192     template <typename Numeric>
00193     template <typename Num2>
00194     BoxND<Numeric>::BoxND(const std::vector<Num2>& limits)
00195     {
00196         const unsigned long dim = limits.size();
00197         if (dim)
00198         {
00199             this->reserve(dim);
00200             Numeric zero = Numeric();
00201             for (unsigned long i=0; i<dim; ++i)
00202             {
00203                 const Numeric value(static_cast<Numeric>(limits[i]));
00204                 if (value >= zero)
00205                     this->push_back(Interval<Numeric>(zero, value));
00206                 else
00207                     this->push_back(Interval<Numeric>(value, zero));
00208             }
00209         }
00210     }
00211 
00212     template <typename Numeric>
00213     template <typename Num2>
00214     BoxND<Numeric>& BoxND<Numeric>::copyFrom(const BoxND<Num2>& r)
00215     {
00216         if ((void *)this == (void *)(&r))
00217             return *this;
00218         const unsigned long n = r.size();
00219         this->clear();
00220         this->reserve(n);
00221         for (unsigned long i=0; i<n; ++i)
00222         {
00223             const Interval<Num2>& ir(r[i]);
00224             this->push_back(Interval<Numeric>(ir.min(), ir.max()));
00225         }
00226         return *this;
00227     }
00228 
00229     template <typename Numeric>
00230     Numeric BoxND<Numeric>::volume() const
00231     {
00232         Numeric v(static_cast<Numeric>(1));
00233         const unsigned long mydim = this->size();
00234         for (unsigned long i=0U; i<mydim; ++i)
00235             v *= (*this)[i].length();
00236         return v;
00237     }
00238 
00239     template <typename Numeric>
00240     Numeric BoxND<Numeric>::overlapVolume(const BoxND& r) const
00241     {
00242         const unsigned long mydim = this->size();
00243         if (mydim == r.size())
00244         {
00245             Numeric v(static_cast<Numeric>(1));
00246             for (unsigned long i=0U; i<mydim; ++i)
00247                 v *= (*this)[i].overlapLength(r[i]);
00248             return v;
00249         }
00250         else
00251             return static_cast<Numeric>(0);
00252     }
00253 
00254     template <typename Numeric>
00255     double BoxND<Numeric>::overlapFraction(const BoxND& r) const
00256     {
00257         const unsigned long mydim = this->size();
00258         if (mydim == r.size())
00259         {
00260             double f = 1.0;
00261             for (unsigned long i=0U; i<mydim; ++i)
00262                 f *= (*this)[i].overlapFraction(r[i]);
00263             return f;
00264         }
00265         else
00266             return 0.0;
00267     }
00268 
00269     template <typename Numeric>
00270     void BoxND<Numeric>::getMidpoint(Numeric* coord,
00271                                      const unsigned long coordLen) const
00272     {
00273         const unsigned long mydim = this->size();
00274         if (coordLen < mydim) throw npstat::NpstatInvalidArgument(
00275             "In npstat::BoxND::getMidpoint: insufficient output buffer length");
00276         if (mydim)
00277         {
00278             assert(coord);
00279             for (unsigned  long i=0U; i<mydim; ++i)
00280                 coord[i] = (*this)[i].midpoint();
00281         }
00282     }
00283 
00284     template <typename Numeric>
00285     template <typename Num2>
00286     bool BoxND<Numeric>::isInsideLower(const Num2* coords,
00287                                        const unsigned long coordLen) const
00288     {
00289         if (coordLen != this->size()) throw npstat::NpstatInvalidArgument(
00290             "In npstat::BoxND::isInsideLower: "
00291             "incompatible point dimensionality");
00292         const Interval<Numeric>* myptr = &(*this)[0];
00293         for (unsigned long i=0; i<coordLen; ++i)
00294             if (!myptr[i].isInsideLower(coords[i]))
00295                 return false;
00296         return true;
00297     }
00298 
00299     template <typename Numeric>
00300     template <typename Num2>
00301     bool BoxND<Numeric>::isInsideUpper(const Num2* coords,
00302                                        const unsigned long coordLen) const
00303     {
00304         if (coordLen != this->size()) throw npstat::NpstatInvalidArgument(
00305             "In npstat::BoxND::isInsideUpper: "
00306             "incompatible point dimensionality");
00307         const Interval<Numeric>* myptr = &(*this)[0];
00308         for (unsigned long i=0; i<coordLen; ++i)
00309             if (!myptr[i].isInsideUpper(coords[i]))
00310                 return false;
00311         return true;
00312     }
00313 
00314     template <typename Numeric>
00315     template <typename Num2>
00316     bool BoxND<Numeric>::isInsideWithBounds(const Num2* coords,
00317                                             const unsigned long coordLen) const
00318     {
00319         if (coordLen != this->size()) throw npstat::NpstatInvalidArgument(
00320             "In npstat::BoxND::isInsideWithBounds: "
00321             "incompatible point dimensionality");
00322         const Interval<Numeric>* myptr = &(*this)[0];
00323         for (unsigned long i=0; i<coordLen; ++i)
00324             if (!myptr[i].isInsideWithBounds(coords[i]))
00325                 return false;
00326         return true;
00327     }
00328 
00329     template <typename Numeric>
00330     template <typename Num2>
00331     bool BoxND<Numeric>::isInside(const Num2* coords,
00332                                   const unsigned long coordLen) const
00333     {
00334         if (coordLen != this->size()) throw npstat::NpstatInvalidArgument(
00335             "In npstat::BoxND::isInside: incompatible point dimensionality");
00336         const Interval<Numeric>* myptr = &(*this)[0];
00337         for (unsigned long i=0; i<coordLen; ++i)
00338             if (!myptr[i].isInside(coords[i]))
00339                 return false;
00340         return true;
00341     }
00342 
00343     template <typename Numeric>
00344     BoxND<Numeric>& BoxND<Numeric>::operator*=(const double r)
00345     {
00346         const unsigned long mydim = this->size();
00347         for (unsigned long i=0; i<mydim; ++i)
00348             (*this)[i] *= r;
00349         return *this;
00350     }
00351 
00352     template <typename Numeric>
00353     BoxND<Numeric>& BoxND<Numeric>::moveToOrigin()
00354     {
00355         const unsigned long mydim = this->size();
00356         for (unsigned long i=0; i<mydim; ++i)
00357             (*this)[i].moveMidpointTo0();
00358         return *this;
00359     }
00360 
00361     template <typename Numeric>
00362     BoxND<Numeric>& BoxND<Numeric>::expand(const double r)
00363     {
00364         const unsigned long mydim = this->size();
00365         for (unsigned long i=0; i<mydim; ++i)
00366             (*this)[i].expand(r);
00367         return *this;
00368     }
00369 
00370     template <typename Numeric>
00371     BoxND<Numeric>& BoxND<Numeric>::operator*=(
00372         const std::vector<double>& scales)
00373     {
00374         const unsigned long mydim = this->size();
00375         if (mydim != scales.size()) throw npstat::NpstatInvalidArgument(
00376             "In npstat::BoxND::operator*=: "
00377             "incompatible argument dimensionality");
00378         for (unsigned long i=0; i<mydim; ++i)
00379             (*this)[i] *= scales[i];
00380         return *this;
00381     }
00382 
00383     template <typename Numeric>
00384     BoxND<Numeric>& BoxND<Numeric>::expand(
00385         const std::vector<double>& scales)
00386     {
00387         const unsigned long mydim = this->size();
00388         if (mydim != scales.size()) throw npstat::NpstatInvalidArgument(
00389             "In npstat::BoxND::expand: incompatible argument dimensionality");
00390         for (unsigned long i=0; i<mydim; ++i)
00391             (*this)[i].expand(scales[i]);
00392         return *this;
00393     }
00394 
00395     template <typename Numeric>
00396     BoxND<Numeric>& BoxND<Numeric>::expand(
00397         const double* scales, const unsigned long lenScales)
00398     {
00399         const unsigned long mydim = this->size();
00400         if (mydim != lenScales) throw npstat::NpstatInvalidArgument(
00401             "In npstat::BoxND::expand: incompatible argument dimensionality");
00402         if (mydim)
00403         {
00404             assert(scales);
00405             for (unsigned long i=0; i<mydim; ++i)
00406                 (*this)[i].expand(scales[i]);
00407         }
00408         return *this;
00409     }
00410 
00411     template <typename Numeric>
00412     BoxND<Numeric>& BoxND<Numeric>::operator/=(const double r)
00413     {
00414         const unsigned long mydim = this->size();
00415         for (unsigned long i=0; i<mydim; ++i)
00416             (*this)[i] /= r;
00417         return *this;
00418     }
00419 
00420     template <typename Numeric>
00421     BoxND<Numeric>& BoxND<Numeric>::operator/=(
00422         const std::vector<double>& scales)
00423     {
00424         const unsigned long mydim = this->size();
00425         if (mydim != scales.size()) throw npstat::NpstatInvalidArgument(
00426             "In npstat::BoxND::operator/=: "
00427             "incompatible argument dimensionality");
00428         for (unsigned long i=0; i<mydim; ++i)
00429             (*this)[i] /= scales[i];
00430         return *this;
00431     }
00432 
00433     template <typename Numeric>
00434     template <typename Num2>
00435     BoxND<Numeric>& BoxND<Numeric>::operator+=(const std::vector<Num2>& shifts)
00436     {
00437         const unsigned long mydim = this->size();
00438         if (mydim != shifts.size()) throw npstat::NpstatInvalidArgument(
00439             "In npstat::BoxND::operator+=: "
00440             "incompatible argument dimensionality");
00441         for (unsigned long i=0; i<mydim; ++i)
00442             (*this)[i] += static_cast<Numeric>(shifts[i]);
00443         return *this;
00444     }
00445 
00446     template <typename Numeric>
00447     template <typename Num2>
00448     BoxND<Numeric>& BoxND<Numeric>::shift(
00449         const Num2* shifts, const unsigned long shiftsLen)
00450     {
00451         const unsigned long mydim = this->size();
00452         if (mydim != shiftsLen) throw npstat::NpstatInvalidArgument(
00453             "In npstat::BoxND::shift: incompatible argument dimensionality");
00454         if (mydim)
00455         {
00456             assert(shifts);
00457             for (unsigned long i=0; i<mydim; ++i)
00458                 (*this)[i] += static_cast<Numeric>(shifts[i]);
00459         }
00460         return *this;
00461     }
00462 
00463     template <typename Numeric>
00464     template <typename Num2>
00465     BoxND<Numeric>& BoxND<Numeric>::operator-=(const std::vector<Num2>& shifts)
00466     {
00467         const unsigned long mydim = this->size();
00468         if (mydim != shifts.size()) throw npstat::NpstatInvalidArgument(
00469             "In npstat::BoxND::operator-=: "
00470             "incompatible argument dimensionality");
00471         for (unsigned long i=0; i<mydim; ++i)
00472             (*this)[i] -= static_cast<Numeric>(shifts[i]);
00473         return *this;
00474     }
00475 
00476     template <typename Numeric>
00477     BoxND<Numeric> BoxND<Numeric>::unitBox(const unsigned long ndim)
00478     {
00479         Interval<Numeric> unit(static_cast<Numeric>(0),
00480                                static_cast<Numeric>(1));
00481         return BoxND<Numeric>(ndim, unit);
00482     }
00483 
00484     template <typename Numeric>
00485     BoxND<Numeric> BoxND<Numeric>::sizeTwoBox(const unsigned long ndim)
00486     {
00487         const Numeric one = static_cast<Numeric>(1);
00488         Interval<Numeric> i(-one, one);
00489         return BoxND<Numeric>(ndim, i);
00490     }
00491 
00492     template <typename Numeric>
00493     BoxND<Numeric> BoxND<Numeric>::allSpace(const unsigned long ndim)
00494     {
00495         const Numeric maxval = std::numeric_limits<Numeric>::max();
00496         Interval<Numeric> i(-maxval, maxval);
00497         return BoxND<Numeric>(ndim, i);
00498     }
00499 
00500     template<typename Numeric>
00501     const char* BoxND<Numeric>::classname()
00502     {
00503         static const std::string na(gs::template_class_name<Numeric>("npstat::BoxND"));
00504         return na.c_str();
00505     }
00506 
00507     template<typename Numeric>
00508     bool BoxND<Numeric>::write(std::ostream& of) const
00509     {
00510         const unsigned long mydim = this->size();
00511         std::vector<Numeric> limits;
00512         limits.reserve(2UL*mydim);
00513         for (unsigned long i=0; i<mydim; ++i)
00514         {
00515             limits.push_back((*this)[i].min());
00516             limits.push_back((*this)[i].max());
00517         }
00518         return gs::write_item(of, limits);
00519     }
00520 
00521     template<typename Numeric>
00522     void BoxND<Numeric>::restore(const gs::ClassId& id, std::istream& in, BoxND* b)
00523     {
00524         static const gs::ClassId current(gs::ClassId::makeId<BoxND<Numeric> >());
00525         current.ensureSameId(id);
00526 
00527         std::vector<Numeric> limits;
00528         gs::restore_item(in, &limits);
00529         if (in.fail())
00530             throw gs::IOReadFailure("In npstat::BoxND::restore: input stream failure");
00531         const unsigned long nlimits = limits.size();
00532         if (nlimits % 2UL)
00533             throw gs::IOInvalidData("In npstat::BoxND::restore: bad limits");
00534         assert(b);
00535         b->clear();
00536         b->reserve(nlimits/2UL);
00537         for (unsigned long i=0; i<nlimits/2UL; ++i)
00538             b->push_back(npstat::Interval<Numeric>(limits[2U*i], limits[2U*i+1U]));
00539     }
00540 }
00541 
00542 template <typename Numeric>
00543 bool operator==(const npstat::BoxND<Numeric>& l, const npstat::BoxND<Numeric>& r)
00544 {
00545     const unsigned long dim = l.size();
00546     if (dim != r.size())
00547         return false;
00548     for (unsigned long i=0; i<dim; ++i)
00549         if (l[i] != r[i])
00550             return false;
00551     return true;
00552 }
00553 
00554 template <typename Numeric>
00555 bool operator!=(const npstat::BoxND<Numeric>& l, const npstat::BoxND<Numeric>& r)
00556 {
00557     return !(l == r);
00558 }
00559 
00560 
00561 #endif // NPSTAT_BOXND_HH_
00562