Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
EvaluateFuncs.h
Go to the documentation of this file.
1/*
2 * Project: RooFit
3 * Authors:
4 * Jonas Rembser, CERN 2023
5 * Garima Singh, CERN 2023
6 *
7 * Copyright (c) 2023, CERN
8 *
9 * Redistribution and use in source and binary forms,
10 * with or without modification, are permitted according to the terms
11 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)
12 */
13
14#ifndef RooFit_Detail_EvaluateFuncs_h
15#define RooFit_Detail_EvaluateFuncs_h
16
17#include <TMath.h>
19
20#include <cmath>
21
22namespace RooFit {
23
24namespace Detail {
25
26namespace EvaluateFuncs {
27
28/// @brief Function to evaluate an un-normalized RooGaussian.
29inline double gaussianEvaluate(double x, double mean, double sigma)
30{
31 const double arg = x - mean;
32 const double sig = sigma;
33 return std::exp(-0.5 * arg * arg / (sig * sig));
34}
35
36/// In pdfMode, a coefficient for the constant term of 1.0 is implied if lowestOrder > 0.
37template <bool pdfMode = false>
38inline double polynomialEvaluate(double const *coeffs, int nCoeffs, int lowestOrder, double x)
39{
40 double retVal = coeffs[nCoeffs - 1];
41 for (int i = nCoeffs - 2; i >= 0; i--)
42 retVal = coeffs[i] + x * retVal;
43 retVal = retVal * std::pow(x, lowestOrder);
44 return retVal + (pdfMode && lowestOrder > 0 ? 1.0 : 0.0);
45}
46
47inline double chebychevEvaluate(double *coeffs, unsigned int nCoeffs, double x_in, double xMin, double xMax)
48{
49 // transform to range [-1, +1]
50 const double xPrime = (x_in - 0.5 * (xMax + xMin)) / (0.5 * (xMax - xMin));
51
52 // extract current values of coefficients
53 double sum = 1.;
54 if (nCoeffs > 0) {
55 double curr = xPrime;
56 double twox = 2 * xPrime;
57 double last = 1;
58 double newval = twox * curr - last;
59 last = curr;
60 curr = newval;
61 for (unsigned int i = 0; nCoeffs != i; ++i) {
62 sum += last * coeffs[i];
63 newval = twox * curr - last;
64 last = curr;
65 curr = newval;
66 }
67 }
68 return sum;
69}
70
71inline double constraintSumEvaluate(double const *comp, unsigned int compSize)
72{
73 double sum = 0;
74 for (unsigned int i = 0; i < compSize; i++) {
75 sum -= std::log(comp[i]);
76 }
77 return sum;
78}
79
80inline unsigned int getUniformBinning(double low, double high, double val, unsigned int numBins)
81{
82 double binWidth = (high - low) / numBins;
83 return val >= high ? numBins - 1 : std::abs((val - low) / binWidth);
84}
85
86inline double poissonEvaluate(double x, double par)
87{
88 if (par < 0)
89 return TMath::QuietNaN();
90
91 if (x < 0)
92 return 0;
93 else if (x == 0.0)
94 return std::exp(-par);
95 else {
96 double out = x * std::log(par) - TMath::LnGamma(x + 1.) - par;
97 return std::exp(out);
98 }
99}
100
101inline double interpolate6thDegree(double x, double low, double high, double nominal, double boundary)
102{
103 double t = x / boundary;
104 double eps_plus = high - nominal;
105 double eps_minus = nominal - low;
106 double S = 0.5 * (eps_plus + eps_minus);
107 double A = 0.0625 * (eps_plus - eps_minus);
108
109 return x * (S + t * A * (15 + t * t * (-10 + t * t * 3)));
110}
111
112inline double interpolate6thDegreeExp(double x, double low, double high, double nominal, double boundary)
113{
114 double x0 = boundary;
115
116 high /= nominal;
117 low /= nominal;
118
119 // GHL: Swagato's suggestions
120 double powUp = std::pow(high, x0);
121 double powDown = std::pow(low, x0);
122 double logHi = std::log(high);
123 double logLo = std::log(low);
124 double powUpLog = high <= 0.0 ? 0.0 : powUp * logHi;
125 double powDownLog = low <= 0.0 ? 0.0 : -powDown * logLo;
126 double powUpLog2 = high <= 0.0 ? 0.0 : powUpLog * logHi;
127 double powDownLog2 = low <= 0.0 ? 0.0 : -powDownLog * logLo;
128
129 double S0 = 0.5 * (powUp + powDown);
130 double A0 = 0.5 * (powUp - powDown);
131 double S1 = 0.5 * (powUpLog + powDownLog);
132 double A1 = 0.5 * (powUpLog - powDownLog);
133 double S2 = 0.5 * (powUpLog2 + powDownLog2);
134 double A2 = 0.5 * (powUpLog2 - powDownLog2);
135
136 // fcns+der+2nd_der are eq at bd
137
138 double a = 1. / (8 * x0) * (15 * A0 - 7 * x0 * S1 + x0 * x0 * A2);
139 double b = 1. / (8 * x0 * x0) * (-24 + 24 * S0 - 9 * x0 * A1 + x0 * x0 * S2);
140 double c = 1. / (4 * std::pow(x0, 3)) * (-5 * A0 + 5 * x0 * S1 - x0 * x0 * A2);
141 double d = 1. / (4 * std::pow(x0, 4)) * (12 - 12 * S0 + 7 * x0 * A1 - x0 * x0 * S2);
142 double e = 1. / (8 * std::pow(x0, 5)) * (+3 * A0 - 3 * x0 * S1 + x0 * x0 * A2);
143 double f = 1. / (8 * std::pow(x0, 6)) * (-8 + 8 * S0 - 5 * x0 * A1 + x0 * x0 * S2);
144
145 // evaluate the 6-th degree polynomial using Horner's method
146 double value = 1. + x * (a + x * (b + x * (c + x * (d + x * (e + x * f)))));
147 return value;
148}
149
150inline double
151flexibleInterp(unsigned int code, double low, double high, double boundary, double nominal, double paramVal, double res)
152{
153 if (code == 0) {
154 // piece-wise linear
155 if (paramVal > 0)
156 return paramVal * (high - nominal);
157 else
158 return paramVal * (nominal - low);
159 } else if (code == 1) {
160 // piece-wise log
161 if (paramVal >= 0)
162 return res * (std::pow(high / nominal, +paramVal) - 1);
163 else
164 return res * (std::pow(low / nominal, -paramVal) - 1);
165 } else if (code == 2) {
166 // parabolic with linear
167 double a = 0.5 * (high + low) - nominal;
168 double b = 0.5 * (high - low);
169 double c = 0;
170 if (paramVal > 1) {
171 return (2 * a + b) * (paramVal - 1) + high - nominal;
172 } else if (paramVal < -1) {
173 return -1 * (2 * a - b) * (paramVal + 1) + low - nominal;
174 } else {
175 return a * std::pow(paramVal, 2) + b * paramVal + c;
176 }
177 } else if (code == 3) {
178 // parabolic version of log-normal
179 double a = 0.5 * (high + low) - nominal;
180 double b = 0.5 * (high - low);
181 double c = 0;
182 if (paramVal > 1) {
183 return (2 * a + b) * (paramVal - 1) + high - nominal;
184 } else if (paramVal < -1) {
185 return -1 * (2 * a - b) * (paramVal + 1) + low - nominal;
186 } else {
187 return a * std::pow(paramVal, 2) + b * paramVal + c;
188 }
189 } else if (code == 4) {
190 double x = paramVal;
191 if (x >= boundary) {
192 return x * (high - nominal);
193 } else if (x <= -boundary) {
194 return x * (nominal - low);
195 }
196
197 return interpolate6thDegree(x, low, high, nominal, boundary);
198 } else if (code == 5) {
199 double x = paramVal;
200 double mod = 1.0;
201 if (x >= boundary) {
202 mod = std::pow(high / nominal, +paramVal);
203 } else if (x <= -boundary) {
204 mod = std::pow(low / nominal, -paramVal);
205 } else {
206 mod = interpolate6thDegreeExp(x, low, high, nominal, boundary);
207 }
208 return res * (mod - 1.0);
209 }
210
211 return 0.0;
212}
213
214inline double logNormalEvaluate(double x, double k, double m0)
215{
216 return ROOT::Math::lognormal_pdf(x, std::log(m0), std::abs(std::log(k)));
217}
218
219inline double logNormalEvaluateStandard(double x, double sigma, double mu)
220{
221 return ROOT::Math::lognormal_pdf(x, mu, std::abs(sigma));
222}
223
224} // namespace EvaluateFuncs
225
226} // namespace Detail
227
228} // namespace RooFit
229
230#endif
#define d(i)
Definition RSha256.hxx:102
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
#define S0(x)
Definition RSha256.hxx:88
#define S1(x)
Definition RSha256.hxx:89
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
#define e(i)
Definition RSha256.hxx:103
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
double lognormal_pdf(double x, double m, double s, double x0=0)
Probability density function of the lognormal distribution.
const Double_t sigma
Double_t x[n]
Definition legend1.C:17
double poissonEvaluate(double x, double par)
double constraintSumEvaluate(double const *comp, unsigned int compSize)
double gaussianEvaluate(double x, double mean, double sigma)
Function to evaluate an un-normalized RooGaussian.
double flexibleInterp(unsigned int code, double low, double high, double boundary, double nominal, double paramVal, double res)
double polynomialEvaluate(double const *coeffs, int nCoeffs, int lowestOrder, double x)
In pdfMode, a coefficient for the constant term of 1.0 is implied if lowestOrder > 0.
double logNormalEvaluate(double x, double k, double m0)
double logNormalEvaluateStandard(double x, double sigma, double mu)
double interpolate6thDegreeExp(double x, double low, double high, double nominal, double boundary)
unsigned int getUniformBinning(double low, double high, double val, unsigned int numBins)
double interpolate6thDegree(double x, double low, double high, double nominal, double boundary)
double chebychevEvaluate(double *coeffs, unsigned int nCoeffs, double x_in, double xMin, double xMax)
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
Definition JSONIO.h:26
Double_t QuietNaN()
Returns a quiet NaN as defined by IEEE 754.
Definition TMath.h:902
Double_t LnGamma(Double_t z)
Computation of ln[gamma(z)] for all z.
Definition TMath.cxx:509
static uint64_t sum(uint64_t i)
Definition Factory.cxx:2345