37 #ifndef ROOT_Math_PdfFuncMathCore
38 #define ROOT_Math_PdfFuncMathCore
82 inline double beta_pdf(
double x,
double a,
double b) {
85 if (x < 0 || x > 1.0)
return 0;
88 if (a < 1)
return std::numeric_limits<double>::infinity();
89 else if (a > 1)
return 0;
90 else if ( a == 1)
return b;
94 if (b < 1)
return std::numeric_limits<double>::infinity();
95 else if (b > 1)
return 0;
96 else if ( b == 1)
return a;
98 return std::exp( ROOT::Math::lgamma(a + b) - ROOT::Math::lgamma(a) - ROOT::Math::lgamma(b) +
99 std::log(x) * (a -1.) + ROOT::Math::log1p(-x ) * (b - 1.) );
118 inline double binomial_pdf(
unsigned int k,
double p,
unsigned int n) {
123 double coeff = ROOT::Math::lgamma(n+1) - ROOT::Math::lgamma(k+1) - ROOT::Math::lgamma(n-k+1);
124 return std::exp(coeff + k * std::log(p) + (n - k) * ROOT::Math::log1p(-p));
146 inline double negative_binomial_pdf(
unsigned int k,
double p,
double n) {
151 if (n < 0)
return 0.0;
152 if (p < 0 || p > 1.0)
return 0.0;
154 double coeff = ROOT::Math::lgamma(k+n) - ROOT::Math::lgamma(k+1.0) - ROOT::Math::lgamma(n);
155 return std::exp(coeff + n * std::log(p) +
double(k) * ROOT::Math::log1p(-p));
175 inline double breitwigner_pdf(
double x,
double gamma,
double x0 = 0) {
177 double gammahalf = gamma/2.0;
178 return gammahalf/(M_PI * ((x-x0)*(x-x0) + gammahalf*gammahalf));
201 inline double cauchy_pdf(
double x,
double b = 1,
double x0 = 0) {
203 return b/(M_PI * ((x-x0)*(x-x0) + b*b));
225 inline double chisquared_pdf(
double x,
double r,
double x0 = 0) {
233 if (x == x0 && a == 0)
return 0.5;
235 return std::exp ((r/2 - 1) * std::log((x-x0)/2) - (x-x0)/2 - ROOT::Math::lgamma(r/2))/2;
254 inline double crystalball_function(
double x,
double alpha,
double n,
double sigma,
double mean = 0) {
258 if (sigma < 0.)
return 0.;
259 double z = (x - mean)/sigma;
260 if (alpha < 0) z = -z;
261 double abs_alpha = std::abs(alpha);
266 return std::exp(- 0.5 * z * z);
268 double nDivAlpha = n/abs_alpha;
269 double AA = std::exp(-0.5*abs_alpha*abs_alpha);
270 double B = nDivAlpha -abs_alpha;
271 double arg = nDivAlpha/(B-z);
272 return AA * std::pow(arg,n);
278 inline double crystalball_pdf(
double x,
double alpha,
double n,
double sigma,
double mean = 0) {
282 if (sigma < 0.)
return 0.;
283 if ( n <= 1)
return std::numeric_limits<double>::quiet_NaN();
284 double abs_alpha = std::abs(alpha);
285 double C = n/abs_alpha * 1./(n-1.) * std::exp(-alpha*alpha/2.);
286 double D = std::sqrt(M_PI/2.)*(1.+ROOT::Math::erf(abs_alpha/std::sqrt(2.)));
287 double N = 1./(sigma*(C+D));
288 return N * crystalball_function(x,alpha,n,sigma,mean);
306 inline double exponential_pdf(
double x,
double lambda,
double x0 = 0) {
311 return lambda * std::exp (-lambda * (x-x0));
332 inline double fdistribution_pdf(
double x,
double n,
double m,
double x0 = 0) {
337 return std::numeric_limits<double>::quiet_NaN();
341 return std::exp((n/2) * std::log(n) + (m/2) * std::log(m) + ROOT::Math::lgamma((n+m)/2) - ROOT::Math::lgamma(n/2) - ROOT::Math::lgamma(m/2)
342 + (n/2 -1) * std::log(x-x0) - ((n+m)/2) * std::log(m + n*(x-x0)) );
363 inline double gamma_pdf(
double x,
double alpha,
double theta,
double x0 = 0) {
368 }
else if ((x-x0) == 0) {
376 }
else if (alpha == 1) {
377 return std::exp(-(x-x0)/theta)/theta;
379 return std::exp((alpha - 1) * std::log((x-x0)/theta) - (x-x0)/theta - ROOT::Math::lgamma(alpha))/theta;
402 inline double gaussian_pdf(
double x,
double sigma = 1,
double x0 = 0) {
404 double tmp = (x-x0)/sigma;
405 return (1.0/(std::sqrt(2 * M_PI) * std::fabs(sigma))) * std::exp(-tmp*tmp/2);
425 inline double bigaussian_pdf(
double x,
double y,
double sigmax = 1,
double sigmay = 1,
double rho = 0,
double x0 = 0,
double y0 = 0) {
426 double u = (x-x0)/sigmax;
427 double v = (y-y0)/sigmay;
428 double c = 1. - rho*rho;
429 double z = u*u - 2.*rho*u*v + v*v;
430 return 1./(2 * M_PI * sigmax * sigmay * std::sqrt(c) ) * std::exp(- z / (2. * c) );
455 double landau_pdf(
double x,
double xi = 1,
double x0 = 0);
475 inline double lognormal_pdf(
double x,
double m,
double s,
double x0 = 0) {
479 double tmp = (std::log((x-x0)) - m)/s;
480 return 1.0 / ((x-x0) * std::fabs(s) * std::sqrt(2 * M_PI)) * std::exp(-(tmp * tmp) /2);
501 inline double normal_pdf(
double x,
double sigma =1,
double x0 = 0) {
504 double tmp = (x-x0)/sigma;
505 return (1.0/(std::sqrt(2 * M_PI) * std::fabs(sigma))) * std::exp(-tmp*tmp/2);
524 inline double poisson_pdf(
unsigned int n,
double mu) {
528 return std::exp (n*std::log(mu) - ROOT::Math::lgamma(n+1) - mu);
532 return std::exp(-mu);
555 inline double tdistribution_pdf(
double x,
double r,
double x0 = 0) {
558 return (std::exp (ROOT::Math::lgamma((r + 1.0)/2.0) - ROOT::Math::lgamma(r/2.0)) / std::sqrt (M_PI * r))
559 * std::pow ((1.0 + (x-x0)*(x-x0)/r), -(r + 1.0)/2.0);
580 inline double uniform_pdf(
double x,
double a,
double b,
double x0 = 0) {
585 if ((x-x0) < b && (x-x0) >= a)
598 #endif // ROOT_Math_PdfFunc