21 #if defined(DEBUG_AST)
40 #if defined(DEBUG_AST)
43 for (
auto const&
n :
e->abstractSyntaxTree()) {
47 #define DEBUG_STATE(_v_) std::cout << _v_ << std::endl
49 inline void printAST(
void*) {}
50 #define DEBUG_STATE(_v_)
53 struct EvaluatorInfo {
54 std::shared_ptr<reco::formula::EvaluatorBase> evaluator;
55 std::shared_ptr<reco::formula::EvaluatorBase> top;
56 int nextParseIndex = 0;
57 unsigned int maxNumVariables = 0;
58 unsigned int maxNumParameters = 0;
61 class ExpressionElementFinderBase {
63 virtual bool checkStart(
char)
const = 0;
65 virtual EvaluatorInfo createEvaluator(std::string::const_iterator, std::string::const_iterator)
const = 0;
67 virtual ~ExpressionElementFinderBase() =
default;
70 std::string::const_iterator findMatchingParenthesis(std::string::const_iterator iBegin,
71 std::string::const_iterator iEnd) {
80 for (
auto it = iBegin + 1; it != iEnd; ++it) {
84 }
else if (*it ==
')') {
91 return iBegin +
index;
94 class ConstantFinder :
public ExpressionElementFinderBase {
95 bool checkStart(
char iSymbol)
const final {
96 if (iSymbol ==
'-' or iSymbol ==
'.' or std::isdigit(iSymbol)) {
102 EvaluatorInfo createEvaluator(std::string::const_iterator iBegin, std::string::const_iterator iEnd)
const final {
107 double value = stod(
s, &endIndex);
109 info.nextParseIndex = endIndex;
110 info.evaluator = std::make_shared<reco::formula::ConstantEvaluator>(
value);
112 }
catch (std::invalid_argument
const&) {
119 class ParameterFinder :
public ExpressionElementFinderBase {
120 bool checkStart(
char iSymbol)
const final {
121 if (iSymbol ==
'[') {
127 EvaluatorInfo createEvaluator(std::string::const_iterator iBegin, std::string::const_iterator iEnd)
const final {
129 if (iEnd == iBegin) {
132 if (*iBegin !=
'[') {
135 info.nextParseIndex = 1;
139 unsigned long value = stoul(
s, &endIndex);
141 if (iBegin + endIndex + 1 == iEnd
or *(iBegin + 1 + endIndex) !=
']') {
145 info.nextParseIndex = endIndex + 2;
147 info.evaluator = std::make_shared<reco::formula::ParameterEvaluator>(
value);
149 }
catch (std::invalid_argument
const&) {
156 class VariableFinder :
public ExpressionElementFinderBase {
157 bool checkStart(
char iSymbol)
const final {
158 if (iSymbol ==
'x' or iSymbol ==
'y' or iSymbol ==
'z' or iSymbol ==
't') {
164 EvaluatorInfo createEvaluator(std::string::const_iterator iBegin, std::string::const_iterator iEnd)
const final {
166 if (iBegin == iEnd) {
169 unsigned int index = 4;
191 info.nextParseIndex = 1;
193 info.evaluator = std::make_shared<reco::formula::VariableEvaluator>(
index);
199 class ExpressionFinder;
201 class FunctionFinder :
public ExpressionElementFinderBase {
203 FunctionFinder(ExpressionFinder
const* iEF) : m_expressionFinder(iEF){};
205 bool checkStart(
char iSymbol)
const final {
return std::isalpha(iSymbol); }
207 EvaluatorInfo createEvaluator(std::string::const_iterator iBegin, std::string::const_iterator iEnd)
const final;
210 ExpressionFinder
const* m_expressionFinder;
213 EvaluatorInfo createBinaryOperatorEvaluator(ExpressionFinder
const&,
214 std::string::const_iterator iBegin,
215 std::string::const_iterator iEnd);
217 class ExpressionFinder {
220 m_elements.reserve(4);
221 m_elements.emplace_back(
new FunctionFinder{
this});
222 m_elements.emplace_back(
new ConstantFinder{});
223 m_elements.emplace_back(
new ParameterFinder{});
224 m_elements.emplace_back(
new VariableFinder{});
227 bool checkStart(
char iChar)
const {
228 if (
'(' == iChar
or '-' == iChar
or '+' == iChar) {
231 for (
auto const&
e : m_elements) {
232 if (
e->checkStart(iChar)) {
239 EvaluatorInfo createEvaluator(std::string::const_iterator iBegin,
240 std::string::const_iterator iEnd,
241 std::shared_ptr<reco::formula::BinaryOperatorEvaluatorBase> iPreviousBinary)
const {
242 EvaluatorInfo leftEvaluatorInfo;
244 if (iBegin == iEnd) {
245 return leftEvaluatorInfo;
248 if (*iBegin ==
'+' and iEnd - iBegin > 1 and not std::isdigit(*(iBegin + 1))) {
249 leftEvaluatorInfo = createEvaluator(iBegin + 1, iEnd, iPreviousBinary);
252 leftEvaluatorInfo.nextParseIndex += 1;
253 if (
nullptr == leftEvaluatorInfo.evaluator.get()) {
254 return leftEvaluatorInfo;
258 else if (*iBegin ==
'-' and iEnd - iBegin > 1 and not std::isdigit(*(iBegin + 1))) {
259 leftEvaluatorInfo = createEvaluator(iBegin + 1, iEnd, iPreviousBinary);
262 leftEvaluatorInfo.nextParseIndex += 1;
263 if (
nullptr == leftEvaluatorInfo.evaluator.get()) {
264 return leftEvaluatorInfo;
266 leftEvaluatorInfo.evaluator =
267 std::make_shared<reco::formula::UnaryMinusEvaluator>(
std::move(leftEvaluatorInfo.top));
268 leftEvaluatorInfo.top = leftEvaluatorInfo.evaluator;
271 else if (*iBegin ==
'(') {
272 auto endParenthesis = findMatchingParenthesis(iBegin, iEnd);
273 if (iBegin == endParenthesis) {
274 return leftEvaluatorInfo;
277 createEvaluator(iBegin + 1, endParenthesis, std::shared_ptr<reco::formula::BinaryOperatorEvaluatorBase>());
278 ++leftEvaluatorInfo.nextParseIndex;
279 if (leftEvaluatorInfo.evaluator.get() ==
nullptr) {
280 return leftEvaluatorInfo;
283 ++leftEvaluatorInfo.nextParseIndex;
284 leftEvaluatorInfo.top->setPrecedenceToParenthesis();
286 printAST(leftEvaluatorInfo.top.get());
287 leftEvaluatorInfo.evaluator = leftEvaluatorInfo.top;
290 int maxParseDistance = 0;
291 for (
auto const&
e : m_elements) {
292 if (
e->checkStart(*iBegin)) {
293 leftEvaluatorInfo =
e->createEvaluator(iBegin, iEnd);
294 if (leftEvaluatorInfo.evaluator !=
nullptr) {
297 if (leftEvaluatorInfo.nextParseIndex > maxParseDistance) {
298 maxParseDistance = leftEvaluatorInfo.nextParseIndex;
302 if (leftEvaluatorInfo.evaluator.get() ==
nullptr) {
304 leftEvaluatorInfo.nextParseIndex = maxParseDistance;
305 return leftEvaluatorInfo;
309 if (leftEvaluatorInfo.nextParseIndex == iEnd - iBegin) {
310 if (iPreviousBinary) {
311 iPreviousBinary->setRightEvaluator(leftEvaluatorInfo.top);
312 leftEvaluatorInfo.top = iPreviousBinary;
315 printAST(leftEvaluatorInfo.evaluator.get());
316 return leftEvaluatorInfo;
320 auto fullExpression = createBinaryOperatorEvaluator(*
this, iBegin + leftEvaluatorInfo.nextParseIndex, iEnd);
321 fullExpression.nextParseIndex += leftEvaluatorInfo.nextParseIndex;
322 fullExpression.maxNumVariables =
std::max(leftEvaluatorInfo.maxNumVariables, fullExpression.maxNumVariables);
323 fullExpression.maxNumParameters =
std::max(leftEvaluatorInfo.maxNumParameters, fullExpression.maxNumParameters);
324 if (iBegin + fullExpression.nextParseIndex != iEnd) {
326 fullExpression.evaluator.reset();
329 if (fullExpression.evaluator ==
nullptr) {
331 return fullExpression;
335 printAST(fullExpression.evaluator.get());
337 auto topNode = fullExpression.top;
338 auto binaryEval = dynamic_cast<reco::formula::BinaryOperatorEvaluatorBase*>(fullExpression.evaluator.get());
339 if (iPreviousBinary) {
340 if (iPreviousBinary->precedence() >= fullExpression.evaluator->precedence()) {
342 iPreviousBinary->setRightEvaluator(leftEvaluatorInfo.evaluator);
343 binaryEval->setLeftEvaluator(iPreviousBinary);
345 binaryEval->setLeftEvaluator(leftEvaluatorInfo.evaluator);
346 if (iPreviousBinary->precedence() < topNode->precedence()) {
348 topNode = iPreviousBinary;
349 iPreviousBinary->setRightEvaluator(fullExpression.top);
355 std::shared_ptr<reco::formula::EvaluatorBase> toSwap = iPreviousBinary;
356 auto parentBinary = dynamic_cast<reco::formula::BinaryOperatorEvaluatorBase*>(topNode.get());
358 if (parentBinary->lhs() == binaryEval
or
359 parentBinary->lhs()->precedence() > iPreviousBinary->precedence()) {
360 parentBinary->swapLeftEvaluator(toSwap);
361 iPreviousBinary->setRightEvaluator(toSwap);
364 parentBinary = const_cast<reco::formula::BinaryOperatorEvaluatorBase*>(
365 dynamic_cast<const reco::formula::BinaryOperatorEvaluatorBase*>(parentBinary->lhs()));
366 assert(parentBinary !=
nullptr);
368 }
while (iPreviousBinary->rhs() ==
nullptr);
372 binaryEval->setLeftEvaluator(leftEvaluatorInfo.top);
375 printAST(binaryEval);
377 printAST(topNode.get());
378 fullExpression.top = topNode;
379 return fullExpression;
383 std::vector<std::unique_ptr<ExpressionElementFinderBase>> m_elements;
386 template <
typename Op>
387 EvaluatorInfo createBinaryOperatorEvaluatorT(
int iSymbolLength,
389 ExpressionFinder
const& iEF,
390 std::string::const_iterator iBegin,
391 std::string::const_iterator iEnd) {
392 auto op = std::make_shared<reco::formula::BinaryOperatorEvaluator<Op>>(iPrec);
393 EvaluatorInfo evalInfo = iEF.createEvaluator(iBegin + iSymbolLength, iEnd, op);
394 evalInfo.nextParseIndex += iSymbolLength;
396 if (evalInfo.evaluator.get() ==
nullptr) {
400 evalInfo.evaluator = op;
405 double operator()(
double iLHS,
double iRHS)
const {
return std::pow(iLHS, iRHS); }
408 EvaluatorInfo createBinaryOperatorEvaluator(ExpressionFinder
const& iEF,
409 std::string::const_iterator iBegin,
410 std::string::const_iterator iEnd) {
411 EvaluatorInfo evalInfo;
412 if (iBegin == iEnd) {
416 if (*iBegin ==
'+') {
417 return createBinaryOperatorEvaluatorT<std::plus<double>>(
421 else if (*iBegin ==
'-') {
422 return createBinaryOperatorEvaluatorT<std::minus<double>>(
424 }
else if (*iBegin ==
'*') {
425 return createBinaryOperatorEvaluatorT<std::multiplies<double>>(
427 }
else if (*iBegin ==
'/') {
428 return createBinaryOperatorEvaluatorT<std::divides<double>>(
432 else if (*iBegin ==
'^') {
433 return createBinaryOperatorEvaluatorT<power>(
435 }
else if (*iBegin ==
'<' and iBegin + 1 != iEnd and *(iBegin + 1) ==
'=') {
436 return createBinaryOperatorEvaluatorT<std::less_equal<double>>(
439 }
else if (*iBegin ==
'>' and iBegin + 1 != iEnd and *(iBegin + 1) ==
'=') {
440 return createBinaryOperatorEvaluatorT<std::greater_equal<double>>(
443 }
else if (*iBegin ==
'<') {
444 return createBinaryOperatorEvaluatorT<std::less<double>>(
447 }
else if (*iBegin ==
'>') {
448 return createBinaryOperatorEvaluatorT<std::greater<double>>(
451 }
else if (*iBegin ==
'=' and iBegin + 1 != iEnd and *(iBegin + 1) ==
'=') {
452 return createBinaryOperatorEvaluatorT<std::equal_to<double>>(
455 }
else if (*iBegin ==
'!' and iBegin + 1 != iEnd and *(iBegin + 1) ==
'=') {
456 return createBinaryOperatorEvaluatorT<std::not_equal_to<double>>(
462 template <
typename Op>
463 EvaluatorInfo checkForSingleArgFunction(std::string::const_iterator iBegin,
464 std::string::const_iterator iEnd,
465 ExpressionFinder
const* iExpressionFinder,
469 if (iName.size() + 2 > static_cast<unsigned int>(iEnd - iBegin)) {
472 auto pos = iName.find(&(*iBegin), 0, iName.size());
474 if (std::string::npos ==
pos or *(iBegin + iName.size()) !=
'(') {
478 info.nextParseIndex = iName.size() + 1;
480 auto itEndParen = findMatchingParenthesis(iBegin + iName.size(), iEnd);
481 if (iBegin + iName.size() == itEndParen) {
485 auto argEvaluatorInfo = iExpressionFinder->createEvaluator(
486 iBegin + iName.size() + 1, itEndParen, std::shared_ptr<reco::formula::BinaryOperatorEvaluatorBase>());
487 info.nextParseIndex += argEvaluatorInfo.nextParseIndex;
488 if (argEvaluatorInfo.evaluator.get() ==
nullptr or info.nextParseIndex + 1 != 1 + itEndParen - iBegin) {
492 ++
info.nextParseIndex;
494 info.evaluator = std::make_shared<reco::formula::FunctionOneArgEvaluator>(
std::move(argEvaluatorInfo.top), op);
499 std::string::const_iterator findCommaNotInParenthesis(std::string::const_iterator iBegin,
500 std::string::const_iterator iEnd) {
502 std::string::const_iterator it = iBegin;
503 for (; it != iEnd; ++it) {
506 }
else if (*it ==
')') {
508 }
else if (*it ==
',' and
level == 0) {
516 template <
typename Op>
517 EvaluatorInfo checkForTwoArgsFunction(std::string::const_iterator iBegin,
518 std::string::const_iterator iEnd,
519 ExpressionFinder
const* iExpressionFinder,
523 if (iName.size() + 2 > static_cast<unsigned int>(iEnd - iBegin)) {
526 auto pos = iName.find(&(*iBegin), 0, iName.size());
528 if (std::string::npos ==
pos or *(iBegin + iName.size()) !=
'(') {
532 info.nextParseIndex = iName.size() + 1;
534 auto itEndParen = findMatchingParenthesis(iBegin + iName.size(), iEnd);
535 if (iBegin + iName.size() == itEndParen) {
539 auto itComma = findCommaNotInParenthesis(iBegin + iName.size() + 1, itEndParen);
541 auto arg1EvaluatorInfo = iExpressionFinder->createEvaluator(
542 iBegin + iName.size() + 1, itComma, std::shared_ptr<reco::formula::BinaryOperatorEvaluatorBase>());
543 info.nextParseIndex += arg1EvaluatorInfo.nextParseIndex;
544 if (arg1EvaluatorInfo.evaluator.get() ==
nullptr or info.nextParseIndex != itComma - iBegin) {
548 ++
info.nextParseIndex;
550 auto arg2EvaluatorInfo = iExpressionFinder->createEvaluator(
551 itComma + 1, itEndParen, std::shared_ptr<reco::formula::BinaryOperatorEvaluatorBase>());
552 info.nextParseIndex += arg2EvaluatorInfo.nextParseIndex;
554 if (arg2EvaluatorInfo.evaluator.get() ==
nullptr or info.nextParseIndex + 1 != 1 + itEndParen - iBegin) {
558 ++
info.nextParseIndex;
560 info.evaluator = std::make_shared<reco::formula::FunctionTwoArgsEvaluator>(
569 double const kLog10Inv = 1. /
std::log(10.);
579 const std::string k_TMath__Landau(
"TMath::Landau");
611 EvaluatorInfo FunctionFinder::createEvaluator(std::string::const_iterator iBegin,
612 std::string::const_iterator iEnd)
const {
615 info = checkForSingleArgFunction(
616 iBegin, iEnd, m_expressionFinder, k_erf, [](
double iArg) ->
double {
return std::erf(iArg); });
617 if (
info.evaluator.get() !=
nullptr) {
621 info = checkForSingleArgFunction(
622 iBegin, iEnd, m_expressionFinder, k_TMath__Erf, [](
double iArg) ->
double {
return std::erf(iArg); });
623 if (
info.evaluator.get() !=
nullptr) {
627 info = checkForSingleArgFunction(
628 iBegin, iEnd, m_expressionFinder, k_TMath__Landau, [](
double iArg) ->
double {
return TMath::Landau(iArg); });
629 if (
info.evaluator.get() !=
nullptr) {
633 info = checkForSingleArgFunction(
634 iBegin, iEnd, m_expressionFinder, k_log, [](
double iArg) ->
double {
return std::log(iArg); });
635 if (
info.evaluator.get() !=
nullptr) {
639 info = checkForSingleArgFunction(
640 iBegin, iEnd, m_expressionFinder, k_TMath__Log, [](
double iArg) ->
double {
return std::log(iArg); });
641 if (
info.evaluator.get() !=
nullptr) {
645 info = checkForSingleArgFunction(
646 iBegin, iEnd, m_expressionFinder, k_log10, [](
double iArg) ->
double {
return std::log(iArg) * kLog10Inv; });
647 if (
info.evaluator.get() !=
nullptr) {
651 info = checkForSingleArgFunction(
652 iBegin, iEnd, m_expressionFinder, k_exp, [](
double iArg) ->
double {
return std::exp(iArg); });
653 if (
info.evaluator.get() !=
nullptr) {
657 info = checkForSingleArgFunction(
658 iBegin, iEnd, m_expressionFinder, k_sqrt, [](
double iArg) ->
double {
return std::sqrt(iArg); });
659 if (
info.evaluator.get() !=
nullptr) {
663 info = checkForSingleArgFunction(
664 iBegin, iEnd, m_expressionFinder, k_TMath__Sqrt, [](
double iArg) ->
double {
return std::sqrt(iArg); });
665 if (
info.evaluator.get() !=
nullptr) {
669 info = checkForSingleArgFunction(
670 iBegin, iEnd, m_expressionFinder, k_abs, [](
double iArg) ->
double {
return std::abs(iArg); });
671 if (
info.evaluator.get() !=
nullptr) {
675 info = checkForSingleArgFunction(
676 iBegin, iEnd, m_expressionFinder, k_TMath__Abs, [](
double iArg) ->
double {
return std::abs(iArg); });
677 if (
info.evaluator.get() !=
nullptr) {
681 info = checkForSingleArgFunction(
682 iBegin, iEnd, m_expressionFinder, k_cos, [](
double iArg) ->
double {
return std::cos(iArg); });
683 if (
info.evaluator.get() !=
nullptr) {
687 info = checkForSingleArgFunction(
688 iBegin, iEnd, m_expressionFinder, k_TMath__Cos, [](
double iArg) ->
double {
return std::cos(iArg); });
689 if (
info.evaluator.get() !=
nullptr) {
693 info = checkForSingleArgFunction(
694 iBegin, iEnd, m_expressionFinder, k_sin, [](
double iArg) ->
double {
return std::sin(iArg); });
695 if (
info.evaluator.get() !=
nullptr) {
699 info = checkForSingleArgFunction(
700 iBegin, iEnd, m_expressionFinder, k_TMath__Sin, [](
double iArg) ->
double {
return std::sin(iArg); });
701 if (
info.evaluator.get() !=
nullptr) {
705 info = checkForSingleArgFunction(
706 iBegin, iEnd, m_expressionFinder, k_tan, [](
double iArg) ->
double {
return std::tan(iArg); });
707 if (
info.evaluator.get() !=
nullptr) {
711 info = checkForSingleArgFunction(
712 iBegin, iEnd, m_expressionFinder, k_TMath__Tan, [](
double iArg) ->
double {
return std::tan(iArg); });
713 if (
info.evaluator.get() !=
nullptr) {
717 info = checkForSingleArgFunction(
718 iBegin, iEnd, m_expressionFinder, k_acos, [](
double iArg) ->
double {
return std::acos(iArg); });
719 if (
info.evaluator.get() !=
nullptr) {
723 info = checkForSingleArgFunction(
724 iBegin, iEnd, m_expressionFinder, k_TMath__ACos, [](
double iArg) ->
double {
return std::acos(iArg); });
725 if (
info.evaluator.get() !=
nullptr) {
729 info = checkForSingleArgFunction(
730 iBegin, iEnd, m_expressionFinder, k_asin, [](
double iArg) ->
double {
return std::asin(iArg); });
731 if (
info.evaluator.get() !=
nullptr) {
735 info = checkForSingleArgFunction(
736 iBegin, iEnd, m_expressionFinder, k_TMath__ASin, [](
double iArg) ->
double {
return std::asin(iArg); });
737 if (
info.evaluator.get() !=
nullptr) {
741 info = checkForSingleArgFunction(
742 iBegin, iEnd, m_expressionFinder, k_atan, [](
double iArg) ->
double {
return std::atan(iArg); });
743 if (
info.evaluator.get() !=
nullptr) {
747 info = checkForSingleArgFunction(
748 iBegin, iEnd, m_expressionFinder, k_TMath__ATan, [](
double iArg) ->
double {
return std::atan(iArg); });
749 if (
info.evaluator.get() !=
nullptr) {
753 info = checkForSingleArgFunction(
754 iBegin, iEnd, m_expressionFinder, k_cosh, [](
double iArg) ->
double {
return std::cosh(iArg); });
755 if (
info.evaluator.get() !=
nullptr) {
759 info = checkForSingleArgFunction(
760 iBegin, iEnd, m_expressionFinder, k_TMath__CosH, [](
double iArg) ->
double {
return std::cosh(iArg); });
761 if (
info.evaluator.get() !=
nullptr) {
765 info = checkForSingleArgFunction(
766 iBegin, iEnd, m_expressionFinder, k_sinh, [](
double iArg) ->
double {
return std::sinh(iArg); });
767 if (
info.evaluator.get() !=
nullptr) {
771 info = checkForSingleArgFunction(
772 iBegin, iEnd, m_expressionFinder, k_TMath__SinH, [](
double iArg) ->
double {
return std::sinh(iArg); });
773 if (
info.evaluator.get() !=
nullptr) {
777 info = checkForSingleArgFunction(
778 iBegin, iEnd, m_expressionFinder, k_tanh, [](
double iArg) ->
double {
return std::tanh(iArg); });
779 if (
info.evaluator.get() !=
nullptr) {
783 info = checkForSingleArgFunction(
784 iBegin, iEnd, m_expressionFinder, k_TMath__TanH, [](
double iArg) ->
double {
return std::tanh(iArg); });
785 if (
info.evaluator.get() !=
nullptr) {
789 info = checkForSingleArgFunction(
790 iBegin, iEnd, m_expressionFinder, k_acosh, [](
double iArg) ->
double {
return std::acosh(iArg); });
791 if (
info.evaluator.get() !=
nullptr) {
795 info = checkForSingleArgFunction(
796 iBegin, iEnd, m_expressionFinder, k_TMath__ACosH, [](
double iArg) ->
double {
return std::acosh(iArg); });
797 if (
info.evaluator.get() !=
nullptr) {
801 info = checkForSingleArgFunction(
802 iBegin, iEnd, m_expressionFinder, k_asinh, [](
double iArg) ->
double {
return std::asinh(iArg); });
803 if (
info.evaluator.get() !=
nullptr) {
807 info = checkForSingleArgFunction(
808 iBegin, iEnd, m_expressionFinder, k_TMath__ASinH, [](
double iArg) ->
double {
return std::asinh(iArg); });
809 if (
info.evaluator.get() !=
nullptr) {
813 info = checkForSingleArgFunction(
814 iBegin, iEnd, m_expressionFinder, k_atanh, [](
double iArg) ->
double {
return std::atanh(iArg); });
815 if (
info.evaluator.get() !=
nullptr) {
819 info = checkForSingleArgFunction(
820 iBegin, iEnd, m_expressionFinder, k_TMath__ATanH, [](
double iArg) ->
double {
return std::atanh(iArg); });
821 if (
info.evaluator.get() !=
nullptr) {
825 info = checkForTwoArgsFunction(iBegin, iEnd, m_expressionFinder, k_atan2, [](
double iArg1,
double iArg2) ->
double {
826 return std::atan2(iArg1, iArg2);
828 if (
info.evaluator.get() !=
nullptr) {
832 info = checkForTwoArgsFunction(
833 iBegin, iEnd, m_expressionFinder, k_TMath__ATan2, [](
double iArg1,
double iArg2) ->
double {
834 return std::atan2(iArg1, iArg2);
836 if (
info.evaluator.get() !=
nullptr) {
840 info = checkForTwoArgsFunction(iBegin, iEnd, m_expressionFinder, k_pow, [](
double iArg1,
double iArg2) ->
double {
843 if (
info.evaluator.get() !=
nullptr) {
847 info = checkForTwoArgsFunction(
848 iBegin, iEnd, m_expressionFinder, k_TMath__Power, [](
double iArg1,
double iArg2) ->
double {
851 if (
info.evaluator.get() !=
nullptr) {
855 info = checkForTwoArgsFunction(iBegin, iEnd, m_expressionFinder, k_max, [](
double iArg1,
double iArg2) ->
double {
858 if (
info.evaluator.get() !=
nullptr) {
862 info = checkForTwoArgsFunction(iBegin, iEnd, m_expressionFinder, k_min, [](
double iArg1,
double iArg2) ->
double {
865 if (
info.evaluator.get() !=
nullptr) {
869 info = checkForTwoArgsFunction(
870 iBegin, iEnd, m_expressionFinder, k_TMath__Max, [](
double iArg1,
double iArg2) ->
double {
873 if (
info.evaluator.get() !=
nullptr) {
877 info = checkForTwoArgsFunction(
878 iBegin, iEnd, m_expressionFinder, k_TMath__Min, [](
double iArg1,
double iArg2) ->
double {
881 if (
info.evaluator.get() !=
nullptr) {
888 ExpressionFinder
const s_expressionFinder;
905 formula.reserve(iFormula.size());
906 std::copy_if(iFormula.begin(), iFormula.end(), std::back_inserter(
formula), [](
const char iC) {
return iC !=
' '; });
908 auto info = s_expressionFinder.createEvaluator(
909 formula.begin(),
formula.end(), std::shared_ptr<reco::formula::BinaryOperatorEvaluatorBase>());
911 if (
info.nextParseIndex != static_cast<int>(
formula.size())
or info.top.get() ==
nullptr) {
913 if (
formula.size() != iFormula.size()) {
923 <<
"While parsing '" << iFormula <<
"' could not parse beyond '"
928 printAST(
info.top.get());
939 return m_evaluator->evaluate(iVariables, iParameters);
944 <<
"FormulaEvaluator expected at least " <<
m_nVariables <<
" but was passed only " << iSize;
948 <<
"FormulaEvaluator expected at least " <<
m_nParameters <<
" but was passed only " << iSize;