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