CMS 3D CMS Logo

BoxND.h
Go to the documentation of this file.
1 #ifndef NPSTAT_BOXND_HH_
2 #define NPSTAT_BOXND_HH_
3 
14 #include <vector>
15 
16 #include "Alignment/Geners/interface/ClassId.hh"
18 
19 namespace npstat {
23  template <typename Numeric>
24  struct BoxND : public std::vector<Interval<Numeric> > {
26  inline BoxND() {}
27 
29  inline explicit BoxND(const unsigned long dim) : std::vector<Interval<Numeric> >(dim) {}
30 
32  inline BoxND(const unsigned long dim, const Interval<Numeric>& v) : std::vector<Interval<Numeric> >(dim, v) {}
33 
39  template <typename Num2>
40  explicit BoxND(const std::vector<Num2>& limits);
41 
43  template <typename Num2>
44  explicit BoxND(const BoxND<Num2>& r);
45 
50  template <typename Num2>
51  BoxND& copyFrom(const BoxND<Num2>& r);
52 
54  inline unsigned long dim() const { return this->size(); }
55 
57  Numeric volume() const;
58 
63  void getMidpoint(Numeric* coord, unsigned long coordLen) const;
64 
66 
71  template <typename Num2>
72  bool isInsideLower(const Num2* coord, unsigned long coordLen) const;
73  template <typename Num2>
74  bool isInsideUpper(const Num2* coord, unsigned long coordLen) const;
75  template <typename Num2>
76  bool isInsideWithBounds(const Num2* coord, unsigned long coordLen) const;
77  template <typename Num2>
78  bool isInside(const Num2* coord, unsigned long coordLen) const;
80 
82 
83  BoxND& operator*=(double r);
84  BoxND& operator/=(double r);
86 
88 
89  BoxND& operator*=(const std::vector<double>& scales);
90  BoxND& operator/=(const std::vector<double>& scales);
92 
97  BoxND& expand(double r);
98 
100 
105  BoxND& expand(const std::vector<double>& scales);
106  BoxND& expand(const double* scales, unsigned long lenScales);
108 
110 
111  template <typename Num2>
112  BoxND& operator+=(const std::vector<Num2>& shifts);
113  template <typename Num2>
114  BoxND& operator-=(const std::vector<Num2>& shifts);
115  template <typename Num2>
116  BoxND& shift(const Num2* shifts, unsigned long lenShifts);
118 
120  BoxND& moveToOrigin();
121 
123  Numeric overlapVolume(const BoxND& r) const;
124 
126  double overlapFraction(const BoxND& r) const;
127 
129  static BoxND unitBox(unsigned long ndim);
130 
136  static BoxND sizeTwoBox(unsigned long ndim);
137 
143  static BoxND allSpace(unsigned long ndim);
144 
146 
147  inline gs::ClassId classId() const { return gs::ClassId(*this); }
148  bool write(std::ostream& of) const;
150 
151  static const char* classname();
152  static inline unsigned version() { return 1; }
153  static void restore(const gs::ClassId& id, std::istream& in, BoxND* box);
154  };
155 } // namespace npstat
156 
158 
159 template <typename Numeric>
161 
162 template <typename Numeric>
165 
166 #include <limits>
167 #include <cassert>
169 
170 #include "Alignment/Geners/interface/GenericIO.hh"
171 #include "Alignment/Geners/interface/IOIsUnsigned.hh"
172 
173 namespace npstat {
174  template <typename Numeric>
175  template <typename Num2>
177  const unsigned long dim = r.size();
178  if (dim) {
179  this->reserve(dim);
180  for (unsigned long i = 0; i < dim; ++i) {
181  const Interval<Num2>& ri(r[i]);
182  this->push_back(Interval<Numeric>(ri.min(), ri.max()));
183  }
184  }
185  }
186 
187  template <typename Numeric>
188  template <typename Num2>
189  BoxND<Numeric>::BoxND(const std::vector<Num2>& limits) {
190  const unsigned long dim = limits.size();
191  if (dim) {
192  this->reserve(dim);
193  Numeric zero = Numeric();
194  for (unsigned long i = 0; i < dim; ++i) {
195  const Numeric value(static_cast<Numeric>(limits[i]));
196  if (value >= zero)
197  this->push_back(Interval<Numeric>(zero, value));
198  else
199  this->push_back(Interval<Numeric>(value, zero));
200  }
201  }
202  }
203 
204  template <typename Numeric>
205  template <typename Num2>
207  if ((void*)this == (void*)(&r))
208  return *this;
209  const unsigned long n = r.size();
210  this->clear();
211  this->reserve(n);
212  for (unsigned long i = 0; i < n; ++i) {
213  const Interval<Num2>& ir(r[i]);
214  this->push_back(Interval<Numeric>(ir.min(), ir.max()));
215  }
216  return *this;
217  }
218 
219  template <typename Numeric>
220  Numeric BoxND<Numeric>::volume() const {
221  Numeric v(static_cast<Numeric>(1));
222  const unsigned long mydim = this->size();
223  for (unsigned long i = 0U; i < mydim; ++i)
224  v *= (*this)[i].length();
225  return v;
226  }
227 
228  template <typename Numeric>
229  Numeric BoxND<Numeric>::overlapVolume(const BoxND& r) const {
230  const unsigned long mydim = this->size();
231  if (mydim == r.size()) {
232  Numeric v(static_cast<Numeric>(1));
233  for (unsigned long i = 0U; i < mydim; ++i)
234  v *= (*this)[i].overlapLength(r[i]);
235  return v;
236  } else
237  return static_cast<Numeric>(0);
238  }
239 
240  template <typename Numeric>
241  double BoxND<Numeric>::overlapFraction(const BoxND& r) const {
242  const unsigned long mydim = this->size();
243  if (mydim == r.size()) {
244  double f = 1.0;
245  for (unsigned long i = 0U; i < mydim; ++i)
246  f *= (*this)[i].overlapFraction(r[i]);
247  return f;
248  } else
249  return 0.0;
250  }
251 
252  template <typename Numeric>
253  void BoxND<Numeric>::getMidpoint(Numeric* coord, const unsigned long coordLen) const {
254  const unsigned long mydim = this->size();
255  if (coordLen < mydim)
256  throw npstat::NpstatInvalidArgument("In npstat::BoxND::getMidpoint: insufficient output buffer length");
257  if (mydim) {
258  assert(coord);
259  for (unsigned long i = 0U; i < mydim; ++i)
260  coord[i] = (*this)[i].midpoint();
261  }
262  }
263 
264  template <typename Numeric>
265  template <typename Num2>
266  bool BoxND<Numeric>::isInsideLower(const Num2* coords, const unsigned long coordLen) const {
267  if (coordLen != this->size())
269  "In npstat::BoxND::isInsideLower: "
270  "incompatible point dimensionality");
271  const Interval<Numeric>* myptr = &(*this)[0];
272  for (unsigned long i = 0; i < coordLen; ++i)
273  if (!myptr[i].isInsideLower(coords[i]))
274  return false;
275  return true;
276  }
277 
278  template <typename Numeric>
279  template <typename Num2>
280  bool BoxND<Numeric>::isInsideUpper(const Num2* coords, const unsigned long coordLen) const {
281  if (coordLen != this->size())
283  "In npstat::BoxND::isInsideUpper: "
284  "incompatible point dimensionality");
285  const Interval<Numeric>* myptr = &(*this)[0];
286  for (unsigned long i = 0; i < coordLen; ++i)
287  if (!myptr[i].isInsideUpper(coords[i]))
288  return false;
289  return true;
290  }
291 
292  template <typename Numeric>
293  template <typename Num2>
294  bool BoxND<Numeric>::isInsideWithBounds(const Num2* coords, const unsigned long coordLen) const {
295  if (coordLen != this->size())
297  "In npstat::BoxND::isInsideWithBounds: "
298  "incompatible point dimensionality");
299  const Interval<Numeric>* myptr = &(*this)[0];
300  for (unsigned long i = 0; i < coordLen; ++i)
301  if (!myptr[i].isInsideWithBounds(coords[i]))
302  return false;
303  return true;
304  }
305 
306  template <typename Numeric>
307  template <typename Num2>
308  bool BoxND<Numeric>::isInside(const Num2* coords, const unsigned long coordLen) const {
309  if (coordLen != this->size())
310  throw npstat::NpstatInvalidArgument("In npstat::BoxND::isInside: incompatible point dimensionality");
311  const Interval<Numeric>* myptr = &(*this)[0];
312  for (unsigned long i = 0; i < coordLen; ++i)
313  if (!myptr[i].isInside(coords[i]))
314  return false;
315  return true;
316  }
317 
318  template <typename Numeric>
320  const unsigned long mydim = this->size();
321  for (unsigned long i = 0; i < mydim; ++i)
322  (*this)[i] *= r;
323  return *this;
324  }
325 
326  template <typename Numeric>
328  const unsigned long mydim = this->size();
329  for (unsigned long i = 0; i < mydim; ++i)
330  (*this)[i].moveMidpointTo0();
331  return *this;
332  }
333 
334  template <typename Numeric>
336  const unsigned long mydim = this->size();
337  for (unsigned long i = 0; i < mydim; ++i)
338  (*this)[i].expand(r);
339  return *this;
340  }
341 
342  template <typename Numeric>
343  BoxND<Numeric>& BoxND<Numeric>::operator*=(const std::vector<double>& scales) {
344  const unsigned long mydim = this->size();
345  if (mydim != scales.size())
347  "In npstat::BoxND::operator*=: "
348  "incompatible argument dimensionality");
349  for (unsigned long i = 0; i < mydim; ++i)
350  (*this)[i] *= scales[i];
351  return *this;
352  }
353 
354  template <typename Numeric>
355  BoxND<Numeric>& BoxND<Numeric>::expand(const std::vector<double>& scales) {
356  const unsigned long mydim = this->size();
357  if (mydim != scales.size())
358  throw npstat::NpstatInvalidArgument("In npstat::BoxND::expand: incompatible argument dimensionality");
359  for (unsigned long i = 0; i < mydim; ++i)
360  (*this)[i].expand(scales[i]);
361  return *this;
362  }
363 
364  template <typename Numeric>
365  BoxND<Numeric>& BoxND<Numeric>::expand(const double* scales, const unsigned long lenScales) {
366  const unsigned long mydim = this->size();
367  if (mydim != lenScales)
368  throw npstat::NpstatInvalidArgument("In npstat::BoxND::expand: incompatible argument dimensionality");
369  if (mydim) {
370  assert(scales);
371  for (unsigned long i = 0; i < mydim; ++i)
372  (*this)[i].expand(scales[i]);
373  }
374  return *this;
375  }
376 
377  template <typename Numeric>
379  const unsigned long mydim = this->size();
380  for (unsigned long i = 0; i < mydim; ++i)
381  (*this)[i] /= r;
382  return *this;
383  }
384 
385  template <typename Numeric>
386  BoxND<Numeric>& BoxND<Numeric>::operator/=(const std::vector<double>& scales) {
387  const unsigned long mydim = this->size();
388  if (mydim != scales.size())
390  "In npstat::BoxND::operator/=: "
391  "incompatible argument dimensionality");
392  for (unsigned long i = 0; i < mydim; ++i)
393  (*this)[i] /= scales[i];
394  return *this;
395  }
396 
397  template <typename Numeric>
398  template <typename Num2>
399  BoxND<Numeric>& BoxND<Numeric>::operator+=(const std::vector<Num2>& shifts) {
400  const unsigned long mydim = this->size();
401  if (mydim != shifts.size())
403  "In npstat::BoxND::operator+=: "
404  "incompatible argument dimensionality");
405  for (unsigned long i = 0; i < mydim; ++i)
406  (*this)[i] += static_cast<Numeric>(shifts[i]);
407  return *this;
408  }
409 
410  template <typename Numeric>
411  template <typename Num2>
412  BoxND<Numeric>& BoxND<Numeric>::shift(const Num2* shifts, const unsigned long shiftsLen) {
413  const unsigned long mydim = this->size();
414  if (mydim != shiftsLen)
415  throw npstat::NpstatInvalidArgument("In npstat::BoxND::shift: incompatible argument dimensionality");
416  if (mydim) {
417  assert(shifts);
418  for (unsigned long i = 0; i < mydim; ++i)
419  (*this)[i] += static_cast<Numeric>(shifts[i]);
420  }
421  return *this;
422  }
423 
424  template <typename Numeric>
425  template <typename Num2>
426  BoxND<Numeric>& BoxND<Numeric>::operator-=(const std::vector<Num2>& shifts) {
427  const unsigned long mydim = this->size();
428  if (mydim != shifts.size())
430  "In npstat::BoxND::operator-=: "
431  "incompatible argument dimensionality");
432  for (unsigned long i = 0; i < mydim; ++i)
433  (*this)[i] -= static_cast<Numeric>(shifts[i]);
434  return *this;
435  }
436 
437  template <typename Numeric>
438  BoxND<Numeric> BoxND<Numeric>::unitBox(const unsigned long ndim) {
439  Interval<Numeric> unit(static_cast<Numeric>(0), static_cast<Numeric>(1));
440  return BoxND<Numeric>(ndim, unit);
441  }
442 
443  template <typename Numeric>
444  BoxND<Numeric> BoxND<Numeric>::sizeTwoBox(const unsigned long ndim) {
445  const Numeric one = static_cast<Numeric>(1);
446  Interval<Numeric> i(-one, one);
447  return BoxND<Numeric>(ndim, i);
448  }
449 
450  template <typename Numeric>
451  BoxND<Numeric> BoxND<Numeric>::allSpace(const unsigned long ndim) {
452  const Numeric maxval = std::numeric_limits<Numeric>::max();
453  Interval<Numeric> i(static_cast<Numeric>(0), maxval);
455  i.setMin(-maxval);
456  return BoxND<Numeric>(ndim, i);
457  }
458 
459  template <typename Numeric>
461  static const std::string na(gs::template_class_name<Numeric>("npstat::BoxND"));
462  return na.c_str();
463  }
464 
465  template <typename Numeric>
466  bool BoxND<Numeric>::write(std::ostream& of) const {
467  const unsigned long mydim = this->size();
468  std::vector<Numeric> limits;
469  limits.reserve(2UL * mydim);
470  for (unsigned long i = 0; i < mydim; ++i) {
471  limits.push_back((*this)[i].min());
472  limits.push_back((*this)[i].max());
473  }
474  return gs::write_item(of, limits);
475  }
476 
477  template <typename Numeric>
478  void BoxND<Numeric>::restore(const gs::ClassId& id, std::istream& in, BoxND* b) {
479  static const gs::ClassId current(gs::ClassId::makeId<BoxND<Numeric> >());
480  current.ensureSameId(id);
481 
482  std::vector<Numeric> limits;
483  gs::restore_item(in, &limits);
484  if (in.fail())
485  throw gs::IOReadFailure("In npstat::BoxND::restore: input stream failure");
486  const unsigned long nlimits = limits.size();
487  if (nlimits % 2UL)
488  throw gs::IOInvalidData("In npstat::BoxND::restore: bad limits");
489  assert(b);
490  b->clear();
491  b->reserve(nlimits / 2UL);
492  for (unsigned long i = 0; i < nlimits / 2UL; ++i)
493  b->push_back(npstat::Interval<Numeric>(limits[2U * i], limits[2U * i + 1U]));
494  }
495 } // namespace npstat
496 
497 template <typename Numeric>
499  const unsigned long dim = l.size();
500  if (dim != r.size())
501  return false;
502  for (unsigned long i = 0; i < dim; ++i)
503  if (l[i] != r[i])
504  return false;
505  return true;
506 }
507 
508 template <typename Numeric>
510  return !(l == r);
511 }
512 
513 #endif // NPSTAT_BOXND_HH_
bool operator!=(const npstat::BoxND< Numeric > &l, const npstat::BoxND< Numeric > &r)
Definition: BoxND.h:509
BoxND(const unsigned long dim)
Definition: BoxND.h:29
size
Write out results.
bool isInside(const Num2 *coord, unsigned long coordLen) const
Definition: BoxND.h:308
bool operator==(const npstat::BoxND< Numeric > &l, const npstat::BoxND< Numeric > &r)
Definition: BoxND.h:498
static BoxND unitBox(unsigned long ndim)
Definition: BoxND.h:438
bool write(std::ostream &of) const
Definition: BoxND.h:466
static void restore(const gs::ClassId &id, std::istream &in, BoxND *box)
Definition: BoxND.h:478
BoxND & operator*=(double r)
Definition: BoxND.h:319
void getMidpoint(Numeric *coord, unsigned long coordLen) const
Definition: BoxND.h:253
bool isInsideWithBounds(const Num2 *coord, unsigned long coordLen) const
Definition: BoxND.h:294
BoxND & expand(double r)
Definition: BoxND.h:335
const Numeric max() const
Definition: Interval.h:81
unsigned long dim() const
Definition: BoxND.h:54
BoxND & moveToOrigin()
Definition: BoxND.h:327
Exceptions for the npstat namespace.
BoxND & operator+=(const std::vector< Num2 > &shifts)
static unsigned version()
Definition: BoxND.h:152
void clear(CLHEP::HepGenMatrix &m)
Helper function: Reset all elements of a matrix to 0.
Definition: matutil.cc:151
bool isInsideLower(const Num2 *coord, unsigned long coordLen) const
Definition: BoxND.h:266
static BoxND allSpace(unsigned long ndim)
Definition: BoxND.h:451
static const char * classname()
Definition: BoxND.h:460
static BoxND sizeTwoBox(unsigned long ndim)
Definition: BoxND.h:444
double f[11][100]
T min(T a, T b)
Definition: MathUtil.h:58
Numeric overlapVolume(const BoxND &r) const
Definition: BoxND.h:229
BoxND & operator-=(const std::vector< Num2 > &shifts)
void setMin(const Numeric value)
Definition: Interval.h:54
Numeric volume() const
Definition: BoxND.h:220
double overlapFraction(const BoxND &r) const
Definition: BoxND.h:241
BoxND & shift(const Num2 *shifts, unsigned long lenShifts)
double b
Definition: hdecay.h:118
BoxND(const unsigned long dim, const Interval< Numeric > &v)
Definition: BoxND.h:32
BoxND & operator/=(double r)
Definition: BoxND.h:378
const Numeric min() const
Definition: Interval.h:78
gs::ClassId classId() const
Definition: BoxND.h:147
BoxND & copyFrom(const BoxND< Num2 > &r)
bool isInsideUpper(const Num2 *coord, unsigned long coordLen) const
Definition: BoxND.h:280
Basic3DVector unit() const