45 ClassImp(RooPolynomial);
50 RooPolynomial::RooPolynomial()
75 RooPolynomial::RooPolynomial(
const char* name,
const char* title,
76 RooAbsReal& x,
const RooArgList& coefList, Int_t lowestOrder) :
77 RooAbsPdf(name, title),
78 _x(
"x",
"Dependent", this, x),
79 _coefList(
"coefList",
"List of coefficients",this),
80 _lowestOrder(lowestOrder)
84 coutE(InputArguments) <<
"RooPolynomial::ctor(" << GetName()
85 <<
") WARNING: lowestOrder must be >=0, setting value to 0" << endl ;
89 RooFIter coefIter = coefList.fwdIterator() ;
91 while((coef = (RooAbsArg*)coefIter.next())) {
92 if (!dynamic_cast<RooAbsReal*>(coef)) {
93 coutE(InputArguments) <<
"RooPolynomial::ctor(" << GetName() <<
") ERROR: coefficient " << coef->GetName()
94 <<
" is not of type RooAbsReal" << endl ;
97 _coefList.add(*coef) ;
103 RooPolynomial::RooPolynomial(
const char* name,
const char* title,
105 RooAbsPdf(name, title),
106 _x(
"x",
"Dependent", this, x),
107 _coefList(
"coefList",
"List of coefficients",this),
114 RooPolynomial::RooPolynomial(
const RooPolynomial& other,
const char* name) :
115 RooAbsPdf(other, name),
116 _x(
"x", this, other._x),
117 _coefList(
"coefList",this,other._coefList),
118 _lowestOrder(other._lowestOrder)
124 RooPolynomial::~RooPolynomial()
129 Double_t RooPolynomial::evaluate()
const
133 const unsigned sz = _coefList.getSize();
134 const int lowestOrder = _lowestOrder;
135 if (!sz)
return lowestOrder ? 1. : 0.;
139 const RooArgSet* nset = _coefList.nset();
140 RooFIter it = _coefList.fwdIterator();
142 while ((c = (RooAbsReal*) it.next())) _wksp.push_back(c->getVal(nset));
144 const Double_t x = _x;
145 Double_t retVal = _wksp[sz - 1];
146 for (
unsigned i = sz - 1; i--; ) retVal = _wksp[i] + x * retVal;
147 return retVal * std::pow(x, lowestOrder) + (lowestOrder ? 1.0 : 0.0);
155 void compute(
size_t batchSize,
const int lowestOrder,
156 double * __restrict output,
157 const double * __restrict
const X,
158 const std::vector<BatchHelpers::BracketAdapterWithMask>& coefList )
160 const int nCoef = coefList.size();
161 if (nCoef==0 && lowestOrder==0) {
162 for (
size_t i=0; i<batchSize; i++) {
166 else if (nCoef==0 && lowestOrder>0) {
167 for (
size_t i=0; i<batchSize; i++) {
171 for (
size_t i=0; i<batchSize; i++) {
172 output[i] = coefList[nCoef-1][i];
175 if (nCoef == 0)
return;
182 for (
int k=nCoef-3; k>=0; k-=2) {
183 for (
size_t i=0; i<batchSize; i++) {
184 double coef1 = coefList[k+1][i];
185 double coef2 = coefList[ k ][i];
186 output[i] = X[i]*(output[i]*X[i] + coef1) + coef2;
191 for (
size_t i=0; i<batchSize; i++) {
192 output[i] = output[i]*X[i] + coefList[0][i];
196 if (lowestOrder == 0)
return;
197 for (
int k=2; k<=lowestOrder; k+=2) {
198 for (
size_t i=0; i<batchSize; i++) {
199 output[i] *= X[i]*X[i];
202 const bool isOdd = lowestOrder%2;
203 for (
size_t i=0; i<batchSize; i++) {
204 if (isOdd) output[i] *= X[i];
212 RooSpan<double> RooPolynomial::evaluateBatch(std::size_t begin, std::size_t batchSize)
const {
213 RooSpan<const double> xData = _x.getValBatch(begin, batchSize);
214 batchSize = xData.size();
219 auto output = _batchData.makeWritableBatchUnInit(begin, batchSize);
220 const int nCoef = _coefList.getSize();
221 const RooArgSet* normSet = _coefList.nset();
222 std::vector<BatchHelpers::BracketAdapterWithMask> coefList;
223 for (
int i=0; i<nCoef; i++) {
224 auto val =
static_cast<RooAbsReal&
>(_coefList[i]).getVal(normSet);
225 auto valBatch =
static_cast<RooAbsReal&
>(_coefList[i]).getValBatch(begin, batchSize, normSet);
226 coefList.emplace_back(val, valBatch);
229 compute(batchSize, _lowestOrder, output.data(), xData.data(), coefList);
236 Int_t RooPolynomial::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars,
const char* )
const
238 if (matchArgs(allVars, analVars, _x))
return 1;
244 Double_t RooPolynomial::analyticalIntegral(Int_t code,
const char* rangeName)
const
248 const Double_t xmin = _x.min(rangeName), xmax = _x.max(rangeName);
249 const int lowestOrder = _lowestOrder;
250 const unsigned sz = _coefList.getSize();
251 if (!sz)
return xmax - xmin;
255 const RooArgSet* nset = _coefList.nset();
256 RooFIter it = _coefList.fwdIterator();
257 unsigned i = 1 + lowestOrder;
259 while ((c = (RooAbsReal*) it.next())) {
260 _wksp.push_back(c->getVal(nset) / Double_t(i));
264 Double_t min = _wksp[sz - 1], max = _wksp[sz - 1];
265 for (
unsigned i = sz - 1; i--; )
266 min = _wksp[i] + xmin * min, max = _wksp[i] + xmax * max;
267 return max * std::pow(xmax, 1 + lowestOrder) - min * std::pow(xmin, 1 + lowestOrder) +
268 (lowestOrder ? (xmax - xmin) : 0.);