Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TUnuranMultiContDist.cxx
Go to the documentation of this file.
1 // @(#)root/unuran:$Id$
2 // Authors: L. Moneta, J. Leydold Wed Feb 28 2007
3 
4 /**********************************************************************
5  * *
6  * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT *
7  * *
8  * *
9  **********************************************************************/
10 
11 // Implementation file for class TUnuranMultiContDist
12 
13 #include "TUnuranMultiContDist.h"
14 #include "Math/WrappedMultiTF1.h"
15 
16 #include "TF1.h"
17 #include <cassert>
18 
19 
20 TUnuranMultiContDist::TUnuranMultiContDist (const ROOT::Math::IMultiGenFunction & pdf, bool isLogPdf) :
21  fPdf(&pdf),
22  fIsLogPdf(isLogPdf),
23  fOwnFunc(false)
24 {
25  //Constructor from generic function interfaces
26 }
27 
28 
29 TUnuranMultiContDist::TUnuranMultiContDist (TF1 * func, unsigned int dim, bool isLogPdf) :
30  fPdf(0),
31  fIsLogPdf(isLogPdf),
32  fOwnFunc(false)
33 {
34  //Constructor from a TF1 objects
35  if (func) {
36  fPdf = new ROOT::Math::WrappedMultiTF1( *func, dim);
37  fOwnFunc = true;
38  }
39 }
40 
41 
42 
43 TUnuranMultiContDist::TUnuranMultiContDist(const TUnuranMultiContDist & rhs) :
44  TUnuranBaseDist(),
45  fPdf(0)
46 {
47  // Implementation of copy ctor using assignment operator
48  operator=(rhs);
49 }
50 
51 TUnuranMultiContDist & TUnuranMultiContDist::operator = (const TUnuranMultiContDist &rhs)
52 {
53  // Implementation of assignment operator (copy only the function pointer not the function itself)
54  if (this == &rhs) return *this; // time saving self-test
55  fXmin = rhs.fXmin;
56  fXmax = rhs.fXmax;
57  fMode = rhs.fMode;
58  fIsLogPdf = rhs.fIsLogPdf;
59  fOwnFunc = rhs.fOwnFunc;
60  if (!fOwnFunc)
61  fPdf = rhs.fPdf;
62  else {
63  if (fPdf) delete fPdf;
64  fPdf = (rhs.fPdf) ? rhs.fPdf->Clone() : 0;
65  }
66  return *this;
67 }
68 
69 TUnuranMultiContDist::~TUnuranMultiContDist() {
70  // destructor implementation
71  if (fOwnFunc && fPdf) delete fPdf;
72 }
73 
74 
75 double TUnuranMultiContDist::Pdf ( const double * x) const {
76  // evaluate the distribution
77  assert(fPdf != 0);
78  return (*fPdf)(x);
79 }
80 
81 
82 void TUnuranMultiContDist::Gradient( const double * x, double * grad) const {
83  // do numerical derivation and return gradient in vector grad
84  // grad must point to a vector of at least ndim size
85  unsigned int ndim = NDim();
86  for (unsigned int i = 0; i < ndim; ++i)
87  grad[i] = Derivative(x,i);
88 
89  return;
90 }
91 
92 double TUnuranMultiContDist::Derivative( const double * x, int coord) const {
93  // do numerical derivation of gradient using 5 point rule
94  // use 5 point rule
95 
96  //double eps = 0.001;
97  //const double kC1 = 8*std::numeric_limits<double>::epsilon();
98  assert(fPdf != 0);
99 
100  double h = 0.001;
101 
102  std::vector<double> xx(NDim() );
103 
104  xx[coord] = x[coord]+h; double f1 = (*fPdf)(&xx.front());
105  xx[coord] = x[coord]-h; double f2 = (*fPdf)(&xx.front());
106 
107  xx[coord] = x[coord]+h/2; double g1 = (*fPdf)(&xx.front());
108  xx[coord] = x[coord]-h/2; double g2 = (*fPdf)(&xx.front());
109 
110  //compute the central differences
111  double h2 = 1/(2.*h);
112  double d0 = f1 - f2;
113  double d2 = 2*(g1 - g2);
114  //double error = kC1*h2*fx; //compute the error
115  double deriv = h2*(4*d2 - d0)/3.;
116  return deriv;
117 }
118 
119 
120