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