44 ClassImp(RooLognormal);
48 RooLognormal::RooLognormal(
const char *name,
const char *title,
49 RooAbsReal& _x, RooAbsReal& _m0,
51 RooAbsPdf(name,title),
52 x(
"x",
"Observable",this,_x),
53 m0(
"m0",
"m0",this,_m0),
56 RooHelpers::checkRangeOfParameters(
this, {&_x, &_m0, &_k}, 0.);
58 auto par =
dynamic_cast<const RooAbsRealLValue*
>(&_k);
59 if (par && par->getMin()<=1 && par->getMax()>=1 ) {
60 oocoutE(
this, InputArguments) <<
"The parameter '" << par->GetName() <<
"' with range [" << par->getMin(
"") <<
", "
61 << par->getMax() <<
"] of the " << this->IsA()->GetName() <<
" '" << this->GetName()
62 <<
"' can reach the unsafe value 1.0 " <<
". Advise to limit its range." << std::endl;
68 RooLognormal::RooLognormal(
const RooLognormal& other,
const char* name) :
69 RooAbsPdf(other,name), x(
"x",this,other.x), m0(
"m0",this,other.m0),
80 Double_t RooLognormal::evaluate()
const
82 Double_t ln_k = TMath::Abs(TMath::Log(k));
83 Double_t ln_m0 = TMath::Log(m0);
85 Double_t ret = ROOT::Math::lognormal_pdf(x,ln_m0,ln_k);
94 template<
class Tx,
class Tm0,
class Tk>
95 void compute(
size_t batchSize,
96 double * __restrict output,
99 const double rootOf2pi = std::sqrt(2 * M_PI);
100 for (
size_t i=0; i<batchSize; i++) {
101 double lnxOverM0 = _rf_fast_log(X[i]/M0[i]);
102 double lnk = _rf_fast_log(K[i]);
103 if (lnk<0) lnk = -lnk;
104 double arg = lnxOverM0/lnk;
106 output[i] = _rf_fast_exp(arg) / (X[i]*lnk*rootOf2pi);
111 RooSpan<double> RooLognormal::evaluateBatch(std::size_t begin, std::size_t batchSize)
const {
112 using namespace BatchHelpers;
113 auto xData = x.getValBatch(begin, batchSize);
114 auto m0Data = m0.getValBatch(begin, batchSize);
115 auto kData = k.getValBatch(begin, batchSize);
116 const bool batchX = !xData.empty();
117 const bool batchM0 = !m0Data.empty();
118 const bool batchK = !kData.empty();
120 if (!batchX && !batchM0 && !batchK) {
123 batchSize = findSize({ xData, m0Data, kData });
124 auto output = _batchData.makeWritableBatchUnInit(begin, batchSize);
126 if (batchX && !batchM0 && !batchK ) {
127 compute(batchSize, output.data(), xData, BracketAdapter<double>(m0), BracketAdapter<double>(k));
129 else if (!batchX && batchM0 && !batchK ) {
130 compute(batchSize, output.data(), BracketAdapter<double>(x), m0Data, BracketAdapter<double>(k));
132 else if (batchX && batchM0 && !batchK ) {
133 compute(batchSize, output.data(), xData, m0Data, BracketAdapter<double>(k));
135 else if (!batchX && !batchM0 && batchK ) {
136 compute(batchSize, output.data(), BracketAdapter<double>(x), BracketAdapter<double>(m0), kData);
138 else if (batchX && !batchM0 && batchK ) {
139 compute(batchSize, output.data(), xData, BracketAdapter<double>(m0), kData);
141 else if (!batchX && batchM0 && batchK ) {
142 compute(batchSize, output.data(), BracketAdapter<double>(x), m0Data, kData);
144 else if (batchX && batchM0 && batchK ) {
145 compute(batchSize, output.data(), xData, m0Data, kData);
153 Int_t RooLognormal::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars,
const char* )
const
155 if (matchArgs(allVars,analVars,x))
return 1 ;
161 Double_t RooLognormal::analyticalIntegral(Int_t code,
const char* rangeName)
const
165 static const Double_t root2 = sqrt(2.) ;
167 Double_t ln_k = TMath::Abs(TMath::Log(k));
168 Double_t ret = 0.5*( RooMath::erf( TMath::Log(x.max(rangeName)/m0)/(root2*ln_k) ) - RooMath::erf( TMath::Log(x.min(rangeName)/m0)/(root2*ln_k) ) ) ;
175 Int_t RooLognormal::getGenerator(
const RooArgSet& directVars, RooArgSet &generateVars, Bool_t )
const
177 if (matchArgs(directVars,generateVars,x))
return 1 ;
183 void RooLognormal::generateEvent(Int_t code)
189 xgen = TMath::Exp(RooRandom::randomGenerator()->Gaus(TMath::Log(m0),TMath::Log(k)));
190 if (xgen<=x.max() && xgen>=x.min()) {