Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
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 "TBuffer.h"
15#include "TMath.h"
16#include "TH3.h"
17#include "TVirtualPad.h"
18#include "TRandom.h"
19#include "TVectorD.h"
20#include "Riostream.h"
21#include "TColor.h"
22#include "TVirtualFitter.h"
23#include "TVirtualHistPainter.h"
25#include <cassert>
26
27
28/** \class TF3
29 \ingroup Functions
30TF3 defines a 3D Function with Parameters.
31
323D implicit functions can be visualized as iso-surfaces. An implicit surface is defined
33by the equation f(x,y,z) = 0 and is rendered in Cartesian coordinates.
34
35In the example below, the drawing options "FB" and "BB" are used to remove the
36front box and back box of the 3D frame keeping only the three axes.
37
38Begin_Macro(source)
39{
40 auto C = new TCanvas("C","C",500,500);
41 auto f3 = new TF3("gyroid",
42 "sin(x)*cos(y) + sin(y)*cos(z) + sin(z)*cos(x)",
43 -4, 4, -4, 4, -4, 4);
44 f3->SetFillColor(50);
45 f3->SetLineColor(15);
46 f3->Draw("FBBB");
47}
48End_Macro
49
50*/
51
52////////////////////////////////////////////////////////////////////////////////
53/// F3 default constructor
54
56{
57 fNpz = 0;
58 fZmin = 0;
59 fZmax = 1;
60}
61
62////////////////////////////////////////////////////////////////////////////////
63/// TF3 constructor using a formula definition and string option args
64///
65/// See TFormula constructor for explanation of the formula syntax.
66
67TF3::TF3(const char *name, const char *formula, Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax,
68 Double_t zmin, Double_t zmax, Option_t *opt)
69 : TF2(name, formula, xmin, xmax, ymax, ymin,
70 opt) // purposely swapped ymax, ymin to signal that TFormula may be 1D or 2D or 3D
71{
72 fZmin = zmin;
73 fZmax = zmax;
74 fNpz = 30;
75 Int_t ndim = GetNdim();
76 // accept 1-d or 2-d formula
77 if (ndim < 3) fNdim = 3;
78 if (ndim > 3 && xmin < xmax && ymin < ymax && zmin < zmax) {
79 Error("TF3","function: %s/%s has dimension %d instead of 3",name,formula,ndim);
80 MakeZombie();
81 }
82}
83
84////////////////////////////////////////////////////////////////////////////////
85/// TF3 constructor using a formula definition and explicit option args
86///
87/// See TFormula constructor for explanation of the formula syntax.
88
89TF3::TF3(const char *name, const char *formula, Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax,
90 Double_t zmin, Double_t zmax, EAddToList addToGlobList, bool vectorize)
91 : TF2(name, formula, xmin, xmax, ymax, ymin, addToGlobList,
92 vectorize) // purposely swapped ymax, ymin to signal that TFormula may be 1D or 2D or 3D
93{
94 fZmin = zmin;
95 fZmax = zmax;
96 fNpz = 30;
97 Int_t ndim = GetNdim();
98 // accept 1-d or 2-d formula
99 if (ndim < 3)
100 fNdim = 3;
101 if (ndim > 3 && xmin < xmax && ymin < ymax && zmin < zmax) {
102 Error("TF3", "function: %s/%s has dimension %d instead of 3", name, formula, ndim);
103 MakeZombie();
104 }
105}
106
107////////////////////////////////////////////////////////////////////////////////
108/// TF3 constructor using a pointer to real function
109///
110/// \param[in] name object name
111/// \param[in] fcn pointer to real function
112/// \param[in] xmin,xmax x axis limits
113/// \param[in] ymin,ymax y axis limits
114/// \param[in] zmin,zmax z axis limits
115/// \param[in] npar is the number of free parameters used by the function
116/// \param[in] ndim number of dimensions
117///
118/// For example, for a 3-dim function with 3 parameters, the user function
119/// looks like:
120///
121/// Double_t fun1(Double_t *x, Double_t *par)
122/// return par[0]*x[2] + par[1]*exp(par[2]*x[0]*x[1]);
123///
124/// \warning A function created with this constructor cannot be Cloned.
125
126TF3::TF3(const char *name,Double_t (*fcn)(Double_t *, 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, EAddToList addToGlobList)
127 :TF2(name,fcn,xmin,xmax,ymin,ymax,npar,ndim,addToGlobList)
128{
129 fZmin = zmin;
130 fZmax = zmax;
131 fNpz = 30;
132}
133
134////////////////////////////////////////////////////////////////////////////////
135/// TF3 constructor using a pointer to real function---
136///
137/// \param[in] name object name
138/// \param[in] fcn pointer to real function
139/// \param[in] xmin,xmax x axis limits
140/// \param[in] ymin,ymax y axis limits
141/// \param[in] zmin,zmax z axis limits
142/// \param[in] npar is the number of free parameters used by the function
143/// \param[in] ndim number of dimensions
144///
145/// For example, for a 3-dim function with 3 parameters, the user function
146/// looks like:
147///
148/// Double_t fun1(Double_t *x, Double_t *par)
149/// return par[0]*x[2] + par[1]*exp(par[2]*x[0]*x[1]);
150///
151/// WARNING! A function created with this constructor cannot be Cloned.
152
153TF3::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, EAddToList addToGlobList)
154 : TF2(name,fcn,xmin,xmax,ymin,ymax,npar,ndim,addToGlobList),
155 fZmin(zmin),
156 fZmax(zmax),
157 fNpz(30)
158{
159}
160
161////////////////////////////////////////////////////////////////////////////////
162/// TF3 constructor using a ParamFunctor
163///
164/// a functor class implementing operator() (double *, double *)
165///
166/// \param[in] name object name
167/// \param[in] f parameter functor
168/// \param[in] xmin,xmax x axis limits
169/// \param[in] ymin,ymax y axis limits
170/// \param[in] zmin,zmax z axis limits
171/// \param[in] npar is the number of free parameters used by the function
172/// \param[in] ndim number of dimensions
173///
174/// \warning A function created with this constructor cannot be Cloned.
175
176TF3::TF3(const char *name, ROOT::Math::ParamFunctor f, Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax, Double_t zmin, Double_t zmax, Int_t npar, Int_t ndim, EAddToList addToGlobList)
177 : TF2(name, f, xmin, xmax, ymin, ymax, npar, ndim, addToGlobList),
178 fZmin(zmin),
179 fZmax(zmax),
180 fNpz(30)
181{
182}
183
184////////////////////////////////////////////////////////////////////////////////
185/// Operator =
186
187TF3& TF3::operator=(const TF3 &rhs)
188{
189 if (this != &rhs)
190 rhs.TF3::Copy(*this);
191 return *this;
192}
193
194////////////////////////////////////////////////////////////////////////////////
195/// F3 default destructor
196
197TF3::~TF3()
198{
199}
200
201////////////////////////////////////////////////////////////////////////////////
202/// Copy constructor.
203
204TF3::TF3(const TF3 &f3) : TF2()
205{
206 f3.TF3::Copy(*this);
207}
208
209////////////////////////////////////////////////////////////////////////////////
210/// Copy this F3 to a new F3
211
212void TF3::Copy(TObject &obj) const
213{
214 TF2::Copy(obj);
215 ((TF3&)obj).fZmin = fZmin;
216 ((TF3&)obj).fZmax = fZmax;
217 ((TF3&)obj).fNpz = fNpz;
218}
219
220////////////////////////////////////////////////////////////////////////////////
221/// Compute distance from point px,py to a function
222///
223/// Compute the closest distance of approach from point px,py to this function.
224/// The distance is computed in pixels units.
225
226
228{
229 return TF1::DistancetoPrimitive(px, py);
230
231}
232
233////////////////////////////////////////////////////////////////////////////////
234/// Draw this function with iso-surfaces.
235
236void TF3::Draw(Option_t *option)
237{
238 TString opt = option;
239 opt.ToLower();
240 if (gPad && !opt.Contains("same")) gPad->Clear();
241
242 AppendPad(option);
243
244}
245
246////////////////////////////////////////////////////////////////////////////////
247/// Execute action corresponding to one event
248///
249/// This member function is called when a F3 is clicked with the locator
250
251void TF3::ExecuteEvent(Int_t event, Int_t px, Int_t py)
252{
253 TF1::ExecuteEvent(event, px, py);
254}
255
256////////////////////////////////////////////////////////////////////////////////
257/// Return minimum/maximum value of the function
258///
259/// To find the minimum on a range, first set this range via the SetRange function
260/// If a vector x of coordinate is passed it will be used as starting point for the minimum.
261/// In addition on exit x will contain the coordinate values at the minimuma
262/// If x is NULL or x is inifinity or NaN, first, a grid search is performed to find the initial estimate of the
263/// minimum location. The range of the function is divided into fNpx and fNpy
264/// sub-ranges. If the function is "good" (or "bad"), these values can be changed
265/// by SetNpx and SetNpy functions
266///
267/// Then, a minimization is used with starting values found by the grid search
268/// The minimizer algorithm used (by default Minuit) can be changed by callinga
269/// ROOT::Math::Minimizer::SetDefaultMinimizerType("..")
270/// Other option for the minimizer can be set using the static method of the MinimizerOptions class
271
273{
274 //First do a grid search with step size fNpx and fNpy
275
276 Double_t xx[3];
277 Double_t rsign = (findmax) ? -1. : 1.;
278 TF3 & function = const_cast<TF3&>(*this); // needed since EvalPar is not const
279 Double_t xxmin = 0, yymin = 0, zzmin = 0, ttmin = 0;
280 if (x == nullptr || ( (x!= nullptr) && ( !TMath::Finite(x[0]) || !TMath::Finite(x[1]) || !TMath::Finite(x[2]) ) ) ){
281 Double_t dx = (fXmax - fXmin)/fNpx;
282 Double_t dy = (fYmax - fYmin)/fNpy;
283 Double_t dz = (fZmax - fZmin)/fNpz;
284 xxmin = fXmin;
285 yymin = fYmin;
286 zzmin = fZmin;
287 ttmin = rsign * TMath::Infinity();
288 for (Int_t i=0; i<fNpx; i++){
289 xx[0]=fXmin + (i+0.5)*dx;
290 for (Int_t j=0; j<fNpy; j++){
291 xx[1]=fYmin+(j+0.5)*dy;
292 for (Int_t k=0; k<fNpz; k++){
293 xx[2] = fZmin+(k+0.5)*dz;
294 Double_t tt = function(xx);
295 if (rsign*tt < rsign*ttmin) {xxmin = xx[0], yymin = xx[1]; zzmin = xx[2]; ttmin=tt;}
296 }
297 }
298 }
299
300 xxmin = TMath::Min(fXmax, xxmin);
301 yymin = TMath::Min(fYmax, yymin);
302 zzmin = TMath::Min(fZmax, zzmin);
303 }
304 else {
305 xxmin = x[0];
306 yymin = x[1];
307 zzmin = x[2];
308 zzmin = function(x);
309 }
310 xx[0] = xxmin;
311 xx[1] = yymin;
312 xx[2] = zzmin;
313
314 double fmin = GetMinMaxNDim(xx,findmax);
315 if (rsign*fmin < rsign*zzmin) {
316 if (x) {x[0] = xx[0]; x[1] = xx[1]; x[2] = xx[2];}
317 return fmin;
318 }
319 // here if minimization failed
320 if (x) { x[0] = xxmin; x[1] = yymin; x[2] = zzmin; }
321 return ttmin;
322}
323
324////////////////////////////////////////////////////////////////////////////////
325/// Compute the X, Y and Z values corresponding to the minimum value of the function
326/// on its range.
327///
328/// Returns the function value at the minimum.
329/// To find the minimum on a subrange, use the SetRange() function first.
330///
331/// Method:
332/// First, a grid search is performed to find the initial estimate of the
333/// minimum location. The range of the function is divided
334/// into fNpx,fNpy and fNpz sub-ranges. If the function is "good" (or "bad"),
335/// these values can be changed by SetNpx(), SetNpy() and SetNpz() functions.
336/// Then, Minuit minimization is used with starting values found by the grid search
337///
338/// Note that this method will always do first a grid search in contrast to GetMinimum
339
341{
342 double xx[3] = { 0,0,0 };
343 xx[0] = TMath::QuietNaN(); // to force to do grid search in TF3::FindMinMax
344 double fmin = FindMinMax(xx, false);
345 x = xx[0]; y = xx[1]; z = xx[2];
346 return fmin;
347
348}
349
350////////////////////////////////////////////////////////////////////////////////
351/// Compute the X, Y and Z values corresponding to the maximum value of the function
352/// on its range.
353///
354/// Return the function value at the maximum. See TF3::GetMinimumXYZ
355
357{
358 double xx[3] = { 0,0,0 };
359 xx[0] = TMath::QuietNaN(); // to force to do grid search in TF3::FindMinMax
360 double fmax = FindMinMax(xx, true);
361 x = xx[0]; y = xx[1]; z = xx[2];
362 return fmax;
363
364}
365
366////////////////////////////////////////////////////////////////////////////////
367/// Return 3 random numbers following this function shape
368///
369/// The distribution contained in this TF3 function is integrated
370/// over the cell contents.
371/// It is normalized to 1.
372/// Getting the three random numbers implies:
373/// - Generating a random number between 0 and 1 (say r1)
374/// - Look in which cell in the normalized integral r1 corresponds to
375/// - make a linear interpolation in the returned cell
376///
377/// IMPORTANT NOTE
378///
379/// The integral of the function is computed at fNpx * fNpy * fNpz points.
380/// If the function has sharp peaks, you should increase the number of
381/// points (SetNpx, SetNpy, SetNpz) such that the peak is correctly tabulated
382/// at several points.
383
384void TF3::GetRandom3(Double_t &xrandom, Double_t &yrandom, Double_t &zrandom, TRandom * rng)
385{
386 // Check if integral array must be built
387 Int_t i,j,k,cell;
391 Int_t ncells = fNpx*fNpy*fNpz;
392 Double_t xx[3];
393 Double_t *parameters = GetParameters();
394 InitArgs(xx,parameters);
395 if (fIntegral.empty() ) {
396 fIntegral.resize(ncells+1);
397 //fIntegral = new Double_t[ncells+1];
398 fIntegral[0] = 0;
399 Double_t integ;
400 Int_t intNegative = 0;
401 cell = 0;
402 for (k=0;k<fNpz;k++) {
403 xx[2] = fZmin+(k+0.5)*dz;
404 for (j=0;j<fNpy;j++) {
405 xx[1] = fYmin+(j+0.5)*dy;
406 for (i=0;i<fNpx;i++) {
407 xx[0] = fXmin+(i+0.5)*dx;
408 integ = EvalPar(xx,parameters);
409 if (integ < 0) {intNegative++; integ = -integ;}
410 fIntegral[cell+1] = fIntegral[cell] + integ;
411 cell++;
412 }
413 }
414 }
415 if (intNegative > 0) {
416 Warning("GetRandom3","function:%s has %d negative values: abs assumed",GetName(),intNegative);
417 }
418 if (fIntegral[ncells] == 0) {
419 Error("GetRandom3","Integral of function is zero");
420 return;
421 }
422 for (i=1;i<=ncells;i++) { // normalize integral to 1
423 fIntegral[i] /= fIntegral[ncells];
424 }
425 }
426
427// return random numbers
428 Double_t r;
429 if (!rng) rng = gRandom;
430 r = rng->Rndm();
431 cell = TMath::BinarySearch(ncells,fIntegral.data(),r);
432 k = cell/(fNpx*fNpy);
433 j = (cell -k*fNpx*fNpy)/fNpx;
434 i = cell -fNpx*(j +fNpy*k);
435 xrandom = fXmin +dx*i +dx*rng->Rndm();
436 yrandom = fYmin +dy*j +dy*rng->Rndm();
437 zrandom = fZmin +dz*k +dz*rng->Rndm();
438}
439
440////////////////////////////////////////////////////////////////////////////////
441/// Return range of function
442
444{
445 xmin = fXmin;
446 xmax = fXmax;
447 ymin = fYmin;
448 ymax = fYmax;
449 zmin = fZmin;
450 zmax = fZmax;
451}
452
453
454////////////////////////////////////////////////////////////////////////////////
455/// Get value corresponding to X in array of fSave values
456
458{
459 if (fSave.size() < 9) return 0;
460 Int_t nsave = fSave.size() - 9;
461 Double_t xmin = fSave[nsave+0];
462 Double_t xmax = fSave[nsave+1];
463 Double_t ymin = fSave[nsave+2];
464 Double_t ymax = fSave[nsave+3];
465 Double_t zmin = fSave[nsave+4];
466 Double_t zmax = fSave[nsave+5];
467 Int_t npx = Int_t(fSave[nsave+6]);
468 Int_t npy = Int_t(fSave[nsave+7]);
469 Int_t npz = Int_t(fSave[nsave+8]);
470 Double_t x = xx[0];
472 if (x < xmin || x > xmax) return 0;
473 if (dx <= 0) return 0;
474 Double_t y = xx[1];
476 if (y < ymin || y > ymax) return 0;
477 if (dy <= 0) return 0;
478 Double_t z = xx[2];
479 Double_t dz = (zmax-zmin)/npz;
480 if (z < zmin || z > zmax) return 0;
481 if (dz <= 0) return 0;
482
483 //we make a trilinear interpolation using the 8 points surrounding x,y,z
484 Int_t ibin = TMath::Min(npx-1, Int_t((x-xmin)/dx));
485 Int_t jbin = TMath::Min(npy-1, Int_t((y-ymin)/dy));
486 Int_t kbin = TMath::Min(npz-1, Int_t((z-zmin)/dz));
487 Double_t xlow = xmin + ibin*dx;
488 Double_t ylow = ymin + jbin*dy;
489 Double_t zlow = zmin + kbin*dz;
490 Double_t t = (x-xlow)/dx;
491 Double_t u = (y-ylow)/dy;
492 Double_t v = (z-zlow)/dz;
493 Int_t k1 = (ibin ) + (npx+1)*((jbin ) + (npy+1)*(kbin ));
494 Int_t k2 = (ibin+1) + (npx+1)*((jbin ) + (npy+1)*(kbin ));
495 Int_t k3 = (ibin+1) + (npx+1)*((jbin+1) + (npy+1)*(kbin ));
496 Int_t k4 = (ibin ) + (npx+1)*((jbin+1) + (npy+1)*(kbin ));
497 Int_t k5 = (ibin ) + (npx+1)*((jbin ) + (npy+1)*(kbin+1));
498 Int_t k6 = (ibin+1) + (npx+1)*((jbin ) + (npy+1)*(kbin+1));
499 Int_t k7 = (ibin+1) + (npx+1)*((jbin+1) + (npy+1)*(kbin+1));
500 Int_t k8 = (ibin ) + (npx+1)*((jbin+1) + (npy+1)*(kbin+1));
501 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] +
502 (1-t)*(1-u)*v*fSave[k5] + t*(1-u)*v*fSave[k6] + t*u*v*fSave[k7] + (1-t)*u*v*fSave[k8];
503 return r;
504}
505
506////////////////////////////////////////////////////////////////////////////////
507/// Create the basic function objects
508
510{
511 TF3 *f3;
513 if (!gROOT->GetListOfFunctions()->FindObject("xyzgaus")) {
514 f3 = new TF3("xyzgaus", "xyzgaus", -1, 1, -1, 1, -1, 1);
515 f3->SetParameters(1, 0, 1, 0, 1, 0, 1);
516 }
517}
518
519////////////////////////////////////////////////////////////////////////////////
520/// Return Integral of a 3d function in range [ax,bx],[ay,by],[az,bz]
521/// with a desired relative accuracy.
522
524{
525 Double_t a[3], b[3];
526 a[0] = ax;
527 b[0] = bx;
528 a[1] = ay;
529 b[1] = by;
530 a[2] = az;
531 b[2] = bz;
532 Double_t relerr = 0;
533 Int_t n = 3;
535 Int_t nfnevl, ifail;
536 Double_t result = IntegralMultiple(n,a,b,maxpts,epsrel,epsrel, relerr,nfnevl,ifail);
537 if (ifail > 0) {
538 Warning("Integral","failed for %s code=%d, maxpts=%d, epsrel=%g, nfnevl=%d, relerr=%g ",GetName(),ifail,maxpts,epsrel,nfnevl,relerr);
539 }
540 if (gDebug) {
541 Info("Integral","Integral of %s using %d and tol=%f is %f , relerr=%f nfcn=%d",GetName(),maxpts,epsrel,result,relerr,nfnevl);
542 }
543 return result;
544}
545
546////////////////////////////////////////////////////////////////////////////////
547/// Return kTRUE is the point is inside the function range
548
549Bool_t TF3::IsInside(const Double_t *x) const
550{
551 if (x[0] < fXmin || x[0] > fXmax) return kFALSE;
552 if (x[1] < fYmin || x[1] > fYmax) return kFALSE;
553 if (x[2] < fZmin || x[2] > fZmax) return kFALSE;
554 return kTRUE;
555}
556
557////////////////////////////////////////////////////////////////////////////////
558/// Create a histogram for axis range.
559
561{
562 TH1* h = new TH3F("R__TF3",(char*)GetTitle(),fNpx,fXmin,fXmax
564 ,fNpz,fZmin,fZmax);
565 h->SetDirectory(nullptr);
566 return h;
567}
568
569////////////////////////////////////////////////////////////////////////////////
570/// Paint this 3-D function with its current attributes
571
572void TF3::Paint(Option_t *option)
573{
574
575 TString opt = option;
576 opt.ToLower();
577
578//- Create a temporary histogram and fill each channel with the function value
579 if (!fHistogram) {
580 fHistogram = new TH3F("R__TF3",(char*)GetTitle(),fNpx,fXmin,fXmax
582 ,fNpz,fZmin,fZmax);
583 fHistogram->SetDirectory(nullptr);
584 }
585
586 fHistogram->GetPainter(option)->ProcessMessage("SetF3",this);
587
588 if (opt.Index("tf3") == kNPOS)
589 opt.Append("tf3");
590
591 fHistogram->Paint(opt.Data());
592}
593
594////////////////////////////////////////////////////////////////////////////////
595/// Set the function clipping box (for drawing) "off".
596
598{
600 fClipBox[0] = fClipBox[1] = fClipBox[2] = 0;
601}
602
603////////////////////////////////////////////////////////////////////////////////
604/// Save values of function in array fSave
605
607{
608 if (!fSave.empty()) fSave.clear();
609 Int_t npx = fNpx, npy = fNpy, npz = fNpz;
610 if ((npx < 2) || (npy < 2) || (npz < 2))
611 return;
612
613 Double_t dx = (xmax-xmin)/fNpx;
614 Double_t dy = (ymax-ymin)/fNpy;
615 Double_t dz = (zmax-zmin)/fNpz;
616 if (dx <= 0) {
617 dx = (fXmax-fXmin)/fNpx;
618 npx--;
619 xmin = fXmin + 0.5*dx;
620 xmax = fXmax - 0.5*dx;
621 }
622 if (dy <= 0) {
623 dy = (fYmax-fYmin)/fNpy;
624 npy--;
625 ymin = fYmin + 0.5*dy;
626 ymax = fYmax - 0.5*dy;
627 }
628 if (dz <= 0) {
629 dz = (fZmax-fZmin)/fNpz;
630 npz--;
631 zmin = fZmin + 0.5*dz;
632 zmax = fZmax - 0.5*dz;
633 }
634 Int_t nsave = (npx + 1)*(npy + 1)*(npz + 1);
635 fSave.resize(nsave + 9);
636 Double_t xv[3];
637 Double_t *pp = GetParameters();
638 InitArgs(xv,pp);
639 for (Int_t k = 0, l = 0; k <= npz; k++) {
640 xv[2] = zmin + dz*k;
641 for (Int_t j = 0; j <= npy; j++) {
642 xv[1] = ymin + dy*j;
643 for (Int_t i = 0; i <= npx; i++) {
644 xv[0] = xmin + dx*i;
645 fSave[l++] = EvalPar(xv, pp);
646 }
647 }
648 }
649 fSave[nsave+0] = xmin;
650 fSave[nsave+1] = xmax;
651 fSave[nsave+2] = ymin;
652 fSave[nsave+3] = ymax;
653 fSave[nsave+4] = zmin;
654 fSave[nsave+5] = zmax;
655 fSave[nsave+6] = npx;
656 fSave[nsave+7] = npy;
657 fSave[nsave+8] = npz;
658}
659
660////////////////////////////////////////////////////////////////////////////////
661/// Save primitive as a C++ statement(s) on output stream out
662
663void TF3::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
664{
665 TString f3Name = ProvideSaveName(option);
666 out << " \n";
667 out << " TF3 *";
668
669 if (!fMethodCall)
670 out << f3Name << " = new TF3(\"" << GetName() << "\", \"" << TString(GetTitle()).ReplaceSpecialCppChars() << "\","
671 << fXmin << "," << fXmax << "," << fYmin << "," << fYmax << "," << fZmin << "," << fZmax << ");\n";
672 else
673 out << f3Name << " = new TF3(\"" << GetName() << "\", " << GetTitle() << "," << fXmin << "," << fXmax << ","
674 << fYmin << "," << fYmax << "," << fZmin << "," << fZmax << "," << GetNpar() << ");\n";
675
676 SaveFillAttributes(out, f3Name, -1, 0);
677 SaveMarkerAttributes(out, f3Name, 1, 1, 1);
678 SaveLineAttributes(out, f3Name, 1, 1, 4);
679
680 if (GetNpx() != 30)
681 out << " " << f3Name << "->SetNpx(" << GetNpx() << ");\n";
682 if (GetNpy() != 30)
683 out << " " << f3Name << "->SetNpy(" << GetNpy() << ");\n";
684 if (GetNpz() != 30)
685 out << " " << f3Name << "->SetNpz(" << GetNpz() << ");\n";
686
687 if (GetChisquare() != 0)
688 out << " " << f3Name << "->SetChisquare(" << GetChisquare() << ");\n";
689
690 Double_t parmin, parmax;
691 for (Int_t i = 0; i < GetNpar(); i++) {
692 out << " " << f3Name << "->SetParameter(" << i << "," << GetParameter(i) << ");\n";
693 out << " " << f3Name << "->SetParError(" << i << "," << GetParError(i) << ");\n";
694 GetParLimits(i, parmin, parmax);
695 out << " " << f3Name << "->SetParLimits(" << i << "," << parmin << "," << parmax << ");\n";
696 }
697
698 if (GetXaxis())
699 GetXaxis()->SaveAttributes(out, f3Name, "->GetXaxis()");
700 if (GetYaxis())
701 GetYaxis()->SaveAttributes(out, f3Name, "->GetYaxis()");
702 if (GetZaxis())
703 GetZaxis()->SaveAttributes(out, f3Name, "->GetZaxis()");
704
705 SavePrimitiveDraw(out, f3Name, option);
706}
707
708////////////////////////////////////////////////////////////////////////////////
709/// Set the function clipping box (for drawing) "on" and define the clipping box.
710/// xclip, yclip and zclip is a point within the function range. All the
711/// function values having x<=xclip and y<=yclip and z>=zclip are clipped.
712
713void TF3::SetClippingBoxOn(Double_t xclip, Double_t yclip, Double_t zclip)
714{
716 fClipBox[0] = xclip;
717 fClipBox[1] = yclip;
718 fClipBox[2] = zclip;
719}
720
721////////////////////////////////////////////////////////////////////////////////
722/// Set the number of points used to draw the function
723///
724/// The default number of points along x is 30 for 2-d/3-d functions.
725/// You can increase this value to get a better resolution when drawing
726/// pictures with sharp peaks or to get a better result when using TF3::GetRandom2
727/// the minimum number of points is 4, the maximum is 10000 for 2-d/3-d functions
728
729void TF3::SetNpz(Int_t npz)
730{
731 if (npz < 4) {
732 Warning("SetNpz","Number of points must be >=4 && <= 10000, fNpz set to 4");
733 fNpz = 4;
734 } else if(npz > 10000) {
735 Warning("SetNpz","Number of points must be >=4 && <= 10000, fNpz set to 10000");
736 fNpz = 10000;
737 } else {
738 fNpz = npz;
739 }
740 Update();
741}
742
743////////////////////////////////////////////////////////////////////////////////
744/// Initialize the upper and lower bounds to draw the function
745
747{
748 fXmin = xmin;
749 fXmax = xmax;
750 fYmin = ymin;
751 fYmax = ymax;
752 fZmin = zmin;
753 fZmax = zmax;
754 Update();
755}
756
757////////////////////////////////////////////////////////////////////////////////
758/// Stream an object of class TF3.
759
760void TF3::Streamer(TBuffer &R__b)
761{
762 if (R__b.IsReading()) {
763 UInt_t R__s, R__c;
764 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
765 if (R__v > 0) {
766 R__b.ReadClassBuffer(TF3::Class(), this, R__v, R__s, R__c);
767 return;
768 }
769
770 } else {
771 Int_t saved = 0;
772 if (fType != EFType::kFormula && fSave.empty() ) { saved = 1; Save(fXmin,fXmax,fYmin,fYmax,fZmin,fZmax);}
773
774 R__b.WriteClassBuffer(TF3::Class(),this);
775
776 if (saved) { fSave.clear(); }
777 }
778}
779
780////////////////////////////////////////////////////////////////////////////////
781/// Return x^nx * y^ny * z^nz moment of a 3d function in range [ax,bx],[ay,by],[az,bz]
782/// \author Gene Van Buren <gene@bnl.gov>
783
785{
786 Double_t norm = Integral(ax,bx,ay,by,az,bz,epsilon);
787 if (norm == 0) {
788 Error("Moment3", "Integral zero over range");
789 return 0;
790 }
791
792 // define integrand function as a lambda : g(x,y,z)= x^(nx) * y^(ny) * z^(nz) * f(x,y,z)
793 auto integrand = [&](double *x, double *) {
794 return std::pow(x[0], nx) * std::pow(x[1], ny) * std::pow(x[2], nz) * this->EvalPar(x, nullptr);
795 };
796 // compute integral of g(x,y,z)
797 TF3 fnc("TF3_ExpValHelper", integrand, ax, bx, ay, by, az, bz, 0);
798 // set same points as current function to get correct max points when computing the integral
799 fnc.fNpx = fNpx;
800 fnc.fNpy = fNpy;
801 fnc.fNpz = fNpz;
802 return fnc.Integral(ax, bx, ay, by, az, bz, epsilon) / norm;
803}
804
805////////////////////////////////////////////////////////////////////////////////
806/// Return x^nx * y^ny * z^nz central moment of a 3d function in range [ax,bx],[ay,by],[az,bz]
807/// \author Gene Van Buren <gene@bnl.gov>
808
810{
811 Double_t norm = Integral(ax,bx,ay,by,az,bz,epsilon);
812 if (norm == 0) {
813 Error("CentralMoment3", "Integral zero over range");
814 return 0;
815 }
816
817 Double_t xbar = 0;
818 Double_t ybar = 0;
819 Double_t zbar = 0;
820 if (nx!=0) {
821 // compute first momentum in x
822 auto integrandX = [&](double *x, double *) { return x[0] * this->EvalPar(x, nullptr); };
823 TF3 fncx("TF3_ExpValHelperx", integrandX, ax, bx, ay, by, az, bz, 0);
824 fncx.fNpx = fNpx;
825 fncx.fNpy = fNpy;
826 fncx.fNpz = fNpz;
827 xbar = fncx.Integral(ax, bx, ay, by, az, bz, epsilon) / norm;
828 }
829 if (ny!=0) {
830 auto integrandY = [&](double *x, double *) { return x[1] * this->EvalPar(x, nullptr); };
831 TF3 fncy("TF3_ExpValHelpery", integrandY, ax, bx, ay, by, az, bz, 0);
832 fncy.fNpx = fNpx;
833 fncy.fNpy = fNpy;
834 fncy.fNpz = fNpz;
835 ybar = fncy.Integral(ax,bx,ay,by,az,bz,epsilon)/norm;
836 }
837 if (nz!=0) {
838 auto integrandZ = [&](double *x, double *) { return x[2] * this->EvalPar(x, nullptr); };
839 TF3 fncz("TF3_ExpValHelperz", integrandZ, ax, bx, ay, by, az, bz, 0);
840 fncz.fNpx = fNpx;
841 fncz.fNpy = fNpy;
842 fncz.fNpz = fNpz;
843 zbar = fncz.Integral(ax,bx,ay,by,az,bz,epsilon)/norm;
844 }
845 // define integrand function as a lambda : g(x,y)= (x-xbar)^(nx) * (y-ybar)^(ny) * f(x,y)
846 auto integrand = [&](double *x, double *) {
847 double xxx = (nx != 0) ? std::pow(x[0] - xbar, nx) : 1.;
848 double yyy = (ny != 0) ? std::pow(x[1] - ybar, ny) : 1.;
849 double zzz = (nz != 0) ? std::pow(x[2] - zbar, nz) : 1.;
850 return xxx * yyy * zzz * this->EvalPar(x, nullptr);
851 };
852 // compute integral of g(x,y, z)
853 TF3 fnc("TF3_ExpValHelper",integrand,ax,bx,ay,by,az,bz,0) ;
854 fnc.fNpx = fNpx;
855 fnc.fNpy = fNpy;
856 fnc.fNpz = fNpz;
857 return fnc.Integral(ax,bx,ay,by,az,bz,epsilon)/norm;
858}
ROOT::R::TRInterface & r
Definition Object.C:4
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
#define a(i)
Definition RSha256.hxx:99
#define h(i)
Definition RSha256.hxx:106
int Int_t
Signed integer 4 bytes (int).
Definition RtypesCore.h:59
short Version_t
Class version identifier (short).
Definition RtypesCore.h:79
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int).
Definition RtypesCore.h:60
bool Bool_t
Boolean (0=false, 1=true) (bool).
Definition RtypesCore.h:77
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
constexpr Ssiz_t kNPOS
The equivalent of std::string::npos for the ROOT class TString.
Definition RtypesCore.h:131
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char).
Definition RtypesCore.h:80
Error("WriteTObject","The current directory (%s) is not associated with a file. The object (%s) has not been written.", GetName(), objname)
char name[80]
Definition TGX11.cxx:148
float xmin
float ymin
float xmax
float ymax
Int_t gDebug
Definition TROOT.cxx:777
#define gROOT
Definition TROOT.h:417
externTVirtualMutex * gROOTMutex
Definition TROOT.h:63
externTRandom * gRandom
Definition TRandom.h:62
#define R__LOCKGUARD(mutex)
#define gPad
virtual void SaveFillAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1001)
virtual void SaveLineAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1, Int_t widdef=1)
virtual void SaveMarkerAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1, Int_t sizdef=1)
void SaveAttributes(std::ostream &out, const char *name, const char *subname) override
Save axis attributes as C++ statement(s) on output stream out.
Definition TAxis.cxx:715
Buffer base class used for serializing objects.
Definition TBuffer.h:43
virtual Version_t ReadVersion(UInt_t *start=nullptr, UInt_t *bcnt=nullptr, const TClass *cl=nullptr)=0
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=nullptr)=0
Bool_t IsReading() const
Definition TBuffer.h:86
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
virtual Double_t GetMinMaxNDim(Double_t *x, Bool_t findmax, Double_t epsilon=0, Int_t maxiter=0) const
TAxis * GetYaxis() const
Double_t GetChisquare() const
Return the Chisquare after fitting. See ROOT::Fit::FitResult::Chi2().
Definition TF1.h:409
Double_t fXmin
Lower bounds for the range.
Definition TF1.h:212
std::unique_ptr< TMethodCall > fMethodCall
! Pointer to MethodCall in case of interpreted function
Definition TF1.h:233
virtual void InitArgs(const Double_t *x, const Double_t *params)
TAxis * GetZaxis() const
virtual void GetParLimits(Int_t ipar, Double_t &parmin, Double_t &parmax) const
virtual Int_t GetNpar() const
Definition TF1.h:446
TString ProvideSaveName(Option_t *option)
TH1 * fHistogram
! Pointer to histogram used for visualisation
Definition TF1.h:232
virtual Double_t * GetParameters() const
Definition TF1.h:485
virtual void Update()
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
Computes distance from point (px,py) to the object.
EFType fType
Definition TF1.h:217
virtual Double_t GetParError(Int_t ipar) const
Int_t fNpx
Number of points used for the graphical representation.
Definition TF1.h:216
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Execute action corresponding to an event at (px,py).
std::vector< Double_t > fSave
Array of fNsave function values.
Definition TF1.h:226
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)
virtual void SetParameters(const Double_t *params)
Definition TF1.h:618
std::vector< Double_t > fIntegral
! Integral of function binned on fNpx bins
Definition TF1.h:227
virtual Double_t EvalPar(const Double_t *x, const Double_t *params=nullptr)
@ kFormula
Formula functions which can be stored,.
Definition TF1.h:204
virtual Int_t GetNpx() const
Definition TF1.h:455
Double_t fXmax
Upper bounds for the range.
Definition TF1.h:213
virtual Double_t GetParameter(Int_t ipar) const
Definition TF1.h:477
TAxis * GetXaxis() const
Definition TF2.h:29
void Copy(TObject &f2) const override
Copy this to obj.
Int_t fNpy
Number of points along y used for the graphical representation.
Definition TF2.h:34
Double_t fYmax
Upper bound for the range in y.
Definition TF2.h:33
Double_t fYmin
Lower bound for the range in y.
Definition TF2.h:32
Int_t GetNpy() const
Definition TF2.h:81
Definition TF3.h:28
virtual void SetClippingBoxOff()
void GetRange(Double_t &xmin, Double_t &xmax) const override
Definition TF3.h:127
static TClass * Class()
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)
void Paint(Option_t *option="") override
This method must be overridden if a class wants to paint itself.
Int_t GetNpz() const
Definition TF3.h:78
Bool_t IsInside(const Double_t *x) const override
return kTRUE if the point is inside the function range
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)
virtual Double_t GetMaximumXYZ(Double_t &x, Double_t &y, Double_t &z)
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Execute action corresponding to an event at (px,py).
Double_t fZmin
Lower bound for the range in z.
Definition TF3.h:31
TF3 & operator=(const TF3 &rhs)
virtual Double_t GetMinimumXYZ(Double_t &x, Double_t &y, Double_t &z)
static void InitStandardFunctions()
void Copy(TObject &f3) const override
Copy this to obj.
Double_t FindMinMax(Double_t *x, bool findmax) const override
virtual void GetRandom3(Double_t &xrandom, Double_t &yrandom, Double_t &zrandom, TRandom *rng=nullptr)
~TF3() override
Bool_t fClipBoxOn
! Is clip box on
Definition TF3.h:34
Int_t fNpz
Number of points along z used for the graphical representation.
Definition TF3.h:33
void Draw(Option_t *option="") override
Default Draw method for all objects.
virtual void SetClippingBoxOn(Double_t xclip=0, Double_t yclip=0, Double_t zclip=0)
Double_t fZmax
Upper bound for the range in z.
Definition TF3.h:32
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
Computes distance from point (px,py) to the object.
virtual void SetNpz(Int_t npz=30)
void Streamer(TBuffer &) override
Stream an object of class TObject.
TH1 * CreateHistogram() override
void Save(Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax, Double_t zmin, Double_t zmax) override
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)
Double_t GetSave(const Double_t *x) override
Double_t fClipBox[3]
! Coordinates of clipbox
Definition TF3.h:35
void SetRange(Double_t xmin, Double_t xmax) override
Definition TF3.h:131
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save a primitive as a C++ statement(s) on output stream "out".
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:109
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
Mother of all ROOT objects.
Definition TObject.h:42
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1084
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition TObject.cxx:204
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1098
static void SavePrimitiveDraw(std::ostream &out, const char *variable_name, Option_t *option=nullptr)
Save invocation of primitive Draw() method Skipped if option contains "nodraw" string.
Definition TObject.cxx:845
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:1072
This is the base class for the ROOT Random number generators.
Definition TRandom.h:27
Double_t Rndm() override
Machine independent random number generator.
Definition TRandom.cxx:558
void ToLower()
Change string to lower-case.
Definition TString.cxx:1189
const char * Data() const
Definition TString.h:384
TString & Append(const char *cs)
Definition TString.h:581
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:641
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:660
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
ParamFunctorTempl< double > ParamFunctor
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
Definition RExports.h:168
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:249
Double_t QuietNaN()
Returns a quiet NaN as defined by IEEE 754.
Definition TMath.h:913
Int_t Finite(Double_t x)
Check if it is finite with a mask in order to be consistent in presence of fast math.
Definition TMath.h:781
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:197
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Binary search in an array of n values to locate value.
Definition TMathBase.h:329
Double_t Infinity()
Returns an infinity as defined by the IEEE standard.
Definition TMath.h:928
TLine l
Definition textangle.C:4
auto * tt
Definition textangle.C:16