ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
testFitPerf.cxx
Go to the documentation of this file.
1 #include "TH1.h"
2 #include "TF1.h"
3 #include "TF2.h"
4 #include "TMath.h"
5 #include "TSystem.h"
6 #include "TRandom3.h"
7 #include "TTree.h"
8 #include "TROOT.h"
9 
10 #include "Fit/BinData.h"
11 #include "Fit/UnBinData.h"
12 //#include "Fit/BinPoint.h"
13 #include "Fit/Fitter.h"
14 #include "HFitInterface.h"
15 
16 #include "Math/IParamFunction.h"
17 #include "Math/WrappedTF1.h"
18 #include "Math/WrappedMultiTF1.h"
21 
22 #include "TGraphErrors.h"
23 
24 #include "TStyle.h"
25 
26 #include "TSeqCollection.h"
27 
28 #include "Math/Polynomial.h"
29 #include "Math/DistFunc.h"
30 
31 #include <string>
32 #include <iostream>
33 
34 #include "TStopwatch.h"
35 
36 #include "TVirtualFitter.h"
37 // #include "TFitterFumili.h"
38 // #include "TFumili.h"
39 
40 #include "GaussFunction.h"
41 
42 // #include "RooDataHist.h"
43 // #include "RooDataSet.h"
44 // #include "RooRealVar.h"
45 // #include "RooGaussian.h"
46 // #include "RooMinuit.h"
47 // #include "RooChi2Var.h"
48 // #include "RooGlobalFunc.h"
49 // #include "RooFitResult.h"
50 // #include "RooProdPdf.h"
51 
52 #include <cassert>
53 
54 #include "MinimizerTypes.h"
55 
56 #ifdef USE_VC
57 #include "Vc/Vc"
58 //#include "Vc/Allocator"
59 //Vc_DECLARE_ALLOCATOR(Vc::double_v)
60 #endif
61 
62 //#define USE_AOS
63 
64 #ifdef USE_VDT
65 #include "vdtMath.h"
66 #endif
67 
68 //#define DEBUG
69 
70 int nfit;
71 const int N = 20;
72 double iniPar[2*N];
73 int ndimObs;
75 
76 void printData(const ROOT::Fit::UnBinData & data) {
77  for (unsigned int i = 0; i < data.Size(); ++i) {
78  std::cout << data.Coords(i)[0] << "\t";
79  }
80  std::cout << "\ndata size is " << data.Size() << std::endl;
81 }
82 
83 void printResult(int iret) {
84  std::cout << "\n************************************************************\n";
85  std::cout << "Test\t\t\t\t";
86  if (iret == 0) std::cout << "OK";
87  else std::cout << "FAILED";
88  std::cout << "\n************************************************************\n";
89 }
90 
91 bool USE_BRANCH = false;
92 ROOT::Fit::UnBinData * FillUnBinData(TTree * tree, bool copyData = true, unsigned int dim = 1 ) {
93 
94  // fill the unbin data set from a TTree
95  ROOT::Fit::UnBinData * d = 0;
96  // for the large tree
97  if (std::string(tree->GetName()) == "t2") {
98  d = new ROOT::Fit::UnBinData();
99  // large tree
100  unsigned int n = tree->GetEntries();
101 #ifdef DEBUG
102  std::cout << "number of unbin data is " << n << " of dim " << N << std::endl;
103 #endif
104  d->Initialize(n,N);
105  TBranch * bx = tree->GetBranch("x");
106  double vx[N];
107  bx->SetAddress(vx);
108  std::vector<double> m(N);
109  for (int unsigned i = 0; i < n; ++i) {
110  bx->GetEntry(i);
111  d->Add(vx);
112  for (int j = 0; j < N; ++j)
113  m[j] += vx[j];
114  }
115 
116 #ifdef DEBUG
117  std::cout << "average values of means :\n";
118  for (int j = 0; j < N; ++j)
119  std::cout << m[j]/n << " ";
120  std::cout << "\n";
121 #endif
122 
123  return d;
124  }
125  if (USE_BRANCH)
126  {
127  d = new ROOT::Fit::UnBinData();
128  unsigned int n = tree->GetEntries();
129  //std::cout << "number of unbin data is " << n << std::endl;
130 
131  if (dim == 2) {
132  d->Initialize(n,2);
133  TBranch * bx = tree->GetBranch("x");
134  TBranch * by = tree->GetBranch("y");
135  double v[2];
136  bx->SetAddress(&v[0]);
137  by->SetAddress(&v[1]);
138  for (int unsigned i = 0; i < n; ++i) {
139  bx->GetEntry(i);
140  by->GetEntry(i);
141  d->Add(v);
142  }
143  }
144  else if (dim == 1) {
145  d->Initialize(n,1);
146  TBranch * bx = tree->GetBranch("x");
147  double v[1];
148  bx->SetAddress(&v[0]);
149  for (int unsigned i = 0; i < n; ++i) {
150  bx->GetEntry(i);
151  d->Add(v);
152  }
153  }
154 
155  return d;
156 
157  //printData(d);
158  }
159  else {
160  tree->SetEstimate(tree->GetEntries());
161 
162  // use TTREE::Draw
163  if (dim == 2) {
164  tree->Draw("x:y",0,"goff"); // goff is used to turn off the graphics
165  double * x = tree->GetV1();
166  double * y = tree->GetV2();
167 
168  if (x == 0 || y == 0) {
169  USE_BRANCH= true;
170  return FillUnBinData(tree, true, dim);
171  }
172 
173  // use array pre-allocated in tree->Draw . This is faster
174  //assert(x != 0);
175  unsigned int n = tree->GetSelectedRows();
176 
177  if (copyData) {
178  d = new ROOT::Fit::UnBinData(n,2);
179  double vx[2];
180  for (int unsigned i = 0; i < n; ++i) {
181  vx[0] = x[i];
182  vx[1] = y[i];
183  d->Add(vx);
184  }
185  }
186  else // use data pointers directly
187  d = new ROOT::Fit::UnBinData(n,x,y);
188 
189  }
190  else if ( dim == 1) {
191 
192  tree->Draw("x",0,"goff"); // goff is used to turn off the graphics
193  double * x = tree->GetV1();
194 
195  if (x == 0) {
196  USE_BRANCH= true;
197  return FillUnBinData(tree, true, dim);
198  }
199  unsigned int n = tree->GetSelectedRows();
200 
201  if (copyData) {
202  d = new ROOT::Fit::UnBinData(n,1);
203  for (int unsigned i = 0; i < n; ++i) {
204  d->Add(x[i]);
205  }
206  }
207  else
208  d = new ROOT::Fit::UnBinData(n,x);
209  }
210  return d;
211  }
212 
213  //std::copy(x,x+n, d.begin() );
214  return 0;
215 }
216 
217 
218 
219 
220 // print the data
221 template <class T>
222 void printData(const T & data) {
223  for (typename T::const_iterator itr = data.begin(); itr != data.end(); ++itr) {
224  std::cout << itr->Coords()[0] << " " << itr->Value() << " " << itr->Error() << std::endl;
225  }
226  std::cout << "\ndata size is " << data.Size() << std::endl;
227 }
228 
229 
230 // new likelihood function for unbinned data
231 using namespace ROOT::Fit;
232 
233 template <class F>
234 struct VecNLL {
235 
236  VecNLL( ROOT::Fit::UnBinData & data, F & f) :
237  fData(&data), fFunc(f)
238  { } //GetData(); }
239 
240  // void GetData() {
241 
242  // const UnBinData & data = *fData;
243  // //const ROOT::Math::IParamMultiFunction & func = *fFunc; //fNLL.ModelFunction();
244 
245  // unsigned int n = data.Size();
246 
247  // fX = std::vector<T>(n);
248  // fY = std::vector<T>(n);
249  // for (int i = 0; i<n; i++) {
250  // fX[i] = *(data.Coords(i));
251  // fY[i] = *(data.Coords(i)+1);
252  // }
253 
254  // }
255 
256 
257  // re-implement likelihood evaluation
258  double operator() (const double * p) const {
259 
260  const UnBinData & data = *fData;
261  //const ROOT::Math::IParamMultiFunction & func = *fFunc; //fNLL.ModelFunction();
262 
263 
264  unsigned int n = data.Size();
265 
266 #ifdef DEBUG
267  std::cout << "\n\nFit data size = " << n << std::endl;
268  std::cout << "func pointer is " << typeid(func).name() << std::endl;
269 #endif
270 
271  //unsigned int nRejected = 0;
272 
273 
274 #ifndef USE_VC
275 #if !defined(USE_VDT) && !defined(USE_AOS)
276  double logl = 0;
277  for (unsigned int i = 0; i < n; i++) {
278 
279  const double * x = data.Coords(i);
280 
281  double fval = fFunc(x,p);
282  //double logval = ROOT::Math::Util::EvalLog( fval);
283  double logval = std::log( fval);
284 
285  logl += logval;
286 
287  // if (i < 4) {
288  // std::cout << x[0] << std::endl;
289  // std::cout << logval << std::endl;
290  // std::cout << logl << std::endl << std::endl;
291  // }
292 
293  }
294 
295  // std::cout << "Scal: par = " << p[0] << " " << p[1] << " log l = " << logl << std::endl;
296  return - logl;
297 #else
298  // VDT implementation
299  double logl = 0;
300  std::vector<double> fval(n);
301  std::vector<double> logval(n);
302 
303 #ifndef USE_AOS
304  for (unsigned int i = 0; i < n; i++) {
305 
306  const double * x = data.Coords(i);
307 
308  fval[i] = fFunc(x,p);
309  }
310 #else
311  //std::vector<double> x(n * data.NDim() );
312  const double * x = data.Coords(0);
313 
314  fFunc(n, data.NDim(), x, p, &fval[0] );
315 
316 #endif
317 
318  // for (unsigned int i = 0; i < n; i++) {
319 
320 
321  //double logval = ROOT::Math::Util::EvalLog( fval);
322 #ifdef USE_VDT
323  vdt::fast_logv(n, &fval[0], &logval[0]);
324 #endif
325 
326  for (unsigned int i = 0; i < n; i++) {
327 
328 #ifndef USE_VDT
329  logval[i] = std::log( fval[i]);
330 #endif
331 
332  logl += logval[i];
333  }
334 
335 
336  // if (i < 4) {
337  // std::cout << x[0] << std::endl;
338  // std::cout << logval << std::endl;
339  // std::cout << logl << std::endl << std::endl;
340  // }
341 
342 
343  // std::cout << "Scal: par = " << p[0] << " " << p[1] << " log l = " << logl << std::endl;
344  return - logl;
345 
346 #endif
347 #else
348  // VC implementation
349 
350  Vc::double_v logl = 0.0;
351 
352  std::vector <Vc::double_v> x(ndimObs);
353 
354  for (unsigned int i = 0; i < n; i +=Vc::double_v::Size) {
355  for (unsigned int j = 0; j < data.NDim(); ++j) {
356  for (int k = 0; k< Vc::double_v::Size; ++k) {
357  int ipoint = i + k;
358  x[j][k] = *(data.Coords(ipoint)+j);
359  }
360  }
361 
362  Vc::double_v logval = std::log( fFunc ( &x[0], p ) );
363  logl += logval;
364 
365  // if (i == 0) {
366  // std::cout << x[0] << std::endl;
367  // std::cout << logval << std::endl;
368  // std::cout << logl << std::endl << std::endl;;
369  // }
370  }
371  double ret = 0;
372  for (int k = 0; k< Vc::double_v::Size; ++k) {
373  ret += logl[k];
374  }
375 
376 // std::cout << "Vc:: par = " << p[0] << " " << p[1] << " log l = " << ret << std::endl;
377 
378  return -ret;
379 #endif
380 
381  }
382 
383  // members
384 
385  ROOT::Fit::UnBinData * fData;
386  F fFunc;
387 
388 };
389 
390 
391 
392 // fitting using new fitter
394 template <class MinType, class T>
395 int DoBinFit(T * hist, Func & func, bool debug = false, bool useGrad = false) {
396 
397  //std::cout << "Fit histogram " << std::endl;
398 
400  ROOT::Fit::FillData(d,hist);
401 
402  //printData(d);
403 
404  // create the fitter
405 
406  ROOT::Fit::Fitter fitter;
407  fitter.Config().SetMinimizer(MinType::name().c_str(),MinType::name2().c_str());
408 
409  if (debug)
410  fitter.Config().MinimizerOptions().SetPrintLevel(3);
411 
412 
413  // create the function
414  if (!useGrad) {
415 
416  // use simply TF1 wrapper
417  //ROOT::Math::WrappedMultiTF1 f(*func);
418  //ROOT::Math::WrappedTF1 f(*func);
419  fitter.SetFunction(func);
420 
421  } else { // only for gaus fits
422  // use function gradient
423 #ifdef USE_MATHMORE_FUNC
424  // use mathmore for polynomial
425  ROOT::Math::Polynomial pol(2);
426  assert(pol.NPar() == func->GetNpar());
427  pol.SetParameters(func->GetParameters() );
428  ROOT::Math::WrappedParamFunction<ROOT::Math::Polynomial> f(pol,1,func->GetParameters(),func->GetParameters()+func->GetNpar() );
429 #endif
431  f.SetParameters(func.Parameters());
432  fitter.SetFunction(f);
433  }
434 
435 
436  bool ret = fitter.Fit(d);
437  if (!ret) {
438  std::cout << " Fit Failed " << std::endl;
439  return -1;
440  }
441  if (debug)
442  fitter.Result().Print(std::cout);
443  return 0;
444 }
445 
446 // unbin fit
447 template <class MinType, class T>
448 int DoUnBinFit(T * tree, Func & func, bool debug = false, bool copyData = false ) {
449 
450  ROOT::Fit::UnBinData * d = FillUnBinData(tree, copyData, func.NDim() );
451  // need to have done Tree->Draw() before fit
452  //FillUnBinData(d,tree);
453 
454  //std::cout << "data size type and size is " << typeid(*d).name() << " " << d->Size() << std::endl;
455  if (debug) {
456  if (copyData)
457  std::cout << "\tcopy data in FitData\n";
458  else
459  std::cout << "\tre-use original data \n";
460  }
461 
462 
463  //printData(d);
464 
465  // create the fitter
466  //std::cout << "Fit parameter 2 " << f.Parameters()[2] << std::endl;
467 
468  ROOT::Fit::Fitter fitter;
469  fitter.Config().SetMinimizer(MinType::name().c_str(),MinType::name2().c_str());
470 
471  if (debug)
472  fitter.Config().MinimizerOptions().SetPrintLevel(3);
473 
474  // set tolerance 1 for tree to be same as in TTTreePlayer::UnBinFIt
475  fitter.Config().MinimizerOptions().SetTolerance(1);
476 
477 
478  // create the function
479 
480  // need to fix param 0 , normalization in the unbinned fits
481  //fitter.Config().ParSettings(0).Fix();
482 
483  fitter.SetFunction(func);
484  bool ret = fitter.Fit(*d);
485 
486  if (!ret) {
487  std::cout << " Fit Failed " << std::endl;
488  return -1;
489  }
490  if (debug)
491  fitter.Result().Print(std::cout);
492 
493  delete d;
494 
495  return 0;
496 
497 }
498 
499 
500 template <class MinType, class T, class VFunc>
501 int DoUnBinFitVec(T * tree, VFunc & func, int ndim, int npar, const double * p0, bool debug = false, bool copyData = false ) {
502 
503  ROOT::Fit::UnBinData * d = FillUnBinData(tree, copyData, ndim );
504  // need to have done Tree->Draw() before fit
505  //FillUnBinData(d,tree);
506 
507  //std::cout << "data size type and size is " << typeid(*d).name() << " " << d->Size() << std::endl;
508  if (debug) {
509  if (copyData)
510  std::cout << "\tcopy data in FitData\n";
511  else
512  std::cout << "\tre-use original data \n";
513  }
514 
515 
516  //printData(d);
517 
518  // create the fitter
519  //std::cout << "Fit parameter 2 " << f.Parameters()[2] << std::endl;
520 
521  ROOT::Fit::Fitter fitter;
522  fitter.Config().SetMinimizer(MinType::name().c_str(),MinType::name2().c_str());
523 
524  if (debug)
525  fitter.Config().MinimizerOptions().SetPrintLevel(3);
526 
527  // set tolerance 1 for tree to be same as in TTTreePlayer::UnBinFIt
528  fitter.Config().MinimizerOptions().SetTolerance(1);
529 
530 
531  // create the function
532 
533  // need to fix param 0 , normalization in the unbinned fits
534  //fitter.Config().ParSettings(0).Fix();
535 
536  VecNLL<VFunc> fcn(*d, func);
537  bool ret = fitter.FitFCN(npar, fcn, p0);
538 
539  if (!ret) {
540  std::cout << " Fit Failed " << std::endl;
541  return -1;
542  }
543  if (debug)
544  fitter.Result().Print(std::cout);
545 
546  std::cout << "use vec nll : nll = " << fitter.Result().MinFcnValue() << std::endl;
547 
548 
549  delete d;
550 
551  return 0;
552 
553 }
554 
555 
556 template <class MinType>
557 int DoFit(TTree * tree, Func & func, bool debug = false, bool copyData = false ) {
558  return DoUnBinFit<MinType, TTree>(tree, func, debug, copyData);
559 }
560 
561 template <class MinType>
562 int DoFit(TH1 * h1, Func & func, bool debug = false, bool copyData = false ) {
563  return DoBinFit<MinType, TH1>(h1, func, debug, copyData);
564 }
565 template <class MinType>
566 int DoFit(TGraph * gr, Func & func, bool debug = false, bool copyData = false ) {
567  return DoBinFit<MinType, TGraph>(gr, func, debug, copyData);
568 }
569 
570 template <class MinType, class F>
571 int DoFitVec(TTree * tree, F & func, int n1, int n2, const double * p, bool debug = false, bool copyData = false ) {
572  return DoUnBinFitVec<MinType, TTree>(tree, func, n1,n2,p,debug, copyData);
573 }
574 
575 template <class MinType, class F>
576 int DoFitVec(TH1 * h1, F & func, int, int , const double *, bool debug = false, bool copyData = false ) {
577  return DoBinFit<MinType, TH1>(h1, func, debug, copyData);
578 }
579 template <class MinType, class F>
580 int DoFitVec(TGraph * gr, F & func, int, int , const double *, bool debug = false, bool copyData = false ) {
581  return DoBinFit<MinType, TGraph>(gr, func, debug, copyData);
582 }
583 
584 
585 template <class MinType, class FitObj, class FuncObj>
586 int FitUsingNewFitter(FitObj * fitobj, FuncObj func, bool useGrad=false) {
587 
588  std::cout << "\n************************************************************\n";
589  std::cout << "\tFit using new Fit::Fitter " << typeid(*fitobj).name() << std::endl;
590  std::cout << "\tMinimizer is " << MinType::name() << " " << MinType::name2() << " func dim = " << ndimObs << std::endl;
591 
592  int iret = 0;
593  TStopwatch w; w.Start();
594 
595 #define USE_VECNLL
596 #ifndef USE_VECNLL
597 
598 #ifdef DEBUG
599  // std::cout << "initial Parameters " << iniPar << " " << *iniPar << " " << *(iniPar+1) << std::endl;
600  func.SetParameters(iniPar);
601  iret |= DoFit<MinType>(fitobj,func,true, useGrad);
602  if (iret != 0) {
603  std::cout << "Fit failed " << std::endl;
604  }
605 
606 #else
607  for (int i = 0; i < nfit; ++i) {
608  func.SetParameters(iniPar);
609  iret = DoFit<MinType>(fitobj,func, false, useGrad);
610  if (iret != 0) {
611  std::cout << "Fit failed " << std::endl;
612  break;
613  }
614  }
615 #endif
616 
617 #else
618 
619  // use vectorized function
620 
621  for (int i = 0; i < nfit; ++i) {
622  iret = DoFitVec<MinType>(fitobj,func, ndimObs, ndimPars, iniPar, false, useGrad);
623  if (iret != 0) {
624  std::cout << "Fit failed " << std::endl;
625  break;
626  }
627  }
628 
629 #endif
630 
631  w.Stop();
632  std::cout << "\nTime: \t" << w.RealTime() << " , " << w.CpuTime() << std::endl;
633  std::cout << "\n************************************************************\n";
634 
635  return iret;
636 }
637 
638 
639 
640 double poly2(const double *x, const double *p) {
641  return p[0] + (p[1]+p[2]*x[0] ) * x[0];
642 }
643 
644 int testPolyFit() {
645 
646  int iret = 0;
647 
648 
649  std::cout << "\n\n************************************************************\n";
650  std::cout << "\t POLYNOMIAL FIT\n";
651  std::cout << "************************************************************\n";
652 
653  std::string fname("pol2");
654  //TF1 * func = (TF1*)gROOT->GetFunction(fname.c_str());
655  TF1 * f1 = new TF1("pol2",fname.c_str(),-5,5.);
656 
657  f1->SetParameter(0,1);
658  f1->SetParameter(1,0.0);
659  f1->SetParameter(2,1.0);
660 
661 
662  // fill an histogram
663  TH1D * h1 = new TH1D("h1","h1",20,-5.,5.);
664 // h1->FillRandom(fname.c_str(),100);
665  for (int i = 0; i <1000; ++i)
666  h1->Fill( f1->GetRandom() );
667 
668  //h1->Print();
669  //h1->Draw();
670  iniPar[0] = 2.; iniPar[1] = 2.; iniPar[2] = 2.;
671 
672 
673  // dummy for testing
674  //iret |= FitUsingNewFitter<DUMMY>(h1,f1);
675 
676  // use simply TF1 wrapper
677  //ROOT::Math::WrappedMultiTF1 f2(*f1);
678  ROOT::Math::WrappedParamFunction<> f2(&poly2,1,iniPar,iniPar+3);
679 
680 
681  // if Minuit2 is later than TMinuit on Interl is much slower , why ??
682  iret |= FitUsingNewFitter<MINUIT2>(h1,f2);
683  iret |= FitUsingNewFitter<TMINUIT>(h1,f2);
684 
685  // test with linear fitter
686  // for this test need to pass a multi-dim function
687  ROOT::Math::WrappedTF1 wf(*f1);
689  iret |= FitUsingNewFitter<LINEAR>(h1,lfunc,true);
690 
691  // test with a graph
692 
693  gStyle->SetErrorX(0.); // to seto zero error on X
694  TGraphErrors * gr = new TGraphErrors(h1);
695 
696  iret |= FitUsingNewFitter<MINUIT2>(gr,f2);
697 
698 
699  std::cout << "\n-----> test now TGraphErrors with errors in X coordinates\n\n";
700  // try with error in X
701  gStyle->SetErrorX(0.5); // to set zero error on X
702  TGraphErrors * gr2 = new TGraphErrors(h1);
703 
704  iret |= FitUsingNewFitter<MINUIT2>(gr2,f2);
705 
706  printResult(iret);
707 
708  return iret;
709 }
710 
711 template <class T>
712 struct GausFunctions {
713  typedef T value_type;
714 
715  static T gaussian(const T *x, const double *p) {
716  //return p[0]*TMath::Gaus(x[0],p[1],p[2]);
717  T tmp = (x[0]-p[1])/p[2];
718  return p[0] * std::exp(-tmp*tmp/2);
719 }
720 
721  static T gausnorm(const T *x, const double *p) {
722  //return p[0]*TMath::Gaus(x[0],p[1],p[2]);
723  T invsig = 1./p[1];
724  T tmp = (x[0]-p[0]) * invsig;
725  const T sqrt_2pi = 1./std::sqrt(2.* 3.14159 );
726  return std::exp(-0.5 * tmp*tmp ) * sqrt_2pi * invsig;
727 }
728  static T gausnorm2D(const T *x, const double *p) {
729  //return p[0]*TMath::Gaus(x[0],p[1],p[2]);
730  return gausnorm(x,p)*gausnorm(x+1,p+2);
731  }
732  static T gausnormN(const T *x, const double *p) {
733  //return p[0]*TMath::Gaus(x[0],p[1],p[2]);
734  T f = 1.0;
735  for (int i = 0; i < N; ++i)
736  f *= gausnorm(x+i,p+2*i);
737 
738  return f;
739  }
740 
741  static void gausnorm_v(unsigned int n, unsigned int stride, const double *x, const double *p, double * res) {
742 
743  double invsig = 1./p[1];
744  std::vector<double> arg(n);
745  for (unsigned int i = 0; i< n; ++i){
746  double tmp = (x[i*stride]-p[0]) * invsig;
747  arg[i] = -0.5 *tmp*tmp;
748  }
749  const double sqrt_2pi = 1./std::sqrt(2.* 3.14159 );
750 #ifdef USE_VDT
751  vdt::fast_expv(n,&arg[0],res);
752  for (unsigned int i = 0; i< n; ++i){
753 #else
754  for (unsigned int i = 0; i< n; ++i){
755  res[i] = std::exp(arg[i]);
756 #endif
757  res[i] *= sqrt_2pi * invsig;
758  }
759 
760  }
761 
762  static void gausnorm2D_v(unsigned int n, unsigned int stride,const double *x, const double *p, double * res) {
763  std::vector<double> tmp(n);
764  gausnorm_v(n,2,x,p,&tmp[0]);
765  gausnorm_v(n,2,x+1,p+2,res);
766  for (unsigned int i = 0; i< n; ++i){
767  res[i] *= tmp[i];
768  }
769  }
770  static void gausnormN_v(unsigned int n, unsigned int stride,const double *x, const double *p, double * res) {
771  std::vector<double> tmp(n);
772  gausnorm_v(n,stride,x,p,res);
773  for (int j = 1; j < stride; ++j) {
774  gausnorm_v(n,stride,x+j,p+2*j,&tmp[0]);
775  for (unsigned int i = 0; i< n; ++i){
776  res[i] *= tmp[i];
777  }
778  }
779  }
780 
781 };
782 
783 double gaussian (const double *x, const double *p) {
785 }
786 double gausnorm (const double *x, const double *p) {
788 }
789 double gausnorm2D (const double *x, const double *p) {
791 }
792 double gausnormN (const double *x, const double *p) {
794 }
795 
796 int testGausFit() {
797 
798  int iret = 0;
799 
800  std::cout << "\n\n************************************************************\n";
801  std::cout << "\t GAUSSIAN FIT\n";
802  std::cout << "************************************************************\n";
803 
804 
805 
806  //std::string fname = std::string("gaus");
807  //TF1 * func = (TF1*)gROOT->GetFunction(fname.c_str());
808  //TF1 * f1 = new TF1("gaus",fname.c_str(),-5,5.);
809  //TF1 * f1 = new TF1("gaussian",gaussian,-5,5.,3);
810  //f2->SetParameters(0,1,1);
811 
812  // fill an histogram
813  int nbin = 10000;
814  TH1D * h2 = new TH1D("h2","h2",nbin,-5.,5.);
815 // h1->FillRandom(fname.c_str(),100);
816  for (int i = 0; i < 10000000; ++i)
817  h2->Fill( gRandom->Gaus(0,10) );
818 
819  iniPar[0] = 100.; iniPar[1] = 2.; iniPar[2] = 2.;
820 
821 
822  // use simply TF1 wrapper
823  //ROOT::Math::WrappedMultiTF1 f2(*f1);
824  ROOT::Math::WrappedParamFunction<> f2(&gaussian,1,iniPar,iniPar+3);
825 
826 
827  iret |= FitUsingNewFitter<MINUIT2>(h2,f2);
828  iret |= FitUsingNewFitter<TMINUIT>(h2,f2);
829 
830 // iret |= FitUsingNewFitter<GSL_PR>(h2,f2);
831 
832 
833 
834 
835  iret |= FitUsingNewFitter<GSL_FR>(h2,f2);
836  iret |= FitUsingNewFitter<GSL_PR>(h2,f2);
837  iret |= FitUsingNewFitter<GSL_BFGS>(h2,f2);
838  iret |= FitUsingNewFitter<GSL_BFGS2>(h2,f2);
839 
840 
841  // test also fitting a TGraphErrors with histogram data
842  gStyle->SetErrorX(0.); // to seto zero error on X
843  TGraphErrors * gr = new TGraphErrors(h2);
844 
845 
846  iret |= FitUsingNewFitter<MINUIT2>(gr,f2);
847 
848  // try with error in X
849  gStyle->SetErrorX(0.5); // to seto zero error on X
850  TGraphErrors * gr2 = new TGraphErrors(h2);
851 
852  iret |= FitUsingNewFitter<MINUIT2>(gr2,f2);
853 
854 
855 
856 //#ifdef LATER
857  // test using grad function
858  std::cout << "\n\nTest Using pre-calculated gradients\n\n";
859  bool useGrad=true;
860  iret |= FitUsingNewFitter<MINUIT2>(h2,f2,useGrad);
861  iret |= FitUsingNewFitter<TMINUIT>(h2,f2,useGrad);
862  iret |= FitUsingNewFitter<GSL_FR>(h2,f2,useGrad);
863  iret |= FitUsingNewFitter<GSL_PR>(h2,f2,useGrad);
864  iret |= FitUsingNewFitter<GSL_BFGS>(h2,f2,useGrad);
865  iret |= FitUsingNewFitter<GSL_BFGS2>(h2,f2,useGrad);
866 
867 
868  // test LS algorithm
869  std::cout << "\n\nTest Least Square algorithms\n\n";
870  iret |= FitUsingNewFitter<GSL_NLS>(h2,f2);
871  iret |= FitUsingNewFitter<FUMILI2>(h2,f2);
872  iret |= FitUsingNewFitter<TFUMILI>(h2,f2);
873 
874 // iret |= FitUsingTFit<TH1,FUMILI2>(h2,f1);
875 // iret |= FitUsingTFit<TH1,TFUMILI>(h2,f1);
876 //#endif
877 
878  //iret |= FitUsingRooFit(h2,f1);
879 
880  printResult(iret);
881 
882  return iret;
883 }
884 
885 int testTreeFit() {
886 
887  std::cout << "\n\n************************************************************\n";
888  std::cout << "\t UNBINNED TREE (GAUSSIAN) FIT\n";
889  std::cout << "************************************************************\n";
890 
891 
892  TTree t1("t1","a simple Tree with simple variables");
893  double x, y;
894  Int_t ev;
895  t1.Branch("x",&x,"x/D");
896  t1.Branch("y",&y,"y/D");
897 // t1.Branch("pz",&pz,"pz/F");
898 // t1.Branch("random",&random,"random/D");
899  t1.Branch("ev",&ev,"ev/I");
900 
901  //fill the tree
902  int nrows = 10000;
903 #ifdef TREE_FIT2D
904  nrows = 10000;
905 #endif
906  for (Int_t i=0;i<nrows;i++) {
907  gRandom->Rannor(x,y);
908  x *= 2; x += 1.;
909  y *= 3; y -= 2;
910 
911  ev = i;
912  t1.Fill();
913 
914  }
915  //t1.Draw("x"); // to select fit variable
916 
917  //TF1 * f1 = new TF1("gausnorm", gausnorm, -10,10, 2);
918  //TF2 * f2 = new TF2("gausnorm2D", gausnorm2D, -10,10, -10,10, 4);
919 
920  ROOT::Math::WrappedParamFunction<> wf1(&gausnorm,1,iniPar,iniPar+2);
921  ROOT::Math::WrappedParamFunction<> wf2(&gausnorm2D,2,iniPar,iniPar+4);
922 
923 
924  iniPar[0] = 0;
925  iniPar[1] = 1;
926  iniPar[2] = 0;
927  iniPar[3] = 1;
928 
929  // use simply TF1 wrapper
930  //ROOT::Math::WrappedMultiTF1 f2(*f1);
931 
932  int iret = 0;
933 
934  // fit 1D first
935 
936 
937 
938  // iret |= FitUsingNewFitter<MINUIT2>(&t1,wf1,false); // not copying the data
939  // iret |= FitUsingNewFitter<TMINUIT>(&t1,wf1,false); // not copying the data
940 
941 
942  ndimObs = wf1.NDim();
943  ndimPars = wf1.NPar();
944 
945 #ifdef USE_AOS
946  iret |= FitUsingNewFitter<MINUIT2>(&t1,&GausFunctions<double>::gausnorm_v,true); // copying the data
947 #else
948 
949 
950 #ifndef USE_VC
951  iret |= FitUsingNewFitter<MINUIT2>(&t1,wf1,true); // copying the data
952  iret |= FitUsingNewFitter<MINUIT2>(&t1,&GausFunctions<double>::gausnorm,true); // copying the data
953 #else
954  iret |= FitUsingNewFitter<MINUIT2>(&t1,&GausFunctions<Vc::double_v>::gausnorm,true); // copying the data
955 #endif
956 // iret |= FitUsingNewFitter<TMINUIT>(&t1,wf1,true); // copying the data
957 
958 #endif
959  // fit 2D
960 
961  ndimObs = wf2.NDim();
962  ndimPars = wf2.NPar();
963 
964 
965 #ifndef USE_AOS
966 #ifndef USE_VC
967  iret |= FitUsingNewFitter<MINUIT2>(&t1,wf2, true);
968  iret |= FitUsingNewFitter<MINUIT2>(&t1,&GausFunctions<double>::gausnorm2D, true);
969 #else
970  iret |= FitUsingNewFitter<MINUIT2>(&t1,&GausFunctions<Vc::double_v>::gausnorm2D, true);
971 #endif
972 
973 #else
974  iret |= FitUsingNewFitter<MINUIT2>(&t1,&GausFunctions<double>::gausnorm2D_v,true); // copying the data
975 #endif
976 
977  //iret |= FitUsingNewFitter<MINUIT2>(&t1,wf2, false);
978 
979 
980 
981 
982  printResult(iret);
983  return iret;
984 
985 }
986 
987 int testLargeTreeFit(int nevt = 1000) {
988 
989 
990 
991  std::cout << "\n\n************************************************************\n";
992  std::cout << "\t UNBINNED TREE (GAUSSIAN MULTI-DIM) FIT\n";
993  std::cout << "************************************************************\n";
994 
995  TTree t1("t2","a large Tree with simple variables");
996  double x[N];
997  Int_t ev;
998  t1.Branch("x",x,"x[20]/D");
999  t1.Branch("ev",&ev,"ev/I");
1000 
1001  //fill the tree
1002  TRandom3 r;
1003  for (Int_t i=0;i<nevt;i++) {
1004  for (int j = 0; j < N; ++j) {
1005  double mu = double(j)/10.;
1006  double s = 1.0 + double(j)/10.;
1007  x[j] = r.Gaus(mu,s);
1008  }
1009 
1010  ev = i;
1011  t1.Fill();
1012 
1013  }
1014  //t1.Draw("x"); // to select fit variable
1015 
1016 
1017  for (int i = 0; i <N; ++i) {
1018  iniPar[2*i] = 0;
1019  iniPar[2*i+1] = 1;
1020  }
1021 
1022  // use simply TF1 wrapper
1023  //ROOT::Math::WrappedMultiTF1 f2(*f1);
1024 
1026 
1027  ndimObs = f2.NDim();
1028  ndimPars = f2.NPar();
1029 
1030 
1031  int iret = 0;
1032 
1033 
1034 #ifndef USE_VC
1035 
1036 #ifndef USE_AOS
1037  iret |= FitUsingNewFitter<MINUIT2>(&t1,f2);
1038  iret |= FitUsingNewFitter<MINUIT2>(&t1,&GausFunctions<double>::gausnormN,true);
1039 #else
1040  iret |= FitUsingNewFitter<MINUIT2>(&t1,&GausFunctions<double>::gausnormN_v,true);
1041 #endif
1042  // iret |= FitUsingNewFitter<GSL_BFGS2>(&t1,f2);
1043 #else
1044  iret |= FitUsingNewFitter<MINUIT2>(&t1,&GausFunctions<Vc::double_v>::gausnormN,true);
1045 #endif
1046 
1047 
1048  printResult(iret);
1049  return iret;
1050 
1051 
1052 }
1053 
1054 
1056 
1057  int iret = 0;
1058 
1059 
1060 
1061 
1062 #ifdef DEBUG
1063  nfit = 1;
1064 #else
1065  nfit = 10;
1066 #endif
1067  iret |= testTreeFit();
1068 
1069  nfit = 1;
1070  iret |= testLargeTreeFit(2000);
1071 
1072 
1073 #ifdef LATER
1074 
1075 #ifndef DEBUG
1076  nfit = 10;
1077 #endif
1078  iret |= testGausFit();
1079 
1080 
1081 
1082 #ifndef DEBUG
1083  nfit = 1000;
1084 #endif
1085  iret |= testPolyFit();
1086 
1087 
1088 #endif
1089 
1090 
1091  //return iret;
1092 
1093 
1094 
1095  if (iret != 0)
1096  std::cerr << "testFitPerf :\t FAILED " << std::endl;
1097  else
1098  std::cerr << "testFitPerf :\t OK " << std::endl;
1099  return iret;
1100 }
1101 
1102 int main() {
1103  return testFitPerf();
1104 }
1105 
const FitConfig & Config() const
access to the fit configuration (const method)
Definition: Fitter.h:382
virtual const double * Parameters() const =0
Access the parameter values.
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition: TH1.cxx:3159
const int N
Definition: testFitPerf.cxx:60
unsigned int NDim() const
Retrieve the dimension of the function.
virtual void Rannor(Float_t &a, Float_t &b)
Return 2 numbers distributed following a gaussian with mean=0 and sigma=1.
Definition: TRandom.cxx:460
void SetPrintLevel(int level)
set print level
Random number generator class based on M.
Definition: TRandom3.h:29
Double_t RealTime()
Stop the stopwatch (if it is running) and return the realtime (in seconds) passed between the start a...
Definition: TStopwatch.cxx:108
virtual void SetAddress(void *add)
Set address of this branch.
Definition: TBranch.cxx:2049
void fcn(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag)
Definition: Ifit.C:26
void Start(Bool_t reset=kTRUE)
Start the stopwatch.
Definition: TStopwatch.cxx:56
void SetTolerance(double tol)
set the tolerance
virtual Double_t Gaus(Double_t mean=0, Double_t sigma=1)
Samples a random number from the standard Normal (Gaussian) Distribution with the given mean and sigm...
Definition: TRandom.cxx:235
const char * Size
Definition: TXMLSetup.cxx:56
#define assert(cond)
Definition: unittest.h:542
R__EXTERN TStyle * gStyle
Definition: TStyle.h:423
virtual Int_t Fill()
Fill all branches.
Definition: TTree.cxx:4306
tuple f2
Definition: surfaces.py:24
int ndimObs
Definition: testFitPerf.cxx:73
bool FitFCN(unsigned int npar, Function &fcn, const double *params=0, unsigned int dataSize=0, bool chi2fit=false)
Fit using the a generic FCN function as a C++ callable object implementing double () (const double *)...
Definition: Fitter.h:538
unsigned int NDim() const
return coordinate data dimension
Definition: UnBinData.h:321
double gausnormN(const double *x, const double *p)
Class to Wrap a ROOT Function class (like TF1) in a IParamFunction interface of one dimensions to be ...
Definition: WrappedTF1.h:41
Double_t CpuTime()
Stop the stopwatch (if it is running) and return the cputime (in seconds) passed between the start an...
Definition: TStopwatch.cxx:123
Class describing the unbinned data sets (just x coordinates values) of any dimensions.
Definition: UnBinData.h:47
int Int_t
Definition: RtypesCore.h:41
ROOT::Math::MinimizerOptions & MinimizerOptions()
access to the minimizer control parameter (non const method)
Definition: FitConfig.h:138
TLatex * t1
Definition: textangle.C:20
TFile * f
void printResult(int iret)
Definition: testFitPerf.cxx:71
TTree * T
double sqrt(double)
int DoFit(TTree *tree, Func &func, bool debug=false, bool copyData=false)
void Stop()
Stop the stopwatch.
Definition: TStopwatch.cxx:75
Double_t x[n]
Definition: legend1.C:17
virtual Long64_t GetSelectedRows()
Definition: TTree.h:432
ROOT::Math::IParamMultiFunction Func
int testPolyFit()
int d
Definition: tornado.py:11
const FitResult & Result() const
get fit result
Definition: Fitter.h:354
int ndimPars
Definition: testFitPerf.cxx:74
TH2D * h2
Definition: fit2dHist.C:45
TH1F * h1
Definition: legend1.C:5
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch with the given name in this tree or its friends.
Definition: TTree.cxx:4803
#define F(x, y, z)
bool Fit(const Data &data, const Function &func)
fit a data set using any generic model function If data set is binned a least square fit is performed...
Definition: Fitter.h:146
virtual void SetParameters(const double *p)
Set the parameter values.
void SetMinimizer(const char *type, const char *algo=0)
set minimizer type
Definition: FitConfig.h:152
ROOT::Fit::UnBinData * FillUnBinData(TTree *tree, bool copyData=true, unsigned int dim=1)
Definition: testFitPerf.cxx:80
void FillData(BinData &dv, const TH1 *hist, TF1 *func=0)
fill the data vector from a TH1.
virtual void SetEstimate(Long64_t nentries=1000000)
Set number of entries to estimate variable limits.
Definition: TTree.cxx:8205
ROOT::R::TRInterface & r
Definition: Object.C:4
IParamFunction interface (abstract class) describing multi-dimensional parameteric functions It is a ...
SVector< double, 2 > v
Definition: Dict.h:5
virtual Double_t * GetV2()
Definition: TTree.h:456
VECTOR_NAMESPACE::double_v double_v
Definition: vector.h:80
double gausnorm2D(const double *x, const double *p)
double gaussian(const double *x, const double *p)
int FitUsingNewFitter(FitObj *fitobj, Func &func, bool useGrad=false)
Fitter class, entry point for performing all type of fits.
Definition: Fitter.h:94
virtual unsigned int NDim() const =0
Retrieve the dimension of the function.
TMarker * m
Definition: textangle.C:8
tuple w
Definition: qtexample.py:51
virtual Int_t GetEntry(Long64_t entry=0, Int_t getall=0)
Read all leaves of entry and return total number of bytes read.
Definition: TBranch.cxx:1199
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
int testLargeTreeFit(int nevt=1000)
int nfit
Definition: testFitPerf.cxx:59
Class describing the binned data sets : vectors of x coordinates, y values and optionally error on y ...
Definition: BinData.h:61
int DoBinFit(T *hist, Func &func, bool debug=false, bool useGrad=false)
int main()
R__EXTERN TRandom * gRandom
Definition: TRandom.h:62
1-D histogram with a double per channel (see TH1 documentation)}
Definition: TH1.h:613
void SetFunction(const IModelFunction &func, bool useGradient=false)
Set the fitted function (model function) from a parametric function interface.
Definition: Fitter.cxx:104
Parametric Function class describing polynomials of order n.
Definition: Polynomial.h:63
TGraphErrors * gr
Definition: legend1.C:25
int DoFitVec(TTree *tree, F &func, int n1, int n2, const double *p, bool debug=false, bool copyData=false)
unsigned int NPar() const
Return the number of parameters.
TRObject operator()(const T1 &t1) const
tuple tree
Definition: tree.py:24
void printData(const ROOT::Fit::UnBinData &data)
Definition: testFitPerf.cxx:64
const double * Coords(unsigned int ipoint) const
return pointer to coordinate data
Definition: UnBinData.h:282
TFitResultPtr Fit(FitObject *h1, TF1 *f1, Foption_t &option, const ROOT::Math::MinimizerOptions &moption, const char *goption, ROOT::Fit::DataRange &range)
Definition: HFitImpl.cxx:133
void Add(double x)
add one dim coordinate data (unweighted)
Definition: UnBinData.h:199
virtual void Draw(Option_t *opt)
Default Draw method for all objects.
Definition: TTree.h:360
Double_t y[n]
Definition: legend1.C:17
double func(double *x, double *p)
Definition: stressTF1.cxx:213
The TH1 histogram class.
Definition: TH1.h:80
int testGausFit()
void Print(std::ostream &os, bool covmat=false) const
print the result and optionaly covariance matrix and correlations
Definition: FitResult.cxx:446
#define name(a, b)
Definition: linkTestLib0.cpp:5
double MinFcnValue() const
Return value of the objective function (chi2 or likelihood) used in the fit.
Definition: FitResult.h:125
int DoUnBinFitVec(T *tree, VFunc &func, int ndim, int npar, const double *p0, bool debug=false, bool copyData=false)
virtual Int_t Branch(TCollection *list, Int_t bufsize=32000, Int_t splitlevel=99, const char *name="")
Create one branch for each element in the collection.
Definition: TTree.cxx:1623
MultiDimParamGradFunctionAdapter class to wrap a one-dimensional parametric gradient function in a mu...
double iniPar[2 *N]
Definition: testFitPerf.cxx:61
TF1 * f1
Definition: legend1.C:11
int testFitPerf()
double gausnorm(const double *x, const double *p)
bool debug
unsigned int Size() const
return number of contained points
Definition: UnBinData.h:316
virtual Long64_t GetEntries() const
Definition: TTree.h:386
A TTree object has a header with a name and a title.
Definition: TTree.h:98
int testTreeFit()
void SetParameters(const double *p)
Set the parameter values.
unsigned int NPar() const
Return the number of Parameters.
A TTree is a list of TBranches.
Definition: TBranch.h:58
double exp(double)
void SetErrorX(Float_t errorx=0.5)
Definition: TStyle.h:336
const Int_t n
Definition: legend1.C:16
virtual Double_t * GetV1()
Definition: TTree.h:454
double poly2(const double *x, const double *p)
double log(double)
bool USE_BRANCH
Definition: testFitPerf.cxx:79
WrappedParamFunction class to wrap any multi-dimensional function pbject implementing the operator()(...
int DoUnBinFit(T *tree, Func &func, bool debug=false, bool copyData=false)
void Initialize(unsigned int maxpoints, unsigned int dim=1, bool isWeighted=false)
preallocate a data set given size and dimension of the coordinates if a vector already exists with co...
Definition: UnBinData.cxx:178
Stopwatch class.
Definition: TStopwatch.h:30