46   int n_terms = 
_terms.size();
 
   47   std::string coeff_name = 
Form(
"%s_c%d", 
GetName(), n_terms);
 
   48   std::string term_name = 
Form(
"%s_t%d", 
GetName(), n_terms);
 
   49   auto termList = std::make_unique<RooListProxy>(term_name.c_str(), term_name.c_str(), 
this);
 
   50   auto coeff = std::make_unique<RooRealVar>(coeff_name.c_str(), coeff_name.c_str(), coefficient);
 
   53   for (
const auto &var : 
_vars) {
 
   54      std::string exponent_name = 
Form(
"%s_%s^%d", 
GetName(), var->GetName(), 0);
 
   55      auto exponent = std::make_unique<RooRealVar>(exponent_name.c_str(), exponent_name.c_str(), 0);
 
   56      exponents.addOwned(std::move(exponent));
 
   59   termList->addOwned(std::move(exponents));
 
   60   termList->addOwned(std::move(coeff));
 
   61   _terms.push_back(std::move(termList));
 
   66   int n_terms = 
_terms.size();
 
   67   std::string coeff_name = 
Form(
"%s_c%d", 
GetName(), n_terms);
 
   68   std::string term_name = 
Form(
"%s_t%d", 
GetName(), n_terms);
 
   69   auto termList = std::make_unique<RooListProxy>(term_name.c_str(), term_name.c_str(), 
this);
 
   70   auto coeff = std::make_unique<RooRealVar>(coeff_name.c_str(), coeff_name.c_str(), coefficient);
 
   74   for (
const auto &var : 
_vars) {
 
   76      if (strcmp(var1.
GetName(), var->GetName()) == 0)
 
   78      std::string exponent_name = 
Form(
"%s_%s^%d", 
GetName(), var->GetName(), exp);
 
   79      auto exponent = std::make_unique<RooRealVar>(exponent_name.c_str(), exponent_name.c_str(), exp);
 
   80      exponents.addOwned(std::move(exponent));
 
   83   termList->addOwned(std::move(exponents));
 
   84   termList->addOwned(std::move(coeff));
 
   85   _terms.push_back(std::move(termList));
 
   91   int n_terms = 
_terms.size();
 
   92   std::string coeff_name = 
Form(
"%s_c%d", 
GetName(), n_terms);
 
   93   std::string term_name = 
Form(
"%s_t%d", 
GetName(), n_terms);
 
   94   auto termList = std::make_unique<RooListProxy>(term_name.c_str(), term_name.c_str(), 
this);
 
   95   auto coeff = std::make_unique<RooRealVar>(coeff_name.c_str(), coeff_name.c_str(), coefficient);
 
   98   for (
const auto &var : 
_vars) {
 
  100      if (strcmp(var1.
GetName(), var->GetName()) == 0)
 
  102      if (strcmp(var2.
GetName(), var->GetName()) == 0)
 
  104      std::string exponent_name = 
Form(
"%s_%s^%d", 
GetName(), var->GetName(), exp);
 
  105      auto exponent = std::make_unique<RooRealVar>(exponent_name.c_str(), exponent_name.c_str(), exp);
 
  106      exponents.addOwned(std::move(exponent));
 
  108   termList->addOwned(std::move(exponents));
 
  109   termList->addOwned(std::move(coeff));
 
  110   _terms.push_back(std::move(termList));
 
  117                            << exponents.
size() << 
") provided do not match the number of variables (" << 
_vars.
size()
 
  120   int n_terms = 
_terms.size();
 
  121   std::string coeff_name = 
Form(
"%s_c%d", 
GetName(), n_terms);
 
  122   std::string term_name = 
Form(
"%s_t%d", 
GetName(), n_terms);
 
  123   auto termList = std::make_unique<RooListProxy>(term_name.c_str(), term_name.c_str(), 
this);
 
  124   auto coeff = std::make_unique<RooRealVar>(coeff_name.c_str(), coeff_name.c_str(), coefficient);
 
  125   termList->addOwned(exponents);
 
  126   termList->addOwned(std::move(coeff));
 
  127   _terms.push_back(std::move(termList));
 
  139   : 
RooAbsReal(
name, title), _vars(
"x", 
"list of dependent variables", this)
 
  141   for (
const auto &var : vars) {
 
  143         std::stringstream ss;
 
  144         ss << 
"RooPolyFunc::ctor(" << 
GetName() << 
") ERROR: coefficient " << var->
GetName()
 
  145            << 
" is not of type RooAbsReal";
 
  146         const std::string errorMsg = ss.str();
 
  148         throw std::runtime_error(errorMsg);
 
  160   for (
auto const &term : other.
_terms) {
 
  161      _terms.emplace_back(std::make_unique<RooListProxy>(term->GetName(), 
this, *term));
 
  170   std::stringstream ss;
 
  172   for (
const auto &term : 
_terms) {
 
  173      size_t n_vars = term->size() - 1;
 
  174      auto coef = 
dynamic_cast<RooRealVar *
>(term->at(n_vars));
 
  175      if (coef->getVal() > 0 && !
first)
 
  179      for (
size_t i_var = 0; i_var < n_vars; ++i_var) {
 
  181         auto exp = 
dynamic_cast<RooRealVar *
>(term->at(i_var));
 
  182         if (exp->getVal() == 0)
 
  188         ss << 
"pow(" << var->
GetName() << 
"," << exp->getVal() << 
")";
 
  202   double poly_sum(0.0);
 
  203   for (
const auto &term : 
_terms) {
 
  204      double poly_term(1.0);
 
  205      size_t n_vars = term->size() - 1;
 
  206      for (
size_t i_var = 0; i_var < n_vars; ++i_var) {
 
  208         auto exp = 
dynamic_cast<RooRealVar *
>(term->at(i_var));
 
  209         poly_term *= pow(var->getVal(), exp->getVal());
 
  211      auto coef = 
dynamic_cast<RooRealVar *
>(term->at(n_vars));
 
  212      poly_sum += coef->getVal() * poly_term;
 
  220   std::size_t iObs = 0;
 
  221   for (
auto *var : static_range_cast<RooRealVar *>(observables)) {
 
  222      var->setVal(observableValues[iObs++]);
 
  228   for (
auto *var : static_range_cast<RooRealVar *>(observables)) {
 
  229      var->setConstant(
true);
 
  250std::unique_ptr<RooPolyFunc>
 
  252                          int order, std::vector<double> 
const &observableValues, 
double eps1, 
double eps2)
 
  255   auto taylorPoly = std::make_unique<RooPolyFunc>(
name, title, observables);
 
  261         obsSet.
add(*obs,  
true); 
 
  263      if (obsSet.
size() != observables.
size()) {
 
  264         std::stringstream errorMsgStream;
 
  265         errorMsgStream << 
"RooPolyFunc::taylorExpand(" << 
name << 
") ERROR: duplicate input observables!";
 
  266         const auto errorMsg = errorMsgStream.str();
 
  268         throw std::invalid_argument(errorMsg);
 
  273   std::vector<double> obsValues;
 
  274   if (observableValues.empty()) {
 
  275      obsValues.reserve(observables.
size());
 
  276      for (
auto *var : static_range_cast<RooRealVar *>(observables)) {
 
  277         obsValues.push_back(var->getVal());
 
  279   } 
else if (observableValues.size() == 1) {
 
  280      obsValues.resize(observables.
size());
 
  281      std::fill(obsValues.begin(), obsValues.end(), observableValues[0]);
 
  282   } 
else if (observableValues.size() == observables.
size()) {
 
  283      obsValues = observableValues;
 
  285      std::stringstream errorMsgStream;
 
  286      errorMsgStream << 
"RooPolyFunc::taylorExpand(" << 
name 
  287                     << 
") ERROR: observableValues must be empty, contain one element, or match observables.size()!";
 
  288      const auto errorMsg = errorMsgStream.str();
 
  290      throw std::invalid_argument(errorMsg);
 
  294   if (order >= 3 || order <= 0) {
 
  295      std::stringstream errorMsgStream;
 
  296      errorMsgStream << 
"RooPolyFunc::taylorExpand(" << 
name << 
") ERROR: order must be 0, 1, or 2";
 
  297      const auto errorMsg = errorMsgStream.str();
 
  299      throw std::invalid_argument(errorMsg);
 
  310   for (
int i_order = 0; i_order <= order; ++i_order) {
 
  313         taylorPoly->addTerm(func.
getVal());
 
  317         for (
auto *var : static_range_cast<RooRealVar *>(observables)) {
 
  318            double var1_val = var->getVal();
 
  320            double deriv_val = deriv->
getVal();
 
  322            taylorPoly->addTerm(deriv_val, *var, 1);
 
  323            if (var1_val != 0.0) {
 
  324               taylorPoly->addTerm(deriv_val * var1_val * -1.0);
 
  330         for (
auto *var1 : static_range_cast<RooRealVar *>(observables)) {
 
  331            double var1_val = var1->getVal();
 
  332            auto deriv1 = func.
derivative(*var1, 1, eps1);
 
  333            for (
auto *var2 : static_range_cast<RooRealVar *>(observables)) {
 
  334               double var2_val = var2->
getVal();
 
  335               double deriv_val = 0.0;
 
  336               if (strcmp(var1->GetName(), var2->GetName()) == 0) {
 
  337                  auto deriv2 = func.
derivative(*var2, 2, eps2);
 
  338                  deriv_val = 0.5 * deriv2->getVal();
 
  341                  auto deriv2 = deriv1->derivative(*var2, 1, eps2);
 
  342                  deriv_val = 0.5 * deriv2->getVal();
 
  345               taylorPoly->addTerm(deriv_val, *var1, 1, *var2, 1);
 
  346               if (var1_val != 0.0 || var2_val != 0.0) {
 
  347                  taylorPoly->addTerm(deriv_val * var1_val * var2_val);
 
  348                  taylorPoly->addTerm(deriv_val * var2_val * -1.0, *var1, 1);
 
  349                  taylorPoly->addTerm(deriv_val * var1_val * -1.0, *var2, 1);
 
void fixObservables(const RooAbsCollection &observables)
 
void setCoordinates(const RooAbsCollection &observables, std::vector< double > const &observableValues)
 
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
 
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
 
RooAbsCollection is an abstract container object that can hold multiple RooAbsArg objects.
 
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
 
Storage_t::size_type size() const
 
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
 
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
 
RooDerivative * derivative(RooRealVar &obs, Int_t order=1, double eps=0.001)
Return function representing first, second or third order derivative of this function.
 
RooArgList is a container object that can hold multiple RooAbsArg objects.
 
RooAbsArg * at(Int_t idx) const
Return object at given index, or nullptr if index is out of range.
 
RooArgSet is a container object that can hold multiple RooAbsArg objects.
 
bool add(const RooAbsArg &var, bool valueServer, bool shapeServer, bool silent)
Overloaded RooCollection_t::add() method insert object into set and registers object as server to own...
 
RooPolyFunc implements a polynomial function in multi-variables.
 
double evaluate() const override
Evaluation.
 
RooPolyFunc()
Default constructor.
 
void addTerm(double coefficient)
coverity[UNINIT_CTOR]
 
static std::unique_ptr< RooPolyFunc > taylorExpand(const char *name, const char *title, RooAbsReal &func, const RooArgList &observables, int order=1, std::vector< double > const &observableValues={}, double eps1=1e-6, double eps2=1e-3)
Taylor expanding given function in terms of observables around observableValues.
 
std::string asString() const
Return to RooPolyFunc as a string.
 
std::vector< std::unique_ptr< RooListProxy > > _terms
 
RooRealVar represents a variable that can be changed from the outside.
 
const char * GetName() const override
Returns name of object.
 
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...