test
CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
FormulaEvaluator.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: CommonTools/Utils
4 // Class : FormulaEvaluator
5 //
6 // Implementation:
7 // [Notes on implementation]
8 //
9 // Original Author: Christopher Jones
10 // Created: Thu, 24 Sep 2015 19:07:58 GMT
11 //
12 
13 // system include files
14 #include <cassert>
15 #include <functional>
16 #include <cstdlib>
17 #include <cmath>
18 #include "TMath.h"
19 
20 // user include files
22 #include "formulaEvaluatorBase.h"
31 
32 using namespace reco;
33 
34 namespace {
35  //Formula Parser Code
36  struct EvaluatorInfo {
37  std::shared_ptr<reco::formula::EvaluatorBase> evaluator;
38  std::shared_ptr<reco::formula::EvaluatorBase> top;
39  int nextParseIndex=0;
40  unsigned int maxNumVariables=0;
41  unsigned int maxNumParameters=0;
42  };
43 
44  class ExpressionElementFinderBase {
45  public:
46  virtual bool checkStart(char) const = 0;
47 
48  virtual EvaluatorInfo createEvaluator(std::string::const_iterator, std::string::const_iterator) const = 0;
49  };
50 
51  std::string::const_iterator findMatchingParenthesis(std::string::const_iterator iBegin, std::string::const_iterator iEnd) {
52  if (iBegin == iEnd) {
53  return iBegin;
54  }
55  if( *iBegin != '(') {
56  return iBegin;
57  }
58  int level = 1;
59  size_t index = 0;
60  for( auto it = iBegin+1; it != iEnd; ++it) {
61  ++index;
62  if (*it == '(') {
63  ++level;
64  } else if (*it == ')') {
65  --level;
66  if (level == 0) {
67  break;
68  }
69  }
70  }
71  return iBegin + index;
72  }
73 
74  class ConstantFinder : public ExpressionElementFinderBase {
75  virtual bool checkStart(char iSymbol) const override final {
76  if( iSymbol == '-' or iSymbol == '.' or std::isdigit(iSymbol) ) {
77  return true;
78  }
79  return false;
80  }
81 
82  virtual EvaluatorInfo createEvaluator(std::string::const_iterator iBegin, std::string::const_iterator iEnd) const override final {
83  EvaluatorInfo info;
84  try {
85  size_t endIndex=0;
86  std::string s(iBegin,iEnd);
87  double value = stod(s, &endIndex);
88 
89  info.nextParseIndex = endIndex;
90  info.evaluator = std::make_shared<reco::formula::ConstantEvaluator>(value);
91  info.top = info.evaluator;
92  } catch ( std::invalid_argument ) {}
93 
94  return info;
95 
96  }
97  };
98 
99 
100  class ParameterFinder : public ExpressionElementFinderBase {
101  virtual bool checkStart(char iSymbol) const override final {
102  if( iSymbol == '[') {
103  return true;
104  }
105  return false;
106  }
107 
108  virtual EvaluatorInfo createEvaluator(std::string::const_iterator iBegin, std::string::const_iterator iEnd) const override final {
109  EvaluatorInfo info;
110  if(iEnd == iBegin) {
111  return info;
112  }
113  if(*iBegin != '[') {
114  return info;
115  }
116  info.nextParseIndex = 1;
117  try {
118  size_t endIndex=0;
119  std::string s(iBegin+1,iEnd);
120  unsigned long value = stoul(s, &endIndex);
121 
122  if( iBegin+endIndex+1 == iEnd or *(iBegin+1+endIndex) != ']' ) {
123  return info;
124  }
125 
126 
127  info.nextParseIndex = endIndex+2;
128  info.maxNumParameters = value+1;
129  info.evaluator = std::make_shared<reco::formula::ParameterEvaluator>(value);
130  info.top = info.evaluator;
131  } catch ( std::invalid_argument ) {}
132 
133  return info;
134 
135  }
136  };
137 
138  class VariableFinder : public ExpressionElementFinderBase {
139  virtual bool checkStart(char iSymbol) const override final {
140  if( iSymbol == 'x' or iSymbol == 'y' or iSymbol == 'z' or iSymbol == 't' ) {
141  return true;
142  }
143  return false;
144  }
145 
146  virtual EvaluatorInfo createEvaluator(std::string::const_iterator iBegin, std::string::const_iterator iEnd) const override final {
147  EvaluatorInfo info;
148  if(iBegin == iEnd) {
149  return info;
150  }
151  unsigned int index = 4;
152  switch (*iBegin) {
153  case 'x':
154  { index = 0; break;}
155  case 'y':
156  { index = 1; break;}
157  case 'z':
158  { index = 2; break;}
159  case 't':
160  {index = 3; break;}
161  }
162  if(index == 4) {
163  return info;
164  }
165  info.nextParseIndex = 1;
166  info.maxNumVariables = index+1;
167  info.evaluator = std::make_shared<reco::formula::VariableEvaluator>(index);
168  info.top = info.evaluator;
169  return info;
170  }
171  };
172 
173  class ExpressionFinder;
174 
175  class FunctionFinder : public ExpressionElementFinderBase {
176  public:
177  FunctionFinder(ExpressionFinder const* iEF):
178  m_expressionFinder(iEF) {};
179 
180  virtual bool checkStart(char iSymbol) const override final {
181  return std::isalpha(iSymbol);
182  }
183 
184  virtual EvaluatorInfo createEvaluator(std::string::const_iterator iBegin, std::string::const_iterator iEnd) const override final;
185 
186  private:
187  ExpressionFinder const* m_expressionFinder;
188  };
189 
190 
191  EvaluatorInfo createBinaryOperatorEvaluator( ExpressionFinder const&,
192  std::string::const_iterator iBegin,
193  std::string::const_iterator iEnd) ;
194 
195  class ExpressionFinder {
196 
197  public:
198  ExpressionFinder() {
199  m_elements.reserve(4);
200  m_elements.emplace_back(new FunctionFinder{this});
201  m_elements.emplace_back(new ConstantFinder{});
202  m_elements.emplace_back(new ParameterFinder{});
203  m_elements.emplace_back(new VariableFinder{});
204  }
205 
206  bool checkStart(char iChar) const {
207  if ( '(' == iChar or '-' == iChar or '+' ==iChar) {
208  return true;
209  }
210  for( auto const& e : m_elements) {
211  if (e->checkStart(iChar) ) {
212  return true;
213  }
214  }
215  return false;
216  }
217 
218  EvaluatorInfo createEvaluator(std::string::const_iterator iBegin, std::string::const_iterator iEnd, std::shared_ptr<reco::formula::BinaryOperatorEvaluatorBase> iPreviousBinary) const {
219  EvaluatorInfo leftEvaluatorInfo ;
220  if( iBegin == iEnd) {
221  return leftEvaluatorInfo;
222  }
223  //Start with '+'
224  if (*iBegin == '+' and iEnd -iBegin > 1 and not std::isdigit( *(iBegin+1) ) ) {
225  leftEvaluatorInfo = createEvaluator(iBegin+1, iEnd, iPreviousBinary);
226 
227  //have to account for the '+' we skipped over
228  leftEvaluatorInfo.nextParseIndex +=1;
229  if( nullptr == leftEvaluatorInfo.evaluator.get() ) {
230  return leftEvaluatorInfo;
231  }
232  }
233  //Start with '-'
234  else if (*iBegin == '-' and iEnd -iBegin > 1 and not std::isdigit( *(iBegin+1) ) ) {
235  leftEvaluatorInfo = createEvaluator(iBegin+1, iEnd,iPreviousBinary);
236 
237  //have to account for the '+' we skipped over
238  leftEvaluatorInfo.nextParseIndex +=1;
239  if( nullptr == leftEvaluatorInfo.evaluator.get() ) {
240  return leftEvaluatorInfo;
241  }
242  leftEvaluatorInfo.evaluator = std::make_shared<reco::formula::UnaryMinusEvaluator>( std::move(leftEvaluatorInfo.top));
243  leftEvaluatorInfo.top = leftEvaluatorInfo.evaluator;
244  }
245  //Start with '('
246  else if( *iBegin == '(') {
247  auto endParenthesis = findMatchingParenthesis(iBegin,iEnd);
248  if(iBegin== endParenthesis) {
249  return leftEvaluatorInfo;
250  }
251  leftEvaluatorInfo = createEvaluator(iBegin+1,endParenthesis,std::shared_ptr<reco::formula::BinaryOperatorEvaluatorBase>());
252  ++leftEvaluatorInfo.nextParseIndex;
253  if(leftEvaluatorInfo.evaluator.get() == nullptr) {
254  return leftEvaluatorInfo;
255  }
256  //need to account for closing parenthesis
257  ++leftEvaluatorInfo.nextParseIndex;
258  leftEvaluatorInfo.evaluator->setPrecedenceToParenthesis();
259  } else {
260  //Does not start with a '('
261  int maxParseDistance = 0;
262  for( auto const& e: m_elements) {
263  if(e->checkStart(*iBegin) ) {
264  leftEvaluatorInfo = e->createEvaluator(iBegin,iEnd);
265  if(leftEvaluatorInfo.evaluator != nullptr) {
266  break;
267  }
268  if (leftEvaluatorInfo.nextParseIndex > maxParseDistance) {
269  maxParseDistance = leftEvaluatorInfo.nextParseIndex;
270  }
271  }
272  }
273  if(leftEvaluatorInfo.evaluator.get() == nullptr) {
274  //failed to parse
275  leftEvaluatorInfo.nextParseIndex = maxParseDistance;
276  return leftEvaluatorInfo;
277  }
278  }
279  //did we evaluate the full expression?
280  if(leftEvaluatorInfo.nextParseIndex == iEnd-iBegin) {
281  if (iPreviousBinary) {
282  iPreviousBinary->setRightEvaluator(leftEvaluatorInfo.top);
283  leftEvaluatorInfo.top = iPreviousBinary;
284  }
285  return leftEvaluatorInfo;
286  }
287 
288  //see if this is a binary expression
289  auto fullExpression = createBinaryOperatorEvaluator(*this, iBegin+leftEvaluatorInfo.nextParseIndex, iEnd);
290  fullExpression.nextParseIndex +=leftEvaluatorInfo.nextParseIndex;
291  fullExpression.maxNumVariables = std::max(leftEvaluatorInfo.maxNumVariables, fullExpression.maxNumVariables);
292  fullExpression.maxNumParameters = std::max(leftEvaluatorInfo.maxNumParameters, fullExpression.maxNumParameters);
293  if (iBegin + fullExpression.nextParseIndex != iEnd) {
294  //did not parse the full expression
295  fullExpression.evaluator.reset();
296  }
297 
298  //Now to handle precedence
299  auto topNode = fullExpression.top;
300  auto binaryEval = dynamic_cast<reco::formula::BinaryOperatorEvaluatorBase*>(fullExpression.evaluator.get());
301  if (iPreviousBinary) {
302  if (iPreviousBinary->precedence() >= fullExpression.evaluator->precedence() ) {
303  iPreviousBinary->setRightEvaluator(leftEvaluatorInfo.evaluator);
304  binaryEval->setLeftEvaluator(iPreviousBinary);
305  } else {
306  binaryEval->setLeftEvaluator(leftEvaluatorInfo.evaluator);
307  if(iPreviousBinary->precedence()<topNode->precedence() ) {
308  topNode = iPreviousBinary;
309  iPreviousBinary->setRightEvaluator(fullExpression.top);
310  }else {
311  std::shared_ptr<reco::formula::EvaluatorBase> toSwap = iPreviousBinary;
312  auto topBinary = dynamic_cast<reco::formula::BinaryOperatorEvaluatorBase*>(topNode.get());
313  topBinary->swapLeftEvaluator(toSwap);
314  iPreviousBinary->setRightEvaluator(toSwap);
315  }
316  }
317  } else {
318  binaryEval->setLeftEvaluator(leftEvaluatorInfo.evaluator);
319  if (topNode->precedence() > binaryEval->precedence()) {
320  topNode = fullExpression.evaluator;
321  }
322  }
323  fullExpression.top = topNode;
324  return fullExpression;
325  }
326 
327  private:
328  std::vector<std::unique_ptr<ExpressionElementFinderBase>> m_elements;
329 
330  };
331 
332  template<typename Op>
333  EvaluatorInfo createBinaryOperatorEvaluatorT(int iSymbolLength,
335  ExpressionFinder const& iEF,
336  std::string::const_iterator iBegin,
337  std::string::const_iterator iEnd) {
338  auto op = std::make_shared<reco::formula::BinaryOperatorEvaluator<Op> >(iPrec);
339  EvaluatorInfo evalInfo = iEF.createEvaluator(iBegin+iSymbolLength,iEnd,op);
340  evalInfo.nextParseIndex += iSymbolLength;
341 
342  if(evalInfo.evaluator.get() == nullptr) {
343  return evalInfo;
344  }
345 
346  evalInfo.evaluator = op;
347  return evalInfo;
348  }
349 
350  struct power {
351  double operator()(double iLHS, double iRHS) const {
352  return std::pow(iLHS,iRHS);
353  }
354  };
355 
356 
357  EvaluatorInfo
358  createBinaryOperatorEvaluator( ExpressionFinder const& iEF,
359  std::string::const_iterator iBegin,
360  std::string::const_iterator iEnd) {
361  EvaluatorInfo evalInfo;
362  if(iBegin == iEnd) {
363  return evalInfo;
364  }
365 
366  if(*iBegin == '+') {
367  return createBinaryOperatorEvaluatorT<std::plus<double>>(1,
369  iEF,
370  iBegin,
371  iEnd);
372  }
373 
374  else if(*iBegin == '-') {
375  return createBinaryOperatorEvaluatorT<std::minus<double>>(1,
377  iEF,
378  iBegin,
379  iEnd);
380  }
381  else if(*iBegin == '*') {
382  return createBinaryOperatorEvaluatorT<std::multiplies<double>>(1,
384  iEF,
385  iBegin,
386  iEnd);
387  }
388  else if(*iBegin == '/') {
389  return createBinaryOperatorEvaluatorT<std::divides<double>>(1,
391  iEF,
392  iBegin,
393  iEnd);
394  }
395 
396  else if(*iBegin == '^') {
397  return createBinaryOperatorEvaluatorT<power>(1,
399  iEF,
400  iBegin,
401  iEnd);
402  }
403  else if (*iBegin =='<' and iBegin+1 != iEnd and *(iBegin+1) == '=') {
404  return createBinaryOperatorEvaluatorT<std::less_equal<double>>(2,
406  iEF,
407  iBegin,
408  iEnd);
409 
410  }
411  else if (*iBegin =='>' and iBegin+1 != iEnd and *(iBegin+1) == '=') {
412  return createBinaryOperatorEvaluatorT<std::greater_equal<double>>(2,
414  iEF,
415  iBegin,
416  iEnd);
417 
418  }
419  else if (*iBegin =='<' ) {
420  return createBinaryOperatorEvaluatorT<std::less<double>>(1,
422  iEF,
423  iBegin,
424  iEnd);
425 
426  }
427  else if (*iBegin =='>' ) {
428  return createBinaryOperatorEvaluatorT<std::greater<double>>(1,
430  iEF,
431  iBegin,
432  iEnd);
433 
434  }
435  else if (*iBegin =='=' and iBegin+1 != iEnd and *(iBegin+1) == '=' ) {
436  return createBinaryOperatorEvaluatorT<std::equal_to<double>>(2,
438  iEF,
439  iBegin,
440  iEnd);
441 
442  }
443  else if (*iBegin =='!' and iBegin+1 != iEnd and *(iBegin+1) == '=' ) {
444  return createBinaryOperatorEvaluatorT<std::not_equal_to<double>>(2,
446  iEF,
447  iBegin,
448  iEnd);
449 
450  }
451  return evalInfo;
452  }
453 
454 
455  template<typename Op>
456  EvaluatorInfo
457  checkForSingleArgFunction(std::string::const_iterator iBegin,
458  std::string::const_iterator iEnd,
459  ExpressionFinder const* iExpressionFinder,
460  const std::string& iName,
461  Op op) {
462  EvaluatorInfo info;
463  if(iName.size()+2 > static_cast<unsigned int>(iEnd-iBegin) ) {
464  return info;
465  }
466  auto pos = iName.find(&(*iBegin), 0,iName.size());
467 
468  if(std::string::npos == pos or *(iBegin+iName.size()) != '(') {
469  return info;
470  }
471 
472  info.nextParseIndex = iName.size()+1;
473 
474  auto itEndParen = findMatchingParenthesis(iBegin+iName.size(),iEnd);
475  if(iBegin+iName.size() == itEndParen) {
476  return info;
477  }
478 
479  auto argEvaluatorInfo = iExpressionFinder->createEvaluator(iBegin+iName.size()+1, itEndParen,
480  std::shared_ptr<reco::formula::BinaryOperatorEvaluatorBase>());
481  info.nextParseIndex += argEvaluatorInfo.nextParseIndex;
482  if(argEvaluatorInfo.evaluator.get() == nullptr or info.nextParseIndex+1 != 1+itEndParen - iBegin) {
483  return info;
484  }
485  //account for closing parenthesis
486  ++info.nextParseIndex;
487 
488  info.evaluator = std::make_shared<reco::formula::FunctionOneArgEvaluator>(std::move(argEvaluatorInfo.top),
489  op);
490  info.top = info.evaluator;
491  return info;
492  }
493 
494  std::string::const_iterator findCommaNotInParenthesis(std::string::const_iterator iBegin,
495  std::string::const_iterator iEnd ) {
496  int level = 0;
497  std::string::const_iterator it = iBegin;
498  for(; it != iEnd; ++it) {
499  if (*it == '(') {
500  ++level;
501  } else if(*it == ')') {
502  --level;
503  }
504  else if( *it ==',' and level == 0 ) {
505  return it;
506  }
507  }
508 
509  return it;
510  }
511 
512 
513  template<typename Op>
514  EvaluatorInfo
515  checkForTwoArgsFunction(std::string::const_iterator iBegin,
516  std::string::const_iterator iEnd,
517  ExpressionFinder const* iExpressionFinder,
518  const std::string& iName,
519  Op op) {
520  EvaluatorInfo info;
521  if(iName.size()+2 > static_cast<unsigned int>(iEnd-iBegin) ) {
522  return info;
523  }
524  auto pos = iName.find(&(*iBegin), 0,iName.size());
525 
526  if(std::string::npos == pos or *(iBegin+iName.size()) != '(') {
527  return info;
528  }
529 
530  info.nextParseIndex = iName.size()+1;
531 
532  auto itEndParen = findMatchingParenthesis(iBegin+iName.size(),iEnd);
533  if(iBegin+iName.size() == itEndParen) {
534  return info;
535  }
536 
537  auto itComma = findCommaNotInParenthesis(iBegin+iName.size()+1, itEndParen);
538 
539  auto arg1EvaluatorInfo = iExpressionFinder->createEvaluator(iBegin+iName.size()+1, itComma, std::shared_ptr<reco::formula::BinaryOperatorEvaluatorBase>());
540  info.nextParseIndex += arg1EvaluatorInfo.nextParseIndex;
541  if(arg1EvaluatorInfo.evaluator.get() == nullptr or info.nextParseIndex != itComma-iBegin ) {
542  return info;
543  }
544  //account for commas
545  ++info.nextParseIndex;
546 
547  auto arg2EvaluatorInfo = iExpressionFinder->createEvaluator(itComma+1, itEndParen, std::shared_ptr<reco::formula::BinaryOperatorEvaluatorBase>());
548  info.nextParseIndex += arg2EvaluatorInfo.nextParseIndex;
549 
550  if(arg2EvaluatorInfo.evaluator.get() == nullptr or info.nextParseIndex+1 != 1+itEndParen - iBegin) {
551  return info;
552  }
553  //account for closing parenthesis
554  ++info.nextParseIndex;
555 
556  info.evaluator = std::make_shared<reco::formula::FunctionTwoArgsEvaluator>(std::move(arg1EvaluatorInfo.top),
557  std::move(arg2EvaluatorInfo.top),
558  op);
559  info.top = info.evaluator;
560  return info;
561  }
562 
563  static const std::string k_log("log");
564  static const std::string k_log10("log10");
565  static const std::string k_TMath__Log("TMath::Log");
566  double const kLog10Inv = 1./std::log(10.);
567  static const std::string k_exp("exp");
568  static const std::string k_pow("pow");
569  static const std::string k_TMath__Power("TMath::Power");
570  static const std::string k_max("max");
571  static const std::string k_min("min");
572  static const std::string k_TMath__Max("TMath::Max");
573  static const std::string k_TMath__Min("TMath::Min");
574  static const std::string k_TMath__Erf("TMath::Erf");
575  static const std::string k_erf("erf");
576  static const std::string k_TMath__Landau("TMath::Landau");
577 
578 
579  EvaluatorInfo
580  FunctionFinder::createEvaluator(std::string::const_iterator iBegin, std::string::const_iterator iEnd) const {
581  EvaluatorInfo info;
582 
583  info = checkForSingleArgFunction(iBegin, iEnd, m_expressionFinder,
584  k_erf, [](double iArg)->double { return std::erf(iArg); } );
585  if(info.evaluator.get() != nullptr) {
586  return info;
587  }
588 
589  info = checkForSingleArgFunction(iBegin, iEnd, m_expressionFinder,
590  k_TMath__Erf, [](double iArg)->double { return std::erf(iArg); } );
591  if(info.evaluator.get() != nullptr) {
592  return info;
593  }
594 
595  info = checkForSingleArgFunction(iBegin, iEnd, m_expressionFinder,
596  k_TMath__Landau, [](double iArg)->double { return TMath::Landau(iArg); } );
597  if(info.evaluator.get() != nullptr) {
598  return info;
599  }
600 
601  info = checkForSingleArgFunction(iBegin, iEnd, m_expressionFinder,
602  k_log, [](double iArg)->double { return std::log(iArg); } );
603  if(info.evaluator.get() != nullptr) {
604  return info;
605  }
606 
607  info = checkForSingleArgFunction(iBegin, iEnd, m_expressionFinder,
608  k_TMath__Log, [](double iArg)->double { return std::log(iArg); } );
609  if(info.evaluator.get() != nullptr) {
610  return info;
611  }
612 
613  info = checkForSingleArgFunction(iBegin, iEnd, m_expressionFinder,
614  k_log10, [](double iArg)->double { return std::log(iArg)*kLog10Inv; } );
615  if(info.evaluator.get() != nullptr) {
616  return info;
617  }
618 
619  info = checkForSingleArgFunction(iBegin, iEnd, m_expressionFinder,
620  k_exp, [](double iArg)->double { return std::exp(iArg); } );
621  if(info.evaluator.get() != nullptr) {
622  return info;
623  }
624 
625  info = checkForTwoArgsFunction(iBegin, iEnd, m_expressionFinder,
626  k_pow, [](double iArg1, double iArg2)->double { return std::pow(iArg1,iArg2); } );
627  if(info.evaluator.get() != nullptr) {
628  return info;
629  }
630 
631  info = checkForTwoArgsFunction(iBegin, iEnd, m_expressionFinder,
632  k_TMath__Power, [](double iArg1, double iArg2)->double { return std::pow(iArg1,iArg2); } );
633  if(info.evaluator.get() != nullptr) {
634  return info;
635  }
636 
637  info = checkForTwoArgsFunction(iBegin, iEnd, m_expressionFinder,
638  k_max, [](double iArg1, double iArg2)->double { return std::max(iArg1,iArg2); } );
639  if(info.evaluator.get() != nullptr) {
640  return info;
641  }
642 
643  info = checkForTwoArgsFunction(iBegin, iEnd, m_expressionFinder,
644  k_min, [](double iArg1, double iArg2)->double { return std::min(iArg1,iArg2); } );
645  if(info.evaluator.get() != nullptr) {
646  return info;
647  }
648 
649  info = checkForTwoArgsFunction(iBegin, iEnd, m_expressionFinder,
650  k_TMath__Max, [](double iArg1, double iArg2)->double { return std::max(iArg1,iArg2); } );
651  if(info.evaluator.get() != nullptr) {
652  return info;
653  }
654 
655  info = checkForTwoArgsFunction(iBegin, iEnd, m_expressionFinder,
656  k_TMath__Min, [](double iArg1, double iArg2)->double { return std::min(iArg1,iArg2); } );
657  if(info.evaluator.get() != nullptr) {
658  return info;
659  }
660 
661  return info;
662  };
663 
664  static ExpressionFinder const s_expressionFinder;
665 
666 }
667 //
668 // constants, enums and typedefs
669 //
670 
671 //
672 // static data member definitions
673 //
674 
675 //
676 // constructors and destructor
677 //
679 {
680  auto info = s_expressionFinder.createEvaluator(iFormula.begin(), iFormula.end(),std::shared_ptr<reco::formula::BinaryOperatorEvaluatorBase>());
681 
682  if(info.nextParseIndex != static_cast<int>(iFormula.size()) or info.top.get() == nullptr) {
683  throw cms::Exception("FormulaEvaluatorParseError")<<"While parsing '"<<iFormula<<"' could not parse beyond '"<<std::string(iFormula.begin(),iFormula.begin()+info.nextParseIndex) <<"'";
684  }
685  m_evaluator = std::move(info.top);
686  m_nVariables = info.maxNumVariables;
687  m_nParameters = info.maxNumParameters;
688 }
689 
690 //
691 // const member functions
692 //
693 double
694 FormulaEvaluator::evaluate(double const* iVariables, double const* iParameters) const
695 {
696  return m_evaluator->evaluate(iVariables, iParameters);
697 }
698 
699 void
701  throw cms::Exception("WrongNumVariables")<<"FormulaEvaluator expected at least "<<m_nVariables<<" but was passed only "<<iSize;
702 }
703 void
705  throw cms::Exception("WrongNumParameters")<<"FormulaEvaluator expected at least "<<m_nParameters<<" but was passed only "<<iSize;
706 }
static const TGPicture * info(bool iBackgroundIsBlack)
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventIDconst &, edm::Timestampconst & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
void setRightEvaluator(std::shared_ptr< EvaluatorBase > iOther)
void swapLeftEvaluator(std::shared_ptr< EvaluatorBase > &iNew)
double evaluate(V const &iVariables, P const &iParameters) const
def move
Definition: eostools.py:510
T min(T a, T b)
Definition: MathUtil.h:58
void throwWrongNumberOfParameters(size_t) const
FormulaEvaluator(std::string const &iFormula)
tuple level
Definition: testEve_cfg.py:34
std::shared_ptr< formula::EvaluatorBase const > m_evaluator
void throwWrongNumberOfVariables(size_t) const
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40