46 width(
"width",
"width",this,_width),
47 peak(
"peak",
"peak",this,_peak),
48 tail(
"tail",
"tail",this,_tail)
68 if (std::abs(
tail) < 1.e-7) {
69 return std::exp( -0.5 * std::pow( ( (
x -
peak) /
width ), 2 ));
79 double log = std::log(arg);
80 static const double xi = 2.3548200450309494;
83 double width_zero2 = width_zero * width_zero;
84 double exponent = ( -0.5 / (width_zero2) * log * log ) - ( width_zero2 * 0.5 );
86 return std::exp(exponent) ;
93 {ctx.at(x), ctx.at(peak), ctx.at(width), ctx.at(tail)});
112 assert(code==1 || code==2) ;
117 static const double sqrt2 = 1.4142135623730950;
118 static const double sqlog2 = 0.832554611157697756;
119 static const double sqlog4 = 1.17741002251547469;
120 static const double log4 = 1.38629436111989062;
121 static const double rootpiby2 = 1.2533141373155003;
122 static const double sqpibylog2 = 2.12893403886245236;
125 double A =
x.min(rangeName);
126 double B =
x.max(rangeName);
132 if (std::abs(
tail) < 1.e-7) {
134 double xscale = sqrt2*
width;
147 if ( log_argument_A < 1.e-7) {
148 log_argument_A = 1.e-7;
152 if ( log_argument_B < 1.e-7) {
153 log_argument_B = 1.e-7;
157 double term1_2 = term1 * term1;
160 double erf_termA = ( term1_2 - log4 * std::log( log_argument_A ) ) / ( 2 * term1 * sqlog2 );
161 double erf_termB = ( term1_2 - log4 * std::log( log_argument_B ) ) / ( 2 * term1 * sqlog2 );
163 result = 0.5 /
tail *
width * term1 * ( std::erf(erf_termB) - std::erf(erf_termA)) * sqpibylog2;
167 }
else if (code==2) {
168 double A =
x.min(rangeName);
169 double B =
x.max(rangeName);
175 if (std::abs(
tail) < 1.e-7) {
177 double xscale = sqrt2*
width;
179 result = rootpiby2*
width*(std::erf((B-
x)/xscale)-std::erf((A-
x)/xscale));
190 if ( log_argument_A < 1.e-7) {
191 log_argument_A = 1.e-7;
195 if ( log_argument_B < 1.e-7) {
196 log_argument_B = 1.e-7;
200 double term1_2 = term1 * term1;
203 double erf_termA = ( term1_2 - log4 * std::log( log_argument_A ) ) / ( 2 * term1 * sqlog2 );
204 double erf_termB = ( term1_2 - log4 * std::log( log_argument_B ) ) / ( 2 * term1 * sqlog2 );
206 result = 0.5 /
tail *
width * term1 * ( std::erf(erf_termB) - std::erf(erf_termA)) * sqpibylog2;
213 coutF(Eval) <<
"Error in RooNovosibirsk::analyticalIntegral" << std::endl;
int Int_t
Signed integer 4 bytes (int).
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
RooAbsPdf()
Default constructor.
bool matchArgs(const RooArgSet &allDeps, RooArgSet &analDeps, const RooArgProxy &a, const Proxies &... proxies) const
RooArgSet is a container object that can hold multiple RooAbsArg objects.
std::span< double > output()
RooBatchCompute::Config config(RooAbsArg const *arg) const
Int_t getAnalyticalIntegral(RooArgSet &allVars, RooArgSet &analVars, const char *rangeName=nullptr) const override
Interface function getAnalyticalIntergral advertises the analytical integrals that are supported.
double evaluate() const override
If tail=eta=0 the Belle distribution becomes gaussian.
double analyticalIntegral(Int_t code, const char *rangeName=nullptr) const override
Implements the actual analytical integral(s) advertised by getAnalyticalIntegral.
void doEval(RooFit::EvalContext &) const override
Compute multiple values of Novosibirsk distribution.
void compute(Config cfg, Computer comp, std::span< double > output, VarSpan vars, ArgSpan extraArgs={})
Double_t ASinH(Double_t)
Returns the area hyperbolic sine of x.