HackAnalysis  2
MathUtils.h
1 // -*- C++ -*-
2 //
3 // This file is part of HEPUtils -- https://bitbucket.org/andybuckley/heputils
4 // Copyright (C) 2013-2018 Andy Buckley <andy.buckley@cern.ch>
5 //
6 // Embedding of HEPUtils code in other projects is permitted provided this
7 // notice is retained and the HEPUtils namespace and include path are changed.
8 //
9 
10 // Duly: HEPUtils namespace changed to HEP
11 #pragma once
12 
13 #if __cplusplus <= 199711L
14 #error "This library needs at least a C++11 compliant compiler: are you using -std=c++11?"
15 #endif
16 
17 #include <cmath>
18 #include <vector>
19 #include <cassert>
20 #include <cstdlib>
21 #include <cstddef>
22 #include <type_traits>
23 
26 
27 namespace HEP {
28 
29 
31 
32 
34  template <typename N1>
35  constexpr typename std::enable_if<std::is_arithmetic<N1>::value, int>::type
36  sign(const N1& val) {
37  // if (val == 0) return 0;
38  // return (val < 0) ? -1 : 1;
39  return (val == 0) ? 0 : (val < 0) ? -1 : 1;
40  }
41 
43  template <typename N1>
44  constexpr typename std::enable_if<std::is_arithmetic<N1>::value, N1>::type
45  sqr(const N1 val) {
46  return val * val;
47  }
48 
50  template <typename N1, typename N2>
51  constexpr typename std::enable_if<std::is_arithmetic<N1>::value && std::is_arithmetic<N2>::value, typename std::common_type<N1,N2>::type>::type
52  add_quad(const N1& a, const N2& b) {
53  return sqrt(a*a + b*b);
54  }
55 
57  template <typename N1, typename N2, typename N3>
58  constexpr typename std::enable_if<std::is_arithmetic<N1>::value && std::is_arithmetic<N2>::value && std::is_arithmetic<N3>::value, typename std::common_type<N1,N2,N3>::type>::type
59  add_quad(const N1& a, const N2& b, const N3& c) {
60  return sqrt(a*a + b*b + c*c);
61  }
62 
64 
65 
67 
68 
72  template <typename N1, typename N2, typename N3>
73  constexpr typename std::enable_if<std::is_arithmetic<N1>::value && std::is_arithmetic<N2>::value && std::is_arithmetic<N3>::value, bool>::type
74  in_range(const N1& val, const N2& low, const N3& high) {
75  return val >= low && val < high;
76  }
77 
81  template <typename N1, typename N2, typename N3>
82  constexpr typename std::enable_if<std::is_arithmetic<N1>::value && std::is_arithmetic<N2>::value && std::is_arithmetic<N3>::value, bool>::type
83  in_closed_range(const N1& val, const N2& low, const N3& high) {
84  return val >= low && val <= high;
85  }
86 
90  template <typename N1, typename N2, typename N3>
91  constexpr typename std::enable_if<std::is_arithmetic<N1>::value && std::is_arithmetic<N2>::value && std::is_arithmetic<N3>::value, bool>::type
92  in_open_range(const N1& val, const N2& low, const N3& high) {
93  return val > low && val < high;
94  }
95 
96 
98  inline std::vector<double> linspace(size_t nbins, double start, double end, bool include_end=true) {
99  assert(end >= start);
100  assert(nbins > 0);
101  std::vector<double> rtn;
102  const double interval = (end-start)/static_cast<double>(nbins);
103  // Add all edges except the last
104  for (size_t i = 0; i < nbins; ++i) {
105  rtn.push_back(start + i*interval);
106  }
107  // Add the last edge
108  assert(rtn.size() == nbins);
109  if (include_end) rtn.push_back(end); // exact end, not result of n * interval
110  return rtn;
111  }
112 
113 
115  inline std::vector<double> logspace(size_t nbins, double start, double end, double offset=0, bool include_end=true) {
116  assert(end >= start);
117  assert(start+offset > 0);
118  assert(nbins > 0);
119  const double logstart = std::log(start+offset);
120  const double logend = std::log(end+offset);
121  const std::vector<double> logvals = linspace(nbins, logstart, logend, false);
122  assert(logvals.size() == nbins);
123  std::vector<double> rtn; rtn.reserve(nbins+1);
124  rtn.push_back(start); //< exact start, not exp(log(start))
125  for (size_t i = 1; i < logvals.size(); ++i) {
126  rtn.push_back(std::exp(logvals[i]));
127  }
128  assert(rtn.size() == nbins);
129  if (include_end) rtn.push_back(end); //< exact end, not exp(n * loginterval)
130  return rtn;
131  }
132 
134 
135 
137 
138 
139  inline double deltaphi(double a, double b) {
140  double rtn = a - b;
141  rtn = fmod(rtn, 2*M_PI);
142  assert(rtn >= -2*M_PI && rtn <= 2*M_PI);
143  if (rtn == 0) return 0;
144  if (rtn > M_PI) rtn -= 2*M_PI;
145  if (rtn <= -M_PI) rtn += 2*M_PI;
146  assert(rtn > -M_PI && rtn <= M_PI);
147  rtn = fabs(rtn);
148  assert(rtn > 0 && rtn <= M_PI);
149  return rtn;
150  }
151 
153 
154 
156 
157 
158  inline double rand01() {
159  return rand() / (double)RAND_MAX;
160  }
161 
163 
164 
165 }
Modified by Mark Goodsell goodsell@lpthe.jussieu.fr
Definition: ATLAS_SUSY_2018_16.cc:27
std::vector< double > linspace(size_t nbins, double start, double end, bool include_end=true)
Make a list of nbins + 1 values linearly spaced between start and end inclusive.
Definition: MathUtils.h:98
constexpr std::enable_if< std::is_arithmetic< N1 >::value &&std::is_arithmetic< N2 >::value, typename std::common_type< N1, N2 >::type >::type add_quad(const N1 &a, const N2 &b)
Convenience function for adding two numbers in quadrature.
Definition: MathUtils.h:52
constexpr std::enable_if< std::is_arithmetic< N1 >::value &&std::is_arithmetic< N2 >::value &&std::is_arithmetic< N3 >::value, bool >::type in_closed_range(const N1 &val, const N2 &low, const N3 &high)
Boolean function to determine if value is within the given range.
Definition: MathUtils.h:83
constexpr std::enable_if< std::is_arithmetic< N1 >::value &&std::is_arithmetic< N2 >::value &&std::is_arithmetic< N3 >::value, bool >::type in_open_range(const N1 &val, const N2 &low, const N3 &high)
Boolean function to determine if value is within the given range.
Definition: MathUtils.h:92
std::vector< double > logspace(size_t nbins, double start, double end, double offset=0, bool include_end=true)
Make a list of nbins + 1 values exponentially spaced between start and end inclusive.
Definition: MathUtils.h:115
constexpr std::enable_if< std::is_arithmetic< N1 >::value, N1 >::type sqr(const N1 val)
Convenience function for squaring (better than repeating long expressions/calcs or using intermediate...
Definition: MathUtils.h:45
constexpr std::enable_if< std::is_arithmetic< N1 >::value &&std::is_arithmetic< N2 >::value &&std::is_arithmetic< N3 >::value, bool >::type in_range(const N1 &val, const N2 &low, const N3 &high)
Boolean function to determine if value is within the given range.
Definition: MathUtils.h:74
constexpr std::enable_if< std::is_arithmetic< N1 >::value, int >::type sign(const N1 &val)
Convenience function for getting the sign of a number.
Definition: MathUtils.h:36