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