38 ClassImp(RooBifurGauss);
42 RooBifurGauss::RooBifurGauss(
const char *name,
const char *title,
43 RooAbsReal& _x, RooAbsReal& _mean,
44 RooAbsReal& _sigmaL, RooAbsReal& _sigmaR) :
45 RooAbsPdf(name, title),
46 x (
"x" ,
"Dependent" , this, _x),
47 mean (
"mean" ,
"Mean" , this, _mean),
48 sigmaL(
"sigmaL",
"Left Sigma" , this, _sigmaL),
49 sigmaR(
"sigmaR",
"Right Sigma", this, _sigmaR)
56 RooBifurGauss::RooBifurGauss(
const RooBifurGauss& other,
const char* name) :
57 RooAbsPdf(other,name), x(
"x",this,other.x), mean(
"mean",this,other.mean),
58 sigmaL(
"sigmaL",this,other.sigmaL), sigmaR(
"sigmaR", this, other.sigmaR)
64 Double_t RooBifurGauss::evaluate()
const {
65 Double_t arg = x - mean;
70 if (TMath::Abs(sigmaL) > 1e-30) {
71 coef = -0.5/(sigmaL*sigmaL);
74 if (TMath::Abs(sigmaR) > 1e-30) {
75 coef = -0.5/(sigmaR*sigmaR);
79 return exp(coef*arg*arg);
87 template<
class Tx,
class Tm,
class Tsl,
class Tsr>
88 void compute(
size_t batchSize,
89 double * __restrict output,
90 Tx X, Tm M, Tsl SL, Tsr SR)
92 for (
size_t i=0; i<batchSize; i++) {
93 const double arg = X[i]-M[i];
94 output[i] = arg / ((arg < 0.0)*SL[i] + (arg >= 0.0)*SR[i]);
97 for (
size_t i=0; i<batchSize; i++) {
98 if (X[i]-M[i]>1e-30 || X[i]-M[i]<-1e-30) {
99 output[i] = _rf_fast_exp(-0.5*output[i]*output[i]);
108 RooSpan<double> RooBifurGauss::evaluateBatch(std::size_t begin, std::size_t batchSize)
const {
109 using namespace BatchHelpers;
111 EvaluateInfo info = getInfo( {&x, &mean, &sigmaL, &sigmaR}, begin, batchSize );
112 if (info.nBatches == 0) {
115 auto output = _batchData.makeWritableBatchUnInit(begin, batchSize);
116 auto xData = x.getValBatch(begin, info.size);
118 if (info.nBatches==1 && !xData.empty()) {
119 compute(info.size, output.data(), xData.data(),
120 BracketAdapter<double> (mean),
121 BracketAdapter<double> (sigmaL),
122 BracketAdapter<double> (sigmaR));
125 compute(info.size, output.data(),
126 BracketAdapterWithMask (x,x.getValBatch(begin,info.size)),
127 BracketAdapterWithMask (mean,mean.getValBatch(begin,info.size)),
128 BracketAdapterWithMask (sigmaL,sigmaL.getValBatch(begin,info.size)),
129 BracketAdapterWithMask (sigmaR,sigmaR.getValBatch(begin,info.size)));
137 Int_t RooBifurGauss::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars,
const char* )
const
139 if (matchArgs(allVars,analVars,x))
return 1 ;
145 Double_t RooBifurGauss::analyticalIntegral(Int_t code,
const char* rangeName)
const
150 static Double_t root2 = sqrt(2.) ;
151 static Double_t rootPiBy2 = sqrt(atan2(0.0,-1.0)/2.0);
162 Double_t xscaleL = root2*sigmaL;
163 Double_t xscaleR = root2*sigmaR;
165 Double_t integral = 0.0;
166 if(x.max(rangeName) < mean)
168 integral = sigmaL * ( RooMath::erf((x.max(rangeName) - mean)/xscaleL) - RooMath::erf((x.min(rangeName) - mean)/xscaleL) );
170 else if (x.min(rangeName) > mean)
172 integral = sigmaR * ( RooMath::erf((x.max(rangeName) - mean)/xscaleR) - RooMath::erf((x.min(rangeName) - mean)/xscaleR) );
176 integral = sigmaR*RooMath::erf((x.max(rangeName) - mean)/xscaleR) - sigmaL*RooMath::erf((x.min(rangeName) - mean)/xscaleL);
180 return integral*rootPiBy2;