12#if __cplusplus >= 201103L
13#define ROOT_CPLUSPLUS11 1
31#include <unordered_map>
37#pragma optimize("",off)
216static std::unordered_map<std::string, void *>
gClingFunctions = std::unordered_map<std::string, void * >();
223 for (
int i = 0; i < nobjects; ++i) {
224 if (fromv5[i] && target[i]) {
241 const static std::set<char> ops {
'+',
'^',
'-',
'/',
'*',
'<',
'>',
'|',
'&',
'!',
'=',
'?',
'%'};
242 return ops.end() != ops.find(
c);
249 char brackets[] = {
')',
'(',
'{',
'}'};
250 Int_t bracketsLen =
sizeof(brackets)/
sizeof(
char);
251 for(
Int_t i = 0; i < bracketsLen; ++i)
273 if ( (formula[i] ==
'e' || formula[i] ==
'E') && (i > 0 && i < formula.Length()-1) ) {
275 if ( (isdigit(formula[i-1]) || formula[i-1] ==
'.') && ( isdigit(formula[i+1]) || formula[i+1] ==
'+' || formula[i+1] ==
'-' ) )
285 if ( (formula[i] ==
'x' || formula[i] ==
'X') && (i > 0 && i < formula.Length()-1) && formula[i-1] ==
'0') {
286 if (isdigit(formula[i+1]) )
288 static char hex_values[12] = {
'a',
'A',
'b',
'B',
'c',
'C',
'd',
'D',
'e',
'E',
'f',
'F'};
289 for (
int jjj = 0; jjj < 12; ++jjj) {
290 if (formula[i+1] == hex_values[jjj])
307 Bool_t foundOpenParenthesis =
false;
308 if (pos == 0 || pos == formula.Length()-1)
return false;
309 for (
int i = pos-1; i >=0; i--) {
310 if (formula[i] ==
']' )
return false;
311 if (formula[i] ==
'[' ) {
312 foundOpenParenthesis =
true;
316 if (!foundOpenParenthesis )
return false;
319 for (
int i = pos+1; i < formula.Length(); i++) {
320 if (formula[i] ==
']' )
return true;
333 TRegexp numericPattern(
"p?[0-9]+");
336 int patternStart = numericPattern.
Index(
a, &len);
337 bool aNumeric = (patternStart == 0 && len ==
a.Length());
339 patternStart = numericPattern.
Index(
b, &len);
340 bool bNumeric = (patternStart == 0 && len ==
b.Length());
342 if (aNumeric && !bNumeric)
344 else if (!aNumeric && bNumeric)
346 else if (!aNumeric && !bNumeric)
349 int aInt = (
a[0] ==
'p') ? TString(
a(1,
a.Length())).Atoi() :
a.Atoi();
350 int bInt = (
b[0] ==
'p') ? TString(
b(1,
b.Length())).Atoi() :
b.Atoi();
361 for (
int i = 0; i < formula.Length(); i++) {
364 if (isalpha(formula[i]) || formula[i] ==
'{' || formula[i] ==
'[') {
368 || (formula[i] ==
'{' && formula[j] ==
'}'));
371 TString
name = (TString)formula(i, j - i);
376 if (substitutions.find(
name) != substitutions.end()) {
377 formula.Replace(i,
name.Length(),
"(" + substitutions[
name] +
")");
378 i += substitutions[
name].Length() + 2 - 1;
380 }
else if (isalpha(formula[i])) {
383 i +=
name.Length() - 1;
409 if (strlen(
name)!=1)
return false;
410 for (
auto const & specialName : {
"x",
"y",
"z",
"t"}){
411 if (strcmp(
name,specialName)==0)
return true;
424 gROOT->GetListOfFunctions()->Remove(
this);
432 for (
int i = 0; i < nLinParts; ++i)
delete fLinearParts[i];
439 fClingInput(formula),fFormula(formula)
450#ifndef R__HAS_VECCORE
457 if (addToGlobList &&
gROOT) {
462 gROOT->GetListOfFunctions()->Remove(old);
464 Error(
"TFormula",
"The name %s is reserved as a TFormula variable name.\n",
name);
466 gROOT->GetListOfFunctions()->Add(
this);
486 fClingInput(formula),fFormula(formula)
499 for (
int i = 0; i < npar; ++i) {
503 assert (
fNpar == npar);
513 if (addToGlobList &&
gROOT) {
518 gROOT->GetListOfFunctions()->Remove(old);
520 Error(
"TFormula",
"The name %s is reserved as a TFormula variable name.\n",
name);
522 gROOT->GetListOfFunctions()->Add(
this);
527 Error(
"TFormula",
"Syntax error in building the lambda expression %s", formula );
532 TNamed(formula.
GetName(),formula.GetTitle()), fMethod(nullptr)
540 gROOT->GetListOfFunctions()->Remove(old);
543 Error(
"TFormula",
"The name %s is reserved as a TFormula variable name.\n",formula.
GetName());
545 gROOT->GetListOfFunctions()->Add(
this);
565 std::string lambdaExpression = formula;
585 TString lambdaName =
TString::Format(
"lambda__id%zu", hasher(lambdaExpression) );
589 TString lineExpr =
TString::Format(
"std::function<double(double*,double*)> %s = %s ;",lambdaName.Data(), lambdaExpression.c_str() );
610 TString formula = expression;
611 if (formula.IsNull() ) {
613 if (formula.IsNull() ) formula =
GetTitle();
616 if (formula.IsNull() )
return -1;
628 return (ret) ? 0 : 1;
638 return (ret) ? 0 : 1;
667 for (
int i = 0; i < nLinParts; ++i)
delete fnew.
fLinearParts[i];
674 for (
int i = 0; i < nLinParts; ++i) {
678 linearOld->
Copy(*linearNew);
703 Error(
"TFormula",
"Syntax error in building the lambda expression %s",
fFormula.Data() );
756 for (
int i = 0; i < nLinParts; ++i)
delete fLinearParts[i];
763static std::unique_ptr<TMethodCall>
765 bool IsVectorized,
bool IsGradient =
false) {
766 std::unique_ptr<TMethodCall> Method = std::unique_ptr<TMethodCall>(
new TMethodCall());
768 TString prototypeArguments =
"";
769 if (HasVariables || HasParameters) {
771 prototypeArguments.Append(
"ROOT::Double_v*");
773 prototypeArguments.Append(
"Double_t*");
775 auto AddDoublePtrParam = [&prototypeArguments] () {
776 prototypeArguments.Append(
",");
777 prototypeArguments.Append(
"Double_t*");
788 Method->InitWithPrototype(FuncName, prototypeArguments);
789 if (!Method->IsValid()) {
790 Error(
"prepareMethod",
791 "Can't compile function %s prototype with arguments %s", FuncName,
792 prototypeArguments.Data());
804 Error(
"prepareFuncPtr",
"Callfunc retuned from Cling is not valid");
811 Error(
"prepareFuncPtr",
"Compiled function pointer is null");
847 TString triggerAutoparsing =
"namespace ROOT_TFormula_triggerAutoParse {\n"; triggerAutoparsing +=
fClingInput +
"\n}";
868 const TString defvars[] = {
"x",
"y",
"z",
"t"};
869 const pair<TString, Double_t> defconsts[] = {{
"pi",
TMath::Pi()},
887 const pair<TString,TString> funShortcuts[] =
888 { {
"sin",
"TMath::Sin" },
889 {
"cos",
"TMath::Cos" }, {
"exp",
"TMath::Exp"}, {
"log",
"TMath::Log"}, {
"log10",
"TMath::Log10"},
890 {
"tan",
"TMath::Tan"}, {
"sinh",
"TMath::SinH"}, {
"cosh",
"TMath::CosH"},
891 {
"tanh",
"TMath::TanH"}, {
"asin",
"TMath::ASin"}, {
"acos",
"TMath::ACos"},
892 {
"atan",
"TMath::ATan"}, {
"atan2",
"TMath::ATan2"}, {
"sqrt",
"TMath::Sqrt"},
893 {
"ceil",
"TMath::Ceil"}, {
"floor",
"TMath::Floor"}, {
"pow",
"TMath::Power"},
894 {
"binomial",
"TMath::Binomial"},{
"abs",
"TMath::Abs"},
895 {
"min",
"TMath::Min"},{
"max",
"TMath::Max"},{
"sign",
"TMath::Sign" },
899 std::vector<TString> defvars2(10);
900 for (
int i = 0; i < 9; ++i)
903 for (
const auto &var : defvars) {
904 int pos =
fVars.size();
917 for (
auto con : defconsts) {
918 fConsts[con.first] = con.second;
923 for (
auto fun : funShortcuts) {
936 const pair<TString,TString> vecFunShortcuts[] =
937 { {
"sin",
"vecCore::math::Sin" },
938 {
"cos",
"vecCore::math::Cos" }, {
"exp",
"vecCore::math::Exp"}, {
"log",
"vecCore::math::Log"}, {
"log10",
"vecCore::math::Log10"},
939 {
"tan",
"vecCore::math::Tan"},
941 {
"asin",
"vecCore::math::ASin"},
942 {
"acos",
"TMath::Pi()/2-vecCore::math::ASin"},
943 {
"atan",
"vecCore::math::ATan"},
944 {
"atan2",
"vecCore::math::ATan2"}, {
"sqrt",
"vecCore::math::Sqrt"},
945 {
"ceil",
"vecCore::math::Ceil"}, {
"floor",
"vecCore::math::Floor"}, {
"pow",
"vecCore::math::Pow"},
946 {
"cbrt",
"vecCore::math::Cbrt"},{
"abs",
"vecCore::math::Abs"},
947 {
"min",
"vecCore::math::Min"},{
"max",
"vecCore::math::Max"},{
"sign",
"vecCore::math::Sign" }
951 for (
auto fun : vecFunShortcuts) {
968 Int_t polPos = formula.Index(
"pol");
971 Bool_t defaultVariable =
false;
973 Int_t openingBracketPos = formula.Index(
'(', polPos);
974 Bool_t defaultCounter = openingBracketPos ==
kNPOS;
975 Bool_t defaultDegree =
true;
978 if (!defaultCounter) {
981 sdegree = formula(polPos + 3, openingBracketPos - polPos - 3);
982 if (!sdegree.IsDigit())
983 defaultCounter =
true;
985 if (!defaultCounter) {
987 counter = TString(formula(openingBracketPos + 1, formula.Index(
')', polPos) - openingBracketPos)).Atoi();
989 Int_t temp = polPos + 3;
990 while (temp < formula.Length() && isdigit(formula[temp])) {
991 defaultDegree =
false;
994 degree = TString(formula(polPos + 3, temp - polPos - 3)).Atoi();
999 if (polPos - 1 < 0 || !
IsFunctionNameChar(formula[polPos - 1]) || formula[polPos - 1] ==
':') {
1001 defaultVariable =
true;
1003 Int_t tmp = polPos - 1;
1007 variable = formula(tmp + 1, polPos - (tmp + 1));
1009 Int_t param = counter + 1;
1013 replacement.Append(
TString::Format(
"+[%d]*%s^%d", param, variable.Data(), tmp));
1015 replacement.Append(
TString::Format(
"+[%d]*%s", param, variable.Data()));
1021 replacement.Insert(0,
'(');
1022 replacement.Append(
')');
1025 if (defaultCounter && !defaultDegree) {
1027 }
else if (defaultCounter && defaultDegree) {
1028 pattern =
TString::Format(
"%spol", (defaultVariable ?
"" : variable.Data()));
1030 pattern =
TString::Format(
"%spol%d(%d)", (defaultVariable ?
"" : variable.Data()),
degree, counter);
1033 if (!formula.Contains(pattern)) {
1034 Error(
"HandlePolN",
"Error handling polynomial function - expression is %s - trying to replace %s with %s ",
1035 formula.Data(), pattern.Data(), replacement.Data());
1038 if (formula == pattern) {
1043 formula.ReplaceAll(pattern, replacement);
1044 polPos = formula.Index(
"pol");
1070 map< pair<TString,Int_t> ,pair<TString,TString> > functions;
1073 map<TString,Int_t> functionsNumbers;
1074 functionsNumbers[
"gaus"] = 100;
1075 functionsNumbers[
"bigaus"] = 102;
1076 functionsNumbers[
"landau"] = 400;
1077 functionsNumbers[
"expo"] = 200;
1078 functionsNumbers[
"crystalball"] = 500;
1081 formula.ReplaceAll(
"xyzgaus",
"gaus[x,y,z]");
1082 formula.ReplaceAll(
"xygaus",
"gaus[x,y]");
1083 formula.ReplaceAll(
"xgaus",
"gaus[x]");
1084 formula.ReplaceAll(
"ygaus",
"gaus[y]");
1085 formula.ReplaceAll(
"zgaus",
"gaus[z]");
1086 formula.ReplaceAll(
"xexpo",
"expo[x]");
1087 formula.ReplaceAll(
"yexpo",
"expo[y]");
1088 formula.ReplaceAll(
"zexpo",
"expo[z]");
1089 formula.ReplaceAll(
"xylandau",
"landau[x,y]");
1090 formula.ReplaceAll(
"xyexpo",
"expo[x,y]");
1092 const char * defaultVariableNames[] = {
"x",
"y",
"z"};
1094 for (map<pair<TString, Int_t>, pair<TString, TString>>::iterator it = functions.begin(); it != functions.end();
1097 TString funName = it->first.first;
1098 Int_t funDim = it->first.second;
1099 Int_t funPos = formula.Index(funName);
1105 Int_t lastFunPos = funPos + funName.Length();
1108 Int_t iposBefore = funPos - 1;
1111 if (iposBefore >= 0) {
1112 assert(iposBefore < formula.Length());
1113 if (isalpha(formula[iposBefore])) {
1116 funPos = formula.Index(funName, lastFunPos);
1121 Bool_t isNormalized =
false;
1122 if (lastFunPos < formula.Length()) {
1124 isNormalized = (formula[lastFunPos] ==
'n');
1127 if (lastFunPos < formula.Length()) {
1128 char c = formula[lastFunPos];
1131 if (isalnum(
c) || (!
IsOperator(
c) &&
c !=
'(' &&
c !=
')' &&
c !=
'[' &&
c !=
']')) {
1133 funPos = formula.Index(funName, lastFunPos);
1144 TString varList =
"";
1145 Bool_t defaultVariables =
false;
1148 Int_t openingBracketPos = funPos + funName.Length() + (isNormalized ? 1 : 0);
1150 if (openingBracketPos > formula.Length() || formula[openingBracketPos] !=
'[') {
1153 for (
Int_t idim = 0; idim < dim; ++idim)
1154 variables[idim] = defaultVariableNames[idim];
1155 defaultVariables =
true;
1158 closingBracketPos = formula.Index(
']', openingBracketPos);
1159 varList = formula(openingBracketPos + 1, closingBracketPos - openingBracketPos - 1);
1160 dim = varList.CountChar(
',') + 1;
1163 TString varName =
"";
1164 for (
Int_t i = 0; i < varList.Length(); ++i) {
1166 varName.Append(varList[i]);
1168 if (varList[i] ==
',') {
1181 if (dim != funDim) {
1182 pair<TString, Int_t> key = make_pair(funName, dim);
1183 if (functions.find(key) == functions.end()) {
1184 Error(
"PreProcessFormula",
"Dimension of function %s is detected to be of dimension %d and is not "
1185 "compatible with existing pre-defined function which has dim %d",
1186 funName.Data(), dim, funDim);
1190 funPos = formula.Index(funName, lastFunPos);
1195 Int_t openingParenthesisPos = (closingBracketPos ==
kNPOS) ? openingBracketPos : closingBracketPos + 1;
1196 bool defaultCounter = (openingParenthesisPos > formula.Length() || formula[openingParenthesisPos] !=
'(');
1201 if (defaultCounter) {
1207 TRegexp counterPattern(
"([0-9]+)");
1209 if (counterPattern.
Index(formula, &len, openingParenthesisPos) == -1) {
1210 funPos = formula.Index(funName, funPos + 1);
1214 TString(formula(openingParenthesisPos + 1, formula.Index(
')', funPos) - openingParenthesisPos - 1))
1220 TString body = (isNormalized ? it->second.second : it->second.first);
1221 if (isNormalized && body ==
"") {
1222 Error(
"PreprocessFormula",
"%d dimension function %s has no normalized form.", it->first.second,
1226 for (
int i = 0; i < body.Length(); ++i) {
1227 if (body[i] ==
'{') {
1230 Int_t num = TString(body(i, body.Index(
'}', i) - i)).Atoi();
1234 body.Replace(i, pattern.Length(), variable, variable.Length());
1235 i += variable.Length() - 1;
1236 }
else if (body[i] ==
'[') {
1239 while (tmp < body.Length() && body[tmp] !=
']') {
1242 Int_t num = TString(body(i + 1, tmp - 1 - i)).Atoi();
1246 body.Replace(i + 1, tmp - 1 - i, replacement, replacement.Length());
1247 i += replacement.Length() + 1;
1251 if (defaultCounter && defaultVariables) {
1252 pattern =
TString::Format(
"%s%s", funName.Data(), (isNormalized ?
"n" :
""));
1254 if (!defaultCounter && defaultVariables) {
1255 pattern =
TString::Format(
"%s%s(%d)", funName.Data(), (isNormalized ?
"n" :
""), counter);
1257 if (defaultCounter && !defaultVariables) {
1258 pattern =
TString::Format(
"%s%s[%s]", funName.Data(), (isNormalized ?
"n" :
""), varList.Data());
1260 if (!defaultCounter && !defaultVariables) {
1262 TString::Format(
"%s%s[%s](%d)", funName.Data(), (isNormalized ?
"n" :
""), varList.Data(), counter);
1264 TString replacement = body;
1267 if (
fNumber == 0 && formula.Length() <= (pattern.Length() - funPos) + 1) {
1268 fNumber = functionsNumbers[funName] + 10 * (dim - 1);
1273 formula.Replace(funPos, pattern.Length(), replacement, replacement.Length());
1275 funPos = formula.Index(funName);
1285 TRegexp rangePattern(
"\\[[0-9]+\\.\\.[0-9]+\\]");
1288 while ((matchIdx = rangePattern.
Index(formula, len, matchIdx)) != -1) {
1289 int startIdx = matchIdx + 1;
1290 int endIdx = formula.Index(
"..", startIdx) + 2;
1291 int startCnt = TString(formula(startIdx, formula.Length())).Atoi();
1292 int endCnt = TString(formula(endIdx, formula.Length())).Atoi();
1294 if (endCnt <= startCnt)
1295 Error(
"HandleParamRanges",
"End parameter (%d) <= start parameter (%d) in parameter range", endCnt, startCnt);
1297 TString newString =
"[";
1298 for (
int cnt = startCnt;
cnt < endCnt;
cnt++)
1303 formula.Replace(matchIdx, formula.Index(
"]", matchIdx) + 1 - matchIdx, newString);
1305 matchIdx += newString.Length();
1319 std::map<std::pair<TString, Int_t>, std::pair<TString, TString>> parFunctions;
1323 for (
Int_t i = 0; i < formula.Length(); ++i) {
1327 if (formula[i] ==
'[') {
1328 while (formula[i] !=
']')
1333 if (formula[i] ==
'\"') {
1336 while (formula[i] !=
'\"');
1344 while (!
IsOperator(formula[i]) && i < formula.Length())
1350 if (isalpha(formula[i]) && !
IsOperator(formula[i])) {
1356 TString
name = (TString)formula(i, j - i);
1363 std::vector<int> argSeparators;
1364 argSeparators.push_back(j);
1366 for (k = j + 1; depth >= 1 && k < formula.Length(); k++) {
1367 if (formula[k] ==
',' && depth == 1) {
1369 argSeparators.push_back(k);
1370 }
else if (formula[k] ==
'(')
1372 else if (formula[k] ==
')')
1375 argSeparators.push_back(k - 1);
1381 obj =
gROOT->GetListOfFunctions()->FindObject(
name);
1386 TF1 *
f1 =
dynamic_cast<TF1 *
>(obj);
1394 bool nameRecognized = (
f != NULL);
1399 TString replacementFormula;
1401 ndim =
f->GetNdim();
1402 npar =
f->GetNpar();
1403 replacementFormula =
f->GetExpFormula();
1407 for (
auto keyval : parFunctions) {
1409 pair<TString, Int_t> name_ndim = keyval.first;
1411 pair<TString, TString> formulaPair = keyval.second;
1414 if (
name == name_ndim.first)
1415 replacementFormula = formulaPair.first;
1416 else if (
name == name_ndim.first +
"n" && formulaPair.second !=
"")
1417 replacementFormula = formulaPair.second;
1422 ndim = name_ndim.second;
1427 while ((idx = replacementFormula.Index(
'[', idx)) !=
kNPOS) {
1428 npar = max(npar, 1 + TString(replacementFormula(idx + 1, replacementFormula.Length())).Atoi());
1429 idx = replacementFormula.Index(
']', idx);
1431 Error(
"HandleFunctionArguments",
"Square brackets not matching in formula %s",
1432 (
const char *)replacementFormula);
1439 if (nArguments == ndim + npar || nArguments == npar || nArguments == ndim) {
1440 nameRecognized =
true;
1445 if (nameRecognized && ndim > 4)
1446 Error(
"HandleFunctionArguments",
"Number of dimensions %d greater than 4. Cannot parse formula.", ndim);
1449 if (nameRecognized && j < formula.Length() && formula[j] ==
'(') {
1454 map<TString, TString> argSubstitutions;
1456 const char *defaultVariableNames[] = {
"x",
"y",
"z",
"t"};
1459 bool canReplace =
false;
1460 if (nArguments == ndim + npar) {
1462 for (
int argNr = 0; argNr < nArguments; argNr++) {
1466 TString(formula(argSeparators[argNr] + 1, argSeparators[argNr + 1] - argSeparators[argNr] - 1));
1473 argSubstitutions[oldName] = newName;
1476 argSubstitutions[defaultVariableNames[argNr]] = newName;
1479 int parNr = argNr - ndim;
1482 argSubstitutions[oldName] = newName;
1485 if (
f && oldName == newName)
1491 }
else if (nArguments == npar) {
1496 bool varsImplicit =
true;
1497 for (
int argNr = 0; argNr < nArguments && varsImplicit; argNr++) {
1498 int openIdx = argSeparators[argNr] + 1;
1499 int closeIdx = argSeparators[argNr + 1] - 1;
1502 if (formula[openIdx] !=
'[' || formula[closeIdx] !=
']' || closeIdx <= openIdx + 1)
1503 varsImplicit =
false;
1506 for (
int idx = openIdx + 1; idx < closeIdx && varsImplicit; idx++)
1508 varsImplicit =
false;
1511 Warning(
"HandleFunctionArguments",
1512 "Argument %d is not a parameter. Cannot assume variables are implicit.", argNr);
1519 for (
int dim = 0; dim < ndim; dim++) {
1520 argSubstitutions[
TString::Format(
"{V%d}", dim)] = defaultVariableNames[dim];
1524 for (
int argNr = 0; argNr < nArguments; argNr++) {
1528 TString(formula(argSeparators[argNr] + 1, argSeparators[argNr + 1] - argSeparators[argNr] - 1));
1532 argSubstitutions[oldName] = newName;
1535 if (
f && oldName == newName)
1542 if (!canReplace && nArguments == ndim) {
1546 for (
int argNr = 0; argNr < nArguments; argNr++) {
1549 TString(formula(argSeparators[argNr] + 1, argSeparators[argNr + 1] - argSeparators[argNr] - 1));
1553 argSubstitutions[oldName] = newName;
1556 argSubstitutions[defaultVariableNames[argNr]] = newName;
1561 for (
int parNr = 0; parNr < npar; parNr++)
1575 formula.Replace(i, k - i, replacementFormula);
1576 i += replacementFormula.Length() - 1;
1579 Warning(
"HandleFunctionArguments",
"Unable to make replacement. Number of parameters doesn't work : "
1580 "%d arguments, %d dimensions, %d parameters",
1581 nArguments, ndim, npar);
1600 Int_t caretPos = formula.Last(
'^');
1603 TString right, left;
1604 Int_t temp = caretPos;
1607 if (formula[temp] ==
')') {
1610 while (depth != 0 && temp > 0) {
1611 if (formula[temp] ==
')')
1613 if (formula[temp] ==
'(')
1628 assert(temp + 1 >= 0);
1629 Int_t leftPos = temp + 1;
1630 left = formula(leftPos, caretPos - leftPos);
1636 if (temp >= formula.Length()) {
1637 Error(
"HandleExponentiation",
"Invalid position of operator ^");
1640 if (formula[temp] ==
'(') {
1643 while (depth != 0 && temp < formula.Length()) {
1644 if (formula[temp] ==
')')
1646 if (formula[temp] ==
'(')
1653 if (formula[temp] ==
'-' || formula[temp] ==
'+')
1659 while (temp < formula.Length() && ((depth > 0) || !
IsOperator(formula[temp]))) {
1665 if (temp < formula.Length() && formula[temp] ==
'(')
1667 if (temp < formula.Length() && formula[temp] ==
')') {
1675 right = formula(caretPos + 1, (temp - 1) - caretPos);
1678 TString pattern =
TString::Format(
"%s^%s", left.Data(), right.Data());
1679 TString replacement =
TString::Format(
"pow(%s,%s)", left.Data(), right.Data());
1683 formula.Replace(leftPos, pattern.Length(), replacement, replacement.Length());
1685 caretPos = formula.Last(
'^');
1695 Int_t linPos = formula.Index(
"@");
1696 if (linPos ==
kNPOS )
return;
1697 Int_t nofLinParts = formula.CountChar((
int)
'@');
1698 assert(nofLinParts > 0);
1709 while (temp >= 0 && formula[temp] !=
'@') {
1712 left = formula(temp + 1, linPos - (temp + 1));
1715 while (temp < formula.Length() && formula[temp] !=
'@') {
1718 TString right = formula(linPos + 1, temp - (linPos + 1));
1722 TString replacement =
1723 (
first) ?
TString::Format(
"([%d]*(%s))+([%d]*(%s))", Nlinear, left.Data(), Nlinear + 1, right.Data())
1725 Nlinear += (
first) ? 2 : 1;
1727 formula.ReplaceAll(pattern, replacement);
1735 linPos = formula.Index(
"@");
1749 formula.ReplaceAll(
"**",
"^");
1750 formula.ReplaceAll(
"++",
"@");
1751 formula.ReplaceAll(
" ",
"");
1761 formula.ReplaceAll(
"--",
"- -");
1762 formula.ReplaceAll(
"++",
"+ +");
1815 for (
Int_t i = 0; i < formula.Length(); ++i) {
1819 if (formula[i] ==
'[') {
1823 while (i < formula.Length() && formula[i] !=
']') {
1824 param.Append(formula[i++]);
1829 int paramIndex = -1;
1830 if (param.IsDigit()) {
1831 paramIndex = param.Atoi();
1832 param.Insert(0,
'p');
1835 for (
int idx = 0; idx <= paramIndex; ++idx) {
1843 param.ReplaceAll(
"\\s",
" ");
1855 formula.Replace(tmp, i - tmp, replacement, replacement.Length());
1859 int deltai = replacement.Length() - (i-tmp);
1865 if (formula[i] ==
'\"') {
1869 }
while (formula[i] !=
'\"');
1878 while (!
IsOperator(formula[i]) && i < formula.Length()) {
1887 if (isalpha(formula[i]) &&
1895 if (formula[i] ==
':' && ((i + 1) < formula.Length())) {
1896 if (formula[i + 1] ==
':') {
1905 name.Append(formula[i++]);
1908 if (formula[i] ==
'(') {
1910 if (formula[i] ==
')') {
1917 while (depth != 0 && i < formula.Length()) {
1918 switch (formula[i]) {
1919 case '(': depth++;
break;
1920 case ')': depth--;
break;
1928 body.Append(formula[i++]);
1931 Int_t originalBodyLen = body.Length();
1933 formula.Replace(i - originalBodyLen, originalBodyLen, body, body.Length());
1934 i += body.Length() - originalBodyLen;
1947 obj =
gROOT->GetListOfFunctions()->FindObject(
name);
1952 TF1 *
f1 =
dynamic_cast<TF1 *
>(obj);
1962 TString replacementFormula =
f->GetExpFormula();
1975 std::vector<TString> newNames;
1978 newNames.resize(
f->GetNpar());
1980 for (
int jpar =
f->GetNpar() - 1; jpar >= 0; --jpar) {
1982 TString pj = TString(
f->GetParName(jpar));
1983 if (pj[0] ==
'p' && TString(pj(1, pj.Length())).IsDigit()) {
1988 replacementFormula.ReplaceAll(oldName, newName);
1989 newNames[jpar] = newName;
1991 newNames[jpar] =
f->GetParName(jpar);
1999 for (
int jpar = 0; jpar <
f->GetNpar(); ++jpar) {
2000 if (nparOffset > 0) {
2002 assert((
int)newNames.size() ==
f->GetNpar());
2009 replacementFormula.Insert(0,
'(');
2010 replacementFormula.Insert(replacementFormula.Length(),
')');
2011 formula.Replace(i -
name.Length(),
name.Length(), replacementFormula, replacementFormula.Length());
2013 i += replacementFormula.Length() -
name.Length();
2025 formula.Replace(i -
name.Length(),
name.Length(), replacement, replacement.Length());
2057 for (list<TFormulaFunction>::iterator funcsIt =
fFuncs.begin(); funcsIt !=
fFuncs.end(); ++funcsIt) {
2068 TString shortcut = it->first;
2069 TString full = it->second;
2073 Ssiz_t index = formula.Index(shortcut, 0);
2074 while (index !=
kNPOS) {
2077 Ssiz_t i2 = index + shortcut.Length();
2078 if ((index > 0) && (isalpha(formula[index - 1]) || formula[index - 1] ==
':')) {
2079 index = formula.Index(shortcut, i2);
2082 if (i2 < formula.Length() && formula[i2] !=
'(') {
2083 index = formula.Index(shortcut, i2);
2087 formula.Replace(index, shortcut.Length(), full);
2088 Ssiz_t inext = index + full.Length();
2089 index = formula.Index(shortcut, inext);
2096#ifdef TFORMULA_CHECK_FUNCTIONS
2098 if (fun.
fName.Contains(
"::"))
2102 size_t index =
name.rfind(
"::");
2103 assert(index != std::string::npos);
2104 TString className = fun.
fName(0, fun.
fName(0, index).Length());
2105 TString functionName = fun.
fName(index + 2, fun.
fName.Length());
2111 TIter next(methodList);
2113 while ((p = (
TMethod *)next())) {
2114 if (strcmp(p->
GetName(), functionName.Data()) == 0 &&
2129 if (
f && fun.
GetNargs() <=
f->GetNargs() && fun.
GetNargs() >=
f->GetNargs() -
f->GetNargsOpt()) {
2137 Info(
"TFormula",
"Could not find %s function with %d argument(s)", fun.
GetName(), fun.
GetNargs());
2155 formula.ReplaceAll(pattern, replacement);
2160 map<TString, TFormulaVariable>::iterator varsIt =
fVars.find(fun.
GetName());
2161 if (varsIt !=
fVars.end()) {
2163 TString
name = (*varsIt).second.GetName();
2164 Double_t value = (*varsIt).second.fValue;
2170 int varDim = (*varsIt).second.fArrayPos;
2171 if (varDim >=
fNdim) {
2176 if (
v.second.fArrayPos < varDim && !
v.second.fFound) {
2178 v.second.fFound =
true;
2185 TString replacement =
TString::Format(
"x[%d]", (*varsIt).second.fArrayPos);
2186 formula.ReplaceAll(pattern, replacement);
2196 TString funname = fun.
GetName();
2197 if (funname.Contains(
"x[") && funname.Contains(
"]")) {
2198 TString sdigit = funname(2, funname.Index(
"]"));
2199 int digit = sdigit.Atoi();
2200 if (digit >=
fNdim) {
2203 for (
int j = 0; j <
fNdim; ++j) {
2207 fVars[vname].fFound =
true;
2216 formula.ReplaceAll(pattern, funname);
2222 if (paramsIt !=
fParams.end()) {
2226 if (formula.Index(pattern) !=
kNPOS) {
2230 formula.ReplaceAll(pattern, replacement);
2239 map<TString, Double_t>::iterator constIt =
fConsts.find(fun.
GetName());
2240 if (constIt !=
fConsts.end()) {
2243 formula.ReplaceAll(pattern, value);
2259 if (!hasParameters) {
2272 Bool_t inputIntoCling = (formula.Length() > 0);
2273 if (inputIntoCling) {
2276 std::string inputFormula(formula.Data());
2280 std::string inputFormulaVecFlag = inputFormula;
2282 inputFormulaVecFlag +=
" (vectorized)";
2284 TString argType =
fVectorized ?
"ROOT::Double_v" :
"Double_t";
2287 TString argumentsPrototype =
TString::Format(
"%s%s%s", ( (hasVariables || hasParameters) ? (argType +
" *x").Data() :
""),
2288 (hasParameters ?
"," :
""), (hasParameters ?
"Double_t *p" :
""));
2305 inputIntoCling =
false;
2315 argumentsPrototype.Data(), inputFormula.c_str());
2334 if (inputIntoCling) {
2360 for (list<TFormulaFunction>::iterator it =
fFuncs.begin(); it !=
fFuncs.end(); ++it) {
2362 if (!it->fFound && !it->IsFuncCall()) {
2364 if (it->GetNargs() == 0)
2365 Error(
"ProcessFormula",
"\"%s\" has not been matched in the formula expression", it->GetName());
2367 Error(
"ProcessFormula",
"Could not find %s function with %d argument(s)", it->GetName(), it->GetNargs());
2378 auto itvar =
fVars.begin();
2381 if (!itvar->second.fFound) {
2383 itvar =
fVars.erase(itvar);
2386 }
while (itvar !=
fVars.end());
2397 make_pair(make_pair(
"gaus", 1), make_pair(
"[0]*exp(-0.5*(({V0}-[1])/[2])*(({V0}-[1])/[2]))",
2398 "[0]*exp(-0.5*(({V0}-[1])/[2])*(({V0}-[1])/[2]))/(sqrt(2*pi)*[2])")));
2399 functions.insert(make_pair(make_pair(
"landau", 1), make_pair(
"[0]*TMath::Landau({V0},[1],[2],false)",
2400 "[0]*TMath::Landau({V0},[1],[2],true)")));
2401 functions.insert(make_pair(make_pair(
"expo", 1), make_pair(
"exp([0]+[1]*{V0})",
"")));
2403 make_pair(make_pair(
"crystalball", 1), make_pair(
"[0]*ROOT::Math::crystalball_function({V0},[3],[4],[2],[1])",
2404 "[0]*ROOT::Math::crystalball_pdf({V0},[3],[4],[2],[1])")));
2406 make_pair(make_pair(
"breitwigner", 1), make_pair(
"[0]*ROOT::Math::breitwigner_pdf({V0},[2],[1])",
2407 "[0]*ROOT::Math::breitwigner_pdf({V0},[2],[4],[1])")));
2409 functions.insert(make_pair(make_pair(
"cheb0", 1), make_pair(
"ROOT::Math::Chebyshev0({V0},[0])",
"")));
2410 functions.insert(make_pair(make_pair(
"cheb1", 1), make_pair(
"ROOT::Math::Chebyshev1({V0},[0],[1])",
"")));
2411 functions.insert(make_pair(make_pair(
"cheb2", 1), make_pair(
"ROOT::Math::Chebyshev2({V0},[0],[1],[2])",
"")));
2412 functions.insert(make_pair(make_pair(
"cheb3", 1), make_pair(
"ROOT::Math::Chebyshev3({V0},[0],[1],[2],[3])",
"")));
2414 make_pair(make_pair(
"cheb4", 1), make_pair(
"ROOT::Math::Chebyshev4({V0},[0],[1],[2],[3],[4])",
"")));
2416 make_pair(make_pair(
"cheb5", 1), make_pair(
"ROOT::Math::Chebyshev5({V0},[0],[1],[2],[3],[4],[5])",
"")));
2418 make_pair(make_pair(
"cheb6", 1), make_pair(
"ROOT::Math::Chebyshev6({V0},[0],[1],[2],[3],[4],[5],[6])",
"")));
2420 make_pair(make_pair(
"cheb7", 1), make_pair(
"ROOT::Math::Chebyshev7({V0},[0],[1],[2],[3],[4],[5],[6],[7])",
"")));
2421 functions.insert(make_pair(make_pair(
"cheb8", 1),
2422 make_pair(
"ROOT::Math::Chebyshev8({V0},[0],[1],[2],[3],[4],[5],[6],[7],[8])",
"")));
2423 functions.insert(make_pair(make_pair(
"cheb9", 1),
2424 make_pair(
"ROOT::Math::Chebyshev9({V0},[0],[1],[2],[3],[4],[5],[6],[7],[8],[9])",
"")));
2426 make_pair(make_pair(
"cheb10", 1),
2427 make_pair(
"ROOT::Math::Chebyshev10({V0},[0],[1],[2],[3],[4],[5],[6],[7],[8],[9],[10])",
"")));
2430 make_pair(make_pair(
"gaus", 2), make_pair(
"[0]*exp(-0.5*(({V0}-[1])/[2])^2 - 0.5*(({V1}-[3])/[4])^2)",
"")));
2432 make_pair(make_pair(
"landau", 2),
2433 make_pair(
"[0]*TMath::Landau({V0},[1],[2],false)*TMath::Landau({V1},[3],[4],false)",
"")));
2434 functions.insert(make_pair(make_pair(
"expo", 2), make_pair(
"exp([0]+[1]*{V0})",
"exp([0]+[1]*{V0}+[2]*{V1})")));
2437 make_pair(make_pair(
"gaus", 3), make_pair(
"[0]*exp(-0.5*(({V0}-[1])/[2])^2 - 0.5*(({V1}-[3])/[4])^2 - 0.5*(({V2}-[5])/[6])^2)",
"")));
2440 make_pair(make_pair(
"bigaus", 2), make_pair(
"[0]*ROOT::Math::bigaussian_pdf({V0},{V1},[2],[4],[5],[1],[3])",
2441 "[0]*ROOT::Math::bigaussian_pdf({V0},{V1},[2],[4],[5],[1],[3])")));
2533 if (i < 0 || i >=
n ) {
2534 Error(
"GetLinearPart",
"Formula %s has only %d linear parts - requested %d",
GetName(),
n,i);
2580 Bool_t anyNewVar =
false;
2581 for (
Int_t i = 0; i < size; ++i) {
2583 const TString &vname = vars[i];
2593 Int_t multiplier = 2;
2594 if (
fFuncs.size() > 100) {
2607 if (anyNewVar && !
fFormula.IsNull()) {
2619 Error(
"SetName",
"The name \'%s\' is reserved as a TFormula variable name.\n"
2620 "\tThis function will not be renamed.",
2625 auto listOfFunctions =
gROOT->GetListOfFunctions();
2626 TObject* thisAsFunctionInList =
nullptr;
2628 if (listOfFunctions){
2629 thisAsFunctionInList = listOfFunctions->
FindObject(
this);
2630 if (thisAsFunctionInList) listOfFunctions->Remove(thisAsFunctionInList);
2633 if (thisAsFunctionInList) listOfFunctions->Add(thisAsFunctionInList);
2647 for(
Int_t i = 0; i < size; ++i)
2651 fVars[
v.first].fValue =
v.second;
2654 Error(
"SetVariables",
"Variable %s is not defined.",
v.first.Data());
2665 if (
fVars.end() == nameIt) {
2666 Error(
"GetVariable",
"Variable %s is not defined.",
name);
2669 return nameIt->second.fValue;
2678 if (
fVars.end() == nameIt) {
2679 Error(
"GetVarNumber",
"Variable %s is not defined.",
name);
2682 return nameIt->second.fArrayPos;
2690 if (ivar < 0 || ivar >=
fNdim)
return "";
2693 for (
auto &
v :
fVars) {
2694 if (
v.second.fArrayPos == ivar)
return v.first;
2696 Error(
"GetVarName",
"Variable with index %d not found !!",ivar);
2707 Error(
"SetVariable",
"Variable %s is not defined.",
name.Data());
2746 auto ret =
fParams.insert(std::make_pair(
name, pos));
2752 if (ret.first ==
fParams.begin())
2755 auto previous = (ret.first);
2757 pos = previous->second + 1;
2765 Warning(
"inserting parameter %s at pos %d when vector size is %d \n",
name.Data(), pos,
2775 for (
auto it = ret.first; it !=
fParams.end(); ++it) {
2785 if (processFormula) {
2813 Error(
"GetParameter",
"Parameter %s is not defined.",
name);
2828 Error(
"GetParameter",
"wrong index used - use GetParameter(name)");
2837 if (ipar < 0 || ipar >=
fNpar)
return "";
2841 if (p.second == ipar)
return p.first.Data();
2843 Error(
"GetParName",
"Parameter with index %d not found !!",ipar);
2876 Error(
"SetParameter",
"Parameter %s is not defined.",
name.Data());
2883 for (map<TString, TFormulaVariable>::iterator it =
fParams.begin(); it !=
fParams.end(); ++it) {
2884 if (!it->second.fFound) {
2903 for(
Int_t i = 0 ; i < size ; ++i)
2905 pair<TString, Double_t> p = params[i];
2907 Error(
"SetParameters",
"Parameter %s is not defined", p.first.Data());
2910 fParams[p.first].fValue = p.second;
2911 fParams[p.first].fFound =
true;
2915 for (map<TString, TFormulaVariable>::iterator it =
fParams.begin(); it !=
fParams.end(); ++it) {
2916 if (!it->second.fFound) {
2927 if(!params || size < 0 || size >
fNpar)
return;
2930 Warning(
"SetParameters",
"size is not same of cling parameter size %d - %d",size,
int(
fClingParameters.size()) );
2931 for (
Int_t i = 0; i < size; ++i) {
2979 if (param < 0 || param >=
fNpar)
return;
2987void TFormula::SetParNames(
const char *name0,
const char *name1,
const char *name2,
const char *name3,
2988 const char *name4,
const char *name5,
const char *name6,
const char *name7,
2989 const char *name8,
const char *name9,
const char *name10)
3019 if (ipar < 0 || ipar >
fNpar) {
3020 Error(
"SetParName",
"Wrong Parameter index %d ",ipar);
3026 if (it.second == ipar) {
3033 if (oldName.IsNull() ) {
3034 Error(
"SetParName",
"Parameter %d is not existing.",ipar);
3047 if (!formula.IsNull() ) {
3049 for(list<TFormulaFunction>::iterator it =
fFuncs.begin(); it !=
fFuncs.end(); ++it)
3051 if (oldName == it->GetName()) {
3058 Error(
"SetParName",
"Parameter %s is not defined.", oldName.Data());
3062 TString newName =
name;
3063 newName.ReplaceAll(
" ",
"\\s");
3066 formula.ReplaceAll(pattern, replacement);
3074#ifdef R__HAS_VECCORE
3076 Info(
"SetVectorized",
"Cannot vectorized a function of zero dimension");
3081 Error(
"SetVectorized",
"Cannot set vectorized to %d -- Formula is missing", vectorized);
3101 Warning(
"SetVectorized",
"Cannot set vectorized -- try building with option -Dbuiltin_veccore=On");
3111#ifdef R__HAS_VECCORE
3115 return vecCore::Get( ret, 0 );
3122 Info(
"EvalPar",
"Function is vectorized - converting Double_t into ROOT::Double_v and back");
3125 const int maxDim = 4;
3126 std::array<ROOT::Double_v, maxDim> xvec;
3127 for (
int i = 0; i <
fNdim; i++)
3131 return vecCore::Get(ans, 0);
3134 std::vector<ROOT::Double_v> xvec(
fNdim);
3135 for (
int i = 0; i <
fNdim; i++)
3139 return vecCore::Get(ans, 0);
3144 Error(
"EvalPar",
"Formula is vectorized (even though VECCORE is disabled!)");
3151static bool functionExists(
const string &
Name) {
3166 gInterpreter->Declare(
"#include <Math/CladDerivator.h>\n#pragma clad OFF");
3177 "#pragma clad ON\n" +
3178 "void " + GradReqFuncName +
"() {\n" +
3179 "clad::gradient(" + std::string(
fClingName.Data()) +
");\n }\n" +
3190 GradFuncName.c_str(),
3204 Error(
"GradientPar",
"Could not initialize the formula!");
3209 Error(
"GradientPar",
"Could not generate a gradient for the formula %s!",
3214 if ((
int)result.size() <
fNpar) {
3216 "The size of gradient result is %zu but %d is required. Resizing.",
3217 result.size(),
fNpar);
3218 result.resize(
fNpar);
3240 (*fGradFuncPtr)(0, 2, args,
nullptr);
3252 (*fGradFuncPtr)(0, 3, args,
nullptr);
3257#ifdef R__HAS_VECCORE
3267 return DoEvalVec(
x, params);
3270 return DoEval(
nullptr, params);
3275 Info(
"EvalPar",
"Function is not vectorized - converting ROOT::Double_v into Double_t and back");
3277 const int vecSize = vecCore::VectorSize<ROOT::Double_v>();
3278 std::vector<Double_t> xscalars(vecSize*
fNdim);
3280 for (
int i = 0; i < vecSize; i++)
3281 for (
int j = 0; j <
fNdim; j++)
3282 xscalars[i*
fNdim+j] = vecCore::Get(
x[j],i);
3285 for (
int i = 0; i < vecSize; i++)
3286 vecCore::Set(answers, i,
DoEval(&xscalars[i*
fNdim], params));
3297 double xxx[4] = {
x,
y,z,t};
3306 double xxx[3] = {
x,
y,z};
3315 double xxx[2] = {
x,
y};
3338 Error(
"Eval",
"Formula is invalid and not ready to execute ");
3339 for (
auto it =
fFuncs.begin(); it !=
fFuncs.end(); ++it) {
3342 printf(
"%s is unknown.\n", fun.
GetName());
3352 auto thisFormula =
const_cast<TFormula*
>(
this);
3356 Error(
"DoEval",
"Formula has error and it is not properly initialized ");
3364 double *
v =
const_cast<double*
>(
x);
3365 double * p = (params) ?
const_cast<double*
>(params) :
const_cast<double*
>(
fClingParameters.data());
3372 double * vars = (
x) ?
const_cast<double*
>(
x) :
const_cast<double*
>(
fClingVariables.data());
3375 (*fFuncPtr)(0, 1, args, &result);
3377 double *pars = (params) ?
const_cast<double *
>(params) :
const_cast<double *
>(
fClingParameters.data());
3379 (*fFuncPtr)(0, 2, args, &result);
3386#ifdef R__HAS_VECCORE
3390 Error(
"Eval",
"Formula is invalid and not ready to execute ");
3391 for (
auto it =
fFuncs.begin(); it !=
fFuncs.end(); ++it) {
3394 printf(
"%s is unknown.\n", fun.
GetName());
3404 auto thisFormula =
const_cast<TFormula*
>(
this);
3414 (*fFuncPtr)(0, 1, args, &result);
3416 double *pars = (params) ?
const_cast<double *
>(params) :
const_cast<double *
>(
fClingParameters.data());
3418 (*fFuncPtr)(0, 2, args, &result);
3435 Info(
"ReInitializeEvalMethod",
"compile now lambda expression function using Cling");
3444 if (!
fLazyInitialization)
Warning(
"ReInitializeEvalMethod",
"Formula is NOT properly initialized - try calling again TFormula::PrepareEvalMethod");
3492 TString opt(option);
3501 if (opt.Contains(
"CLING") ) {
3503 std::size_t found = clingFunc.find(
"return");
3504 std::size_t found2 = clingFunc.rfind(
";");
3505 if (found == std::string::npos || found2 == std::string::npos) {
3506 Error(
"GetExpFormula",
"Invalid Cling expression - return default formula expression");
3509 TString clingFormula =
fClingInput(found+7,found2-found-7);
3511 if (!opt.Contains(
"P"))
return clingFormula;
3514 while (i < clingFormula.Length()-2 ) {
3516 if (clingFormula[i] ==
'p' && clingFormula[i+1] ==
'[' && isdigit(clingFormula[i+2]) ) {
3518 while ( isdigit(clingFormula[j]) ) { j++;}
3519 if (clingFormula[j] !=
']') {
3520 Error(
"GetExpFormula",
"Parameters not found - invalid expression - return default cling formula");
3521 return clingFormula;
3523 TString parNumbName = clingFormula(i+2,j-i-2);
3524 int parNumber = parNumbName.Atoi();
3525 assert(parNumber <
fNpar);
3527 clingFormula.Replace(i,j-i+1, replacement );
3528 i += replacement.Length();
3532 return clingFormula;
3534 if (opt.Contains(
"P") ) {
3538 while (i < expFormula.Length()-2 ) {
3540 if (expFormula[i] ==
'[') {
3542 while ( expFormula[j] !=
']' ) { j++;}
3543 if (expFormula[j] !=
']') {
3544 Error(
"GetExpFormula",
"Parameter names not found - invalid expression - return default formula");
3547 TString parName = expFormula(i+1,j-i-1);
3549 expFormula.Replace(i,j-i+1, replacement );
3550 i += replacement.Length();
3556 Warning(
"GetExpFormula",
"Invalid option - return default formula expression");
3561 std::unique_ptr<TInterpreterValue>
v =
gInterpreter->MakeInterpreterValue();
3563 return v->ToString();
3572 printf(
" Formula expression: \n");
3573 printf(
"\t%s \n",
fFormula.Data() );
3574 TString opt(option);
3579 if (opt.Contains(
"V") ) {
3581 printf(
"List of Variables: \n");
3583 for (
int ivar = 0; ivar <
fNdim ; ++ivar) {
3588 printf(
"List of Parameters: \n");
3593 for (
int ipar = 0; ipar <
fNpar ; ++ipar) {
3597 printf(
"Expression passed to Cling:\n");
3600 printf(
"Generated Gradient:\n");
3607 Warning(
"Print",
"Formula is not ready to execute. Missing parameters/variables");
3608 for (list<TFormulaFunction>::const_iterator it =
fFuncs.begin(); it !=
fFuncs.end(); ++it) {
3611 printf(
"%s is unknown.\n", fun.
GetName());
3634 if (
b.IsReading() ) {
3638 if (v <= 8 && v > 3 &&
v != 6) {
3651 Error(
"Streamer",
"Old formula read from file is NOT valid");
3704 if (
fNpar != (
int) parValues.size() ) {
3705 Error(
"Streamer",
"number of parameters computed (%d) is not same as the stored parameters (%d)",
fNpar,
int(parValues.size()) );
3708 if (
v > 11 &&
fNdim != ndim) {
3709 Error(
"Streamer",
"number of dimension computed (%d) is not same as the stored value (%d)",
fNdim, ndim );
3724 assert(
fNpar == (
int) parValues.size() );
3727 if (
fParams.size() != paramMap.size() ) {
3728 Warning(
"Streamer",
"number of parameters list found (%zu) is not same as the stored one (%zu) - use re-created list",
fParams.size(),paramMap.size()) ;
3744 gROOT->GetListOfFunctions()->Add(
this);
3747 Error(
"Streamer",
"Formula read from file is NOT ready to execute");
3755 Error(
"Streamer",
"Reading version %d is not supported",
v);
static double p3(double t, double a, double b, double c, double d)
static double p1(double t, double a, double b)
static double p2(double t, double a, double b, double c)
void Error(const char *location, const char *msgfmt,...)
void GetParameters(TFitEditor::FuncParams_t &pars, TF1 *func)
Stores the parameters of the given function into pars.
R__EXTERN TInterpreter * gCling
R__EXTERN TVirtualMutex * gROOTMutex
typedef void((*Func_t)())
#define R__LOCKGUARD(mutex)
Buffer base class used for serializing objects.
The ROOT global object gROOT contains a list of all defined classes.
const TList * GetListOfAllPublicMethods(Bool_t load=kTRUE)
Returns a list of all public methods of this class and its base classes.
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
virtual TFormula * GetFormula()
Global functions class (global functions are obtained from CINT).
Int_t GetNargsOpt() const
Number of function optional (default) arguments.
Int_t GetNargs() const
Number of function arguments.
virtual Bool_t Declare(const char *code)=0
virtual Bool_t CallFunc_IsValid(CallFunc_t *) const
virtual Long_t ProcessLine(const char *line, EErrorCode *error=0)=0
virtual CallFuncIFacePtr_t CallFunc_IFacePtr(CallFunc_t *) const
Method or function calling interface.
CallFunc_t * GetCallFunc() const
Each ROOT class (see TClass) has a linked list of methods.
The TNamed class is the base class for all named ROOT classes.
virtual void Copy(TObject &named) const
Copy this to obj.
virtual void SetName(const char *name)
Set the name of the TNamed.
virtual const char * GetTitle() const
Returns title of object.
virtual const char * GetName() const
Returns name of object.
Mother of all ROOT objects.
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
virtual void Delete(Option_t *option="")
Delete this object.
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Regular expression class.
Ssiz_t Index(const TString &str, Ssiz_t *len, Ssiz_t start=0) const
Find the first occurrence of the regexp in string and return the position, or -1 if there is no match...
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
std::string GetName(const std::string &scope_name)
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
static constexpr double degree
void variables(TString dataset, TString fin="TMVA.root", TString dirName="InputVariables_Id", TString title="TMVA Input Variables", Bool_t isRegression=kFALSE, Bool_t useTMVAStyle=kTRUE)
constexpr Double_t G()
Gravitational constant in: .
constexpr Double_t C()
Velocity of light in .
Short_t Max(Short_t a, Short_t b)
Double_t QuietNaN()
Returns a quiet NaN as defined by IEEE 754
Double_t Floor(Double_t x)
constexpr Double_t K()
Boltzmann's constant in .
constexpr Double_t Sqrt2()
constexpr Double_t E()
Base of natural log:
constexpr Double_t Sigma()
Stefan-Boltzmann constant in .
constexpr Double_t H()
Planck's constant in .
constexpr Double_t LogE()
Base-10 log of e (to convert ln to log)
constexpr Double_t Ln10()
Natural log of 10 (to convert log to ln)
constexpr Double_t EulerGamma()
Euler-Mascheroni Constant.
constexpr Double_t R()
Universal gas constant ( ) in
Double_t Log10(Double_t x)
Double_t Infinity()
Returns an infinity as defined by the IEEE standard.
void(* Generic_t)(void *, int, void **, void *)