ATLAS Offline Software
LegendrePoly.h
Go to the documentation of this file.
1 
2 
3 /*
4  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
5 */
6 #ifndef MUONCALIBMATH_LEGENDREPOLYS_H
7 #define MUONCALIBMATH_LEGENDREPOLYS_H
8 
9 #include <cmath>
10 
11 
12 #define POLYSWITCH(order , x) \
13  case order: { \
14  return Legendre::poly<order>(x); \
15  break; \
16  }
17 #define DERIVPOLYSWITICH(l, d, x) \
18  case l: { \
19  return Legendre::derivative<l,d>(x); \
20  break; \
21  } \
22 
23 
24 #define DERIVORDERSWITCH(l, d, x) \
25  case d: { \
26  switch (l) { \
27  DERIVPOLYSWITICH(0, d, x) \
28  DERIVPOLYSWITICH(1, d, x) \
29  DERIVPOLYSWITICH(2, d, x) \
30  DERIVPOLYSWITICH(3, d, x) \
31  DERIVPOLYSWITICH(4, d, x) \
32  DERIVPOLYSWITICH(5, d, x) \
33  DERIVPOLYSWITICH(6, d, x) \
34  DERIVPOLYSWITICH(7, d, x) \
35  DERIVPOLYSWITICH(8, d, x) \
36  DERIVPOLYSWITICH(9, d, x) \
37  DERIVPOLYSWITICH(10, d, x) \
38  DERIVPOLYSWITICH(11, d, x) \
39  DERIVPOLYSWITICH(12, d, x) \
40  DERIVPOLYSWITICH(13, d, x) \
41  DERIVPOLYSWITICH(14, d, x) \
42  DERIVPOLYSWITICH(15, d, x) \
43  DERIVPOLYSWITICH(16, d, x) \
44  default: \
45  break; \
46  } \
47  break; \
48  }
49 
50 
51 
52 namespace MuonCalib{
54  constexpr unsigned long factorial(int n) {
55  if (n > 1) {
56  unsigned long f = n*factorial(n-1);
57  return f;
58  } else {
59  return 1;
60  }
61  }
63  constexpr unsigned long binomial(unsigned int n, unsigned k) {
64  unsigned long b = factorial(n) / (factorial(k) * factorial(n-k));
65  return b;
66  }
67 
68 
69  namespace Legendre{
73  constexpr double coeff(unsigned int l, unsigned int k) {
74  if (k %2 != l %2) {
75  return 0.;
76  } else if (k > 1) {
77  const double a_k = -(1.*(l- k +2)*(l+ k-1)) / (1.*(k * (k-1))) * coeff(l, k-2);
78  return a_k;
79  } else {
80  unsigned fl = (l - l %2) /2;
81  unsigned long binom = binomial(l,fl) * binomial(2*l - 2*fl,l);
82  return (fl % 2 ? -1. : 1.) * std::pow(0.5, l) * (1.*binom);
83  }
84  }
89  template <unsigned int l, unsigned int k>
90  constexpr double polySum(const double x) {
91  const double a_n = coeff(l,k);
92  if constexpr (k > 1) {
93  return a_n* std::pow(x,k) + polySum<l, k-2>(x);
94  } else{
95  return a_n*std::pow(x,k);
96  }
97  }
103  template <unsigned int l, unsigned int k, unsigned int d>
104  constexpr double derivativeSum(const double x) {
105  static_assert(d> 0);
106  if constexpr(k <= l && k>=d) {
107  constexpr unsigned long powFac = factorial(k) / factorial(k-d);
108  const double a_n = coeff(l,k) * powFac;
109  return a_n *std::pow(x,k-d) + derivativeSum<l, k-2, d>(x);
110  } else {
111  return 0.;
112  }
113  }
114 
115  template <unsigned int l>
116  constexpr double poly(const double x) {
117  return polySum<l,l>(x);
118  }
119  template <unsigned int l, unsigned d>
120  constexpr double derivative(const double x) {
121  return derivativeSum<l,l,d>(x);
122  }
123  }
124 
125  constexpr double legendrePoly(const unsigned int l, const double x) {
126  double value{0.};
127  switch (l) {
128  POLYSWITCH( 0, x);
129  POLYSWITCH( 1, x);
130  POLYSWITCH( 2, x);
131  POLYSWITCH( 3, x);
132  POLYSWITCH( 4, x);
133  POLYSWITCH( 5, x);
134  POLYSWITCH( 6, x);
135  POLYSWITCH( 7, x);
136  POLYSWITCH( 8, x);
137  POLYSWITCH( 9, x);
138  POLYSWITCH(10, x);
139  POLYSWITCH(11, x);
140  POLYSWITCH(12, x);
141  POLYSWITCH(13, x);
142  POLYSWITCH(14, x);
143  POLYSWITCH(15, x);
144  POLYSWITCH(16, x);
145  default:
146  value = std::legendre(l, x);
147  }
148  return value;
149  }
150  constexpr double legendreDeriv(const unsigned int l,
151  const double x,
152  const unsigned int derivOrder){
153  double value{0.};
154  switch (derivOrder) {
155  case 0:
156  value = legendrePoly(l,x);
157  break;
158  DERIVORDERSWITCH(l,1,x)
159  DERIVORDERSWITCH(l,2,x)
160  DERIVORDERSWITCH(l,3,x)
161  DERIVORDERSWITCH(l,4,x)
162  DERIVORDERSWITCH(l,5,x)
163  default:
164  break;
165 
166  }
167  return value;
168 
169  }
170 
171 
172 }
173 #undef POLYSWITCH
174 #undef DERIVPOLYSWITICH
175 #endif
MuonCalib::Legendre::derivativeSum
constexpr double derivativeSum(const double x)
Assembles the n-th derivative of the legendre polynomial.
Definition: LegendrePoly.h:104
CLHEP::binom
double binom(int n, int k)
Definition: RandBinomialFixedP.cxx:19
MuonCalib::Legendre::polySum
constexpr double polySum(const double x)
Assembles the sum of the legendre monomials.
Definition: LegendrePoly.h:90
hist_file_dump.d
d
Definition: hist_file_dump.py:137
MuonCalib::legendreDeriv
constexpr double legendreDeriv(const unsigned int l, const double x, const unsigned int derivOrder)
Definition: LegendrePoly.h:150
athena.value
value
Definition: athena.py:124
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
x
#define x
MuonCalib::Legendre::derivative
constexpr double derivative(const double x)
Definition: LegendrePoly.h:120
MuonCalib::Legendre::poly
constexpr double poly(const double x)
Definition: LegendrePoly.h:116
beamspotman.n
n
Definition: beamspotman.py:731
MuonCalib
CscCalcPed - algorithm that finds the Cathode Strip Chamber pedestals from an RDO.
Definition: CscCalcPed.cxx:22
hist_file_dump.f
f
Definition: hist_file_dump.py:135
DERIVORDERSWITCH
#define DERIVORDERSWITCH(l, d, x)
Definition: LegendrePoly.h:24
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
MuonCalib::binomial
constexpr unsigned long binomial(unsigned int n, unsigned k)
Calculates the binomial coefficient at compile time.
Definition: LegendrePoly.h:63
MuonCalib::legendrePoly
constexpr double legendrePoly(const unsigned int l, const double x)
Definition: LegendrePoly.h:125
MuonCalib::Legendre::coeff
constexpr double coeff(unsigned int l, unsigned int k)
Calculates the n-th coefficient of the legendre polynomial series.
Definition: LegendrePoly.h:73
POLYSWITCH
#define POLYSWITCH(order, x)
Definition: LegendrePoly.h:12
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15
fitman.k
k
Definition: fitman.py:528
MuonCalib::factorial
constexpr unsigned long factorial(int n)
Evaluated the n-th factorial at compile time.
Definition: LegendrePoly.h:54