Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
LegendrePoly.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 #ifndef MUONCALIBMATH_LEGENDREPOLYS_H
5 #define MUONCALIBMATH_LEGENDREPOLYS_H
6 
7 #include <cmath>
8 
9 #define POLYSWITCH(order , x) \
10  case order: { \
11  return Legendre::poly<order>(x); \
12  break; \
13  }
14 #define DERIVPOLYSWITICH(l, d, x) \
15  case l: { \
16  return Legendre::derivative<l,d>(x); \
17  break; \
18  } \
19 
20 
21 #define DERIVORDERSWITCH(l, d, x) \
22  case d: { \
23  switch (l) { \
24  DERIVPOLYSWITICH(0, d, x) \
25  DERIVPOLYSWITICH(1, d, x) \
26  DERIVPOLYSWITICH(2, d, x) \
27  DERIVPOLYSWITICH(3, d, x) \
28  DERIVPOLYSWITICH(4, d, x) \
29  DERIVPOLYSWITICH(5, d, x) \
30  DERIVPOLYSWITICH(6, d, x) \
31  DERIVPOLYSWITICH(7, d, x) \
32  DERIVPOLYSWITICH(8, d, x) \
33  DERIVPOLYSWITICH(9, d, x) \
34  DERIVPOLYSWITICH(10, d, x) \
35  DERIVPOLYSWITICH(11, d, x) \
36  DERIVPOLYSWITICH(12, d, x) \
37  DERIVPOLYSWITICH(13, d, x) \
38  DERIVPOLYSWITICH(14, d, x) \
39  DERIVPOLYSWITICH(15, d, x) \
40  DERIVPOLYSWITICH(16, d, x) \
41  default: \
42  break; \
43  } \
44  break; \
45  }
46 
47 
48 
49 namespace MuonCalib{
51  constexpr unsigned long factorial(const int n) {
52  if (n > 1) {
53  unsigned long f = n*factorial(n-1);
54  return f;
55  } else {
56  return 1;
57  }
58  }
60  constexpr unsigned long binomial(const unsigned n, const unsigned k) {
61  unsigned long b = factorial(n) / (factorial(k) * factorial(n-k));
62  return b;
63  }
65  template <int k> constexpr double pow(const double x) {
66  if constexpr (k < 0) {
67  return pow<-k>(1./x);
68  } else if constexpr(k > 0) {
69  return x*pow<k-1>(x);
70  } else {
71  return 1.;
72  }
73  }
75  constexpr double pow(double x, int power) {
76  double res{1.};
77  if (power < 0) {
78  x = 1./x;
79  power = - power;
80  }
81  for (int iter = 1; iter<=power; ++iter) {
82  res*=x;
83  }
84  return res;
85  }
86 
87 
88  namespace Legendre{
92  constexpr double coeff(const unsigned l, const unsigned k) {
93  if (k %2 != l %2) {
94  return 0.;
95  } else if (k > 1) {
96  const double a_k = -(1.*(l- k +2)*(l+ k-1)) / (1.*(k * (k-1))) * coeff(l, k-2);
97  return a_k;
98  } else {
99  unsigned fl = (l - l %2) /2;
100  unsigned long binom = binomial(l,fl) * binomial(2*l - 2*fl,l);
101  return (fl % 2 ? -1. : 1.) * pow(0.5, l) * (1.*binom);
102  }
103  }
108  template <unsigned l, unsigned k>
109  constexpr double polySum(const double x) {
110  const double a_n = coeff(l,k);
111  if constexpr (k > 1) {
112  return a_n* pow<k>(x) + polySum<l, k-2>(x);
113  } else{
114  return a_n*pow<k>(x);
115  }
116  }
122  template <unsigned l, unsigned k, unsigned d>
123  constexpr double derivativeSum(const double x) {
124  if constexpr(k <= l && k>=d) {
125  constexpr unsigned long powFac = factorial(k) / factorial(k-d);
126  const double a_n = coeff(l,k) * powFac;
127  return a_n *pow<k-d>(x) + derivativeSum<l, k-2, d>(x);
128  } else {
129  return 0.;
130  }
131  }
136  constexpr double derivativeSum(const unsigned l, const unsigned d, const double x) {
137  double sum{0.};
138  for (int k=l; k>= static_cast<int>(d) && k >=0; k-=2) {
139  const double a_n = coeff(l,k) * factorial(k) / factorial(k-d);
140  sum += a_n * pow(x,k-d);
141  }
142  return sum;
143  }
145  constexpr double polySum(const unsigned l, const double x) {
146  double sum{0.};
147  for (unsigned k = l%2; k<=l; k+=2) {
148  sum += pow(x,k) * coeff(l,k);
149  }
150  return sum;
151  }
155  template <unsigned l>
156  constexpr double poly(const double x) {
157  return polySum<l,l>(x);
158  }
163  template <unsigned l, unsigned d>
164  constexpr double derivative(const double x) {
165  return derivativeSum<l,l,d>(x);
166  }
167  }
171  constexpr double legendrePoly(const unsigned l, const double x) {
172  switch (l) {
173  POLYSWITCH( 0, x);
174  POLYSWITCH( 1, x);
175  POLYSWITCH( 2, x);
176  POLYSWITCH( 3, x);
177  POLYSWITCH( 4, x);
178  POLYSWITCH( 5, x);
179  POLYSWITCH( 6, x);
180  POLYSWITCH( 7, x);
181  POLYSWITCH( 8, x);
182  POLYSWITCH( 9, x);
183  POLYSWITCH(10, x);
184  POLYSWITCH(11, x);
185  POLYSWITCH(12, x);
186  POLYSWITCH(13, x);
187  POLYSWITCH(14, x);
188  POLYSWITCH(15, x);
189  POLYSWITCH(16, x);
190  default:
191  return Legendre::polySum(l, x);
192  }
193  }
198  constexpr double legendreDeriv(const unsigned l, const unsigned d, const double x){
199  switch (d) {
200  case 0:
201  return legendrePoly(l,x);
202  break;
203  DERIVORDERSWITCH(l,1,x)
204  DERIVORDERSWITCH(l,2,x)
205  DERIVORDERSWITCH(l,3,x)
206  DERIVORDERSWITCH(l,4,x)
207  DERIVORDERSWITCH(l,5,x)
208  default:
209  return Legendre::derivativeSum(l, d, x);
210  }
211  return 0.;
212  }
213 }
214 #undef POLYSWITCH
215 #undef DERIVORDERSWITCH
216 #undef DERIVPOLYSWITICH
217 #endif
MuonCalib::factorial
constexpr unsigned long factorial(const int n)
Evaluated the n-th factorial at compile time.
Definition: LegendrePoly.h:51
MuonCalib::Legendre::derivativeSum
constexpr double derivativeSum(const double x)
Assembles the n-th derivative of the legendre polynomial.
Definition: LegendrePoly.h:123
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:109
hist_file_dump.d
d
Definition: hist_file_dump.py:143
MuonCalib::legendreDeriv
constexpr double legendreDeriv(const unsigned l, const unsigned d, const double x)
Evaluates the n-th derivative of the l-th Legendre polynomial.
Definition: LegendrePoly.h:198
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
x
#define x
MuonCalib::Legendre::derivative
constexpr double derivative(const double x)
Evaluates the d-th derivative of the n-th Legendre polynomial at x.
Definition: LegendrePoly.h:164
MuonCalib::Legendre::poly
constexpr double poly(const double x)
Evaluates the n-th Legendre polynomial at x.
Definition: LegendrePoly.h:156
convertTimingResiduals.sum
sum
Definition: convertTimingResiduals.py:55
beamspotman.n
n
Definition: beamspotman.py:731
res
std::pair< std::vector< unsigned int >, bool > res
Definition: JetGroupProductTest.cxx:11
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:141
DERIVORDERSWITCH
#define DERIVORDERSWITCH(l, d, x)
Definition: LegendrePoly.h:21
MuonCalib::legendrePoly
constexpr double legendrePoly(const unsigned l, const double x)
Calculates the legendre polynomial of rank l at x.
Definition: LegendrePoly.h:171
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
MuonCalib::Legendre::coeff
constexpr double coeff(const unsigned l, const unsigned k)
Calculates the n-th coefficient of the legendre polynomial series.
Definition: LegendrePoly.h:92
POLYSWITCH
#define POLYSWITCH(order, x)
Definition: LegendrePoly.h:9
MuonCalib::binomial
constexpr unsigned long binomial(const unsigned n, const unsigned k)
Calculates the binomial coefficient at compile time.
Definition: LegendrePoly.h:60
MuonCalib::pow
constexpr double pow(const double x)
Calculate the power of a variable x at compile time.
Definition: LegendrePoly.h:65
fitman.k
k
Definition: fitman.py:528