1 #include <flow/AliFMDFlowEfficiency.h>
5 T sign(const T& x, const T& y)
7 return (y >= 0 ? fabs(x) : -fabs(x));
10 //____________________________________________________________________
12 AliFMDFlowEfficiency::LnGamma(Double_t z)
15 Double_t c[] = { 2.5066282746310005, 76.18009172947146,
16 -86.50532032941677, 24.01409824083091,
17 -1.231739572450155, 0.1208650973866179e-2,
22 t = (x+.5 * log(t) - t);
23 Double_t s = 1.000000000190015;
24 for (UInt_t i = 1; i < 7; i++) {
28 Double_t v = t + log(c[0]*s/x);
32 //____________________________________________________________________
34 AliFMDFlowEfficiency::BetaCf(Double_t x, Double_t a, Double_t b)
36 Int_t itmax = 500; // Maximum # of iterations
37 Double_t eps = 3e-14; // Precision.
38 Double_t fpmin = 1e-30;
44 Double_t d = 1 - qab * x / qap;
45 if (fabs(d) < fpmin) d = fpmin;
49 for (m = 1; m <= itmax; m++) {
51 Double_t aa = m * (b - m) * x / ((qam + m2) * (a + m2));
53 if (fabs(d) < fpmin) d = fpmin;
55 if (fabs(c) < fpmin) d = fpmin;
58 aa = -(a + m) * (qab + m) * x / ((a + m2) * (qap + m2));
60 if (fabs(d) < fpmin) d = fpmin;
62 if (fabs(c) < fpmin) d = fpmin;
66 if (fabs(dd - 1) <= eps) break;
69 std::cerr << "a or b too big, or max # iterations too small"
77 //____________________________________________________________________
79 AliFMDFlowEfficiency::IBetaI(Double_t a, Double_t b, Double_t x)
83 std::cerr << "x not in [0,1]" << std::endl;
86 if (x == 0 || x == 1) bt = 0;
88 bt = (exp(LnGamma(a + b) - LnGamma(a) - LnGamma(b)
89 + a * log(x) + b * log(1 - x)));
90 if (x < (a + 1) / (a + b + 2))
91 return bt * BetaCf(x, a, b) / a;
92 return 1 - bt * BetaCf(1-x, b, a)/ b;
95 //____________________________________________________________________
97 AliFMDFlowEfficiency::BetaAB(Double_t a, Double_t b, Int_t k, Int_t n)
101 Int_t c2 = n - k + 1;
102 return IBetaI(c1, c2, b) - IBetaI(c1, c2, a);
105 //____________________________________________________________________
107 AliFMDFlowEfficiency::SearchUpper(Double_t low, Int_t k, Int_t n, Double_t c)
109 Double_t integral = BetaAB(low, 1, k, n);
110 if (integral == c) return 1; // lucky -- this is the solution
111 if (integral < c) return -1;// no solution exists
112 Double_t too_high = 1; // upper edge estimate
113 Double_t too_low = low;
116 // Use a bracket-and-bisect search. Loop 20 times, to end up with a
117 // root guaranteed accurate to better than 0.1%.
118 for (UInt_t i = 0; i < 20; i++) {
119 test = 0.5 * (too_low + too_high);
120 integral = BetaAB(low, test, k, n);
121 if (integral > c) too_high = test;
126 //____________________________________________________________________
128 AliFMDFlowEfficiency::SearchLower(Double_t high, Int_t k, Int_t n, Double_t c)
130 Double_t integral = BetaAB(0, high, k, n);
131 if (integral == c) return 0; // lucky -- this is the solution
132 if (integral < c) return -1;// no solution exists
133 Double_t too_low = 0; // lower edge estimate
134 Double_t too_high = high;
137 // Use a bracket-and-bisect search. Loop 20 times, to end up with a
138 // root guaranteed accurate to better than 0.1%.
139 for (UInt_t i = 0; i < 20; i++) {
140 test = 0.5 * (too_high + too_low);
141 integral = BetaAB(test, high, k, n);
142 if (integral > c) too_low = test;
143 else too_high = test;
148 //____________________________________________________________________
150 AliFMDFlowEfficiency::Brent(Double_t ax, Double_t bx, Double_t cx,
151 Double_t& xmin, Int_t k, Int_t n, Double_t c,
154 const Int_t itmax = 100;
155 const Double_t gold = 0.3819660;
156 const Double_t eps = 1e-10;
159 Double_t a = (ax < cx ? ax : cx);
160 Double_t b = (ax > cx ? ax : cx);
166 Double_t fw = Length(x, k, n, c);
170 for (iter = 1; iter <= itmax; iter++) {
171 Double_t xm = .5 * (a + b);
172 Double_t tol1 = tol * fabs(x) + eps;
173 Double_t tol2 = 2 * tol1;
174 if (fabs(x - xm) < (tol2 - .5 * (b-a))) {
178 if (fabs(e) > tol1) {
179 Double_t r = (x - w) * (fx - fv);
180 Double_t q = (x - v) * (fx - fw);
181 Double_t p = (x - v) * q - (x - w) * r;
187 if (fabs(p) >= fabs(.5 * q * t) ||
190 e = (x > xm ? a - x : b - x);
196 if (u - a < tol2 || b - u < tol2)
197 d = sign(tol1, xm - x);
201 e = (x >= xm ? a - x : b - x);
204 Double_t u = (fabs(d) >= tol1 ? x + d : x + sign(tol1, d));
205 Double_t fu = Length(u, k, n, c);
219 if (fu <= fw || w == x) {
225 else if (fu <= fv || v == x || v == w) {
231 std::cerr << "Brett: too many iterations" << std::endl;
236 //____________________________________________________________________
238 AliFMDFlowEfficiency::Length(Double_t l, Int_t k, Int_t n, Double_t c)
240 Double_t h = SearchUpper(l, k, n, c);
241 if (h == -1) return 2;
245 //____________________________________________________________________
247 AliFMDFlowEfficiency::Interval(Int_t k, Int_t n,
248 Double_t& low, Double_t& high,
257 Double_t e = Double_t(k) / n;
262 h = SearchUpper(l, k, n, c);
266 l = SearchLower(h, k, n, c);
269 Brent(0, .5, 1, l, n, k, 1e-9, c);
270 h = l + Length(l, n, k, c);
277 //____________________________________________________________________