1 | // |
---|
2 | // $Id: utils.cc 2955 2011-06-28 18:38:08Z mabl $ |
---|
3 | // |
---|
4 | #include <math.h> |
---|
5 | #include "utils.hh" |
---|
6 | |
---|
7 | |
---|
8 | |
---|
9 | //_____________________________________________________________________________________________________ |
---|
10 | pair<Int_t, Double_t*> &findRoots(Double_t a, Double_t b, Double_t c) { |
---|
11 | // |
---|
12 | // Solutions of: |
---|
13 | // a x^2 + b x + c = 0 |
---|
14 | // |
---|
15 | // q = -1/2 (b + sign(b) sqrt(b^2 - 4 a c) |
---|
16 | // |
---|
17 | // x_1 = q / a |
---|
18 | // x_2 = c / q |
---|
19 | // |
---|
20 | // cfr. |
---|
21 | // Numerical Recipes in Fortran (5.6 Quadratic and Cubic Equations) |
---|
22 | // W. H. Press et al. |
---|
23 | // Cambridge University Press |
---|
24 | // Second Edition |
---|
25 | // |
---|
26 | |
---|
27 | // \Delta=b^2-4ac |
---|
28 | Double_t det = b*b - 4*a*c; |
---|
29 | static Double_t roots[2]; |
---|
30 | static pair<Int_t, Double_t*> p; |
---|
31 | p.second = roots; |
---|
32 | |
---|
33 | |
---|
34 | // det < 0 OR a=b=0: no solution |
---|
35 | if(det < -kTolerance || (fabs(a) < kTolerance && fabs(b) < kTolerance) ) { |
---|
36 | p.first=0; |
---|
37 | p.second=0; |
---|
38 | if((fabs(a) < kTolerance && fabs(b) < kTolerance)) |
---|
39 | cout << "\nWARNING : <findRoots> algo called with coeff. a=b=0"<<endl; |
---|
40 | } |
---|
41 | else { |
---|
42 | Double_t q = -0.5 * (b + sign(b)*sqrt(det)); |
---|
43 | |
---|
44 | // if det=0 OR a=0 OR b=c=0: one solution |
---|
45 | if(fabs(det) < kTolerance || fabs(a) < kTolerance || (fabs(b) < kTolerance && fabs(c) < kTolerance) ) { |
---|
46 | if(fabs(a) < kTolerance) p.second[0] = c/q; // b cannot be null here, so q |
---|
47 | else p.second[0] = q/a; |
---|
48 | p.first = 1; |
---|
49 | } |
---|
50 | |
---|
51 | // if det > 0 : two solutions |
---|
52 | else { |
---|
53 | p.second[0] = q/a; |
---|
54 | p.second[1] = c/q; |
---|
55 | p.first = 2; |
---|
56 | } |
---|
57 | } |
---|
58 | |
---|
59 | return p; |
---|
60 | } |
---|
61 | |
---|
62 | //_____________________________________________________________________________________________________ |
---|
63 | Int_t zbrac(Float_t (*func)(Float_t), Float_t *x1, Float_t *x2) { |
---|
64 | // |
---|
65 | // Numerical Recipes in C. Chapter 9. Root Finding and Nonlinear Sets of Equations |
---|
66 | // |
---|
67 | |
---|
68 | if(*x1 == *x2) return -1; |
---|
69 | Float_t f1 = (*func)(*x1); |
---|
70 | Float_t f2 = (*func)(*x2); |
---|
71 | for (Int_t j=1;j<NTRY;j++) { |
---|
72 | if (f1*f2 < 0) return 1; |
---|
73 | if (fabs(f1) < fabs(f2)) |
---|
74 | f1 = (*func)(*x1 += FACTOR*(*x1-*x2)); |
---|
75 | else |
---|
76 | f2 = (*func)(*x2 += FACTOR*(*x2-*x1)); |
---|
77 | } |
---|
78 | return 0; |
---|
79 | } |
---|
80 | |
---|
81 | //_____________________________________________________________________________________________________ |
---|
82 | Float_t rtbis(Float_t (*func)(Float_t), Float_t x1, Float_t x2, Float_t xacc) { |
---|
83 | // |
---|
84 | // |
---|
85 | // |
---|
86 | |
---|
87 | Float_t dx,f,fmid,xmid,rtb; |
---|
88 | f = (*func)(x1); |
---|
89 | fmid = (*func)(x2); |
---|
90 | if(f*fmid >=0) return -1; |
---|
91 | rtb = f<0 ? (dx = x2-x1,x1) : (dx=x1-x2,x2); |
---|
92 | for (Int_t j=1;j<=JMAX;j++) { |
---|
93 | fmid = (*func)(xmid=rtb+(dx*=0.5)); |
---|
94 | if (fmid <=0) rtb = xmid; |
---|
95 | if (fabs(dx) < xacc || fmid == 0) return rtb; |
---|
96 | } |
---|
97 | return 0; |
---|
98 | } |
---|