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 // GHL: Swagato's suggestions
117 double powUp = std::pow(high / nominal, x0);
118 double powDown = std::pow(low / nominal, x0);
119 double logHi = std::log(high);
120 double logLo = std::log(low);
121 double powUpLog = high <= 0.0 ? 0.0 : powUp * logHi;
122 double powDownLog = low <= 0.0 ? 0.0 : -powDown * logLo;
123 double powUpLog2 = high <= 0.0 ? 0.0 : powUpLog * logHi;
124 double powDownLog2 = low <= 0.0 ? 0.0 : -powDownLog * logLo;
125
126 double S0 = 0.5 * (powUp + powDown);
127 double A0 = 0.5 * (powUp - powDown);
128 double S1 = 0.5 * (powUpLog + powDownLog);
129 double A1 = 0.5 * (powUpLog - powDownLog);
130 double S2 = 0.5 * (powUpLog2 + powDownLog2);
131 double A2 = 0.5 * (powUpLog2 - powDownLog2);
132
133 // fcns+der+2nd_der are eq at bd
134
135 double a = 1. / (8 * x0) * (15 * A0 - 7 * x0 * S1 + x0 * x0 * A2);
136 double b = 1. / (8 * x0 * x0) * (-24 + 24 * S0 - 9 * x0 * A1 + x0 * x0 * S2);
137 double c = 1. / (4 * std::pow(x0, 3)) * (-5 * A0 + 5 * x0 * S1 - x0 * x0 * A2);
138 double d = 1. / (4 * std::pow(x0, 4)) * (12 - 12 * S0 + 7 * x0 * A1 - x0 * x0 * S2);
139 double e = 1. / (8 * std::pow(x0, 5)) * (+3 * A0 - 3 * x0 * S1 + x0 * x0 * A2);
140 double f = 1. / (8 * std::pow(x0, 6)) * (-8 + 8 * S0 - 5 * x0 * A1 + x0 * x0 * S2);
141
142 // evaluate the 6-th degree polynomial using Horner's method
143 double value = 1. + x * (a + x * (b + x * (c + x * (d + x * (e + x * f)))));
144 return value;
145}
146
147inline double
148flexibleInterp(unsigned int code, double low, double high, double boundary, double nominal, double paramVal, double res)
149{
150 if (code == 0) {
151 // piece-wise linear
152 if (paramVal > 0)
153 return paramVal * (high - nominal);
154 else
155 return paramVal * (nominal - low);
156 } else if (code == 1) {
157 // piece-wise log
158 if (paramVal >= 0)
159 return res * (std::pow(high / nominal, +paramVal) - 1);
160 else
161 return res * (std::pow(low / nominal, -paramVal) - 1);
162 } else if (code == 2) {
163 // parabolic with linear
164 double a = 0.5 * (high + low) - nominal;
165 double b = 0.5 * (high - low);
166 double c = 0;
167 if (paramVal > 1) {
168 return (2 * a + b) * (paramVal - 1) + high - nominal;
169 } else if (paramVal < -1) {
170 return -1 * (2 * a - b) * (paramVal + 1) + low - nominal;
171 } else {
172 return a * std::pow(paramVal, 2) + b * paramVal + c;
173 }
174 } else if (code == 3) {
175 // parabolic version of log-normal
176 double a = 0.5 * (high + low) - nominal;
177 double b = 0.5 * (high - low);
178 double c = 0;
179 if (paramVal > 1) {
180 return (2 * a + b) * (paramVal - 1) + high - nominal;
181 } else if (paramVal < -1) {
182 return -1 * (2 * a - b) * (paramVal + 1) + low - nominal;
183 } else {
184 return a * std::pow(paramVal, 2) + b * paramVal + c;
185 }
186 } else if (code == 4) {
187 double x = paramVal;
188 if (x >= boundary) {
189 return x * (high - nominal);
190 } else if (x <= -boundary) {
191 return x * (nominal - low);
192 }
193
194 return interpolate6thDegree(x, low, high, nominal, boundary);
195 } else if (code == 5) {
196 double x = paramVal;
197 double mod = 1.0;
198 if (x >= boundary) {
199 mod = std::pow(high / nominal, +paramVal);
200 } else if (x <= -boundary) {
201 mod = std::pow(low / nominal, -paramVal);
202 } else {
203 mod = interpolate6thDegreeExp(x, low, high, nominal, boundary);
204 }
205 return res * (mod - 1.0);
206 }
207
208 return 0.0;
209}
210
211inline double logNormalEvaluate(double x, double k, double m0)
212{
213 return ROOT::Math::lognormal_pdf(x, std::log(m0), std::abs(std::log(k)));
214}
215
216inline double logNormalEvaluateStandard(double x, double sigma, double mu)
217{
218 return ROOT::Math::lognormal_pdf(x, mu, std::abs(sigma));
219}
220
221} // namespace EvaluateFuncs
222
223} // namespace Detail
224
225} // namespace RooFit
226
227#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