CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
deltaPhi.h
Go to the documentation of this file.
1 #ifndef DataFormats_Math_deltaPhi_h
2 #define DataFormats_Math_deltaPhi_h
3 
4 /* function to compute deltaPhi
5  *
6  * Ported from original code in RecoJets
7  * by Fedor Ratnikov, FNAL
8  * stabilize range reduction
9  */
10 
11 #include <cmath>
13 
14 namespace reco {
15 
16  // reduce to [-pi,pi]
17  template <typename T>
18  constexpr T reduceRange(T x) {
19  constexpr T o2pi = 1. / (2. * M_PI);
20  if (std::abs(x) <= T(M_PI))
21  return x;
22  T n = std::round(x * o2pi);
23  return x - n * T(2. * M_PI);
24  }
25 
26  constexpr double deltaPhi(double phi1, double phi2) { return reduceRange(phi1 - phi2); }
27 
28  constexpr double deltaPhi(float phi1, double phi2) { return deltaPhi(static_cast<double>(phi1), phi2); }
29 
30  constexpr double deltaPhi(double phi1, float phi2) { return deltaPhi(phi1, static_cast<double>(phi2)); }
31 
32  constexpr float deltaPhi(float phi1, float phi2) { return reduceRange(phi1 - phi2); }
33 
34  template <typename T1, typename T2>
35  constexpr auto deltaPhi(T1 const& t1, T2 const& t2) -> decltype(deltaPhi(t1.phi(), t2.phi())) {
36  return deltaPhi(t1.phi(), t2.phi());
37  }
38 
39  template <typename T>
40  constexpr T deltaPhi(T phi1, T phi2) {
41  return reduceRange(phi1 - phi2);
42  }
43 } // namespace reco
44 
45 // lovely! VI
46 using reco::deltaPhi;
47 
48 template <typename T1, typename T2 = T1>
49 struct DeltaPhi {
50  constexpr auto operator()(const T1& t1, const T2& t2) -> decltype(reco::deltaPhi(t1, t2)) const {
51  return reco::deltaPhi(t1, t2);
52  }
53 };
54 
55 namespace angle0to2pi {
56 
58 
59  // make0To2pi constrains an angle to be >= 0 and < 2pi.
60  // This function is a faster version of reco::reduceRange.
61  // In timing tests, it is almost always faster than reco::reduceRange.
62  // It also protects against floating-point value drift over repeated calculations.
63  // This implementation uses multiplication instead of division and avoids
64  // calling fmod to improve performance.
65 
66  template <class valType>
67  inline constexpr valType make0To2pi(valType angle) {
68  constexpr valType twoPi = 2. * M_PI;
69  constexpr valType oneOverTwoPi = 1. / (2. * M_PI);
70  constexpr valType epsilon = 1.e-13;
71 
72  if ((std::abs(angle) <= epsilon) || (std::abs(twoPi - std::abs(angle)) <= epsilon))
73  return (0.);
74  if (std::abs(angle) > twoPi) {
75  valType nFac = trunc(angle * oneOverTwoPi);
76  angle -= (nFac * twoPi);
77  if (std::abs(angle) <= epsilon)
78  return (0.);
79  }
80  if (angle < 0.)
81  angle += twoPi;
82  return (angle);
83  }
84 } // namespace angle0to2pi
85 
86 #endif
constexpr double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:26
constexpr T reduceRange(T x)
Definition: deltaPhi.h:18
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
constexpr auto operator()(const T1 &t1, const T2 &t2) -> decltype(reco::deltaPhi(t1, t2)) const
Definition: deltaPhi.h:50
#define M_PI
constexpr valType make0To2pi(valType angle)
Definition: deltaPhi.h:67
long double T
constexpr double twoPi()
Definition: Pi.h:32
T angle(T x1, T y1, T z1, T x2, T y2, T z2)
Definition: angle.h:11