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;
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;
358 if (parentBinary->lhs() == binaryEval
or 359 parentBinary->lhs()->precedence() > iPreviousBinary->precedence()) {
361 iPreviousBinary->setRightEvaluator(toSwap);
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;
void tanh(data_T data[CONFIG_T::n_in], res_T res[CONFIG_T::n_in])
Sin< T >::type sin(const T &t)
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::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Cos< T >::type cos(const T &t)
Tan< T >::type tan(const T &t)
Abs< T >::type abs(const T &t)
static std::atomic< unsigned int > lastIndex
Power< A, B >::type pow(const A &a, const B &b)
dd4hep::tools::Evaluator & evaluator()