CMS 3D CMS Logo

GSUtilities.cc
Go to the documentation of this file.
2 
3 #include <TMath.h>
4 
5 // #include <iostream>
6 #include <cmath>
7 
8 #include <map>
9 #include <functional>
10 
11 float GSUtilities::quantile(const float q) const {
12  float qq = q;
13  if (q > 1)
14  qq = 1;
15  else if (q < 0)
16  qq = 0;
17  //
18  // mean and sigma of highest weight component
19  //
20  int iwMax(-1);
21  float wMax(0.);
22  for (unsigned i = 0; i < theNComp; i++) {
23  if (theWeights[i] > wMax) {
24  iwMax = i;
25  wMax = theWeights[i];
26  }
27  }
28  //
29  // Find start values: begin with mean and
30  // go towards f(x)=0 until two points on
31  // either side are found (assumes monotonously
32  // increasing function)
33  //
34  double x1(theParameters[iwMax]);
35  double y1(cdf(x1) - qq);
36  double dx = y1 > 0. ? -theErrors[iwMax] : theErrors[iwMax];
37  double x2(x1 + dx);
38  double y2(cdf(x2) - qq);
39  int cnt = 0;
40  while (y1 * y2 > 0.) {
41  x1 = x2;
42  y1 = y2;
43  x2 += dx;
44  y2 = cdf(x2) - qq;
45  cnt++;
46  }
47  // std::cout << "(" << x1 << "," << y1 << ") / ("
48  // << x2 << "," << y2 << ")" << std::endl;
49  //
50  // now use bisection to find final value
51  //
52  double x(0.);
53  while (true) {
54  // use linear interpolation
55  x = -(x2 * y1 - x1 * y2) / (y2 - y1);
56  double y = cdf(x) - qq;
57  // std::cout << x << " " << y << std::endl;
58  if (fabs(y) < 1.e-6)
59  break;
60  if (y * y1 > 0.) {
61  y1 = y;
62  x1 = x;
63  } else {
64  y2 = y;
65  x2 = x;
66  }
67  }
68  return x;
69 }
70 
72  int iwMax(-1);
73  float wMax(0.);
74  for (unsigned i = 0; i < theNComp; i++) {
75  if (theWeights[i] > wMax) {
76  iwMax = i;
77  wMax = theWeights[i];
78  }
79  }
80  return theErrors[iwMax];
81 }
82 
83 float GSUtilities::mode() const {
84  //
85  // start values = means of components
86  //
87  typedef std::multimap<double, double, std::greater<double> > StartMap;
88  StartMap xStart;
89  for (unsigned i = 0; i < theNComp; i++) {
90  xStart.insert(std::pair<double, float>(pdf(theParameters[i]), theParameters[i]));
91  }
92  //
93  // now try with each start value
94  //
95  typedef std::multimap<double, double, std::greater<double> > ResultMap;
96  ResultMap xFound;
97  for (StartMap::const_iterator i = xStart.begin(); i != xStart.end(); i++) {
98  double x = findMode((*i).second);
99  xFound.insert(std::pair<double, double>(pdf(x), x));
100  // std::cout << "Started at " << (*i).second
101  // << " , found " << x << std::endl;
102  }
103  //
104  // results
105  //
106  // for ( ResultMap::const_iterator i=xFound.begin();
107  // i!=xFound.end(); i++ ) {
108  // std::cout << "pdf at " << (*i).second << " = " << (*i).first << std::endl;
109  // }
110  return xFound.begin()->second;
111 }
112 
113 double GSUtilities::findMode(const double xStart) const {
114  //
115  // try with Newton
116  //
117  double y1(0.);
118  double x(xStart);
119  double y2(pdf(xStart));
120  double yd(dpdf1(xStart));
121  int nLoop(0);
122  if ((y1 + y2) < 10 * DBL_MIN)
123  return xStart;
124  while (nLoop++ < 20 && fabs(y2 - y1) / (y2 + y1) > 1.e-6) {
125  // std::cout << "dy = " << y2-y1 << std::endl;
126  double yd2 = dpdf2(x);
127  if (fabs(yd2) < 10 * DBL_MIN)
128  return xStart;
129  x -= yd / dpdf2(x);
130  yd = dpdf1(x);
131  y1 = y2;
132  y2 = pdf(x);
133  // std::cout << "New x / yd = " << x << " / " << yd << std::endl;
134  }
135  if (nLoop >= 20)
136  return xStart;
137  return x;
138 }
139 
140 double GSUtilities::pdf(const double& x) const {
141  double result(0.);
142  for (unsigned i = 0; i < theNComp; i++)
144  return result;
145 }
146 
147 double GSUtilities::cdf(const double& x) const {
148  double result(0.);
149  for (unsigned i = 0; i < theNComp; i++)
151  return result;
152 }
153 
154 double GSUtilities::dpdf1(const double& x) const {
155  double result(0.);
156  for (unsigned i = 0; i < theNComp; i++) {
157  double dx = (x - theParameters[i]) / theErrors[i];
159  }
160  return result;
161 }
162 
163 double GSUtilities::dpdf2(const double& x) const {
164  double result(0.);
165  for (unsigned i = 0; i < theNComp; i++) {
166  double dx = (x - theParameters[i]) / theErrors[i];
167  result += theWeights[i] / theErrors[i] / theErrors[i] * (dx * dx - 1) * gauss(x, theParameters[i], theErrors[i]);
168  }
169  return result;
170 }
171 
172 double GSUtilities::gauss(const double& x, const double& mean, const double& sigma) const {
173  const double fNorm(1. / sqrt(2 * TMath::Pi()));
174  double result(0.);
175 
176  double d((x - mean) / sigma);
177  if (fabs(d) < 20.)
178  result = exp(-d * d / 2.);
179  result *= fNorm / sigma;
180  return result;
181 }
182 
183 double GSUtilities::gaussInt(const double& x, const double& mean, const double& sigma) const {
184  return TMath::Freq((x - mean) / sigma);
185 }
186 
188  double s0(0.);
189  double s1(0.);
190  for (unsigned i = 0; i < theNComp; i++) {
191  s0 += theWeights[i];
192  s1 += theWeights[i] * theParameters[i];
193  }
194  return s1 / s0;
195 }
196 
198  double s0(0.);
199  for (unsigned i = 0; i < theNComp; i++) {
200  s0 += theWeights[i];
201  }
202  return 1. / (sqrt(s0));
203 }
204 
205 float GSUtilities::maxWeight() const {
206  // Look for the highest weight component
207  //
208  //int iwMax(-1);
209  float wMax(0.);
210  for (unsigned i = 0; i < theNComp; i++) {
211  if (theWeights[i] > wMax) {
212  //iwMax = i;
213  wMax = theWeights[i];
214  }
215  }
216  return wMax;
217 }
218 
220  float mod = mode();
221  float min = getMin(mod);
222  float max = getMax(mod);
223  int nBins = 1000;
224  float dx = (max - min) / (float)nBins;
225 
226  float x1 = mod, x2 = mod, x1f = mod, x2f = mod;
227  float I = 0;
228  int cnt = 0;
229  while (I < .68) {
230  x1 -= dx;
231  x2 += dx;
232  if (pdf(x1) >= pdf(x2)) {
233  x1f = x1;
234  x2 -= dx;
235  } else {
236  x2f = x2;
237  x1 += dx;
238  }
239  I = cdf(x2f) - cdf(x1f);
240  cnt++;
241  // for crazy pdf's return a crazy value
242  if (cnt > 2500)
243  return 100000.;
244  }
245  return (x2f - x1f) / 2;
246 }
247 
248 float GSUtilities::getMin(float x) {
249  int cnt = 0;
250  float dx;
251  if (fabs(x) < 2)
252  dx = .5;
253  else
254  dx = fabs(x) / 10;
255  while (cdf(x) > .1 && cnt < 1000) {
256  x -= dx;
257  cnt++;
258  }
259  return x;
260 }
261 
262 float GSUtilities::getMax(float x) {
263  int cnt = 0;
264  float dx;
265  if (fabs(x) < 2)
266  dx = .5;
267  else
268  dx = fabs(x) / 10;
269  while (cdf(x) < .9 && cnt < 1000) {
270  x += dx;
271  cnt++;
272  }
273  return x;
274 }
const double Pi
float getMax(float)
Definition: GSUtilities.cc:262
double findMode(const double) const
Definition: GSUtilities.cc:113
double cdf(const double &) const
value of integral(pdf)
Definition: GSUtilities.cc:147
double gauss(const double &, const double &, const double &) const
value of gaussian distribution
Definition: GSUtilities.cc:172
float errorHighestWeight() const
Definition: GSUtilities.cc:71
float quantile(const float) const
Definition: GSUtilities.cc:11
double combinedMean() const
mean value of combined state
Definition: GSUtilities.cc:187
unsigned theNComp
Definition: GSUtilities.h:74
float * theErrors
Definition: GSUtilities.h:77
T sqrt(T t)
Definition: SSEVec.h:19
float maxWeight() const
Definition: GSUtilities.cc:205
double dpdf1(const double &) const
first derivative of pdf
Definition: GSUtilities.cc:154
float errorMode()
Definition: GSUtilities.cc:219
const std::complex< double > I
Definition: I.h:8
float * theWeights
Definition: GSUtilities.h:75
float mode() const
mode
Definition: GSUtilities.cc:83
float getMin(float)
Definition: GSUtilities.cc:248
d
Definition: ztail.py:151
double dpdf2(const double &) const
second derivative of pdf
Definition: GSUtilities.cc:163
float * theParameters
Definition: GSUtilities.h:76
double pdf(const double &) const
value of the pdf
Definition: GSUtilities.cc:140
float x
T mod(const T &a, const T &b)
Definition: ecalDccMap.h:4
double gaussInt(const double &, const double &, const double &) const
integrated value of gaussian distribution
Definition: GSUtilities.cc:183
double errorCombinedMean() const
Definition: GSUtilities.cc:197