ATLAS Offline Software
Loading...
Searching...
No Matches
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
49namespace 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 }
59
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 }
64
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 }
74
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 }
104
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 }
117
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 }
132
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 }
144
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 }
152
155 template <unsigned l>
156 constexpr double poly(const double x) {
157 return polySum<l,l>(x);
158 }
159
163 template <unsigned l, unsigned d>
164 constexpr double derivative(const double x) {
165 return derivativeSum<l,l,d>(x);
166 }
167 }
168
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 }
194
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;
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
std::pair< std::vector< unsigned int >, bool > res
#define DERIVORDERSWITCH(l, d, x)
#define POLYSWITCH(order, x)
Definition LegendrePoly.h:9
#define x
constexpr double coeff(const unsigned l, const unsigned k)
Calculates the n-th coefficient of the legendre polynomial series.
constexpr double poly(const double x)
Evaluates the n-th Legendre polynomial at x.
constexpr double polySum(const double x)
Assembles the sum of the legendre monomials.
constexpr double derivative(const double x)
Evaluates the d-th derivative of the n-th Legendre polynomial at x.
constexpr double derivativeSum(const double x)
Assembles the n-th derivative of the legendre polynomial.
CscCalcPed - algorithm that finds the Cathode Strip Chamber pedestals from an RDO.
constexpr unsigned long factorial(const int n)
Evaluated the n-th factorial at compile time.
constexpr double legendrePoly(const unsigned l, const double x)
Calculates the legendre polynomial of rank l at x.
constexpr double legendreDeriv(const unsigned l, const unsigned d, const double x)
Evaluates the n-th derivative of the l-th Legendre polynomial.
constexpr unsigned long binomial(const unsigned n, const unsigned k)
Calculates the binomial coefficient at compile time.
constexpr double pow(const double x)
Calculate the power of a variable x at compile time.