5 #if ROOT_VERSION_CODE < 331013
21 TPolinom::TPolinom(
const TPolinom& from )
30 SetCoefs(from.fNP,from.fCoe);
31 if (!from.fEmx)
return *
this;
32 int n = (fNP+1)*(fNP+2)/2;
34 TCL::ucopy(from.fEmx,fEmx,n);
38 TPolinom::TPolinom(
double c0)
44 TPolinom::TPolinom(
double c0,
double c1)
52 TPolinom::TPolinom(
double c0,
double c1,
double c2)
66 void TPolinom::Clear(
const char *)
68 if (fCoe!=f2Coe)
delete [] fCoe; fCoe=0;
69 delete [] fEmx; fEmx=0;
73 void TPolinom::Print(
const char*)
const
75 Info(
"Print",
"Power %d ",fNP);
78 for (
int i=0,n=1;i<=fNP;i++,e+=n++) {
79 double err = (fEmx)? sqrt(e[i]):0;
80 Info(
"Print",
"Coef[%d] = %g +- %g",i,fCoe[i],err);
86 void TPolinom::SetCoefs(
int npw,
const double *coefs)
88 if (fNP!=npw || !fCoe) {
90 if (fCoe !=f2Coe)
delete [] fCoe;
93 fCoe =
new double[fNP+1];
94 memset(fCoe,0,(fNP+1)*
sizeof(
double));
97 if (coefs) {memcpy(fCoe,coefs,(fNP+1)*
sizeof(
double));}
98 else {memset(fCoe,0 ,(fNP+1)*
sizeof(
double));}
101 double TPolinom::Eval(
double x,
int n,
double *coe)
104 for (
int i = n; i>=0; i--) {res = coe[i]+x*res;}
108 double TPolinom::Eval(
double x)
const
110 return Eval(x,fNP,fCoe);
113 double TPolinom::Deriv(
double x)
const
116 for (
int i = fNP; i>0; i--) {res = fCoe[i]*i+x*res;}
120 void TPolinom::Move(
double x)
127 fEmx[0]+=x*(2*fEmx[1]+x*fEmx[2]);
133 TArrayD arr((il*(il*3+1))/2);
134 double *tra = arr.GetArray();
135 double *tmp = tra+il*il;
136 tra[0]=1;
for (
int i=1;i<il;i++) tra[i]=tra[i-1]*x;
139 for (
int irow=1;irow<il;irow++) {
141 for (
int icol=irow;icol<il;icol++) {
142 t[icol] = (t[icol-bak]*icol)/div;
145 TCL::vmatl(tra,fCoe,tmp ,il);
146 TCL::ucopy(tmp, fCoe,il);
149 TCL::ucopy(tmp, fEmx ,il*(il+1)/2);
152 void TPolinom::Backward()
154 for (
int i=1;i<=fNP;i+=2) { fCoe[i]=-fCoe[i];}
156 for (
int i=0,li=0;i<=fNP;li+=++i) {
157 for (
int j=0 ;j<=i ;j++) {
if ((i^j)&1) fEmx[li+j]*=-1;}}
160 double TPolinom::GetEmx(
int i,
int j)
const
164 if (i<j) {ii=j;jj=i;}
165 return fEmx[((ii+1)*ii)/2+jj];
168 double TPolinom::Evrr(
double x)
const
172 double *xx = arr.GetArray();
174 for (
int i=1;i<=fNP;i++) xx[i]=xx[i-1]*x;
185 enum EPoliFitter {kX,kY,kW,kXYW=3};
188 TPoliFitter::TPoliFitter(
int np):
TPolinom(np),fArr(100)
195 memcpy(fBeg,fr.fBeg,fEnd-fBeg+1);
196 fDat = fArr.GetArray();
197 fC = fDat+fN; fP = fC+fNP+1;
200 void TPoliFitter::Add(
double x,
double y,
double err2)
202 if (fArr.GetSize()<=fN+kXYW) { fArr.Set(fN*2+kXYW); fDat = fArr.GetArray();}
209 void TPoliFitter::AddErr(
double err2)
211 fArr[fN-kXYW+kW]=1./err2;
214 const double *TPoliFitter::GetX(
int i)
const
215 {
return fDat+i*kXYW;}
217 double *TPoliFitter::GetX(
int i)
218 {
return fDat+i*kXYW;}
220 void TPoliFitter::Clear(
const char *)
222 memset(fBeg,0,fEnd-fBeg+1);
224 fDat = fArr.GetArray();
227 void TPoliFitter::Print(
const char* tit)
const
229 if (!tit || !*tit) tit =
"Print";
231 Info(tit,
"NPoints %d Wtot=%g",fN/kXYW,fWtot);
232 for (
int l=0;l<fN;l+=kXYW) {
233 double dy = fDat[l+kY]-Eval(fDat[l+kX]);
234 double dXi2 = dy*dy*fDat[l+kW]*fWtot;
235 printf(
"%d - \tX=%g \tY=%g \tW=%g \tdY=%g \tdXi2=%g\n"
236 ,l/kXYW,fDat[l+kX],fDat[l+kY],fDat[l+kW]
242 void TPoliFitter::Prepare()
244 int need = fN+(fNP+1) + (fNP+1)*(fNP+2)/2;
245 if (need > fArr.GetSize()) fArr.Set(need);
246 fDat = fArr.GetArray();
247 fC = fDat+fN; fP = fC+fNP+1;
248 TCL::vzero(fC,(fNP+1) + (fNP+1)*(fNP+2)/2);
250 for (
int l=0;l<fN;l+=kXYW) {fWtot+=fDat[l+kW];}
251 for (
int l=0;l<fN;l+=kXYW) {fDat[l+kW]/=fWtot;}
254 int lNew = 1,lLst=0,pLst=0,lOld,pOld;
255 for (
int pNew=1;pNew<=fNP;) {
256 TCL::vzero(fC,pNew+1);
257 for (
int l=0;l<fN;l+=kXYW) {
258 double x = fDat[l+kX],wt=fDat[l+kW];
260 double yNew = Eval(x,pLst,fP+lLst)*x;
261 fC[pNew]+=yNew*yNew*wt;
263 for (lOld = lLst,pOld=pLst;pOld>=0;lOld-=pOld,pOld--) {
264 fC[pOld]+= yNew * TPolinom::Eval(x,pOld,fP+lOld);
269 TCL::ucopy(fP+lLst,fP+lNew+1,pLst+1);
270 for (lOld = lLst,pOld=pLst;pOld>=0;lOld-=pOld,pOld--) {
271 TCL::vlinco(fP+lNew,1.,fP+lOld,-fC[pOld],fP+lNew,pOld+1);
273 double nor = fC[pNew]-TCL::vdot(fC,fC,pNew);
275 TCL::vscale(fP+lNew,1./nor,fP+lNew,pNew+1);
276 lLst = lNew; pLst=pNew;
277 lNew += pNew+1; pNew++;
281 double TPoliFitter::Fit()
286 TCL::vzero(fC,fNP+1);
288 for (
int l=0;l<fN;l+=kXYW) {
289 double x = fDat[l+kX];
290 double y = fDat[l+kY];
291 double w = fDat[l+kW];
294 for (lp=0,np=0;np<=fNP; lp+=++np ) {
295 fC[np]+=Eval(x,np,fP+lp)*y*w;
298 TCL::vzero(fCoe,fNP+1);
299 for (lp=0,np=0;np<=fNP; np++, lp+=np ) {
300 fChi2-=fC[np]*fC[np];
301 TCL::vlinco(fCoe,1.,fP+lp,fC[np],fCoe,np+1);
304 fNdf = fNuse-(fNP+1);
305 if (fNdf>0) fChi2/=fNdf;
309 void TPoliFitter::MakeErrs()
312 int n = (fNP+1)*(fNP+2)/2;
313 fEmx =
new double[n];
315 TCL::vscale(fEmx,1./fWtot,fEmx,n);
318 double TPoliFitter::EvalChi2()
320 double Xi2=0;
int n=0;
321 for (
int l=0;l<fN;l+=kXYW) {
322 double x = fDat[l+kX];
323 double y = fDat[l+kY];
324 double w = fDat[l+kW];
327 Xi2+= (y-ye)*(y-ye)*w;
335 double TPoliFitter::FixAt(
double x,
double y)
338 if (fabs(x)>1e-8) Move(x);
340 double emx0 = fEmx[0];
341 double h = y-fCoe[0];
342 double lamda = h/emx0;
344 for (
int i=0,n=1;i<=fNP;i++,e+=n++) {fCoe[i]+= e[0]*lamda;}
347 for (
int i=0,n=1;i<=fNP;i++,e+=n++) {e[0]=0;}
352 double addXi2 = h*h/emx0;
353 fChi2 += (addXi2-fChi2)/fNdf;
354 if (fabs(x)>1e-8) Move(-x);
358 void TPoliFitter::Skip(
int idx)
360 fDat[kXYW*idx+kW]=-1;
364 void TPoliFitter::SetNdf(
int ndf)
371 void TPoliFitter::DCoeDy(
int iy,
double *dcoe)
const
374 TCL::vzero(dcoe,fNP+1);
375 TArrayD ac(fNP+1);
double *c=ac.GetArray();
377 double x = fDat[l+kX];
378 double w = fDat[l+kW];
380 for (
int lp=0,np=0;np<=fNP; lp+=++np ) {
381 c[np]=Eval(x,np,fP+lp)*w;
383 for (
int lp=0,np=0;np<=fNP; np++, lp+=np ) {
384 TCL::vlinco(dcoe,1.,fP+lp,c[np],dcoe,np+1);
388 double TPoliFitter::EvalOrt(
int idx,
double x)
const
390 int lp = (idx*(idx+1))/2;
391 return Eval(x,idx,fP+lp);
394 double TPoliFitter::MakeMatrix(TMatrixD &Akj)
const
400 for (
int k=0;k<N;k++) {
401 double Xk = GetX(k)[0];
402 double Wk = GetX(k)[2];
403 for (
int j=0;j<=k;j++) {
404 double Xj = GetX(j)[0];
405 double Wj = GetX(j)[2];
407 for (
int i=0;i<=fNP;i++) {
408 double Fik = EvalOrt(i,Xk);
409 double Fij = EvalOrt(i,Xj);
412 Akj[k][j] = -Fkj*Wk*Wj*fWtot;
413 Akj[j][k] = Akj[k][j];
415 Akj[k][k]+= Wk*fWtot;
427 #include "TVectorD.h"
430 void TPoliFitter::Show()
const
432 static TCanvas *myCanvas = 0;
433 static TGraph *ptGraph = 0;
434 static TGraph *ciGraph = 0;
435 double x[100],y[100];
437 if (nPts>100) nPts=100;
438 for (
int i=0;i<nPts;i++) {
439 x[i]=fDat[i*3+0]; y[i]=fDat[i*3+1];
443 if(!myCanvas) myCanvas =
new TCanvas(
"TPoliFitter",
"",600,800);
446 delete ptGraph;
delete ciGraph;
447 ptGraph =
new TGraph(nPts , x, y);
448 ptGraph->SetMarkerColor(kRed);
452 double dx = (x[nPts-1]-x[0])/99;
453 for (
int i=0;i<100;i++) {
458 ciGraph =
new TGraph(100 , x, y);
459 ciGraph->Draw(
"Same CP");
461 myCanvas->Modified();
463 while(!gSystem->ProcessEvents()){};
467 void TPoliFitter::Test(
int kase)
469 static TCanvas* myCanvas=0;
470 static TH1F *hh[6]={0};
471 static const char *hNams[]={
"dA0",
"dA1",
"dA2",
"dY",
"Xi2",
"Xi2E",0};
472 if(!myCanvas) myCanvas=
new TCanvas(
"C1",
"",600,800);
474 myCanvas->Divide(1,6);
476 for (
int i=0;i<6;i++) {
477 int low = (i>=4)? 0:-5;
478 delete hh[i]; hh[i]=
new TH1F(hNams[i],hNams[i],100,low,5);
479 myCanvas->cd(i+1); hh[i]->Draw();
484 double A[3]={1,2,3},B[3]={1,2,3};
486 B[0] = A[0]+ 5*(A[1]+5*A[2]);
487 B[1] = A[1] + 2*A[2]*5;
491 double y5 = B[0] + 5.5*(B[1]+5.5*B[2]);
492 for (
int ievt=0;ievt <10000; ievt++) {
496 for (
double x=0;x<nPts;x++) {
497 double y = A[0]+x*(A[1]+x*A[2]);
498 double dy = gRandom->Gaus(0,0.1);
499 pf.Add(x,y+dy,0.1*0.1);
501 double Xi2 = pf.Fit();
503 if (kase==1) { pf.Move(5) ;}
504 if (kase==2) { pf.FixAt(0.,A[0]);}
505 double Xi2E = pf.EvalChi2();
510 const double *c = pf.Coe();
512 double del = pf.Eval(5.5)-y5;
513 del /= sqrt(pf.Evrr(5.5));
515 for (
int i=0;i<3;i++) {
516 del = (c[i]-B[i])/sqrt(pf.GetEmx(i,i)+1e-10);
521 myCanvas->Modified();
523 while(!gSystem->ProcessEvents()){};
526 void TPoliFitter::TestCorr()
528 static TCanvas* myCanvas=0;
529 static TH1F *hh[6]={0,0,0,0,0,0};
530 static const char *hNams[]={
"C01",
"C01-",
"C02",
"C02-",
"C12",
"C12-",0};
531 if(!myCanvas) myCanvas=
new TCanvas(
"C1",
"",600,800);
533 myCanvas->Divide(1,6);
535 for (
int i=0;i<6;i++) {
536 delete hh[i]; hh[i]=
new TH1F(hNams[i],hNams[i],100,-1,1);
537 myCanvas->cd(i+1); hh[i]->Draw();
542 double A[3]={1,2,3},B[3]={1,2,3};
544 for (
int ievt=0;ievt <1000; ievt++) {
547 for (
double x=0;x<10;x++) {
548 double y = A[0]+x*(A[1]+x*A[2]);
549 double dy = gRandom->Gaus(0,0.1);
550 pf.Add(x,y+dy,0.1*0.1);
552 double Xi2 = pf.Fit();
if (Xi2){};
555 const double *c = pf.Coe();
557 for (
int i=0;i<3;i++) {
558 double deli = (c[i]-B[i]);
560 for (
int j=i+1;j<3;j++) {
561 double delj = (c[j]-B[j]);
565 hh[ih+0]->Fill(deli*delj*100);
566 hh[ih+1]->Fill((deli*delj-pf.GetEmx(i,j))*100);
571 myCanvas->Modified();
573 while(!gSystem->ProcessEvents()){};
576 void TPoliFitter::Dest(
int kase)
579 static TCanvas* myCanvas=0;
580 static TH1F *hh[5]={0,0,0,0,0};
581 static const char *hNams[]={
"Der0",
"Der1",
"Der2",0};
582 if(!myCanvas) myCanvas=
new TCanvas(
"C1",
"",600,800);
584 myCanvas->Divide(1,3);
586 for (
int i=0;i<3;i++) {
587 delete hh[i]; hh[i]=
new TH1F(hNams[i],hNams[i],100,-1,1);
588 myCanvas->cd(i+1); hh[i]->Draw();
593 for (
int ievt=0;ievt <1000; ievt++) {
597 for (
double x=0;x<nPts;x++) {
598 double y = A[0]+x*(A[1]+x*A[2]);
599 double dy = gRandom->Gaus(0,0.1);
600 pf.Add(x,y+dy,0.1*0.1);
602 double Xi2 = pf.Fit();
604 double coe[3],doe[3];
605 TCL::ucopy(pf.Coe(),coe,3);
607 for (
int ip=0;ip<nPts;ip++) {
610 double y=pf.GetX(ip)[1];
612 pff.GetX(ip)[1]=y+dy;
613 Xi2 = pff.Fit();
if(Xi2){};
614 for (
int ih=0;ih<3;ih++) {
615 double tst = (pff.Coe()[ih]-coe[ih])/dy;
616 tst = (tst-doe[ih])/(fabs(doe[ih])+1e-10);
622 myCanvas->Modified();
624 while(!gSystem->ProcessEvents()){};
627 void TPoliFitter::Test2()
631 TMatrixD G(nPts,nPts);
632 TVectorD Y(nPts),D(nPts),Y1(nPts),D1(nPts);
636 for (
int ix=0;ix<nPts;ix++) {
638 double y = A[0]+x*(A[1]+x*A[2]);
639 double err = 0.1*sqrt(ix+1.);
640 double dy = gRandom->Gaus(0,err);
642 pf.Add(x,y+dy,err*err);
644 double Xi2 = pf.Fit();
646 printf(
"Make Akj[][] matrix\n");
647 Xi2= pf.MakeMatrix(G);
648 double myXi2 = (Y*(G*Y));
651 printf(
"TPoliFitter::Test2() Xi2=%g myXi2=%g\n",Xi2,myXi2);
652 for (
int ix=0;ix<nPts;ix++) {
653 double sav = pf.GetX(ix)[1];
654 double delta = sav*1e-3;
655 pf.GetX(ix)[1] = sav + delta;
656 Y1[ix] = sav + delta;
658 double Xi21 = pf.Fit()*pf.Ndf();
659 pf.GetX(ix)[1] = sav;
661 double num = (Xi21-Xi2)/delta;
662 double ana = 0.5*(D[ix]+D1[ix]);
663 double dif = 200*fabs(num-ana)/(fabs(num)+fabs(ana)+1e-10);
664 printf(
"TPoliFitter::Test2() d/d[%d] \tAna=%g \tNum=%g \tDif=%g\n"
static float * trsmul(const float *g, float *gi, int n)
static float * trsinv(const float *g, float *gi, int n)
static float * trasat(const float *a, const float *s, float *r, int m, int n)