124 _x(
"x",
"x",
this,
x),
125 _lambda(
"lambda",
"Lambda",
this, lambda),
127 _beta(
"beta",
"Asymmetry parameter beta",
this, beta),
128 _sigma(
"sigma",
"Width parameter sigma",
this,
argSigma),
129 _mu(
"mu",
"Location parameter mu",
this, mu),
130 _a(
"a",
"Left tail location a",
this,
a),
131 _n(
"n",
"Left tail parameter n",
this,
n),
132 _a2(
"a2",
"Right tail location a2",
this,
a2),
133 _n2(
"n2",
"Right tail parameter n2",
this,
n2)
137 if (
zeta.getVal() == 0. &&
zeta.isConstant()) {
139 std::string(
"Lambda needs to be negative when ") +
_zeta.
GetName() +
" is zero.");
166const double ln2 = std::log(2.);
177 const double nu = std::abs(
ni);
187 const double nu = std::abs(
ni);
197double LogEval(
double d,
double l,
double alpha,
double beta,
double delta) {
198 const double gamma = alpha;
200 const double thing = delta*delta +
d*
d;
203 return std::exp(
logno + beta*
d
204 + (0.5-
l)*(std::log(alpha)-0.5*std::log(
thing))
210double diff_eval(
double d,
double l,
double alpha,
double beta,
double delta){
211 const double gamma = alpha;
214 const double thing = delta*delta +
d*
d;
218 const double ns1 = 0.5-
l;
220 return no * std::pow(alpha,
ns1) * std::pow(
thing,
l/2. - 1.25)
224 * std::exp(beta*
d) * 0.5;
248 const double beta =
_beta;
265 out = A * std::pow(B-
d, -
_n);
273 out = A * std::pow(B+
d, -
_n2);
279 else if (
_zeta < 0.) {
280 coutE(Eval) <<
"The parameter " <<
_zeta.
GetName() <<
" of the RooHypatia2 " <<
GetName() <<
" cannot be < 0." << std::endl;
283 const double delta =
_sigma;
287 const double phi = 1. +
_a *
_a;
293 out = A*std::pow(B-
d, -
_n);
297 const double phi = 1. +
_a2*
_a2;
303 out = A*std::pow(B+
d, -
_n2);
306 out = std::exp(beta*
d) * std::pow(1. +
d*
d/(delta*delta),
_lambda - 0.5);
310 coutE(Eval) <<
"zeta = 0 only supported for lambda < 0. lambda = " <<
double(
_lambda) << std::endl;
320template<
typename Tx,
typename Tl,
typename Tz,
typename Tb,
typename Ts,
typename Tm,
typename Ta,
typename Tn,
321typename Ta2,
typename Tn2>
322void compute(std::span<double>
output,
Tx x,
Tl lambda,
Tz zeta,
Tb beta,
Ts sigma,
Tm mu,
Ta a,
Tn n,
Ta2 a2,
Tn2 n2) {
327 for (std::size_t i = 0; i <
N; ++i) {
329 const double d =
x[i] - mu[i];
345 const double A =
k1 * std::pow(B+
asigma,
n[i]);
347 output[i] = A * std::pow(B-
d, -
n[i]);
363 const double delta =
sigma[i];
367 const double phi = 1. +
a[i] *
a[i];
368 const double k1 =
cons1 * std::pow(phi, lambda[i]-0.5);
369 const double k2 =
beta[i]*
k1 -
cons1*(lambda[i]-0.5) * std::pow(phi, lambda[i]-1.5) * 2.*
a[i]/delta;
371 const double A =
k1*std::pow(B+
asigma,
n[i]);
377 const double phi = 1. +
a2[i]*
a2[i];
378 const double k1 =
cons1 * std::pow(phi, lambda[i]-0.5);
379 const double k2 =
beta[i]*
k1 +
cons1*(lambda[i]-0.5) * std::pow(phi, lambda[i]-1.5) * 2.*
a2[i]/delta;
386 output[i] = std::exp(beta[i]*
d) * std::pow(1. +
d*
d/(delta*delta), lambda[i] - 0.5);
393std::pair<double, double>
computeAB_zetaNZero(
double asigma,
double lambda,
double alpha,
double beta,
double delta,
double n) {
396 const double B = -
asigma + (right ? -1 : 1.) *
n*
k1/
k2;
397 const double A =
k1 * std::pow(B+
asigma,
n);
405 const double phi = 1. +
a *
a;
406 const double k1 =
cons1 * std::pow(phi, lambda-0.5);
407 const double k2 =
beta*
k1 + (right ? 1. : -1) *
cons1*(lambda-0.5) * std::pow(phi, lambda-1.5) * 2.*
a/delta;
408 const double B = -
asigma + (right ? -1. : 1.) *
n*
k1/
k2;
409 const double A =
k1*std::pow(B+
asigma,
n);
437 for (std::size_t i = 0; i <
N; ++i) {
438 const double d =
x[i] - mu[i];
450 }
else if (
zeta == 0. && lambda < 0.) {
451 const double delta =
sigma;
456 for (std::size_t i = 0; i <
N; ++i) {
457 const double d =
x[i] - mu[i];
466 output[i] = std::exp(beta*
d) * std::pow(1. +
d*
d/(delta*delta), lambda - 0.5);
483 auto mu = ctx.
at(
_mu);
490 for (
const auto& i:{lambda,
zeta, beta, sig, mu,
a,
n,
a2,
n2}) {
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Abstract interface for all probability density functions.
Abstract base class for objects that represent a real value and implements functionality common to al...
Little adapter that gives a bracket operator to types that don't have one.
std::span< const double > at(RooAbsArg const *arg, RooAbsArg const *caller=nullptr)
std::span< double > output()
RooHypatia2 is the two-sided version of the Hypatia distribution described in https://arxiv....
void doEval(RooFit::EvalContext &) const override
Base function for computing multiple values of a RooAbsReal.
double evaluate() const override
Evaluate this PDF / function / constant. Needs to be overridden by all derived classes.
const char * GetName() const override
Returns name of object.
double beta(double x, double y)
Calculates the beta function.
double cyl_bessel_k(double nu, double x)
Calculates the modified Bessel functions of the second kind (also called irregular modified (cylindri...
Namespace for dispatching RooFit computations to various backends.
void compute(Config cfg, Computer comp, std::span< double > output, VarSpan vars, ArgSpan extraArgs={})
void checkRangeOfParameters(const RooAbsReal *callingClass, std::initializer_list< const RooAbsReal * > pars, double min=-std::numeric_limits< double >::max(), double max=std::numeric_limits< double >::max(), bool limitsInAllowedRange=false, std::string const &extraMessage="")
Check if the parameters have a range, and warn if the range extends below / above the set limits.
Double_t Gamma(Double_t z)
Computation of gamma(z) for all z.
constexpr Double_t TwoPi()