CMS 3D CMS Logo

LagrangeMultipliersFitter.cc
Go to the documentation of this file.
1 /* From SimpleFits Package
2  * Designed an written by
3  * author: Ian M. Nugent
4  * Humboldt Foundations
5  */
8 #include "TDecompBK.h"
9 #include <iostream>
10 
11 using namespace tauImpactParameter;
12 
14  : isConfigured_(false),
15  isFit_(false),
16  epsilon_(0.00001),
17  weight_(1.0),
18  maxDelta_(0.1),
19  nitermax_(100),
20  chi2_(1e10),
21  D_(1, 1),
22  V_D_(1, 1) {}
23 
25  if (cov_.GetNrows() != par_0_.GetNrows()) {
26  // set cov to cov_0 until value is computed
27  cov_.ResizeTo(par_0_.GetNrows(), par_0_.GetNrows());
28  cov_ = cov_0_;
29  }
30  if (!isConfigured_)
31  return false;
32  if (isFit_)
33  return isConverged();
34  isFit_ = true;
35  niter_ = 0;
36  for (niter_ = 0; niter_ <= nitermax_; niter_++) {
38  if (!passed || (niter_ == nitermax_ && delta_ >= 4.0 * maxDelta_)) {
39  edm::LogWarning("LagrangeMultipliersFitter::Fit")
40  << "Reached Maximum number of iterations..." << niter_ << std::endl;
41  return false;
42  }
43  if (isConverged())
44  break;
45  }
47  return true;
48 }
49 
51  if (V_D_.GetNrows() != nConstraints())
52  V_D_.ResizeTo(nConstraints(), nConstraints());
53  if (D_.GetNrows() != nConstraints() || D_.GetNcols() != par_.GetNrows())
54  D_.ResizeTo(nConstraints(), par_.GetNrows());
55 
56  // Setup intial values
57  TVectorT<double> alpha_A = par_;
58  TVectorT<double> alpha_0 = par_0_;
59  TVectorT<double> delta_alpha_A = alpha_A - alpha_0;
60  D_ = derivative();
61  TVectorT<double> d = value(par_);
62  TVectorT<double> C = D_ * delta_alpha_A - d;
63  TMatrixTSym<double> V_alpha0 = cov_0_;
64  TMatrixTSym<double> V_D_inv = V_alpha0;
65  V_D_inv.Similarity(D_);
66  double det = V_D_inv.Determinant();
67  TDecompBK Inverter(V_D_inv);
68  if (fabs(det) > 1e40) {
69  edm::LogWarning("LagrangeMultipliersFitter::Fit")
70  << "Fit failed: unable to invert SYM gain matrix LARGE Determinant" << det << " \n"
71  << std::endl;
72  return false;
73  }
74  if (!Inverter.Decompose()) {
75  edm::LogWarning("LagrangeMultipliersFitter::Fit") << "Fit failed: unable to invert SYM gain matrix " << det << " \n"
76  << std::endl;
77  return false;
78  }
79  V_D_ = Inverter.Invert();
80 
81  // solve equations
82  TVectorT<double> lambda = -1.0 * V_D_ * C;
83  TMatrixT<double> DT = D_;
84  DT.T();
85  TVectorT<double> alpha = alpha_0 - V_alpha0 * DT * lambda;
86 
87  // do while loop to see if the convergance criteria are satisfied
88  double s(1), stepscale(0.01);
89  chi2prev_ = chi2_;
90  double currentchi2(chiSquareUsingInitalPoint(alpha_A, lambda)), currentdelta(constraintDelta(par_));
91  TVectorT<double> alpha_s = alpha;
92  // convergence in 2 step procedure to minimize chi2 within MaxDelta_ of the constriants
93  // 1) Get within 5x MaxDelta_
94  // 2) converge based on improving chi2 and constrianed delta
95  unsigned int Proc = ConstraintMin;
96  if (constraintDelta(par_) < 5 * maxDelta_)
97  Proc = Chi2AndConstaintMin;
98  int NIter = (int)(1.0 / stepscale);
99  for (int iter = 0; iter < NIter; iter++) {
100  // compute safty cutoff for numberical constraint
101  double diff = 0;
102  for (int l = 0; l < alpha_s.GetNrows(); l++) {
103  if (diff < alpha_s(l) - alpha_A(l))
104  diff = alpha_s(l) - alpha_A(l);
105  }
106  double delta_alpha_s = constraintDelta(alpha_s);
107  if (Proc == ConstraintMin) {
108  if (delta_alpha_s < currentdelta || iter == NIter || diff < 100 * epsilon_) {
109  currentchi2 = chiSquareUsingInitalPoint(alpha_s, lambda);
110  currentdelta = delta_alpha_s;
111  ScaleFactor_ = s;
112  break;
113  }
114  } else if (Proc == Chi2AndConstaintMin) {
115  double chi2_s = chiSquareUsingInitalPoint(alpha_s, lambda);
116  if ((delta_alpha_s < currentdelta /*+maxDelta_*/ && chi2_s < currentchi2) || iter == NIter ||
117  diff < 100 * epsilon_) {
118  currentchi2 = chi2_s;
119  currentdelta = delta_alpha_s;
120  ScaleFactor_ = s;
121  break;
122  }
123  }
124  s -= stepscale;
125  alpha_s = alpha_A + s * (alpha - alpha_A);
126  }
127  // set chi2
128  chi2_ = currentchi2;
129  //set delta
130  delta_ = currentdelta;
131  par_ = alpha_s;
132  return true;
133 }
134 
135 TMatrixD LagrangeMultipliersFitter::derivative() { // alway evaluated at current par
136  TMatrixD Derivatives(nConstraints(), par_.GetNrows());
137  TVectorD par_plus(par_.GetNrows());
138  TVectorD value_par(nConstraints());
139  TVectorD value_par_plus(nConstraints());
140  for (int j = 0; j < par_.GetNrows(); j++) {
141  for (int i = 0; i < par_.GetNrows(); i++) {
142  par_plus(i) = par_(i);
143  if (i == j)
144  par_plus(i) = par_(i) + epsilon_;
145  }
146  value_par = value(par_);
147  value_par_plus = value(par_plus);
148  for (int i = 0; i < nConstraints(); i++) {
149  Derivatives(i, j) = (value_par_plus(i) - value_par(i)) / epsilon_;
150  }
151  }
152  return Derivatives;
153 }
154 
156  if (delta_ < maxDelta_) {
157  return true;
158  }
159  return false;
160 }
161 
162 double LagrangeMultipliersFitter::chiSquare(const TVectorT<double>& delta_alpha,
163  const TVectorT<double>& lambda,
164  const TMatrixT<double>& D,
165  const TVectorT<double>& d) {
166  double c2 = lambda * (D * delta_alpha + d);
167  return c2;
168 }
169 
171  const TVectorT<double>& lambda) {
172  if (cov_0_.GetNrows() != V_alpha0_inv_.GetNrows()) {
173  TMatrixTSym<double> V_alpha0 = cov_0_;
174  V_alpha0_inv_.ResizeTo(cov_0_.GetNrows(), cov_0_.GetNrows());
175  TDecompBK Inverter(V_alpha0);
176  if (!Inverter.Decompose()) { // handle rare case where inversion is not possible (ie assume diagonal)
177  edm::LogWarning("LagrangeMultipliersFitter::chiSquareUsingInitalPoint")
178  << "Error non-invertable Matrix... Calculating under assumption that correlations can be neglected!!!"
179  << std::endl;
180  for (int j = 0; j < par_.GetNrows(); j++) {
181  for (int i = 0; i < par_.GetNrows(); i++) {
182  if (i == j)
183  V_alpha0_inv_(i, j) = 1.0 / V_alpha0(i, j);
184  else
185  V_alpha0_inv_(i, j) = 0.0;
186  }
187  }
188  } else {
189  V_alpha0_inv_ = Inverter.Invert();
190  }
191  }
192 
193  TVectorT<double> alpha_0 = par_0_;
194  TVectorT<double> dalpha = alpha - alpha_0;
195  double c2_var = dalpha * (V_alpha0_inv_ * dalpha);
196  const TVectorT<double>& alpha_v = alpha;
197  double c2_constraints = lambda * value(alpha_v);
198  double c2 = c2_var + c2_constraints;
199  return c2;
200 }
201 
202 double LagrangeMultipliersFitter::constraintDelta(const TVectorT<double>& par) {
203  TVectorD d_par = value(par);
204  double delta_d(0);
205  for (int i = 0; i < d_par.GetNrows(); i++) {
206  delta_d += fabs(d_par(i));
207  }
208  return delta_d;
209 }
210 
212  TMatrixTSym<double> V_alpha0 = cov_0_;
213  TMatrixTSym<double> DTV_DD = V_D_.SimilarityT(D_);
214  TMatrixT<double> DTV_DDV = DTV_DD * V_alpha0;
215  TMatrixT<double> VDTV_DDV = V_alpha0 * DTV_DDV;
216  TMatrixT<double> CovCor = VDTV_DDV;
217  //CovCor*=ScaleFactor_;
218  if (V_corr_prev_.GetNrows() != V_alpha0.GetNrows()) {
219  V_corr_prev_.ResizeTo(V_alpha0.GetNrows(), V_alpha0.GetNrows());
220  V_corr_prev_ = CovCor;
221  } else {
222  V_corr_prev_ *= (1 - ScaleFactor_);
223  CovCor += V_corr_prev_;
224  V_corr_prev_ = CovCor;
225  }
226 
227  TMatrixT<double> V_alpha = V_alpha0 - CovCor;
228  for (int i = 0; i < cov_.GetNrows(); i++) {
229  for (int j = 0; j <= i; j++) {
230  cov_(i, j) = V_alpha(i, j);
231  }
232  }
233  return cov_;
234 }
float alpha
Definition: AMPTWrapper.h:105
virtual TVectorD value(const TVectorD &v)=0
d
Definition: ztail.py:151
DecomposeProduct< arg, typename Div::arg > D
Definition: Factorize.h:141
double chiSquareUsingInitalPoint(const TVectorT< double > &alpha, const TVectorT< double > &lambda)
double constraintDelta(const TVectorT< double > &par)
AlgebraicMatrix Derivatives
Definition: Definitions.h:35
Log< level::Warning, false > LogWarning