CMS 3D CMS Logo

ParabolaFit.cc
Go to the documentation of this file.
1 #include "ParabolaFit.h"
2 #include <iostream>
3 using namespace std;
4 template <class T>
5 T sqr(T t) {
6  return t * t;
7 }
8 
9 void ParabolaFit::addPoint(double x, double y) {
10  hasWeights = false;
11  addPoint(x, y, 1.);
12 }
13 
14 void ParabolaFit::addPoint(double x, double y, double w) {
15  hasValues = false;
16  hasErrors = false;
17  Point p = {x, y, w};
18  points.push_back(p);
19 }
20 
21 const ParabolaFit::Result& ParabolaFit::result(bool doErrors) const {
22  if (hasErrors)
23  return theResult;
24  if (hasValues && !doErrors)
25  return theResult;
26 
27  double F0, F1, F2, F3, F4, F0y, F1y, F2y;
28  F0 = F1 = F2 = F3 = F4 = F0y = F1y = F2y = 0.;
29 
30  typedef vector<Point>::const_iterator IT;
31  for (IT ip = points.begin(); ip != points.end(); ip++) {
32  double pow;
33  double x = ip->x;
34  double y = ip->y;
35  double w = ip->w;
36 
37  F0 += w;
38  F0y += w * y;
39  F1 += w * x;
40  F1y += w * x * y;
41  pow = x * x;
42  F2 += w * pow;
43  F2y += w * pow * y; // x^2
44  pow *= x;
45  F3 += w * pow; // x^3
46  pow *= x;
47  F4 += w * pow; // x^4
48  }
49 
50  Column cA = {F0, F1, F2};
51  Column cB = {F1, F2, F3};
52  Column cC = {F2, F3, F4};
53  Column cY = {F0y, F1y, F2y};
54 
55  double det0 = det(cA, cB, cC);
56 
57  if (!hasFixedParC) {
58  theResult.parA = det(cY, cB, cC) / det0;
59  theResult.parB = det(cA, cY, cC) / det0;
60  theResult.parC = det(cA, cB, cY) / det0;
61  } else {
62  Column cCY = {F0y - theResult.parC * F2, F1y - theResult.parC * F3, F2y - theResult.parC * F4};
63  double det0C = det(cA, cB);
64  theResult.parA = det(cCY, cB) / det0C;
65  theResult.parB = det(cA, cCY) / det0C;
66  }
67 
68  // std::cout <<" result: A="<<theResult.parA<<" B="<<theResult.parB<<" C="<<theResult.parC<<endl;
69  double vAA, vBB, vCC, vAB, vAC, vBC;
70  vAA = vBB = vCC = vAB = vAC = vBC = 0.;
71 
72  hasValues = true;
73  if (!doErrors)
74  return theResult;
75 
76  if (!hasWeights && dof() > 0) {
77  // cout <<" CHI2: " << chi2() <<" DOF: " << dof() << endl;
78  double scale_w = 1. / chi2() / dof();
79  for (IT ip = points.begin(); ip != points.end(); ip++)
80  ip->w *= scale_w;
81  // cout <<" CHI2: " << chi2() <<" DOF: " << dof() << endl;
82  }
83 
84  for (IT ip = points.begin(); ip != points.end(); ip++) {
85  double w = ip->w;
86  Column cX = {1., ip->x, sqr(ip->x)};
87 
88  double dXBC = det(cX, cB, cC);
89  double dAXC = det(cA, cX, cC);
90  double dABX = det(cA, cB, cX);
91 
92  vAA += w * sqr(dXBC);
93  vBB += w * sqr(dAXC);
94  vCC += w * sqr(dABX);
95  vAB += w * dXBC * dAXC;
96  vAC += w * dXBC * dABX;
97  vBC += w * dAXC * dABX;
98  }
99 
100  theResult.varAA = vAA / sqr(det0);
101  theResult.varBB = vBB / sqr(det0);
102  theResult.varCC = vCC / sqr(det0);
103  theResult.varAB = vAB / sqr(det0);
104  theResult.varAC = vAC / sqr(det0);
105  theResult.varBC = vBC / sqr(det0);
106 
107  hasErrors = true;
108  return theResult;
109 }
110 
111 double ParabolaFit::chi2() const {
112  double mychi2 = 0.;
113  for (vector<Point>::const_iterator ip = points.begin(); ip != points.end(); ip++) {
114  mychi2 += ip->w * sqr(ip->y - fun(ip->x));
115  }
116  return mychi2;
117 }
118 
119 double ParabolaFit::fun(double x) const { return theResult.parA + theResult.parB * x + theResult.parC * x * x; }
120 
121 int ParabolaFit::dof() const {
122  int nPar = 3;
123  if (hasFixedParC)
124  nPar--;
125  int nDof = points.size() - nPar;
126  return (nDof > 0) ? nDof : 0;
127 }
128 
129 double ParabolaFit::det(const Column& c1, const Column& c2, const Column& c3) const {
130  return c1.r1 * c2.r2 * c3.r3 + c2.r1 * c3.r2 * c1.r3 + c3.r1 * c1.r2 * c2.r3 - c1.r3 * c2.r2 * c3.r1 -
131  c2.r3 * c3.r2 * c1.r1 - c3.r3 * c1.r2 * c2.r1;
132 }
133 
134 double ParabolaFit::det(const Column& c1, const Column& c2) const { return c1.r1 * c2.r2 - c1.r2 * c2.r1; }
double chi2() const
Definition: ParabolaFit.cc:111
T w() const
int dof() const
Definition: ParabolaFit.cc:121
double fun(double x) const
Definition: ParabolaFit.cc:119
T sqr(T t)
Definition: ParabolaFit.cc:5
void addPoint(double x, double y)
Definition: ParabolaFit.cc:9
std::vector< LinkConnSpec >::const_iterator IT
double det(const Column &c1, const Column &c2, const Column &c3) const
Definition: ParabolaFit.cc:129
float x
long double T
const Result & result(bool doErrors) const
Definition: ParabolaFit.cc:21
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29