Logo ROOT   6.10/09
Reference Guide
TF3.cxx
Go to the documentation of this file.
1 // @(#)root/hist:$Id$
2 // Author: Rene Brun 27/10/95
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "TROOT.h"
13 #include "TF3.h"
14 #include "TMath.h"
15 #include "TH3.h"
16 #include "TVirtualPad.h"
17 #include "TRandom.h"
18 #include "TVectorD.h"
19 #include "Riostream.h"
20 #include "TColor.h"
21 #include "TVirtualFitter.h"
22 #include "TVirtualHistPainter.h"
23 #include "TClass.h"
24 #include <cassert>
25 
27 
28 /** \class TF3
29  \ingroup Hist
30 A 3-Dim function with parameters
31 */
32 
33 ////////////////////////////////////////////////////////////////////////////////
34 /// F3 default constructor
35 
36 TF3::TF3(): TF2()
37 {
38  fNpz = 0;
39  fZmin = 0;
40  fZmax = 1;
41 }
42 
43 
44 ////////////////////////////////////////////////////////////////////////////////
45 /// F3 constructor using a formula definition
46 ///
47 /// See TFormula constructor for explanation of the formula syntax.
48 
49 TF3::TF3(const char *name,const char *formula, Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax, Double_t zmin, Double_t zmax)
50  :TF2(name,formula,xmin,xmax,ymax,ymin)
51 {
52  fZmin = zmin;
53  fZmax = zmax;
54  fNpz = 30;
55  Int_t ndim = GetNdim();
56  if (ndim != 3 && xmin < xmax) {
57  Error("TF3","function: %s/%s has %d parameters instead of 3",name,formula,ndim);
58  MakeZombie();
59  }
60 }
61 
62 ////////////////////////////////////////////////////////////////////////////////
63 /// F3 constructor using a pointer to real function
64 ///
65 /// \param[in] npar is the number of free parameters used by the function
66 ///
67 /// For example, for a 3-dim function with 3 parameters, the user function
68 /// looks like:
69 ///
70 /// Double_t fun1(Double_t *x, Double_t *par)
71 /// return par[0]*x[2] + par[1]*exp(par[2]*x[0]*x[1]);
72 ///
73 /// WARNING! A function created with this constructor cannot be Cloned.
74 
76  :TF2(name,fcn,xmin,xmax,ymin,ymax,npar,ndim)
77 {
78  fZmin = zmin;
79  fZmax = zmax;
80  fNpz = 30;
81 }
82 
83 ////////////////////////////////////////////////////////////////////////////////
84 /// F3 constructor using a pointer to real function---
85 ///
86 /// \param[in] npar is the number of free parameters used by the function
87 ///
88 /// For example, for a 3-dim function with 3 parameters, the user function
89 /// looks like:
90 ///
91 /// Double_t fun1(Double_t *x, Double_t *par)
92 /// return par[0]*x[2] + par[1]*exp(par[2]*x[0]*x[1]);
93 ///
94 /// WARNING! A function created with this constructor cannot be Cloned.
95 
96 TF3::TF3(const char *name,Double_t (*fcn)(const Double_t *, const Double_t *), Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax, Double_t zmin, Double_t zmax, Int_t npar, Int_t ndim)
97  : TF2(name,fcn,xmin,xmax,ymin,ymax,npar,ndim),
98  fZmin(zmin),
99  fZmax(zmax),
100  fNpz(30)
101 {
102 }
103 
104 ////////////////////////////////////////////////////////////////////////////////
105 /// F3 constructor using a ParamFunctor
106 ///
107 /// a functor class implementing operator() (double *, double *)
108 ///
109 /// \param[in] npar is the number of free parameters used by the function
110 ///
111 /// WARNING! A function created with this constructor cannot be Cloned.
112 
114  : TF2(name, f, xmin, xmax, ymin, ymax, npar, ndim),
115  fZmin(zmin),
116  fZmax(zmax),
117  fNpz(30)
118 {
119 }
120 
121 ////////////////////////////////////////////////////////////////////////////////
122 /// Operator =
123 
124 TF3& TF3::operator=(const TF3 &rhs)
125 {
126  if (this != &rhs) {
127  rhs.Copy(*this);
128  }
129  return *this;
130 }
131 
132 ////////////////////////////////////////////////////////////////////////////////
133 /// F3 default destructor
134 
136 {
137 }
138 
139 ////////////////////////////////////////////////////////////////////////////////
140 /// Copy constructor.
141 
142 TF3::TF3(const TF3 &f3) : TF2()
143 {
144  ((TF3&)f3).Copy(*this);
145 }
146 
147 ////////////////////////////////////////////////////////////////////////////////
148 /// Copy this F3 to a new F3
149 
150 void TF3::Copy(TObject &obj) const
151 {
152  TF2::Copy(obj);
153  ((TF3&)obj).fZmin = fZmin;
154  ((TF3&)obj).fZmax = fZmax;
155  ((TF3&)obj).fNpz = fNpz;
156 }
157 
158 ////////////////////////////////////////////////////////////////////////////////
159 /// Compute distance from point px,py to a function
160 ///
161 /// Compute the closest distance of approach from point px,py to this function.
162 /// The distance is computed in pixels units.
163 
164 
166 {
167  return TF1::DistancetoPrimitive(px, py);
168 
169 }
170 
171 ////////////////////////////////////////////////////////////////////////////////
172 /// Draw this function with its current attributes
173 
174 void TF3::Draw(Option_t *option)
175 {
176  TString opt = option;
177  opt.ToLower();
178  if (gPad && !opt.Contains("same")) gPad->Clear();
179 
180  AppendPad(option);
181 
182 }
183 
184 ////////////////////////////////////////////////////////////////////////////////
185 /// Execute action corresponding to one event
186 ///
187 /// This member function is called when a F3 is clicked with the locator
188 
189 void TF3::ExecuteEvent(Int_t event, Int_t px, Int_t py)
190 {
191  TF1::ExecuteEvent(event, px, py);
192 }
193 
194 ////////////////////////////////////////////////////////////////////////////////
195 /// Return minimum/maximum value of the function
196 ///
197 /// To find the minimum on a range, first set this range via the SetRange function
198 /// If a vector x of coordinate is passed it will be used as starting point for the minimum.
199 /// In addition on exit x will contain the coordinate values at the minimuma
200 /// If x is NULL or x is inifinity or NaN, first, a grid search is performed to find the initial estimate of the
201 /// minimum location. The range of the function is divided into fNpx and fNpy
202 /// sub-ranges. If the function is "good" (or "bad"), these values can be changed
203 /// by SetNpx and SetNpy functions
204 ///
205 /// Then, a minimization is used with starting values found by the grid search
206 /// The minimizer algorithm used (by default Minuit) can be changed by callinga
207 /// ROOT::Math::Minimizer::SetDefaultMinimizerType("..")
208 /// Other option for the minimizer can be set using the static method of the MinimizerOptions class
209 
211 {
212  //First do a grid search with step size fNpx and fNpy
213 
214  Double_t xx[3];
215  Double_t rsign = (findmax) ? -1. : 1.;
216  TF3 & function = const_cast<TF3&>(*this); // needed since EvalPar is not const
217  Double_t xxmin = 0, yymin = 0, zzmin = 0, ttmin = 0;
218  if (x == NULL || ( (x!= NULL) && ( !TMath::Finite(x[0]) || !TMath::Finite(x[1]) || !TMath::Finite(x[2]) ) ) ){
219  Double_t dx = (fXmax - fXmin)/fNpx;
220  Double_t dy = (fYmax - fYmin)/fNpy;
221  Double_t dz = (fZmax - fZmin)/fNpz;
222  xxmin = fXmin;
223  yymin = fYmin;
224  zzmin = fZmin;
225  ttmin = rsign * TMath::Infinity();
226  for (Int_t i=0; i<fNpx; i++){
227  xx[0]=fXmin + (i+0.5)*dx;
228  for (Int_t j=0; j<fNpy; j++){
229  xx[1]=fYmin+(j+0.5)*dy;
230  for (Int_t k=0; k<fNpz; k++){
231  xx[2] = fZmin+(k+0.5)*dz;
232  Double_t tt = function(xx);
233  if (rsign*tt < rsign*ttmin) {xxmin = xx[0], yymin = xx[1]; zzmin = xx[2]; ttmin=tt;}
234  }
235  }
236  }
237 
238  xxmin = TMath::Min(fXmax, xxmin);
239  yymin = TMath::Min(fYmax, yymin);
240  zzmin = TMath::Min(fZmax, zzmin);
241  }
242  else {
243  xxmin = x[0];
244  yymin = x[1];
245  zzmin = x[2];
246  zzmin = function(xx);
247  }
248  xx[0] = xxmin;
249  xx[1] = yymin;
250  xx[2] = zzmin;
251 
252  double fmin = GetMinMaxNDim(xx,findmax);
253  if (rsign*fmin < rsign*zzmin) {
254  if (x) {x[0] = xx[0]; x[1] = xx[1]; x[2] = xx[2];}
255  return fmin;
256  }
257  // here if minimization failed
258  if (x) { x[0] = xxmin; x[1] = yymin; x[2] = zzmin; }
259  return ttmin;
260 }
261 
262 ////////////////////////////////////////////////////////////////////////////////
263 /// Compute the X, Y and Z values corresponding to the minimum value of the function
264 /// on its range.
265 ///
266 /// Returns the function value at the minimum.
267 /// To find the minimum on a subrange, use the SetRange() function first.
268 ///
269 /// Method:
270 /// First, a grid search is performed to find the initial estimate of the
271 /// minimum location. The range of the function is divided
272 /// into fNpx,fNpy and fNpz sub-ranges. If the function is "good" (or "bad"),
273 /// these values can be changed by SetNpx(), SetNpy() and SetNpz() functions.
274 /// Then, Minuit minimization is used with starting values found by the grid search
275 ///
276 /// Note that this method will always do first a grid search in contrast to GetMinimum
277 
279 {
280  double xx[3] = { 0,0,0 };
281  xx[0] = TMath::QuietNaN(); // to force to do grid search in TF3::FindMinMax
282  double fmin = FindMinMax(xx, false);
283  x = xx[0]; y = xx[1]; z = xx[2];
284  return fmin;
285 
286 }
287 
288 ////////////////////////////////////////////////////////////////////////////////
289 /// Compute the X, Y and Z values corresponding to the maximum value of the function
290 /// on its range.
291 ///
292 /// Return the function value at the maximum. See TF3::GetMinimumXYZ
293 
295 {
296  double xx[3] = { 0,0,0 };
297  xx[0] = TMath::QuietNaN(); // to force to do grid search in TF3::FindMinMax
298  double fmax = FindMinMax(xx, true);
299  x = xx[0]; y = xx[1]; z = xx[2];
300  return fmax;
301 
302 }
303 
304 ////////////////////////////////////////////////////////////////////////////////
305 /// Return 3 random numbers following this function shape
306 ///
307 /// The distribution contained in this TF3 function is integrated
308 /// over the cell contents.
309 /// It is normalized to 1.
310 /// Getting the three random numbers implies:
311 /// - Generating a random number between 0 and 1 (say r1)
312 /// - Look in which cell in the normalized integral r1 corresponds to
313 /// - make a linear interpolation in the returned cell
314 ///
315 /// IMPORTANT NOTE
316 ///
317 /// The integral of the function is computed at fNpx * fNpy * fNpz points.
318 /// If the function has sharp peaks, you should increase the number of
319 /// points (SetNpx, SetNpy, SetNpz) such that the peak is correctly tabulated
320 /// at several points.
321 
322 void TF3::GetRandom3(Double_t &xrandom, Double_t &yrandom, Double_t &zrandom)
323 {
324  // Check if integral array must be build
325  Int_t i,j,k,cell;
326  Double_t dx = (fXmax-fXmin)/fNpx;
327  Double_t dy = (fYmax-fYmin)/fNpy;
328  Double_t dz = (fZmax-fZmin)/fNpz;
329  Int_t ncells = fNpx*fNpy*fNpz;
330  Double_t xx[3];
331  Double_t *parameters = GetParameters();
332  InitArgs(xx,parameters);
333  if (fIntegral.empty() ) {
334  fIntegral.resize(ncells+1);
335  //fIntegral = new Double_t[ncells+1];
336  fIntegral[0] = 0;
337  Double_t integ;
338  Int_t intNegative = 0;
339  cell = 0;
340  for (k=0;k<fNpz;k++) {
341  xx[2] = fZmin+(k+0.5)*dz;
342  for (j=0;j<fNpy;j++) {
343  xx[1] = fYmin+(j+0.5)*dy;
344  for (i=0;i<fNpx;i++) {
345  xx[0] = fXmin+(i+0.5)*dx;
346  integ = EvalPar(xx,parameters);
347  if (integ < 0) {intNegative++; integ = -integ;}
348  fIntegral[cell+1] = fIntegral[cell] + integ;
349  cell++;
350  }
351  }
352  }
353  if (intNegative > 0) {
354  Warning("GetRandom3","function:%s has %d negative values: abs assumed",GetName(),intNegative);
355  }
356  if (fIntegral[ncells] == 0) {
357  Error("GetRandom3","Integral of function is zero");
358  return;
359  }
360  for (i=1;i<=ncells;i++) { // normalize integral to 1
361  fIntegral[i] /= fIntegral[ncells];
362  }
363  }
364 
365 // return random numbers
366  Double_t r;
367  r = gRandom->Rndm();
368  cell = TMath::BinarySearch(ncells,fIntegral.data(),r);
369  k = cell/(fNpx*fNpy);
370  j = (cell -k*fNpx*fNpy)/fNpx;
371  i = cell -fNpx*(j +fNpy*k);
372  xrandom = fXmin +dx*i +dx*gRandom->Rndm();
373  yrandom = fYmin +dy*j +dy*gRandom->Rndm();
374  zrandom = fZmin +dz*k +dz*gRandom->Rndm();
375 }
376 
377 ////////////////////////////////////////////////////////////////////////////////
378 /// Return range of function
379 
381 {
382  xmin = fXmin;
383  xmax = fXmax;
384  ymin = fYmin;
385  ymax = fYmax;
386  zmin = fZmin;
387  zmax = fZmax;
388 }
389 
390 
391 ////////////////////////////////////////////////////////////////////////////////
392 /// Get value corresponding to X in array of fSave values
393 
395 {
396  //if (fNsave <= 0) return 0;
397  if (fSave.empty()) return 0;
398  Int_t np = fSave.size() - 9;
399  Double_t xmin = Double_t(fSave[np+0]);
400  Double_t xmax = Double_t(fSave[np+1]);
401  Double_t ymin = Double_t(fSave[np+2]);
402  Double_t ymax = Double_t(fSave[np+3]);
403  Double_t zmin = Double_t(fSave[np+4]);
404  Double_t zmax = Double_t(fSave[np+5]);
405  Int_t npx = Int_t(fSave[np+6]);
406  Int_t npy = Int_t(fSave[np+7]);
407  Int_t npz = Int_t(fSave[np+8]);
408  Double_t x = Double_t(xx[0]);
409  Double_t dx = (xmax-xmin)/npx;
410  if (x < xmin || x > xmax) return 0;
411  if (dx <= 0) return 0;
412  Double_t y = Double_t(xx[1]);
413  Double_t dy = (ymax-ymin)/npy;
414  if (y < ymin || y > ymax) return 0;
415  if (dy <= 0) return 0;
416  Double_t z = Double_t(xx[2]);
417  Double_t dz = (zmax-zmin)/npz;
418  if (z < zmin || z > zmax) return 0;
419  if (dz <= 0) return 0;
420 
421  //we make a trilinear interpolation using the 8 points surrounding x,y,z
422  Int_t ibin = Int_t((x-xmin)/dx);
423  Int_t jbin = Int_t((y-ymin)/dy);
424  Int_t kbin = Int_t((z-zmin)/dz);
425  Double_t xlow = xmin + ibin*dx;
426  Double_t ylow = ymin + jbin*dy;
427  Double_t zlow = zmin + kbin*dz;
428  Double_t t = (x-xlow)/dx;
429  Double_t u = (y-ylow)/dy;
430  Double_t v = (z-zlow)/dz;
431  Int_t k1 = (ibin ) + (npx+1)*((jbin ) + (npy+1)*(kbin ));
432  Int_t k2 = (ibin+1) + (npx+1)*((jbin ) + (npy+1)*(kbin ));
433  Int_t k3 = (ibin+1) + (npx+1)*((jbin+1) + (npy+1)*(kbin ));
434  Int_t k4 = (ibin ) + (npx+1)*((jbin+1) + (npy+1)*(kbin ));
435  Int_t k5 = (ibin ) + (npx+1)*((jbin ) + (npy+1)*(kbin+1));
436  Int_t k6 = (ibin+1) + (npx+1)*((jbin ) + (npy+1)*(kbin+1));
437  Int_t k7 = (ibin+1) + (npx+1)*((jbin+1) + (npy+1)*(kbin+1));
438  Int_t k8 = (ibin ) + (npx+1)*((jbin+1) + (npy+1)*(kbin+1));
439  Double_t r = (1-t)*(1-u)*(1-v)*fSave[k1] + t*(1-u)*(1-v)*fSave[k2] + t*u*(1-v)*fSave[k3] + (1-t)*u*(1-v)*fSave[k4] +
440  (1-t)*(1-u)*v*fSave[k5] + t*(1-u)*v*fSave[k6] + t*u*v*fSave[k7] + (1-t)*u*v*fSave[k8];
441  return r;
442 }
443 
444 ////////////////////////////////////////////////////////////////////////////////
445 /// Return Integral of a 3d function in range [ax,bx],[ay,by],[az,bz]
446 /// with a desired relative accuracy.
447 
449 {
450  Double_t a[3], b[3];
451  a[0] = ax;
452  b[0] = bx;
453  a[1] = ay;
454  b[1] = by;
455  a[2] = az;
456  b[2] = bz;
457  Double_t relerr = 0;
458  Int_t n = 3;
459  Int_t maxpts = TMath::Min(100000, 20*fNpx*fNpy*fNpz);
460  Int_t nfnevl,ifail;
461  Double_t result = IntegralMultiple(n,a,b,maxpts,epsrel,epsrel, relerr,nfnevl,ifail);
462  if (ifail > 0) {
463  Warning("Integral","failed code=%d, maxpts=%d, epsrel=%g, nfnevl=%d, relerr=%g ",ifail,maxpts,epsrel,nfnevl,relerr);
464  }
465  return result;
466 }
467 
468 ////////////////////////////////////////////////////////////////////////////////
469 /// Return kTRUE is the point is inside the function range
470 
472 {
473  if (x[0] < fXmin || x[0] > fXmax) return kFALSE;
474  if (x[1] < fYmin || x[1] > fYmax) return kFALSE;
475  if (x[2] < fZmin || x[2] > fZmax) return kFALSE;
476  return kTRUE;
477 }
478 
479 ////////////////////////////////////////////////////////////////////////////////
480 /// Create a histogram for axis range.
481 
483 {
484  TH1* h = new TH3F("R__TF3",(char*)GetTitle(),fNpx,fXmin,fXmax
485  ,fNpy,fYmin,fYmax
486  ,fNpz,fZmin,fZmax);
487  h->SetDirectory(0);
488  return h;
489 }
490 
491 ////////////////////////////////////////////////////////////////////////////////
492 /// Paint this 3-D function with its current attributes
493 
494 void TF3::Paint(Option_t *option)
495 {
496 
497  TString opt = option;
498  opt.ToLower();
499 
500 //- Create a temporary histogram and fill each channel with the function value
501  if (!fHistogram) {
502  fHistogram = new TH3F("R__TF3",(char*)GetTitle(),fNpx,fXmin,fXmax
503  ,fNpy,fYmin,fYmax
504  ,fNpz,fZmin,fZmax);
506  }
507 
508  fHistogram->GetPainter(option)->ProcessMessage("SetF3",this);
509  if (opt.Length() == 0 ) {
510  fHistogram->Paint("tf3");
511  } else {
512  opt += "tf3";
513  fHistogram->Paint(opt.Data());
514  }
515 }
516 
517 ////////////////////////////////////////////////////////////////////////////////
518 /// Set the function clipping box (for drawing) "off".
519 
521 {
522  if (!fHistogram) {
523  fHistogram = new TH3F("R__TF3",(char*)GetTitle(),fNpx,fXmin,fXmax
524  ,fNpy,fYmin,fYmax
525  ,fNpz,fZmin,fZmax);
527  }
528  fHistogram->GetPainter()->ProcessMessage("SetF3ClippingBoxOff",0);
529 }
530 
531 ////////////////////////////////////////////////////////////////////////////////
532 /// Save values of function in array fSave
533 
535 {
536  if (!fSave.empty()) fSave.clear();
537  Int_t nsave = (fNpx+1)*(fNpy+1)*(fNpz+1);
538  Int_t fNsave = nsave+9;
539  assert(fNsave > 9);
540  //fSave = new Double_t[fNsave];
541  fSave.resize(fNsave);
542  Int_t i,j,k,l=0;
543  Double_t dx = (xmax-xmin)/fNpx;
544  Double_t dy = (ymax-ymin)/fNpy;
545  Double_t dz = (zmax-zmin)/fNpz;
546  if (dx <= 0) {
547  dx = (fXmax-fXmin)/fNpx;
548  xmin = fXmin +0.5*dx;
549  xmax = fXmax -0.5*dx;
550  }
551  if (dy <= 0) {
552  dy = (fYmax-fYmin)/fNpy;
553  ymin = fYmin +0.5*dy;
554  ymax = fYmax -0.5*dy;
555  }
556  if (dz <= 0) {
557  dz = (fZmax-fZmin)/fNpz;
558  zmin = fZmin +0.5*dz;
559  zmax = fZmax -0.5*dz;
560  }
561  Double_t xv[3];
562  Double_t *pp = GetParameters();
563  InitArgs(xv,pp);
564  for (k=0;k<=fNpz;k++) {
565  xv[2] = zmin + dz*k;
566  for (j=0;j<=fNpy;j++) {
567  xv[1] = ymin + dy*j;
568  for (i=0;i<=fNpx;i++) {
569  xv[0] = xmin + dx*i;
570  fSave[l] = EvalPar(xv,pp);
571  l++;
572  }
573  }
574  }
575  fSave[nsave+0] = xmin;
576  fSave[nsave+1] = xmax;
577  fSave[nsave+2] = ymin;
578  fSave[nsave+3] = ymax;
579  fSave[nsave+4] = zmin;
580  fSave[nsave+5] = zmax;
581  fSave[nsave+6] = fNpx;
582  fSave[nsave+7] = fNpy;
583  fSave[nsave+8] = fNpz;
584 }
585 
586 ////////////////////////////////////////////////////////////////////////////////
587 /// Save primitive as a C++ statement(s) on output stream out
588 
589 void TF3::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
590 {
591  char quote = '"';
592  out<<" "<<std::endl;
593  if (gROOT->ClassSaved(TF3::Class())) {
594  out<<" ";
595  } else {
596  out<<" TF3 *";
597  }
598  if (!fMethodCall) {
599  out<<GetName()<<" = new TF3("<<quote<<GetName()<<quote<<","<<quote<<GetTitle()<<quote<<","<<fXmin<<","<<fXmax<<","<<fYmin<<","<<fYmax<<","<<fZmin<<","<<fZmax<<");"<<std::endl;
600  } else {
601  out<<GetName()<<" = new TF3("<<quote<<GetName()<<quote<<","<<GetTitle()<<","<<fXmin<<","<<fXmax<<","<<fYmin<<","<<fYmax<<","<<fZmin<<","<<fZmax<<","<<GetNpar()<<");"<<std::endl;
602  }
603 
604  if (GetFillColor() != 0) {
605  if (GetFillColor() > 228) {
607  out<<" "<<GetName()<<"->SetFillColor(ci);" << std::endl;
608  } else
609  out<<" "<<GetName()<<"->SetFillColor("<<GetFillColor()<<");"<<std::endl;
610  }
611  if (GetLineColor() != 1) {
612  if (GetLineColor() > 228) {
614  out<<" "<<GetName()<<"->SetLineColor(ci);" << std::endl;
615  } else
616  out<<" "<<GetName()<<"->SetLineColor("<<GetLineColor()<<");"<<std::endl;
617  }
618  if (GetNpz() != 100) {
619  out<<" "<<GetName()<<"->SetNpz("<<GetNpz()<<");"<<std::endl;
620  }
621  if (GetChisquare() != 0) {
622  out<<" "<<GetName()<<"->SetChisquare("<<GetChisquare()<<");"<<std::endl;
623  }
624  Double_t parmin, parmax;
625  for (Int_t i=0;i<GetNpar();i++) {
626  out<<" "<<GetName()<<"->SetParameter("<<i<<","<<GetParameter(i)<<");"<<std::endl;
627  out<<" "<<GetName()<<"->SetParError("<<i<<","<<GetParError(i)<<");"<<std::endl;
628  GetParLimits(i,parmin,parmax);
629  out<<" "<<GetName()<<"->SetParLimits("<<i<<","<<parmin<<","<<parmax<<");"<<std::endl;
630  }
631  out<<" "<<GetName()<<"->Draw("
632  <<quote<<option<<quote<<");"<<std::endl;
633 }
634 
635 ////////////////////////////////////////////////////////////////////////////////
636 /// Set the function clipping box (for drawing) "on" and define the clipping box.
637 /// xclip, yclip and zclip is a point within the function range. All the
638 /// function values having x<=xclip and y<=yclip and z>=zclip are clipped.
639 
641 {
642  if (!fHistogram) {
643  fHistogram = new TH3F("R__TF3",(char*)GetTitle(),fNpx,fXmin,fXmax
644  ,fNpy,fYmin,fYmax
645  ,fNpz,fZmin,fZmax);
647  }
648 
649  TVectorD v(3);
650  v(0) = xclip;
651  v(1) = yclip;
652  v(2) = zclip;
653  fHistogram->GetPainter()->ProcessMessage("SetF3ClippingBoxOn",&v);
654 }
655 
656 ////////////////////////////////////////////////////////////////////////////////
657 /// Set the number of points used to draw the function
658 ///
659 /// The default number of points along x is 30 for 2-d/3-d functions.
660 /// You can increase this value to get a better resolution when drawing
661 /// pictures with sharp peaks or to get a better result when using TF3::GetRandom2
662 /// the minimum number of points is 4, the maximum is 10000 for 2-d/3-d functions
663 
665 {
666  if (npz < 4) {
667  Warning("SetNpz","Number of points must be >=4 && <= 10000, fNpz set to 4");
668  fNpz = 4;
669  } else if(npz > 10000) {
670  Warning("SetNpz","Number of points must be >=4 && <= 10000, fNpz set to 10000");
671  fNpz = 10000;
672  } else {
673  fNpz = npz;
674  }
675  Update();
676 }
677 
678 ////////////////////////////////////////////////////////////////////////////////
679 /// Initialize the upper and lower bounds to draw the function
680 
682 {
683  fXmin = xmin;
684  fXmax = xmax;
685  fYmin = ymin;
686  fYmax = ymax;
687  fZmin = zmin;
688  fZmax = zmax;
689  Update();
690 }
691 
692 ////////////////////////////////////////////////////////////////////////////////
693 /// Stream an object of class TF3.
694 
695 void TF3::Streamer(TBuffer &R__b)
696 {
697  if (R__b.IsReading()) {
698  UInt_t R__s, R__c;
699  Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
700  if (R__v > 0) {
701  R__b.ReadClassBuffer(TF3::Class(), this, R__v, R__s, R__c);
702  return;
703  }
704 
705  } else {
706  Int_t saved = 0;
707  if (fType > 0 && fSave.empty() ) { saved = 1; Save(fXmin,fXmax,fYmin,fYmax,fZmin,fZmax);}
708 
709  R__b.WriteClassBuffer(TF3::Class(),this);
710 
711  if (saved) { fSave.clear(); }
712  }
713 }
714 
715 ////////////////////////////////////////////////////////////////////////////////
716 /// Return x^nx * y^ny * z^nz moment of a 3d function in range [ax,bx],[ay,by],[az,bz]
717 /// \author Gene Van Buren <gene@bnl.gov>
718 
720 {
721  Double_t norm = Integral(ax,bx,ay,by,az,bz,epsilon);
722  if (norm == 0) {
723  Error("Moment3", "Integral zero over range");
724  return 0;
725  }
726 
727  TF3 fnc("TF3_ExpValHelper",Form("%s*pow(x,%f)*pow(y,%f)*pow(z,%f)",GetName(),nx,ny,nz));
728  return fnc.Integral(ax,bx,ay,by,az,bz,epsilon)/norm;
729 }
730 
731 ////////////////////////////////////////////////////////////////////////////////
732 /// Return x^nx * y^ny * z^nz central moment of a 3d function in range [ax,bx],[ay,by],[az,bz]
733 /// \author Gene Van Buren <gene@bnl.gov>
734 
736 {
737  Double_t norm = Integral(ax,bx,ay,by,az,bz,epsilon);
738  if (norm == 0) {
739  Error("CentralMoment3", "Integral zero over range");
740  return 0;
741  }
742 
743  Double_t xbar = 0;
744  Double_t ybar = 0;
745  Double_t zbar = 0;
746  if (nx!=0) {
747  TF3 fncx("TF3_ExpValHelperx",Form("%s*x",GetName()));
748  xbar = fncx.Integral(ax,bx,ay,by,az,bz,epsilon)/norm;
749  }
750  if (ny!=0) {
751  TF3 fncy("TF3_ExpValHelpery",Form("%s*y",GetName()));
752  ybar = fncy.Integral(ax,bx,ay,by,az,bz,epsilon)/norm;
753  }
754  if (nz!=0) {
755  TF3 fncz("TF3_ExpValHelperz",Form("%s*z",GetName()));
756  zbar = fncz.Integral(ax,bx,ay,by,az,bz,epsilon)/norm;
757  }
758  TF3 fnc("TF3_ExpValHelper",Form("%s*pow(x-%f,%f)*pow(y-%f,%f)*pow(z-%f,%f)",GetName(),xbar,nx,ybar,ny,zbar,nz));
759  return fnc.Integral(ax,bx,ay,by,az,bz,epsilon)/norm;
760 }
761 
const int nx
Definition: kalman.C:16
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual void Copy(TObject &f3) const
Copy this F3 to a new F3.
Definition: TF3.cxx:150
Bool_t IsReading() const
Definition: TBuffer.h:81
virtual void Paint(Option_t *option="")
Control routine to paint any kind of histograms.
Definition: TH1.cxx:5539
Int_t fNpx
Definition: TF1.h:168
float xmin
Definition: THbookFile.cxx:93
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
virtual Double_t Moment3(Double_t nx, Double_t ax, Double_t bx, Double_t ny, Double_t ay, Double_t by, Double_t nz, Double_t az, Double_t bz, Double_t epsilon=0.000001)
Return x^nx * y^ny * z^nz moment of a 3d function in range [ax,bx],[ay,by],[az,bz].
Definition: TF3.cxx:719
virtual void Draw(Option_t *option="")
Draw this function with its current attributes.
Definition: TF3.cxx:174
Double_t fZmax
Definition: TF3.h:32
short Version_t
Definition: RtypesCore.h:61
TVirtualHistPainter * GetPainter(Option_t *option="")
Return pointer to painter.
Definition: TH1.cxx:4100
virtual void SetDirectory(TDirectory *dir)
By default when an histogram is created, it is added to the list of histogram objects in the current ...
Definition: TH1.cxx:8053
virtual void Save(Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax, Double_t zmin, Double_t zmax)
Save values of function in array fSave.
Definition: TF3.cxx:534
const char Option_t
Definition: RtypesCore.h:62
float ymin
Definition: THbookFile.cxx:93
virtual TH1 * CreateHistogram()
Create a histogram for axis range.
Definition: TF3.cxx:482
Double_t QuietNaN()
Definition: TMath.h:784
TH1 * h
Definition: legend2.C:5
static void SaveColor(std::ostream &out, Int_t ci)
Save a color with index > 228 as a C++ statement(s) on output stream out.
Definition: TColor.cxx:2022
virtual ~TF3()
F3 default destructor.
Definition: TF3.cxx:135
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute action corresponding to one event.
Definition: TF1.cxx:1273
Buffer base class used for serializing objects.
Definition: TBuffer.h:40
Double_t fZmin
Definition: TF3.h:31
Int_t GetNpz() const
Definition: TF3.h:93
virtual Double_t IntegralMultiple(Int_t n, const Double_t *a, const Double_t *b, Int_t maxpts, Double_t epsrel, Double_t epsabs, Double_t &relerr, Int_t &nfnevl, Int_t &ifail)
This function computes, to an attempted specified accuracy, the value of the integral.
Definition: TF1.cxx:2626
#define gROOT
Definition: TROOT.h:375
Basic string class.
Definition: TString.h:129
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:168
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1099
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
TArc * a
Definition: textangle.C:12
virtual Double_t GetParError(Int_t ipar) const
Return value of parameter number ipar.
Definition: TF1.cxx:1656
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save primitive as a C++ statement(s) on output stream out.
Definition: TF3.cxx:589
#define NULL
Definition: RtypesCore.h:88
Double_t fYmin
Definition: TF2.h:32
virtual Double_t GetMinimumXYZ(Double_t &x, Double_t &y, Double_t &z)
Compute the X, Y and Z values corresponding to the minimum value of the function on its range...
Definition: TF3.cxx:278
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition: TObject.cxx:112
virtual void SetClippingBoxOn(Double_t xclip=0, Double_t yclip=0, Double_t zclip=0)
Set the function clipping box (for drawing) "on" and define the clipping box.
Definition: TF3.cxx:640
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute distance from point px,py to a function.
Definition: TF1.cxx:1047
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute action corresponding to one event.
Definition: TF3.cxx:189
Double_t x[n]
Definition: legend1.C:17
void Class()
Definition: Class.C:29
virtual void Copy(TObject &f2) const
Copy this F2 to a new F2.
Definition: TF2.cxx:168
TText * tt
Definition: textangle.C:16
const int ny
Definition: kalman.C:17
virtual Double_t GetMaximumXYZ(Double_t &x, Double_t &y, Double_t &z)
Compute the X, Y and Z values corresponding to the maximum value of the function on its range...
Definition: TF3.cxx:294
TF3()
F3 default constructor.
Definition: TF3.cxx:36
Double_t fYmax
Definition: TF2.h:33
virtual void Paint(Option_t *option="")
Paint this 3-D function with its current attributes.
Definition: TF3.cxx:494
Int_t Finite(Double_t x)
Definition: TMath.h:655
virtual Int_t GetNdim() const
Definition: TF1.h:439
virtual void ProcessMessage(const char *mess, const TObject *obj)=0
Double_t Infinity()
Definition: TMath.h:797
std::vector< Double_t > fIntegral
Definition: TF1.h:179
virtual Double_t Rndm()
Machine independent random number generator.
Definition: TRandom.cxx:512
float ymax
Definition: THbookFile.cxx:93
TH1 * fHistogram
Parent object hooking this function (if one)
Definition: TF1.h:184
virtual Double_t Integral(Double_t ax, Double_t bx, Double_t ay, Double_t by, Double_t az, Double_t bz, Double_t epsrel=1.e-6)
Return Integral of a 3d function in range [ax,bx],[ay,by],[az,bz] with a desired relative accuracy...
Definition: TF3.cxx:448
TRandom2 r(17)
virtual Double_t CentralMoment3(Double_t nx, Double_t ax, Double_t bx, Double_t ny, Double_t ay, Double_t by, Double_t nz, Double_t az, Double_t bz, Double_t epsilon=0.000001)
Return x^nx * y^ny * z^nz central moment of a 3d function in range [ax,bx],[ay,by],[az,bz].
Definition: TF3.cxx:735
SVector< double, 2 > v
Definition: Dict.h:5
A 3-Dim function with parameters.
Definition: TF3.h:28
unsigned int UInt_t
Definition: RtypesCore.h:42
virtual void GetRange(Double_t &xmin, Double_t &xmax) const
Return range of a 1-D function.
Definition: TF3.h:139
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:873
char * Form(const char *fmt,...)
Ssiz_t Length() const
Definition: TString.h:388
Int_t fType
Definition: TF1.h:169
virtual void GetRandom3(Double_t &xrandom, Double_t &yrandom, Double_t &zrandom)
Return 3 random numbers following this function shape.
Definition: TF3.cxx:322
TLine * l
Definition: textangle.C:4
float xmax
Definition: THbookFile.cxx:93
virtual void Update()
Called by functions such as SetRange, SetNpx, SetParameters to force the deletion of the associated h...
Definition: TF1.cxx:3430
A 2-Dim function with parameters.
Definition: TF2.h:29
R__EXTERN TRandom * gRandom
Definition: TRandom.h:62
Int_t fNpz
Definition: TF3.h:33
REAL epsilon
Definition: triangle.c:617
const Bool_t kFALSE
Definition: RtypesCore.h:92
virtual Color_t GetLineColor() const
Return the line color.
Definition: TAttLine.h:33
TF3 & operator=(const TF3 &rhs)
Operator =.
Definition: TF3.cxx:124
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
Double_t GetChisquare() const
Definition: TF1.h:398
#define ClassImp(name)
Definition: Rtypes.h:336
double f(double x)
double Double_t
Definition: RtypesCore.h:55
std::vector< Double_t > fSave
Definition: TF1.h:178
Double_t fXmin
Definition: TF1.h:164
Double_t y[n]
Definition: legend1.C:17
virtual Color_t GetFillColor() const
Return the fill area color.
Definition: TAttFill.h:30
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:572
The TH1 histogram class.
Definition: TH1.h:56
virtual void SetClippingBoxOff()
Set the function clipping box (for drawing) "off".
Definition: TF3.cxx:520
virtual void InitArgs(const Double_t *x, const Double_t *params)
Initialize parameters addresses.
Definition: TF1.cxx:2261
THist< 3, float, THistStatContent, THistStatUncertainty > TH3F
Definition: THist.hxx:323
Mother of all ROOT objects.
Definition: TObject.h:37
you should not use this method at all Int_t Int_t z
Definition: TRolke.cxx:630
TMethodCall * fMethodCall
Pointer to histogram used for visualisation.
Definition: TF1.h:185
virtual Int_t GetNpar() const
Definition: TF1.h:435
virtual void GetParLimits(Int_t ipar, Double_t &parmin, Double_t &parmax) const
Return limits for parameter ipar.
Definition: TF1.cxx:1666
virtual void SetRange(Double_t xmin, Double_t xmax)
Initialize the upper and lower bounds to draw the function.
Definition: TF3.h:143
virtual Double_t GetMinMaxNDim(Double_t *x, Bool_t findmax, Double_t epsilon=0, Int_t maxiter=0) const
Find the minimum of a function of whatever dimension.
Definition: TF1.cxx:1450
virtual Double_t GetParameter(Int_t ipar) const
Definition: TF1.h:466
virtual Bool_t IsInside(const Double_t *x) const
Return kTRUE is the point is inside the function range.
Definition: TF3.cxx:471
void MakeZombie()
Definition: TObject.h:49
virtual Double_t FindMinMax(Double_t *x, bool findmax) const
Return minimum/maximum value of the function.
Definition: TF3.cxx:210
Param Functor class for Multidimensional functions.
Definition: ParamFunctor.h:209
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
#define gPad
Definition: TVirtualPad.h:284
virtual Double_t * GetParameters() const
Definition: TF1.h:474
double result[121]
virtual Double_t EvalPar(const Double_t *x, const Double_t *params=0)
Evaluate function with given coordinates and parameters.
Definition: TF1.cxx:1226
const Bool_t kTRUE
Definition: RtypesCore.h:91
double norm(double *x, double *p)
Definition: unuranDistr.cxx:40
const Int_t n
Definition: legend1.C:16
Double_t fXmax
Definition: TF1.h:165
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Definition: TMath.h:1093
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute distance from point px,py to a function.
Definition: TF3.cxx:165
virtual Double_t GetSave(const Double_t *x)
Get value corresponding to X in array of fSave values.
Definition: TF3.cxx:394
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:859
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
Int_t fNpy
Definition: TF2.h:34
const char * Data() const
Definition: TString.h:347
virtual void SetNpz(Int_t npz=30)
Set the number of points used to draw the function.
Definition: TF3.cxx:664