40 ClassImp(RooVoigtian);
44 RooVoigtian::RooVoigtian(
const char *name,
const char *title,
45 RooAbsReal& _x, RooAbsReal& _mean,
46 RooAbsReal& _width, RooAbsReal& _sigma,
48 RooAbsPdf(name,title),
49 x(
"x",
"Dependent",this,_x),
50 mean(
"mean",
"Mean",this,_mean),
51 width(
"width",
"Breit-Wigner Width",this,_width),
52 sigma(
"sigma",
"Gauss Width",this,_sigma),
60 RooVoigtian::RooVoigtian(
const RooVoigtian& other,
const char* name) :
61 RooAbsPdf(other,name), x(
"x",this,other.x), mean(
"mean",this,other.mean),
62 width(
"width",this,other.width),sigma(
"sigma",this,other.sigma),
63 _doFast(other._doFast)
70 Double_t RooVoigtian::evaluate()
const
72 Double_t s = (sigma>0) ? sigma : -sigma ;
73 Double_t w = (width>0) ? width : -width ;
75 Double_t coef= -0.5/(s*s);
76 Double_t arg = x - mean;
79 if (s==0. && w==0.)
return 1.;
82 if (s==0.)
return (1./(arg*arg+0.25*w*w));
85 if (w==0.)
return exp(coef*arg*arg);
88 Double_t c = 1./(sqrt(2.)*s);
91 std::complex<Double_t> z(u,a) ;
92 std::complex<Double_t> v(0.) ;
95 v = RooMath::faddeeva_fast(z);
97 v = RooMath::faddeeva(z);
107 template<
class Tx,
class Tmean,
class Tw
idth,
class Tsigma>
108 void compute(
size_t batchSize,
double * __restrict output,
109 Tx X, Tmean M, Twidth W, Tsigma S)
111 constexpr
double invSqrt2 = 0.707106781186547524400844362105;
112 for (
size_t i=0; i<batchSize; i++) {
113 const double arg = (X[i]-M[i])*(X[i]-M[i]);
114 if (S[i]==0.0 && W[i]==0.0) {
116 }
else if (S[i]==0.0) {
117 output[i] = 1/(arg+0.25*W[i]*W[i]);
118 }
else if (W[i]==0.0) {
119 output[i] = _rf_fast_exp(-0.5*arg/(S[i]*S[i]));
121 output[i] = invSqrt2/S[i];
125 for (
size_t i=0; i<batchSize; i++) {
126 if (S[i]!=0.0 && W[i]!=0.0) {
127 if (output[i] < 0) output[i] = -output[i];
128 const double factor = W[i]>0.0 ? 0.5 : -0.5;
129 std::complex<Double_t> z( output[i]*(X[i]-M[i]) , factor*output[i]*W[i] );
130 output[i] *= RooMath::faddeeva(z).real();
136 RooSpan<double> RooVoigtian::evaluateBatch(std::size_t begin, std::size_t batchSize)
const {
137 using namespace BatchHelpers;
139 EvaluateInfo info = getInfo( {&x, &mean, &width, &sigma}, begin, batchSize );
140 if (info.nBatches == 0) {
143 auto output = _batchData.makeWritableBatchUnInit(begin, batchSize);
144 auto xData = x.getValBatch(begin, info.size);
146 if (info.nBatches==1 && !xData.empty()) {
147 compute(info.size, output.data(), xData.data(),
148 BracketAdapter<double> (mean),
149 BracketAdapter<double> (width),
150 BracketAdapter<double> (sigma));
153 compute(info.size, output.data(),
154 BracketAdapterWithMask (x,x.getValBatch(begin,info.size)),
155 BracketAdapterWithMask (mean,mean.getValBatch(begin,info.size)),
156 BracketAdapterWithMask (width,width.getValBatch(begin,info.size)),
157 BracketAdapterWithMask (sigma,sigma.getValBatch(begin,info.size)));