ROOT logo
// @(#)root/unuran:$Id: TUnuranMultiContDist.cxx 20882 2007-11-19 11:31:26Z rdm $
// Authors: L. Moneta, J. Leydold Wed Feb 28 2007

/**********************************************************************
 *                                                                    *
 * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
 *                                                                    *
 *                                                                    *
 **********************************************************************/

// Implementation file for class TUnuranMultiContDist

#include "TUnuranMultiContDist.h"

#include "TF1.h"
#include <cassert>


TUnuranMultiContDist::TUnuranMultiContDist (TF1 * func, unsigned int dim, bool isLogPdf) : 
   fPdf(func), 
   fDim( dim ),
   fIsLogPdf(isLogPdf)
{
   //Constructor from a TF1 objects
   if (fDim == 0) fDim = func->GetNdim(); 
} 



TUnuranMultiContDist::TUnuranMultiContDist(const TUnuranMultiContDist & rhs) : 
   TUnuranBaseDist()
{
   // Implementation of copy ctor using assignment operator
   operator=(rhs);
}

TUnuranMultiContDist & TUnuranMultiContDist::operator = (const TUnuranMultiContDist &rhs) 
{
   // Implementation of assignment operator (copy only the funciton pointer not the function itself)
   if (this == &rhs) return *this;  // time saving self-test
   fPdf  = rhs.fPdf;
   fDim  = rhs.fDim;
   fXmin = rhs.fXmin;
   fXmax = rhs.fXmax;
   fMode = rhs.fMode;
   fIsLogPdf  = rhs.fIsLogPdf;
   return *this;
}



double TUnuranMultiContDist::Pdf ( const double * x) const {  
   // evaluate the distribution 
   assert(fPdf != 0);
   fPdf->InitArgs(x, (double *) 0);
   return fPdf->EvalPar(x); 
}


void TUnuranMultiContDist::Gradient( const double * x, double * grad) const { 
      // do numerical derivation of gradient
   std::vector<double> g(fDim); 
   for (unsigned int i = 0; i < fDim; ++i) 
      g[i] = Derivative(x,i); 
      
   grad = &g.front();
   return;
}

double TUnuranMultiContDist::Derivative( const double * x, int coord) const { 
    // do numerical derivation of gradient using 5 point rule
   // use 5 point rule 

   //double eps = 0.001; 
   //const double kC1 = 8*std::numeric_limits<double>::epsilon();
   assert(fPdf != 0);

   double h = 0.001; 

   std::vector<double> xx(fDim);
   double * params = fPdf->GetParameters();
   fPdf->InitArgs(&xx.front(), params);
 
   xx[coord] = x[coord]+h;     double f1 = fPdf->EvalPar(&xx.front(),params);
   //xx[coord] = x[coord];       double fx = fPdf->EvalPar(&xx.front(),params);
   xx[coord] = x[coord]-h;     double f2 = fPdf->EvalPar(&xx.front(),params);

   xx[coord] = x[coord]+h/2;   double g1 = fPdf->EvalPar(&xx.front(),params);
   xx[coord] = x[coord]-h/2;   double g2 = fPdf->EvalPar(&xx.front(),params);

   //compute the central differences
   double h2    = 1/(2.*h);
   double d0    = f1 - f2;
   double d2    = 2*(g1 - g2);
   //double error  = kC1*h2*fx;  //compute the error
   double deriv = h2*(4*d2 - d0)/3.;  
   return deriv;
}



 TUnuranMultiContDist.cxx:1
 TUnuranMultiContDist.cxx:2
 TUnuranMultiContDist.cxx:3
 TUnuranMultiContDist.cxx:4
 TUnuranMultiContDist.cxx:5
 TUnuranMultiContDist.cxx:6
 TUnuranMultiContDist.cxx:7
 TUnuranMultiContDist.cxx:8
 TUnuranMultiContDist.cxx:9
 TUnuranMultiContDist.cxx:10
 TUnuranMultiContDist.cxx:11
 TUnuranMultiContDist.cxx:12
 TUnuranMultiContDist.cxx:13
 TUnuranMultiContDist.cxx:14
 TUnuranMultiContDist.cxx:15
 TUnuranMultiContDist.cxx:16
 TUnuranMultiContDist.cxx:17
 TUnuranMultiContDist.cxx:18
 TUnuranMultiContDist.cxx:19
 TUnuranMultiContDist.cxx:20
 TUnuranMultiContDist.cxx:21
 TUnuranMultiContDist.cxx:22
 TUnuranMultiContDist.cxx:23
 TUnuranMultiContDist.cxx:24
 TUnuranMultiContDist.cxx:25
 TUnuranMultiContDist.cxx:26
 TUnuranMultiContDist.cxx:27
 TUnuranMultiContDist.cxx:28
 TUnuranMultiContDist.cxx:29
 TUnuranMultiContDist.cxx:30
 TUnuranMultiContDist.cxx:31
 TUnuranMultiContDist.cxx:32
 TUnuranMultiContDist.cxx:33
 TUnuranMultiContDist.cxx:34
 TUnuranMultiContDist.cxx:35
 TUnuranMultiContDist.cxx:36
 TUnuranMultiContDist.cxx:37
 TUnuranMultiContDist.cxx:38
 TUnuranMultiContDist.cxx:39
 TUnuranMultiContDist.cxx:40
 TUnuranMultiContDist.cxx:41
 TUnuranMultiContDist.cxx:42
 TUnuranMultiContDist.cxx:43
 TUnuranMultiContDist.cxx:44
 TUnuranMultiContDist.cxx:45
 TUnuranMultiContDist.cxx:46
 TUnuranMultiContDist.cxx:47
 TUnuranMultiContDist.cxx:48
 TUnuranMultiContDist.cxx:49
 TUnuranMultiContDist.cxx:50
 TUnuranMultiContDist.cxx:51
 TUnuranMultiContDist.cxx:52
 TUnuranMultiContDist.cxx:53
 TUnuranMultiContDist.cxx:54
 TUnuranMultiContDist.cxx:55
 TUnuranMultiContDist.cxx:56
 TUnuranMultiContDist.cxx:57
 TUnuranMultiContDist.cxx:58
 TUnuranMultiContDist.cxx:59
 TUnuranMultiContDist.cxx:60
 TUnuranMultiContDist.cxx:61
 TUnuranMultiContDist.cxx:62
 TUnuranMultiContDist.cxx:63
 TUnuranMultiContDist.cxx:64
 TUnuranMultiContDist.cxx:65
 TUnuranMultiContDist.cxx:66
 TUnuranMultiContDist.cxx:67
 TUnuranMultiContDist.cxx:68
 TUnuranMultiContDist.cxx:69
 TUnuranMultiContDist.cxx:70
 TUnuranMultiContDist.cxx:71
 TUnuranMultiContDist.cxx:72
 TUnuranMultiContDist.cxx:73
 TUnuranMultiContDist.cxx:74
 TUnuranMultiContDist.cxx:75
 TUnuranMultiContDist.cxx:76
 TUnuranMultiContDist.cxx:77
 TUnuranMultiContDist.cxx:78
 TUnuranMultiContDist.cxx:79
 TUnuranMultiContDist.cxx:80
 TUnuranMultiContDist.cxx:81
 TUnuranMultiContDist.cxx:82
 TUnuranMultiContDist.cxx:83
 TUnuranMultiContDist.cxx:84
 TUnuranMultiContDist.cxx:85
 TUnuranMultiContDist.cxx:86
 TUnuranMultiContDist.cxx:87
 TUnuranMultiContDist.cxx:88
 TUnuranMultiContDist.cxx:89
 TUnuranMultiContDist.cxx:90
 TUnuranMultiContDist.cxx:91
 TUnuranMultiContDist.cxx:92
 TUnuranMultiContDist.cxx:93
 TUnuranMultiContDist.cxx:94
 TUnuranMultiContDist.cxx:95
 TUnuranMultiContDist.cxx:96
 TUnuranMultiContDist.cxx:97
 TUnuranMultiContDist.cxx:98
 TUnuranMultiContDist.cxx:99
 TUnuranMultiContDist.cxx:100
 TUnuranMultiContDist.cxx:101