Garfield++ 3.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
Numerics.hh
Go to the documentation of this file.
1#ifndef G_NUMERICS_H
2#define G_NUMERICS_H
3
4#include <functional>
5#include <complex>
6#include <vector>
7
8namespace Garfield {
9
10/// Collection of numerical routines.
11namespace Numerics {
12
13/// Functions for performing numerical integration (quadrature).
14/// Reimplemented from %QUADPACK.
15///
16/// R. Piessens, E. de Doncker-Kapenger, C. Ueberhuber, D. Kahaner,
17/// %QUADPACK, a Subroutine Package for Automatic Integration,
18/// Springer, 1983
19namespace QUADPACK {
20
21/// Estimates an integral over a semi-infinite or infinite interval.
22/// Calculates an approximation to an integral
23/// \f[ I = \int_{a}^{\infty} f\left(x\right) dx, \f]
24/// or
25/// \f[ I = \int_{-\infty}^{a} f\left(x\right) dx, \f]
26/// or
27/// \f[ I = \int_{-\infty}^{\infty} f\left(x\right) dx \f]
28/// hopefully satisfying
29/// \f[
30/// \left| I - \mathrm{RESULT} \right| \leq
31/// \max(\varepsilon_{\mathrm{abs}}, \varepsilon_{\mathrm{rel}} \left|I\right|).
32/// \f]
33/// \param f function to be integrated.
34/// \param bound value of the finite endpoint of the integration range (if any).
35/// \param inf indicates the type of integration range.
36/// - 1: ( bound, +Infinity)
37/// - -1: (-Infinity, bound)
38/// - 2: (-Infinity, +Infinity)
39/// \param epsabs requested absolute accuracy
40/// \param epsrel requested relative accuracy
41/// \param result the estimated value of the integral
42/// \param abserr estimated error
43/// \param status error flag
44/// - 0: normal and reliable termination, requested accuracy
45/// has been achieved.
46/// - > 0: abnormal termination, estimates for result and error
47/// are less reliable.
48/// - 1: maximum number of subdivisions reached.
49/// - 2: occurance of roundoff error prevents the requested
50/// tolerance from being achieved. Error may be underestimated.
51/// - 3: extremely bad integrand behaviour at some points of the
52/// integration interval.
53/// - 4: algorithm does not converge, roundoff error is detected in
54/// the extrapolation table. It is assumed that the requested
55/// tolerance cannot be achieved and that the returned result
56/// is the best that can be obtained.
57/// - 5: integral is probably divergent, or slowly convergent.
58/// - 6: invalid input.
59void qagi(std::function<double(double)> f, double bound, const int inf,
60 const double epsabs, const double epsrel,
61 double& result, double& abserr, unsigned int& status);
62
63/// 15-point Gauss-Kronrod integration with (semi-)infinite integration range.
64/// \param f function to be integrated.
65/// \param bound finite bound of original integration range (0 if inf = 2).
66/// \param inf indicates the type of integration range.
67/// \param a lower limit for integration over subrange of (0, 1).
68/// \param b upper limit for integration over subrange of (0, 1).
69/// \param result approximation to the integral.
70/// \param abserr estimate of the modulus of the absolute error.
71/// \param resabs approximation to the integral over \f$\left|f\right|\f$.
72/// \param resasc approximation to the integral of
73/// \f$\left|f - I / (b-a)\right|\f$ over \f$(a,b)\f$.
74void qk15i(std::function<double(double)> f, double bound, const int inf,
75 const double a, const double b, double& result, double& abserr,
76 double& resabs, double& resasc);
77
78/// 15-point Gauss-Kronrod integration with finite integration range.
79void qk15(std::function<double(double)> f, const double a, const double b,
80 double& result, double& abserr, double& resabs, double& resasc);
81
82}
83
84/// Linear algebra routines from CERNLIB.
85namespace CERNLIB {
86
87/// Replaces b by the solution x of Ax = b, after which A is undefined.
88/// \param n order of the square matrix A.
89/// \param a n by n matrix.
90/// \param b right-hand side vector.
91/// \returns 0: normal exit, -1: singular matrix.
92int deqn(const int n, std::vector<std::vector<double> >& a,
93 std::vector<double>& b);
94/// Replaces b by the solution x of Ax = b, and replace A by its inverse.
95int deqinv(const int n, std::vector<std::vector<double> >& a,
96 std::vector<double>& b);
97
98void dfact(const int n, std::vector<std::vector<double> >& a,
99 std::vector<int>& ir, int& ifail, double& det, int& jfail);
100void dfeqn(const int n, std::vector<std::vector<double> >& a,
101 std::vector<int>& ir, std::vector<double>& b);
102void dfinv(const int n, std::vector<std::vector<double> >& a,
103 std::vector<int>& ir);
104/// Replace square matrix A by its inverse.
105int dinv(const int n, std::vector<std::vector<double> >& a);
106
107void cfact(const int n, std::vector<std::vector<std::complex<double> > >& a,
108 std::vector<int>& ir, int& ifail, std::complex<double>& det,
109 int& jfail);
110void cfinv(const int n, std::vector<std::vector<std::complex<double> > >& a,
111 std::vector<int>& ir);
112
113/// Replace square matrix A by its inverse.
114int cinv(const int n, std::vector<std::vector<std::complex<double> > >& a);
115
116}
117
118/// Legendre polynomials.
119inline double Legendre(const unsigned int n, const double x) {
120
121 if (std::abs(x) > 1.) return 0.;
122 double p0 = 1.;
123 double p1 = x;
124 if (n == 0) return p0;
125 if (n == 1) return p1;
126 for (unsigned int k = 1; k < n; ++k) {
127 p0 = ((2 * k + 1) * x * p1 - k * p0) / (k + 1);
128 std::swap(p0, p1);
129 }
130 return p1;
131}
132
133/// Modified Bessel functions.
134/// Series expansions from Abramowitz and Stegun.
135inline double BesselI0S(const double xx) {
136 const double y = xx / 3.75;
137 const double y2 = y * y;
138 return 1. + 3.5156229 * y2 + 3.0899424 * y2 * y2 +
139 1.2067492 * pow(y2, 3) + 0.2659732 * pow(y2, 4) +
140 0.0360768 * pow(y2, 5) + 0.0045813 * pow(y2, 6);
141}
142
143inline double BesselI1S(const double xx) {
144 const double y = xx / 3.75;
145 const double y2 = y * y;
146 return xx *
147 (0.5 + 0.87890594 * y2 + 0.51498869 * y2 * y2 +
148 0.15084934 * pow(y2, 3) + 0.02658733 * pow(y2, 4) +
149 0.00301532 * pow(y2, 5) + 0.00032411 * pow(y2, 6));
150}
151
152inline double BesselK0S(const double xx) {
153 const double y = xx / 2.;
154 const double y2 = y * y;
155 return -log(y) * BesselI0S(xx) - 0.57721566 +
156 0.42278420 * y2 + 0.23069756 * y2 * y2 +
157 0.03488590 * pow(y2, 3) + 0.00262698 * pow(y2, 4) +
158 0.00010750 * pow(y2, 5) + 0.00000740 * pow(y2, 6);
159}
160
161inline double BesselK0L(const double xx) {
162 const double y = 2. / xx;
163 return (exp(-xx) / sqrt(xx)) *
164 (1.25331414 - 0.07832358 * y + 0.02189568 * y * y -
165 0.01062446 * pow(y, 3) + 0.00587872 * pow(y, 4) -
166 0.00251540 * pow(y, 5) + 0.00053208 * pow(y, 6));
167}
168
169inline double BesselK1S(const double xx) {
170 const double y = xx / 2.;
171 const double y2 = y * y;
172 return log(y) * BesselI1S(xx) +
173 (1. / xx) *
174 (1. + 0.15443144 * y2 - 0.67278579 * y2 * y2 -
175 0.18156897 * pow(y2, 3) - 0.01919402 * pow(y2, 4) -
176 0.00110404 * pow(y2, 5) - 0.00004686 * pow(y2, 6));
177}
178
179inline double BesselK1L(const double xx) {
180 const double y = 2. / xx;
181 return (exp(-xx) / sqrt(xx)) *
182 (1.25331414 + 0.23498619 * y - 0.03655620 * y * y +
183 0.01504268 * pow(y, 3) - 0.00780353 * pow(y, 4) +
184 0.00325614 * pow(y, 5) - 0.00068245 * pow(y, 6));
185}
186
187/// C++ version of DIVDIF (CERN program library E105) which performs
188/// tabular interpolation using symmetrically placed argument points.
189double Divdif(const std::vector<double>& f, const std::vector<double>& a,
190 int nn, double x, int mm);
191
192/// Interpolation of order 1 and 2 in an irregular rectangular
193/// two-dimensional grid.
194bool Boxin2(const std::vector<std::vector<double> >& value,
195 const std::vector<double>& xAxis, const std::vector<double>& yAxis,
196 const int nx, const int ny, const double xx, const double yy,
197 double& f, const int iOrder);
198/// Interpolation of order 1 and 2 in an irregular rectangular
199/// three-dimensional grid.
200bool Boxin3(const std::vector<std::vector<std::vector<double> > >& value,
201 const std::vector<double>& xAxis, const std::vector<double>& yAxis,
202 const std::vector<double>& zAxis, const int nx, const int ny,
203 const int nz, const double xx, const double yy, const double zz,
204 double& f, const int iOrder);
205
206/// Least-squares minimisation.
207bool LeastSquaresFit(
208 std::function<double(double, const std::vector<double>&)> f,
209 std::vector<double>& par, std::vector<double>& epar,
210 const std::vector<double>& x, const std::vector<double>& y,
211 const std::vector<double>& ey, const unsigned int nMaxIter,
212 const double diff, double& chi2, const double eps,
213 const bool debug, const bool verbose);
214
215}
216}
217
218#endif
void dfinv(const int n, std::vector< std::vector< double > > &a, std::vector< int > &ir)
Definition: Numerics.cc:854
void cfact(const int n, std::vector< std::vector< std::complex< double > > > &a, std::vector< int > &ir, int &ifail, std::complex< double > &det, int &jfail)
Definition: Numerics.cc:994
int deqn(const int n, std::vector< std::vector< double > > &a, std::vector< double > &b)
Definition: Numerics.cc:593
void dfact(const int n, std::vector< std::vector< double > > &a, std::vector< int > &ir, int &ifail, double &det, int &jfail)
Definition: Numerics.cc:668
void cfinv(const int n, std::vector< std::vector< std::complex< double > > > &a, std::vector< int > &ir)
Definition: Numerics.cc:1079
int dinv(const int n, std::vector< std::vector< double > > &a)
Replace square matrix A by its inverse.
Definition: Numerics.cc:787
void dfeqn(const int n, std::vector< std::vector< double > > &a, std::vector< int > &ir, std::vector< double > &b)
Definition: Numerics.cc:753
int cinv(const int n, std::vector< std::vector< std::complex< double > > > &a)
Replace square matrix A by its inverse.
Definition: Numerics.cc:1134
int deqinv(const int n, std::vector< std::vector< double > > &a, std::vector< double > &b)
Replaces b by the solution x of Ax = b, and replace A by its inverse.
Definition: Numerics.cc:909
void qk15(std::function< double(double)> f, const double a, const double b, double &result, double &abserr, double &resabs, double &resasc)
15-point Gauss-Kronrod integration with finite integration range.
Definition: Numerics.cc:499
void qagi(std::function< double(double)> f, double bound, const int inf, const double epsabs, const double epsrel, double &result, double &abserr, unsigned int &status)
Definition: Numerics.cc:144
void qk15i(std::function< double(double)> f, double bound, const int inf, const double a, const double b, double &result, double &abserr, double &resabs, double &resasc)
Definition: Numerics.cc:408
bool Boxin3(const std::vector< std::vector< std::vector< double > > > &value, const std::vector< double > &xAxis, const std::vector< double > &yAxis, const std::vector< double > &zAxis, const int nx, const int ny, const int nz, const double xx, const double yy, const double zz, double &f, const int iOrder)
Definition: Numerics.cc:1495
double BesselK0L(const double xx)
Definition: Numerics.hh:161
double BesselI0S(const double xx)
Definition: Numerics.hh:135
double BesselI1S(const double xx)
Definition: Numerics.hh:143
double Legendre(const unsigned int n, const double x)
Legendre polynomials.
Definition: Numerics.hh:119
double BesselK1S(const double xx)
Definition: Numerics.hh:169
bool LeastSquaresFit(std::function< double(double, const std::vector< double > &)> f, std::vector< double > &par, std::vector< double > &epar, const std::vector< double > &x, const std::vector< double > &y, const std::vector< double > &ey, const unsigned int nMaxIter, const double diff, double &chi2, const double eps, const bool debug, const bool verbose)
Least-squares minimisation.
Definition: Numerics.cc:1838
bool Boxin2(const std::vector< std::vector< double > > &value, const std::vector< double > &xAxis, const std::vector< double > &yAxis, const int nx, const int ny, const double xx, const double yy, double &f, const int iOrder)
Definition: Numerics.cc:1304
double Divdif(const std::vector< double > &f, const std::vector< double > &a, int nn, double x, int mm)
Definition: Numerics.cc:1206
double BesselK0S(const double xx)
Definition: Numerics.hh:152
double BesselK1L(const double xx)
Definition: Numerics.hh:179