12 #if __cplusplus >= 201103L 13 #define ROOT_CPLUSPLUS11 1 28 #include <unordered_map> 42 #pragma optimize("",off) 144 char ops[] = {
'+',
'^',
'-',
'/',
'*',
'<',
'>',
'|',
'&',
'!',
'=',
'?'};
145 Int_t opsLen =
sizeof(ops)/
sizeof(
char);
146 for(
Int_t i = 0; i < opsLen; ++i)
155 char brackets[] = {
')',
'(',
'{',
'}'};
156 Int_t bracketsLen =
sizeof(brackets)/
sizeof(
char);
157 for(
Int_t i = 0; i < bracketsLen; ++i)
166 return !IsBracket(c) && !IsOperator(c) && c !=
',' && c !=
' ';
172 return name ==
"x" || name ==
"z" || name ==
"y" || name ==
"t";
179 if ( (formula[i] ==
'e' || formula[i] ==
'E') && (i > 0 && i < formula.Length()-1) ) {
181 if ( (isdigit(formula[i-1]) || formula[i-1] ==
'.') && ( isdigit(formula[i+1]) || formula[i+1] ==
'+' || formula[i+1] ==
'-' ) )
191 if ( (formula[i] ==
'x' || formula[i] ==
'X') && (i > 0 && i < formula.Length()-1) && formula[i-1] ==
'0') {
192 if (isdigit(formula[i+1]) )
194 static char hex_values[12] = {
'a',
'A',
'b',
'B',
'c',
'C',
'd',
'D',
'e',
'E',
'f',
'F'};
195 for (
int jjj = 0; jjj < 12; ++jjj) {
196 if (formula[i+1] == hex_values[jjj])
213 Bool_t foundOpenParenthesis =
false;
214 if (pos == 0 || pos == formula.Length()-1)
return false;
215 for (
int i = pos-1; i >=0; i--) {
216 if (formula[i] ==
']' )
return false;
217 if (formula[i] ==
'[' ) {
218 foundOpenParenthesis =
true;
222 if (!foundOpenParenthesis )
return false;
225 for (
int i = pos+1; i < formula.Length(); i++) {
226 if (formula[i] ==
']' )
return true;
238 if ( a[0] ==
'p' && a.Length() > 1) {
239 if ( b[0] ==
'p' && b.Length() > 1) {
241 TString lhs =
a(1,a.Length()-1);
242 TString rhs =
b(1,b.Length()-1);
243 if (lhs.IsDigit() && rhs.IsDigit() )
244 return (lhs.Atoi() < rhs.Atoi() );
251 if ( b[0] ==
'p' && b.Length() > 1)
256 if (a.IsDigit() && b.IsDigit() )
257 return (a.Atoi() < b.Atoi() );
270 fReadyToExecute =
false;
271 fClingInitialized =
false;
272 fAllParametersSetted =
false;
279 fLambdaPtr =
nullptr;
284 if (strlen(name)!=1)
return false;
285 for (
auto const & specialName : {
"x",
"y",
"z",
"t"}){
286 if (strcmp(name,specialName)==0)
return true;
299 gROOT->GetListOfFunctions()->Remove(
this);
306 int nLinParts = fLinearParts.size();
308 for (
int i = 0; i < nLinParts; ++i)
delete fLinearParts[i];
315 fClingInput(formula),fFormula(formula)
329 if (addToGlobList &&
gROOT) {
332 old =
dynamic_cast<TFormula*
> (
gROOT->GetListOfFunctions()->FindObject(name) );
334 gROOT->GetListOfFunctions()->Remove(old);
336 Error(
"TFormula",
"The name %s is reserved as a TFormula variable name.\n",name);
338 gROOT->GetListOfFunctions()->Add(
this);
370 for (
int i = 0; i < npar; ++i) {
374 assert (
fNpar == npar);
384 if (addToGlobList &&
gROOT) {
387 old =
dynamic_cast<TFormula*
> (
gROOT->GetListOfFunctions()->FindObject(name) );
389 gROOT->GetListOfFunctions()->Remove(old);
391 Error(
"TFormula",
"The name %s is reserved as a TFormula variable name.\n",name);
393 gROOT->GetListOfFunctions()->Add(
this);
398 Error(
"TFormula",
"Syntax error in building the lambda expression %s", formula );
430 Error(
"TFormula",
"Syntax error in building the lambda expression %s",
fFormula.Data() );
446 gROOT->GetListOfFunctions()->Remove(old);
449 Error(
"TFormula",
"The name %s is reserved as a TFormula variable name.\n",formula.
GetName());
451 gROOT->GetListOfFunctions()->Add(
this);
471 std::string lambdaExpression = formula;
487 TString lambdaName =
TString::Format(
"lambda__id%zu", hasher(lambdaExpression) );
491 TString lineExpr =
TString::Format(
"std::function<double(double*,double*)> %s = %s ;",lambdaName.Data(), lambdaExpression.c_str() );
512 TString formula = expression;
513 if (formula.IsNull() ) {
515 if (formula.IsNull() ) formula =
GetTitle();
518 if (formula.IsNull() )
return -1;
530 return (ret) ? 0 : 1;
540 return (ret) ? 0 : 1;
568 for (
int i = 0; i < nLinParts; ++i)
delete fnew.
fLinearParts[i];
575 for (
int i = 0; i < nLinParts; ++i) {
579 linearOld->
Copy(*linearNew);
602 Error(
"TFormula",
"Syntax error in building the lambda expression %s",
fFormula.Data() );
647 for (
int i = 0; i < nLinParts; ++i)
delete fLinearParts[i];
667 TString prototypeArguments =
"";
670 prototypeArguments.Append(
"Double_t*");
672 if(hasVariables && hasParameters)
674 prototypeArguments.Append(
",");
678 prototypeArguments.Append(
"Double_t*");
684 Error(
"Eval",
"Can't find %s function prototype with arguments %s",
fClingName.Data(),prototypeArguments.Data());
730 const TString defvars[] = {
"x",
"y",
"z",
"t"};
739 const pair<TString,TString> funShortcuts[] =
740 { {
"sin",
"TMath::Sin" },
741 {
"cos",
"TMath::Cos" }, {
"exp",
"TMath::Exp"}, {
"log",
"TMath::Log"}, {
"log10",
"TMath::Log10"},
742 {
"tan",
"TMath::Tan"}, {
"sinh",
"TMath::SinH"}, {
"cosh",
"TMath::CosH"},
743 {
"tanh",
"TMath::TanH"}, {
"asin",
"TMath::ASin"}, {
"acos",
"TMath::ACos"},
744 {
"atan",
"TMath::ATan"}, {
"atan2",
"TMath::ATan2"}, {
"sqrt",
"TMath::Sqrt"},
745 {
"ceil",
"TMath::Ceil"}, {
"floor",
"TMath::Floor"}, {
"pow",
"TMath::Power"},
746 {
"binomial",
"TMath::Binomial"},{
"abs",
"TMath::Abs"},
747 {
"min",
"TMath::Min"},{
"max",
"TMath::Max"},{
"sign",
"TMath::Sign" },
751 std::vector<TString> defvars2(10);
752 for (
int i = 0; i < 9; ++i)
755 for(
auto var : defvars)
757 int pos =
fVars.size();
770 for(
auto con : defconsts)
772 fConsts[con.first] = con.second;
774 for(
auto fun : funShortcuts)
830 Int_t polPos = formula.Index(
"pol");
834 Bool_t defaultVariable =
false;
836 Int_t openingBracketPos = formula.Index(
'(',polPos);
837 Bool_t defaultCounter = openingBracketPos ==
kNPOS;
838 Bool_t defaultDegree =
true;
839 Int_t degree,counter;
845 sdegree = formula(polPos + 3,openingBracketPos - polPos - 3);
846 if (!sdegree.IsDigit() ) defaultCounter =
true;
848 if (!defaultCounter) {
849 degree = sdegree.Atoi();
850 counter = TString(formula(openingBracketPos+1,formula.Index(
')',polPos) - openingBracketPos)).Atoi();
854 Int_t temp = polPos+3;
855 while(temp < formula.Length() && isdigit(formula[temp]))
857 defaultDegree =
false;
860 degree = TString(formula(polPos+3,temp - polPos - 3)).Atoi();
865 if(polPos - 1 < 0 || !
IsFunctionNameChar(formula[polPos-1]) || formula[polPos-1] ==
':' )
868 defaultVariable =
true;
872 Int_t tmp = polPos - 1;
877 variable = formula(tmp + 1, polPos - (tmp+1));
879 Int_t param = counter + 1;
884 replacement.Append(
TString::Format(
"+[%d]*%s^%d",param,variable.Data(),tmp));
892 replacement.Insert(0,
'(');
893 replacement.Append(
')');
896 if(defaultCounter && !defaultDegree)
898 pattern =
TString::Format(
"%spol%d",(defaultVariable ?
"" : variable.Data()),degree);
900 else if(defaultCounter && defaultDegree)
902 pattern =
TString::Format(
"%spol",(defaultVariable ?
"" : variable.Data()));
906 pattern =
TString::Format(
"%spol%d(%d)",(defaultVariable ?
"" : variable.Data()),degree,counter);
909 if (!formula.Contains(pattern)) {
910 Error(
"HandlePolN",
"Error handling polynomial function - expression is %s - trying to replace %s with %s ", formula.Data(), pattern.Data(), replacement.Data() );
913 if (formula == pattern) {
918 formula.ReplaceAll(pattern,replacement);
919 polPos = formula.Index(
"pol");
942 map< pair<TString,Int_t> ,pair<TString,TString> > functions;
943 functions.insert(make_pair(make_pair(
"gaus",1),make_pair(
"[0]*exp(-0.5*(({V0}-[1])/[2])*(({V0}-[1])/[2]))",
"[0]*exp(-0.5*(({V0}-[1])/[2])*(({V0}-[1])/[2]))/(sqrt(2*pi)*[2])")));
944 functions.insert(make_pair(make_pair(
"landau",1),make_pair(
"[0]*TMath::Landau({V0},[1],[2],false)",
"[0]*TMath::Landau({V0},[1],[2],true)")));
945 functions.insert(make_pair(make_pair(
"expo",1),make_pair(
"exp([0]+[1]*{V0})",
"")));
946 functions.insert(make_pair(make_pair(
"crystalball",1),make_pair(
"[0]*ROOT::Math::crystalball_function({V0},[3],[4],[2],[1])",
"[0]*ROOT::Math::crystalball_pdf({V0},[3],[4],[2],[1])")));
947 functions.insert(make_pair(make_pair(
"breitwigner",1),make_pair(
"[0]*ROOT::Math::breitwigner_pdf({V0},[2],[1])",
"[0]*ROOT::Math::breitwigner_pdf({V0},[2],[4],[1])")));
949 functions.insert(make_pair(make_pair(
"cheb0" ,1),make_pair(
"ROOT::Math::Chebyshev0({V0},[0])",
"")));
950 functions.insert(make_pair(make_pair(
"cheb1" ,1),make_pair(
"ROOT::Math::Chebyshev1({V0},[0],[1])",
"")));
951 functions.insert(make_pair(make_pair(
"cheb2" ,1),make_pair(
"ROOT::Math::Chebyshev2({V0},[0],[1],[2])",
"")));
952 functions.insert(make_pair(make_pair(
"cheb3" ,1),make_pair(
"ROOT::Math::Chebyshev3({V0},[0],[1],[2],[3])",
"")));
953 functions.insert(make_pair(make_pair(
"cheb4" ,1),make_pair(
"ROOT::Math::Chebyshev4({V0},[0],[1],[2],[3],[4])",
"")));
954 functions.insert(make_pair(make_pair(
"cheb5" ,1),make_pair(
"ROOT::Math::Chebyshev5({V0},[0],[1],[2],[3],[4],[5])",
"")));
955 functions.insert(make_pair(make_pair(
"cheb6" ,1),make_pair(
"ROOT::Math::Chebyshev6({V0},[0],[1],[2],[3],[4],[5],[6])",
"")));
956 functions.insert(make_pair(make_pair(
"cheb7" ,1),make_pair(
"ROOT::Math::Chebyshev7({V0},[0],[1],[2],[3],[4],[5],[6],[7])",
"")));
957 functions.insert(make_pair(make_pair(
"cheb8" ,1),make_pair(
"ROOT::Math::Chebyshev8({V0},[0],[1],[2],[3],[4],[5],[6],[7],[8])",
"")));
958 functions.insert(make_pair(make_pair(
"cheb9" ,1),make_pair(
"ROOT::Math::Chebyshev9({V0},[0],[1],[2],[3],[4],[5],[6],[7],[8],[9])",
"")));
959 functions.insert(make_pair(make_pair(
"cheb10",1),make_pair(
"ROOT::Math::Chebyshev10({V0},[0],[1],[2],[3],[4],[5],[6],[7],[8],[9],[10])",
"")));
961 functions.insert(make_pair(make_pair(
"gaus",2),make_pair(
"[0]*exp(-0.5*(({V0}-[1])/[2])^2 - 0.5*(({V1}-[3])/[4])^2)",
"")));
962 functions.insert(make_pair(make_pair(
"landau",2),make_pair(
"[0]*TMath::Landau({V0},[1],[2],false)*TMath::Landau({V1},[3],[4],false)",
"")));
963 functions.insert(make_pair(make_pair(
"expo",2),make_pair(
"exp([0]+[1]*{V0})",
"exp([0]+[1]*{V0}+[2]*{V1})")));
965 functions.insert(make_pair(make_pair(
"bigaus",2),make_pair(
"[0]*ROOT::Math::bigaussian_pdf({V0},{V1},[2],[4],[5],[1],[3])",
"[0]*ROOT::Math::bigaussian_pdf({V0},{V1},[2],[4],[5],[1],[3])")));
967 map<TString,Int_t> functionsNumbers;
968 functionsNumbers[
"gaus"] = 100;
969 functionsNumbers[
"bigaus"] = 102;
970 functionsNumbers[
"landau"] = 400;
971 functionsNumbers[
"expo"] = 200;
972 functionsNumbers[
"crystalball"] = 500;
975 formula.ReplaceAll(
"xygaus",
"gaus[x,y]");
976 formula.ReplaceAll(
"xgaus",
"gaus[x]");
977 formula.ReplaceAll(
"ygaus",
"gaus[y]");
978 formula.ReplaceAll(
"zgaus",
"gaus[z]");
979 formula.ReplaceAll(
"xexpo",
"expo[x]");
980 formula.ReplaceAll(
"yexpo",
"expo[y]");
981 formula.ReplaceAll(
"zexpo",
"expo[z]");
982 formula.ReplaceAll(
"xylandau",
"landau[x,y]");
983 formula.ReplaceAll(
"xyexpo",
"expo[x,y]");
985 const char * defaultVariableNames[] = {
"x",
"y",
"z"};
987 for(map<pair<TString,Int_t>,pair<TString,TString> >::iterator it = functions.begin(); it != functions.end(); ++it)
990 TString funName = it->first.first;
991 Int_t funDim = it->first.second;
992 Int_t funPos = formula.Index(funName);
1001 Int_t lastFunPos = funPos + funName.Length();
1004 Int_t iposBefore = funPos - 1;
1006 if (iposBefore >= 0) {
1007 assert( iposBefore < formula.Length() );
1008 if (isalpha(formula[iposBefore] ) ) {
1010 funPos = formula.Index(funName,lastFunPos);
1015 Bool_t isNormalized =
false;
1016 if (lastFunPos < formula.Length() ) {
1018 isNormalized = (formula[lastFunPos] ==
'n');
1019 if (isNormalized) lastFunPos += 1;
1020 if (lastFunPos < formula.Length() ) {
1021 char c = formula[lastFunPos];
1024 if ( isalnum(c ) || ( !
IsOperator(c ) && c !=
'(' && c !=
')' && c !=
'[' && c !=
']' ) ) {
1026 funPos = formula.Index(funName,lastFunPos);
1038 TString varList =
"";
1039 Bool_t defaultVariables =
false;
1042 Int_t openingBracketPos = funPos + funName.Length() + (isNormalized ? 1 : 0);
1044 if(openingBracketPos > formula.Length() || formula[openingBracketPos] !=
'[')
1047 variables.resize(dim);
1048 for (
Int_t idim = 0; idim < dim; ++idim)
1049 variables[idim] = defaultVariableNames[idim];
1050 defaultVariables =
true;
1055 closingBracketPos = formula.Index(
']',openingBracketPos);
1056 varList = formula(openingBracketPos+1,closingBracketPos - openingBracketPos - 1);
1057 dim = varList.CountChar(
',') + 1;
1058 variables.resize(dim);
1060 TString varName =
"";
1061 for(
Int_t i = 0 ; i < varList.Length(); ++i)
1065 varName.Append(varList[i]);
1067 if(varList[i] ==
',')
1069 variables[Nvar] = varName;
1076 variables[Nvar] = varName;
1083 pair<TString,Int_t> key = make_pair(funName,dim);
1084 if(functions.find(key) == functions.end())
1086 Error(
"PreProcessFormula",
"Dimension of function %s is detected to be of dimension %d and is not compatible with existing pre-defined function which has dim %d",
1087 funName.Data(),dim,funDim);
1091 funPos = formula.Index(funName,lastFunPos);
1096 Int_t openingParenthesisPos = (closingBracketPos ==
kNPOS) ? openingBracketPos : closingBracketPos + 1;
1097 bool defaultCounter = (openingParenthesisPos > formula.Length() || formula[openingParenthesisPos] !=
'(');
1108 counter = TString(formula(openingParenthesisPos+1,formula.Index(
')',funPos) - openingParenthesisPos -1)).Atoi();
1112 TString body = (isNormalized ? it->second.second : it->second.first);
1113 if(isNormalized && body ==
"")
1115 Error(
"PreprocessFormula",
"%d dimension function %s has no normalized form.",it->first.second,funName.Data());
1118 for(
int i = 0 ; i < body.Length() ; ++i)
1124 Int_t num = TString(body(i,body.Index(
'}',i) - i)).Atoi();
1125 TString variable = variables[num];
1128 body.Replace(i, pattern.Length(),variable,variable.Length());
1129 i += variable.Length()-1;
1131 else if(body[i] ==
'[')
1135 while(tmp < body.Length() && body[tmp] !=
']')
1139 Int_t num = TString(body(i+1,tmp - 1 - i)).Atoi();
1143 body.Replace(i+1,tmp - 1 - i,replacement,replacement.Length());
1144 i += replacement.Length() + 1;
1148 if(defaultCounter && defaultVariables)
1152 (isNormalized ?
"n" :
""));
1154 if(!defaultCounter && defaultVariables)
1158 (isNormalized ?
"n" :
""),
1161 if(defaultCounter && !defaultVariables)
1165 (isNormalized ?
"n":
""),
1168 if(!defaultCounter && !defaultVariables)
1172 (isNormalized ?
"n" :
""),
1176 TString replacement = body;
1179 if (
fNumber == 0 && formula.Length() <= (pattern.Length()-funPos) +1 ) {
1180 fNumber = functionsNumbers[funName] + 10*(dim-1);
1185 formula.Replace(funPos,pattern.Length(),replacement,replacement.Length());
1187 funPos = formula.Index(funName);
1201 Int_t caretPos = formula.Last(
'^');
1206 Int_t temp = caretPos;
1209 if(formula[temp] ==
')')
1213 while(depth != 0 && temp > 0)
1215 if(formula[temp] ==
')')
1217 if(formula[temp] ==
'(')
1221 if (depth == 0) temp++;
1231 assert(temp+1 >= 0);
1232 Int_t leftPos = temp+1;
1233 left = formula(leftPos, caretPos - leftPos);
1239 if (temp >= formula.Length() ) {
1240 Error(
"HandleExponentiation",
"Invalid position of operator ^");
1243 if(formula[temp] ==
'(')
1247 while(depth != 0 && temp < formula.Length())
1249 if(formula[temp] ==
')')
1251 if(formula[temp] ==
'(')
1259 if (formula[temp] ==
'-' || formula[temp] ==
'+' ) temp++;
1264 while(temp < formula.Length() && ( (depth > 0) || !
IsOperator(formula[temp]) ) )
1270 if (temp < formula.Length() && formula[temp] ==
'(') depth++;
1271 if (temp < formula.Length() && formula[temp] ==
')') {
1279 right = formula(caretPos + 1, (temp - 1) - caretPos );
1283 TString replacement =
TString::Format(
"pow(%s,%s)",left.Data(),right.Data());
1287 formula.Replace(leftPos,pattern.Length(),replacement,replacement.Length());
1289 caretPos = formula.Last(
'^');
1299 Int_t linPos = formula.Index(
"@");
1300 if (linPos ==
kNPOS )
return;
1301 Int_t nofLinParts = formula.CountChar((
int)
'@');
1302 assert(nofLinParts > 0);
1314 while(temp >= 0 && formula[temp] !=
'@')
1318 left = formula(temp+1,linPos - (temp +1));
1321 while(temp < formula.Length() && formula[temp] !=
'@')
1325 TString right = formula(linPos+1,temp - (linPos+1));
1328 TString replacement = (first) ?
TString::Format(
"([%d]*(%s))+([%d]*(%s))",Nlinear,left.Data(),Nlinear+1,right.Data()) :
TString::Format(
"+([%d]*(%s))",Nlinear,right.Data());
1329 Nlinear += (first) ? 2 : 1;
1331 formula.ReplaceAll(pattern,replacement);
1339 linPos = formula.Index(
"@");
1353 formula.ReplaceAll(
"**",
"^");
1354 formula.ReplaceAll(
"++",
"@");
1355 formula.ReplaceAll(
" ",
"");
1363 formula.ReplaceAll(
"--",
"- -");
1364 formula.ReplaceAll(
"++",
"+ +");
1415 for(
Int_t i = 0 ; i < formula.Length(); ++i )
1420 if(formula[i] ==
'[')
1425 while(formula[i] !=
']' && i < formula.Length())
1427 param.Append(formula[i++]);
1432 int paramIndex = -1;
1433 if (param.IsDigit()) {
1434 paramIndex = param.Atoi();
1435 param.Insert(0,
'p');
1438 for (
int idx = 0; idx <= paramIndex; ++idx) {
1446 param.ReplaceAll(
"\\s",
" ");
1450 formula.Replace(tmp,i - tmp, replacement,replacement.Length());
1456 if (formula[i] ==
'\"') {
1460 }
while(formula[i] !=
'\"');
1469 while ( !
IsOperator(formula[i]) && i < formula.Length() ) {
1478 if(isalpha(formula[i]) && !
IsOperator(formula[i]))
1485 if (formula[i] ==
':' && ( (i+1) < formula.Length() ) ) {
1486 if ( formula[i+1] ==
':' ) {
1496 name.Append(formula[i++]);
1499 if(formula[i] ==
'(')
1502 if(formula[i] ==
')')
1510 while(depth != 0 && i < formula.Length())
1514 case '(': depth++;
break;
1515 case ')': depth--;
break;
1516 case ',':
if(depth == 1) args++;
break;
1520 body.Append(formula[i++]);
1523 Int_t originalBodyLen = body.Length();
1525 formula.Replace(i-originalBodyLen,originalBodyLen,body,body.Length());
1526 i += body.Length() - originalBodyLen;
1538 obj =
gROOT->GetListOfFunctions()->FindObject(name);
1543 TF1 *
f1 =
dynamic_cast<TF1*
> (obj);
1558 std::vector<TString> newNames;
1561 newNames.resize(f->
GetNpar() );
1563 for (
int jpar = f->
GetNpar()-1; jpar >= 0; --jpar ) {
1566 if ( pj[0] ==
'p' && TString(pj(1,pj.Length())).IsDigit() ) {
1570 replacementFormula.ReplaceAll(oldName,newName);
1571 newNames[jpar] = newName;
1582 for (
int jpar = 0; jpar < f->
GetNpar(); ++jpar) {
1583 if (nparOffset> 0) {
1585 assert((
int) newNames.size() == f->
GetNpar() );
1593 replacementFormula.Insert(0,
'(');
1594 replacementFormula.Insert(replacementFormula.Length(),
')');
1595 formula.Replace(i-name.Length(),name.Length(), replacementFormula, replacementFormula.Length());
1597 i += replacementFormula.Length()-name.Length();
1608 formula.Replace(i-name.Length(),name.Length(),replacement,replacement.Length());
1641 for(list<TFormulaFunction>::iterator funcsIt =
fFuncs.begin(); funcsIt !=
fFuncs.end(); ++funcsIt)
1654 TString shortcut = it->first;
1655 TString full = it->second;
1658 Ssiz_t index = formula.Index(shortcut,0);
1659 while ( index !=
kNPOS) {
1662 Ssiz_t i2 = index + shortcut.Length();
1663 if ( (index > 0) && (isalpha( formula[index-1] ) || formula[index-1] ==
':' )) {
1664 index = formula.Index(shortcut,i2);
1667 if (i2 < formula.Length() && formula[i2] !=
'(') {
1668 index = formula.Index(shortcut,i2);
1672 formula.Replace(index, shortcut.Length(), full);
1673 Ssiz_t inext = index + full.Length();
1674 index = formula.Index(shortcut,inext);
1678 if(fun.
fName.Contains(
"::"))
1682 size_t index = name.rfind(
"::");
1683 assert(index != std::string::npos);
1684 TString className = fun.
fName(0,fun.
fName(0,index).Length());
1685 TString functionName = fun.
fName(index + 2, fun.
fName.Length());
1691 TIter next(methodList);
1693 while ((p = (
TMethod*) next()))
1695 if (strcmp(p->
GetName(),functionName.Data()) == 0 &&
1722 Info(
"TFormula",
"Could not find %s function with %d argument(s)",fun.
GetName(),fun.
GetNargs());
1742 formula.ReplaceAll(pattern,replacement);
1747 map<TString,TFormulaVariable>::iterator varsIt =
fVars.find(fun.
GetName());
1748 if(varsIt!=
fVars.end())
1751 TString
name = (*varsIt).second.GetName();
1752 Double_t value = (*varsIt).second.fValue;
1756 if(!
fVars[name].fFound)
1761 int varDim = (*varsIt).second.fArrayPos;
1762 if (varDim >=
fNdim) {
1767 if (
v.second.fArrayPos < varDim && !
v.second.fFound ) {
1769 v.second.fFound =
true;
1776 TString replacement =
TString::Format(
"x[%d]",(*varsIt).second.fArrayPos);
1777 formula.ReplaceAll(pattern,replacement);
1787 TString funname = fun.
GetName();
1788 if (funname.Contains(
"x[") && funname.Contains(
"]") ) {
1789 TString sdigit = funname(2,funname.Index(
"]") );
1790 int digit = sdigit.Atoi();
1791 if (digit >=
fNdim) {
1794 for (
int j = 0; j <
fNdim; ++j) {
1798 fVars[vname].fFound =
true;
1807 formula.ReplaceAll(pattern,funname);
1818 if(formula.Index(pattern) !=
kNPOS)
1823 formula.ReplaceAll(pattern,replacement);
1834 map<TString,Double_t>::iterator constIt =
fConsts.find(fun.
GetName());
1839 formula.ReplaceAll(pattern,value);
1862 if (hasParameters && ! hasVariables) {
1865 hasVariables =
true;
1867 Bool_t hasBoth = hasVariables && hasParameters;
1868 Bool_t inputIntoCling = (formula.Length() > 0);
1869 if (inputIntoCling) {
1873 std::string inputFormula = std::string(formula);
1877 TString argumentsPrototype =
1878 TString::Format(
"%s%s%s",(hasVariables ?
"Double_t *x" :
""), (hasBoth ?
"," :
""),
1879 (hasParameters ?
"Double_t *p" :
""));
1893 inputIntoCling =
false;
1912 if(inputIntoCling) {
1933 Bool_t allFunctorsMatched =
true;
1934 for(list<TFormulaFunction>::iterator it =
fFuncs.begin(); it !=
fFuncs.end(); it++)
1938 allFunctorsMatched =
false;
1939 if (it->GetNargs() == 0)
1940 Error(
"ProcessFormula",
"\"%s\" has not been matched in the formula expression",it->GetName() );
1942 Error(
"ProcessFormula",
"Could not find %s function with %d argument(s)",it->GetName(),it->GetNargs());
1945 if (!allFunctorsMatched) {
1953 auto itvar =
fVars.begin();
1956 if ( ! itvar->second.fFound ) {
1958 itvar =
fVars.erase(itvar);
1963 while( itvar !=
fVars.end() );
2047 if (i < 0 || i >= n ) {
2048 Error(
"GetLinearPart",
"Formula %s has only %d linear parts - requested %d",
GetName(),n,i);
2100 Bool_t anyNewVar =
false;
2101 for(
Int_t i = 0 ; i < size; ++i)
2104 const TString & vname = vars[i];
2116 Int_t multiplier = 2;
2131 if(anyNewVar && !
fFormula.IsNull())
2145 Error(
"SetName",
"The name \'%s\' is reserved as a TFormula variable name.\n" 2146 "\tThis function will not be renamed.",name);
2150 auto listOfFunctions =
gROOT->GetListOfFunctions();
2151 TObject* thisAsFunctionInList =
nullptr;
2153 if (listOfFunctions){
2154 thisAsFunctionInList = listOfFunctions->
FindObject(
this);
2155 if (thisAsFunctionInList) listOfFunctions->Remove(thisAsFunctionInList);
2158 if (thisAsFunctionInList) listOfFunctions->Add(thisAsFunctionInList);
2172 for(
Int_t i = 0; i < size; ++i)
2174 pair<TString,Double_t>
v = vars[i];
2177 fVars[v.first].fValue = v.second;
2182 Error(
"SetVariables",
"Variable %s is not defined.",v.first.Data());
2192 TString
sname(name);
2195 Error(
"GetVariable",
"Variable %s is not defined.",sname.Data());
2198 return fVars.find(sname)->second.fValue;
2206 TString
sname(name);
2209 Error(
"GetVarNumber",
"Variable %s is not defined.",sname.Data());
2212 return fVars.find(sname)->second.fArrayPos;
2220 if (ivar < 0 || ivar >=
fNdim)
return "";
2223 for (
auto &
v :
fVars) {
2224 if (
v.second.fArrayPos == ivar)
return v.first;
2226 Error(
"GetVarName",
"Variable with index %d not found !!",ivar);
2238 Error(
"SetVariable",
"Variable %s is not defined.",name.Data());
2281 auto ret =
fParams.insert(std::make_pair(name,pos));
2287 if (ret.first ==
fParams.begin() )
2290 auto previous = (ret.first);
2292 pos = previous->second + 1;
2301 Warning(
"inserting parameter %s at pos %d when vector size is %d \n",name.Data(),pos,(int)
fClingParameters.size() );
2310 for (
auto it = ret.first; it !=
fParams.end(); ++it ) {
2318 if (processFormula) {
2348 Error(
"GetParameter",
"Parameter %s is not defined.",name);
2363 Error(
"GetParameter",
"wrong index used - use GetParameter(name)");
2372 if (ipar < 0 || ipar >=
fNpar)
return "";
2376 if (p.second == ipar)
return p.first.Data();
2378 Error(
"GetParName",
"Parameter with index %d not found !!",ipar);
2413 Error(
"SetParameter",
"Parameter %s is not defined.",name.Data());
2420 for(map<TString,TFormulaVariable>::iterator it = fParams.begin(); it != fParams.end(); it++)
2422 if(!it->second.fFound)
2442 for(
Int_t i = 0 ; i < size ; ++i)
2444 pair<TString,Double_t> p = params[i];
2447 Error(
"SetParameters",
"Parameter %s is not defined",p.first.Data());
2450 fParams[p.first].fValue = p.second;
2451 fParams[p.first].fFound =
true;
2455 for(map<TString,TFormulaVariable>::iterator it =
fParams.begin(); it !=
fParams.end(); it++)
2457 if(!it->second.fFound)
2469 if(!params || size < 0 || size >
fNpar)
return;
2472 Warning(
"SetParameters",
"size is not same of cling parameter size %d - %d",size,
int(
fClingParameters.size()) );
2473 for(
Int_t i = 0; i < size; ++i)
2523 if (param < 0 || param >=
fNpar)
return;
2532 const char *name4,
const char *name5,
const char *name6,
const char *name7,
2533 const char *name8,
const char *name9,
const char *name10)
2552 if (ipar < 0 || ipar >
fNpar) {
2553 Error(
"SetParName",
"Wrong Parameter index %d ",ipar);
2559 if (it.second == ipar) {
2561 fParams.erase(oldName);
2562 fParams.insert(std::make_pair(name, ipar) );
2566 if (oldName.IsNull() ) {
2567 Error(
"SetParName",
"Parameter %d is not existing.",ipar);
2580 if (!formula.IsNull() ) {
2582 for(list<TFormulaFunction>::iterator it =
fFuncs.begin(); it !=
fFuncs.end(); ++it)
2584 if(oldName == it->GetName())
2593 Error(
"SetParName",
"Parameter %s is not defined.",oldName.Data());
2597 TString newName =
name;
2598 newName.ReplaceAll(
" ",
"\\s");
2601 formula.ReplaceAll(pattern,replacement);
2609 return DoEval(x, params);
2617 double xxx[4] = {
x,
y,
z,t};
2626 double xxx[3] = {
x,
y,z};
2635 double xxx[2] = {
x,y};
2659 Error(
"Eval",
"Formula is invalid and not ready to execute ");
2660 for(
auto it =
fFuncs.begin(); it !=
fFuncs.end(); ++it)
2665 printf(
"%s is unknown.\n",fun.
GetName());
2671 std::function<double(double *, double *)> & fptr = * ( (std::function<double(double *, double *)> *)
fLambdaPtr);
2674 double *
v =
const_cast<double*
>(
x);
2675 double * p = (params) ? const_cast<double*>(params) :
const_cast<double*
>(
fClingParameters.data());
2680 Error(
"Eval",
"Formula is invalid or not properly initialized - try calling TFormula::Compile");
2682 #ifdef EVAL_IS_NOT_CONST 2693 double * vars = (
x) ? const_cast<double*>(x) :
const_cast<double*
>(
fClingVariables.data());
2696 (*fFuncPtr)(0, 1, args, &
result);
2698 double * pars = (params) ? const_cast<double*>(params) :
const_cast<double*
>(
fClingParameters.data());
2700 (*fFuncPtr)(0, 2, args, &
result);
2714 TString opt(option);
2723 if (opt.Contains(
"CLING") ) {
2725 std::size_t found = clingFunc.find(
"return");
2726 std::size_t found2 = clingFunc.rfind(
";");
2727 if (found == std::string::npos || found2 == std::string::npos) {
2728 Error(
"GetExpFormula",
"Invalid Cling expression - return default formula expression");
2731 TString clingFormula =
fClingInput(found+7,found2-found-7);
2733 if (!opt.Contains(
"P"))
return clingFormula;
2736 while (i < clingFormula.Length()-2 ) {
2738 if (clingFormula[i] ==
'p' && clingFormula[i+1] ==
'[' && isdigit(clingFormula[i+2]) ) {
2740 while ( isdigit(clingFormula[j]) ) { j++;}
2741 if (clingFormula[j] !=
']') {
2742 Error(
"GetExpFormula",
"Parameters not found - invalid expression - return default cling formula");
2743 return clingFormula;
2745 TString parNumbName = clingFormula(i+2,j-i-2);
2746 int parNumber = parNumbName.Atoi();
2747 assert(parNumber <
fNpar);
2749 clingFormula.Replace(i,j-i+1, replacement );
2750 i += replacement.Length();
2754 return clingFormula;
2756 if (opt.Contains(
"P") ) {
2760 while (i < expFormula.Length()-2 ) {
2762 if (expFormula[i] ==
'[') {
2764 while ( expFormula[j] !=
']' ) { j++;}
2765 if (expFormula[j] !=
']') {
2766 Error(
"GetExpFormula",
"Parameter names not found - invalid expression - return default formula");
2769 TString parName = expFormula(i+1,j-i-1);
2771 expFormula.Replace(i,j-i+1, replacement );
2772 i += replacement.Length();
2778 Warning(
"GetExpFormula",
"Invalid option - return defult formula expression");
2788 printf(
" Formula expression: \n");
2789 printf(
"\t%s \n",
fFormula.Data() );
2790 TString opt(option);
2795 if (opt.Contains(
"V") ) {
2797 printf(
"List of Variables: \n");
2799 for (
int ivar = 0; ivar <
fNdim ; ++ivar) {
2804 printf(
"List of Parameters: \n");
2809 for (
int ipar = 0; ipar <
fNpar ; ++ipar) {
2813 printf(
"Expression passed to Cling:\n");
2818 Warning(
"Print",
"Formula is not ready to execute. Missing parameters/variables");
2819 for(list<TFormulaFunction>::const_iterator it =
fFuncs.begin(); it !=
fFuncs.end(); ++it)
2824 printf(
"%s is unknown.\n",fun.
GetName());
2849 void TFormula::Streamer(
TBuffer &
b)
2855 if (v <= 8 && v > 3 && v != 6) {
2868 Error(
"Streamer",
"Old formula read from file is NOT valid");
2914 if (
fNpar != (
int) parValues.size() ) {
2915 Error(
"Streamer",
"number of parameters computed (%d) is not same as the stored parameters (%d)",
fNpar,
int(parValues.size()) );
2927 assert(
fNpar == (
int) parValues.size() );
2930 if (
fParams.size() != paramMap.size() ) {
2931 Warning(
"Streamer",
"number of parameters list found (%zu) is not same as the stored one (%zu) - use re-created list",
fParams.size(),paramMap.size()) ;
2949 gROOT->GetListOfFunctions()->Add(
this);
2952 Error(
"Streamer",
"Formula read from file is NOT ready to execute");
2960 Error(
"Streamer",
"Reading version %d is not supported",v);
virtual const char * GetName() const
Returns name of object.
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Double_t Floor(Double_t x)
virtual TFormula * GetFormula()
static double p3(double t, double a, double b, double c, double d)
virtual CallFuncIFacePtr_t CallFunc_IFacePtr(CallFunc_t *) const
constexpr Double_t Sqrt2()
CallFunc_t * GetCallFunc() const
Bool_t TestBit(UInt_t f) const
virtual void SetName(const char *name)
Set the name of the TNamed.
Buffer base class used for serializing objects.
R__EXTERN TVirtualMutex * gROOTMutex
const TList * GetListOfAllPublicMethods(Bool_t load=kTRUE)
Returns a list of all public methods of this class and its base classes.
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
constexpr Double_t Ln10()
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
The TNamed class is the base class for all named ROOT classes.
Double_t Log10(Double_t x)
virtual Bool_t Declare(const char *code)=0
static double p2(double t, double a, double b, double c)
void(* Generic_t)(void *, int, void **, void *)
std::vector< std::vector< double > > Data
Method or function calling interface.
virtual void Delete(Option_t *option="")
Delete this object.
Int_t GetNargs() const
Number of function arguments.
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
The ROOT global object gROOT contains a list of all defined classes.
static double p1(double t, double a, double b)
Bool_t IsValid() const
Return true if the method call has been properly initialized and is usable.
void InitWithPrototype(TClass *cl, const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch)
Initialize the method invocation environment.
#define R__LOCKGUARD2(mutex)
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
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.
Mother of all ROOT objects.
constexpr Double_t EulerGamma()
you should not use this method at all Int_t Int_t z
Global functions class (global functions are obtained from CINT).
virtual void Copy(TObject &named) const
Copy this to obj.
Short_t Max(Short_t a, Short_t b)
Each ROOT class (see TClass) has a linked list of methods.
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
constexpr Double_t LogE()
constexpr Double_t Sigma()
R__EXTERN TInterpreter * gCling
Int_t GetNargsOpt() const
Number of function optional (default) arguments.
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)
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
virtual const char * GetTitle() const
Returns title of object.