31#pragma optimize("",off)
187 if (!expression || !*expression) {
188 Error(
"TFormula",
"expression may not be 0 or have 0 length");
194 nch = expression ? strlen(expression) : 0;
195 char *expr =
new char[nch+1];
197 for (i=0;i<nch;i++) {
198 if (expression[i] ==
' ')
continue;
199 if (i > 0 && (expression[i] ==
'*') && (expression[i-1] ==
'*')) {
203 expr[j] = expression[i]; j++;
219 tmp.ReplaceAll(
"gausn",
"");
220 tmp.ReplaceAll(
"landaun",
"");
221 if ( tmp.Contains(
"gaus") )
222 Warning(
"TFormula",
"Cannot use both gaus and gausn - gaus will be treated as gausn");
223 if ( tmp.Contains(
"landau") )
224 Warning(
"TFormula",
"Cannot use both gausn and landau - landau will be treated as landaun");
230 tmp.ReplaceAll(
"landaun",
"");
231 tmp.ReplaceAll(
"gausn",
"");
232 if ( tmp.Contains(
"gaus") ) {
233 Warning(
"TFormula",
"Cannot use both gaus and landaun - gaus will be treated as gausn");
235 if ( tmp.Contains(
"landau") )
236 Warning(
"TFormula",
"Cannot use both landau and landaun - landau will be treated as landaun");
258 if (strcmp(
name,
"x")==0 || strcmp(
name,
"y")==0 ||
259 strcmp(
name,
"z")==0 || strcmp(
name,
"t")==0 )
261 Error(
"TFormula",
"The name \'%s\' is reserved as a TFormula variable name.\n"
262 "\tThis function will not be registered in the list of functions",
name);
267 gROOT->GetListOfFunctions()->Remove(old);
269 gROOT->GetListOfFunctions()->Add(
this);
297 formula.TFormula::Copy(*
this);
306 rhs.TFormula::Copy(*
this);
317 gROOT->GetListOfFunctions()->Remove(
this);
354 if (argStart<0)
return false;
356 TString functionName = chaine(0,argStart);
362 if (scopeEnd>0 && functionName[scopeEnd-1]==
':') {
363 spaceName = functionName(0,scopeEnd-1);
364 functionName.
Remove(0,scopeEnd+1);
369 if (chaine[chaine.
Length()-1] !=
')') {
370 Error(
"AnalyzeFunction",
"We thought we had a function but we dont (in %s)\n",chaine.
Data());
373 TString args = chaine(argStart+1,chaine.
Length()-2-argStart);
383 for(i=0; i<args.
Length(); i++) {
384 if (args[i]==
'"') inString = !inString;
385 if (inString)
continue;
390 case '(': paran++;
break;
391 case ')': paran--;
break;
392 case '[': brack++;
break;
393 case ']': brack--;
break;
395 case ',':
if (paran==0 && brack==0) { foundArg =
true; }
break;
397 if ((i+1)==args.
Length()) {
398 foundArg =
true; i++;
401 TString arg = args(prevComma,i-prevComma);
422 ClassInfo_t *cinfo =
nullptr;
431 static TypeInfo_t *
const doubletype {
gInterpreter->TypeInfo_Factory(
"double") };
433 std::vector<TypeInfo_t*>
proto(nargs,doubletype);
435 CallFunc_t *callfunc =
gInterpreter->CallFunc_Factory();
482 if (prim && (!
IsA()->GetBaseClass(
"TTreeFormula"))) {
491 Error(
"Compile",
"%s requires %d arguments",
496 if (prim->
fType==10){
499 if (prim->
fType==110){
502 if (prim->
fType==1110){
505 if (prim->
fType==-1){
716 Int_t valeur,find,
n,i,j,k,lchain,nomb,virgule,inter,nest;
717 valeur=find=
n=i=j=k=lchain=nomb=virgule=inter=nest = 0;
718 Int_t compt,compt2,compt3,compt4;
723 TString s,chaine_error,chaine1ST;
728 Int_t modulo,plus,puiss10,puiss10bis,moins,multi,divi,puiss,et,ou,petit,grand,egal,diff,peteg,grdeg,etx,oux,rshift,lshift,tercond,terelse;
733 Int_t actionCode,actionParam;
741 while (parenthese && lchain>0 && err==0){
746 if (lchain==0) err=4;
748 for (i=1; i<=lchain; ++i) {
749 if (chaine(i-1,1) ==
"\"") inString = !inString;
751 if (chaine(i-1,1) ==
"[") compt2++;
752 if (chaine(i-1,1) ==
"]") compt2--;
753 if (chaine(i-1,1) ==
"(") compt++;
754 if (chaine(i-1,1) ==
")") compt--;
756 if (compt < 0) err = 40;
757 if (compt2< 0) err = 42;
758 if (compt==0 && (i!=lchain || lchain==1)) parenthese =
kFALSE;
761 if (compt > 0) err = 41;
762 if (compt2> 0) err = 43;
763 if (parenthese) chaine = chaine(1,lchain-2);
767 if (lchain==0) err=4;
768 modulo=plus=moins=multi=divi=puiss=et=ou=petit=grand=egal=diff=peteg=grdeg=etx=oux=rshift=lshift=tercond=terelse=0;
773 compt = compt2 = compt3 = compt4 = 0;puiss10=0;puiss10bis = 0;
778 for (i=1;i<=lchain; i++) {
780 puiss10=puiss10bis=0;
783 isdecimal = isdecimal && (strchr(
"0123456789.",t)!=
nullptr);
785 if ( chaine[i-2] ==
'e' || chaine[i-2] ==
'E' ) puiss10 = 1;
786 }
else if ( strchr(
"+-/[]()&|><=!*/%^\\",t) ) {
791 if (chaine[j-2] ==
'e' || chaine[j-2] ==
'E') {
792 Bool_t isrightdecimal =
true;
794 for(k=j-3; k>=0 && isrightdecimal; --k) {
796 isrightdecimal = isrightdecimal && (strchr(
"0123456789.",t)!=
nullptr);
797 if (!isrightdecimal) {
798 if (strchr(
"+-/[]()&|><=!*/%^\\",t)!=
nullptr) {
803 if (k<0 && isrightdecimal) puiss10bis = 1;
806 if (puiss10 && (i<=lchain)) {
808 puiss10 = (strchr(
"0123456789.",t)!=
nullptr);
810 if (puiss10bis && (j<=lchain)) {
812 puiss10bis = (strchr(
"0123456789.",t)!=
nullptr);
815 if (chaine(i-1,1) ==
"\"") inString = !inString;
816 if (inString)
continue;
817 if (chaine(i-1,1) ==
"[") compt2++;
818 if (chaine(i-1,1) ==
"]") compt2--;
819 if (chaine(i-1,1) ==
"(") compt++;
820 if (chaine(i-1,1) ==
")") compt--;
821 if (chaine(j-1,1) ==
"[") compt3++;
822 if (chaine(j-1,1) ==
"]") compt3--;
823 if (chaine(j-1,1) ==
"(") compt4++;
824 if (chaine(j-1,1) ==
")") compt4--;
825 if (chaine(i-1,2)==
"&&" && !inString && compt==0 && compt2==0 && et==0) {et=i;puiss=0;}
826 if (chaine(i-1,2)==
"||" && compt==0 && compt2==0 && ou==0) {puiss10=0; ou=i;}
827 if (chaine(i-1,1)==
"&" && compt==0 && compt2==0 && etx==0) {etx=i;puiss=0;}
828 if (chaine(i-1,1)==
"|" && compt==0 && compt2==0 && oux==0) {puiss10=0; oux=i;}
829 if (chaine(i-1,2)==
">>" && compt==0 && compt2==0 && rshift==0) {puiss10=0; rshift=i;}
830 if (chaine(i-1,1)==
">" && compt==0 && compt2==0 && rshift==0 && grand==0)
831 {puiss10=0; grand=i;}
832 if (chaine(i-1,2)==
"<<" && compt==0 && compt2==0 && lshift==0) {puiss10=0; lshift=i;}
833 if (chaine(i-1,1)==
"<" && compt==0 && compt2==0 && lshift==0 && petit==0)
837 for(
int ip = i,depth=0; ip < lchain; ++ip) {
841 if (isalnum(
c) ||
c==
'_' ||
c==
',')
continue;
842 if (
c==
':' && chaine(ip+1)==
':') { ++ip;
continue; }
843 if (
c==
'<') { ++depth;
continue; }
845 if (depth) { --depth;
continue; }
861 if ((chaine(i-1,2)==
"<=" || chaine(i-1,2)==
"=<") && compt==0 && compt2==0
862 && peteg==0) {peteg=i; puiss10=0; petit=0;}
863 if ((chaine(i-1,2)==
"=>" || chaine(i-1,2)==
">=") && compt==0 && compt2==0
864 && grdeg==0) {puiss10=0; grdeg=i; grand=0;}
865 if (chaine(i-1,2) ==
"==" && compt == 0 && compt2 == 0 && egal == 0) {puiss10=0; egal=i;}
866 if (chaine(i-1,2) ==
"!=" && compt == 0 && compt2 == 0 && diff == 0) {puiss10=0; diff=i;}
867 if (i>1 && chaine(i-1,1) ==
"+" && compt == 0 && compt2 == 0 && puiss10==0) plus=i;
868 if (chaine(j-1,1) ==
"-" && chaine(j-2,1) !=
"*" && chaine(j-2,1) !=
"/"
869 && chaine(j-2,1)!=
"^" && compt3==0 && compt4==0 && moins==0 && puiss10bis==0) moins=j;
870 if (chaine(i-1,1)==
"%" && compt==0 && compt2==0 && modulo==0) {puiss10=0; modulo=i;}
871 if (chaine(i-1,1)==
"*" && compt==0 && compt2==0 && multi==0) {puiss10=0; multi=i;}
872 if (chaine(j-1,1)==
"/" && chaine(j-2,1)!=
"\\"
873 && compt4==0 && compt3==0 && divi==0)
877 if (chaine(j-1)==
'^' && compt4==0 && compt3==0 && puiss==0) {puiss10=0; puiss=j;}
878 if (chaine(i-1)==
'?' && compt == 0 && compt2 == 0 && tercond == 0) {puiss10=0; tercond=i;}
879 if (chaine(i-1)==
':' && tercond && compt == 0 && compt2 == 0 && terelse == 0) {
880 if (i>2 && chaine(i-2)!=
':' && chaine(i)!=
':') {
881 puiss10=0; terelse=i;
891 if (tercond && terelse) {
892 if (tercond == 1 || terelse == lchain || tercond == (terelse-1) ) {
897 ctemp = chaine(0,tercond-1);
907 ctemp = chaine(tercond,terelse-tercond-1);
910 SetAction(optloc, actionCode, actionParam);
920 ctemp = chaine(terelse,lchain-terelse);
924 SetAction(optloc, actionCode, actionParam);
931 }
else if (ou != 0) {
932 if (ou==1 || ou==lchain-1) {
937 ctemp = chaine(0,ou-1);
946 ctemp = chaine(ou+1,lchain-ou-1);
957 if (et==1 || et==lchain-1) {
962 ctemp = chaine(0,et-1);
972 ctemp = chaine(et+1,lchain-et-1);
983 if (oux==1 || oux==lchain) {
988 ctemp = chaine(0,oux-1);
991 ctemp = chaine(oux,lchain-oux);
1000 if (etx==1 || etx==lchain) {
1005 ctemp = chaine(0,etx-1);
1008 ctemp = chaine(etx,lchain-etx);
1016 }
else if (petit != 0) {
1017 if (petit==1 || petit==lchain) {
1022 ctemp = chaine(0,petit-1);
1025 ctemp = chaine(petit,lchain-petit);
1033 }
else if (grand != 0) {
1034 if (grand==1 || grand==lchain) {
1039 ctemp = chaine(0,grand-1);
1042 ctemp = chaine(grand,lchain-grand);
1050 }
else if (peteg != 0) {
1051 if (peteg==1 || peteg==lchain-1) {
1056 ctemp = chaine(0,peteg-1);
1058 ctemp = chaine(peteg+1,lchain-peteg-1);
1067 }
else if (grdeg != 0) {
1068 if (grdeg==1 || grdeg==lchain-1) {
1073 ctemp = chaine(0,grdeg-1);
1076 ctemp = chaine(grdeg+1,lchain-grdeg-1);
1084 }
else if (egal != 0) {
1085 if (egal==1 || egal==lchain-1) {
1090 ctemp = chaine(0,egal-1);
1094 ctemp = chaine(egal+1,lchain-egal-1);
1100 if (
IsString(optloc) != isstring) {
1102 chaine_error =
"==";
1103 }
else if (isstring) {
1109 }
else if (diff != 0) {
1110 if (diff==1 || diff==lchain-1) {
1112 chaine_error =
"!=";
1115 ctemp = chaine(0,diff-1);
1119 ctemp = chaine(diff+1,lchain-diff-1);
1125 if (
IsString(optloc) != isstring) {
1127 chaine_error =
"!=";
1128 }
else if (isstring) {
1134 }
else if (plus != 0) {
1140 ctemp = chaine(0,plus-1);
1143 ctemp = chaine(plus,lchain-plus);
1154 ctemp = chaine(moins,lchain-moins);
1162 if (moins == lchain) {
1166 ctemp = chaine(0,moins-1);
1169 ctemp = chaine(moins,lchain-moins);
1178 }
else if (modulo != 0) {
1179 if (modulo == 1 || modulo == lchain) {
1183 ctemp = chaine(0,modulo-1);
1186 ctemp = chaine(modulo,lchain-modulo);
1194 }
else if (rshift != 0) {
1195 if (rshift == 1 || rshift == lchain) {
1199 ctemp = chaine(0,rshift-1);
1202 ctemp = chaine(rshift+1,lchain-rshift-1);
1210 }
else if (lshift != 0) {
1211 if (lshift == 1 || lshift == lchain) {
1215 ctemp = chaine(0,lshift-1);
1218 ctemp = chaine(lshift+1,lchain-lshift-1);
1228 if (multi == 1 || multi == lchain) {
1233 ctemp = chaine(0,multi-1);
1236 ctemp = chaine(multi,lchain-multi);
1246 if (divi == 1 || divi == lchain) {
1251 ctemp = chaine(0,divi-1);
1254 ctemp = chaine(divi,lchain-divi);
1264 if (puiss == 1 || puiss == lchain) {
1266 chaine_error =
"**";
1269 if (chaine(lchain-2,2) ==
"^2") {
1270 ctemp =
"sq(" + chaine(0,lchain-2) +
")";
1273 ctemp = chaine(0,puiss-1);
1276 ctemp = chaine(puiss,lchain-puiss);
1294 if ((chaine(0,2)==
"0x")||(chaine(0,2)==
"0X")) isHexa=
kTRUE;
1295 for (j=0; j<chaine.
Length() && err==0; j++) {
1298 if (j>0 && (chaine(j,1)==
"e" || chaine(j,2)==
"e+" || chaine(j,2)==
"e-" || chaine(j,1)==
"E" || chaine(j,2)==
"E+" || chaine(j,2)==
"E-")) {
1301 chaine_error=chaine;
1308 if (chaine(j,2)==
"e+" || chaine(j,2)==
"e-" || chaine(j,2)==
"E+" || chaine(j,2)==
"E-") j++;
1311 if (chaine(j,1) ==
"." && !hasDot) hasDot =
kTRUE;
1316 if (!strchr(
"0123456789",t) && (chaine(j,1)!=
"+" || j!=0)) {
1318 chaine_error=chaine;
1324 if (!strchr(
"0123456789abcdefABCDEF",t) && (j>1)) {
1326 chaine_error=chaine;
1332 if (!isHexa) {
if (sscanf((
const char*)chaine,
"%lg",&vafConst) > 0) err = 0;
else err =1;}
1333 else {
if (sscanf((
const char*)chaine,
"%lx",&vafConst2) > 0) err = 0;
else err=1;
1338 if (vafConst ==
fConst[j] ) k= j;
1357 if (oldformula && strcmp(schain,oldformula->
GetTitle())) {
1368 for (
Int_t ipar=0;ipar<npold;ipar++) {
1388 chaine_error = ctemp;
1389 }
else if ( k >= 0 ) {
1391 actionCode = action;
1400 }
else if (chaine(0,1) ==
"!") {
1401 ctemp = chaine(1,lchain-1);
1408 }
else if (chaine(0,1)==
"\"" && chaine(chaine.
Length()-1,1)==
"\"") {
1414 }
else if (chaine(0,4) ==
"cos(") {
1415 ctemp = chaine(3,lchain-3);
1422 }
else if (chaine(0,4) ==
"sin(") {
1423 ctemp = chaine(3,lchain-3);
1430 }
else if (chaine(0,4) ==
"tan(") {
1431 ctemp = chaine(3,lchain-3);
1438 }
else if (chaine(0,5) ==
"acos(") {
1439 ctemp = chaine(4,lchain-4);
1446 }
else if (chaine(0,5) ==
"asin(") {
1447 ctemp = chaine(4,lchain-4);
1454 }
else if (chaine(0,5) ==
"atan(") {
1455 ctemp = chaine(4,lchain-4);
1462 }
else if (chaine(0,5) ==
"cosh(") {
1463 ctemp = chaine(4,lchain-4);
1470 }
else if (chaine(0,5) ==
"sinh(") {
1471 ctemp = chaine(4,lchain-4);
1478 }
else if (chaine(0,5) ==
"tanh(") {
1479 ctemp = chaine(4,lchain-4);
1486 }
else if (chaine(0,6) ==
"acosh(") {
1487 ctemp = chaine(5,lchain-5);
1494 }
else if (chaine(0,6) ==
"asinh(") {
1495 ctemp = chaine(5,lchain-5);
1502 }
else if (chaine(0,6) ==
"atanh(") {
1503 ctemp = chaine(5,lchain-5);
1510 }
else if (chaine(0,3) ==
"sq(") {
1511 ctemp = chaine(2,lchain-2);
1518 }
else if (chaine(0,4) ==
"log(") {
1519 ctemp = chaine(3,lchain-3);
1526 }
else if (chaine(0,6) ==
"log10(") {
1527 ctemp = chaine(5,lchain-5);
1534 }
else if (chaine(0,4) ==
"exp(") {
1535 ctemp = chaine(3,lchain-3);
1542 }
else if (chaine(0,4) ==
"abs(") {
1543 ctemp = chaine(3,lchain-3);
1550 }
else if (chaine(0,5) ==
"sign(") {
1551 ctemp = chaine(4,lchain-4);
1558 }
else if (chaine(0,4) ==
"int(") {
1559 ctemp = chaine(3,lchain-3);
1566 }
else if (chaine ==
"rndm" || chaine(0,5) ==
"rndm(") {
1571 }
else if (chaine(0,5) ==
"sqrt(") {
1572 ctemp = chaine(4,lchain-4);
1582 }
else if ( chaine ==
"expo" || chaine(0,5)==
"expo("
1583 || (lchain==5 && chaine(1,4)==
"expo")
1584 || (lchain==6 && chaine(2,4)==
"expo")
1585 || chaine(1,5)==
"expo(" || chaine(2,5)==
"expo(" ) {
1587 if (chaine(1,4) ==
"expo") {
1592 else if (ctemp==
"y") {
1595 else if (ctemp==
"z") {
1598 else if (ctemp==
"t") {
1603 chaine_error=chaine1ST;
1605 chaine=chaine(1,lchain-1);
1608 if (chaine(2,4) ==
"expo") {
1609 if (chaine(0,2) !=
"xy") {
1611 chaine_error=chaine1ST;
1616 chaine=chaine(2,lchain-2);
1624 actionCode =
kexpo + inter2;
1636 }
else if (chaine(4,1) ==
"(") {
1637 ctemp = chaine(5,lchain-6);
1639 for (j=0; j<ctemp.
Length(); j++) {
1641 if (strchr(
"0123456789",t)==
nullptr && (ctemp(j,1)!=
"+" || j!=0)) {
1643 chaine_error=chaine1ST;
1647 sscanf(ctemp.
Data(),
"%d",&inter);
1650 actionCode =
kexpo + inter2;
1651 actionParam = inter;
1653 if (inter2 == 5) inter++;
1662 chaine_error=chaine;
1667 }
else if (chaine==
"gaus"
1668 || (lchain==5 && chaine(1,4)==
"gaus")
1669 || (lchain==6 && chaine(2,4)==
"gaus")
1670 || chaine(0,5)==
"gaus(" || chaine(1,5)==
"gaus(" || chaine(2,5)==
"gaus(") {
1672 if (chaine(1,4) ==
"gaus") {
1677 else if (ctemp==
"y") {
1680 else if (ctemp==
"z") {
1683 else if (ctemp==
"t") {
1688 chaine_error=chaine1ST;
1690 chaine=chaine(1,lchain-1);
1693 if (chaine(2,4) ==
"gaus") {
1694 if (chaine(0,2) !=
"xy") {
1696 chaine_error=chaine1ST;
1701 chaine=chaine(2,lchain-2);
1706 if (lchain == 4 && err==0) {
1710 actionCode =
kgaus + inter2;
1722 }
else if (chaine(4,1) ==
"(" && err==0) {
1723 ctemp = chaine(5,lchain-6);
1725 for (j=0; j<ctemp.
Length(); j++) {
1727 if (strchr(
"0123456789",t)==
nullptr && (ctemp(j,1)!=
"+" || j!=0)) {
1729 chaine_error=chaine1ST;
1733 sscanf(ctemp.
Data(),
"%d",&inter);
1736 actionCode =
kgaus + inter2;
1737 actionParam = inter;
1739 if (inter2 == 5) inter += 2;
1746 }
else if (err==0) {
1748 chaine_error=chaine1ST;
1753 }
else if (chaine==
"landau" || (lchain==7 && chaine(1,6)==
"landau")
1754 || (lchain==8 && chaine(2,6)==
"landau")
1755 || chaine(0,7)==
"landau(" || chaine(1,7)==
"landau(" || chaine(2,7)==
"landau(") {
1757 if (chaine(1,6) ==
"landau") {
1762 else if (ctemp==
"y") {
1765 else if (ctemp==
"z") {
1768 else if (ctemp==
"t") {
1773 chaine_error=chaine1ST;
1775 chaine=chaine(1,lchain-1);
1778 if (chaine(2,6) ==
"landau") {
1779 if (chaine(0,2) !=
"xy") {
1781 chaine_error=chaine1ST;
1786 chaine=chaine(2,lchain-2);
1791 if (lchain == 6 && err==0) {
1795 actionCode =
klandau + inter2;
1807 }
else if (chaine(6,1) ==
"(" && err==0) {
1808 ctemp = chaine(7,lchain-8);
1810 for (j=0; j<ctemp.
Length(); j++) {
1812 if (strchr(
"0123456789",t)==
nullptr && (ctemp(j,1)!=
"+" || j!=0)) {
1814 chaine_error=chaine1ST;
1818 sscanf(ctemp.
Data(),
"%d",&inter);
1821 actionCode =
klandau + inter2;
1822 actionParam = inter;
1824 if (inter2 == 5) inter += 2;
1831 }
else if (err==0) {
1833 chaine_error=chaine1ST;
1838 }
else if (chaine(0,3) ==
"pol" || chaine(1,3) ==
"pol") {
1840 if (chaine(1,3) ==
"pol") {
1845 else if (ctemp==
"y") {
1848 else if (ctemp==
"z") {
1851 else if (ctemp==
"t") {
1856 chaine_error=chaine1ST;
1858 chaine=chaine(1,lchain-1);
1861 if (chaine(lchain-1,1) ==
")") {
1863 for (j=3;j<lchain;j++)
if (chaine(j,1)==
"(" && nomb == 0) nomb = j;
1864 if (nomb == 3) err = 23;
1865 if (nomb == 0) err = 40;
1866 ctemp = chaine(nomb+1,lchain-nomb-2);
1867 for (j=0; j<ctemp.
Length(); j++) {
1869 if (strchr(
"0123456789",t)==
nullptr && (ctemp(j,1)!=
"+" || j!=0)) {
1871 chaine_error=chaine1ST;
1875 sscanf(ctemp.
Data(),
"%d",&inter);
1876 if (inter < 0) err = 20;
1885 ctemp = chaine(3,nomb-3);
1886 if (sscanf(ctemp.
Data(),
"%d",&
n) > 0) {
1887 if (
n < 0 ) err = 24;
1888 if (
n >= 20) err = 25;
1893 actionCode =
kpol+(inter2-1);
1894 actionParam =
n*100+inter+2;
1907 }
else if (chaine(0,4) ==
"pow(") {
1908 compt = 4; nomb = 0; virgule = 0; nest=0;
1909 while(compt != lchain) {
1911 if (chaine(compt-1,1) ==
"(") nest++;
1912 else if (chaine(compt-1,1) ==
")") nest--;
1913 else if (chaine(compt-1,1) ==
"," && nest==0) {
1915 if (nomb == 1 && virgule == 0) virgule = compt;
1918 if (nomb != 1) err = 22;
1920 ctemp = chaine(4,virgule-5);
1923 ctemp = chaine(virgule,lchain-virgule-1);
1931 }
else if (chaine(0,7) ==
"strstr(") {
1932 compt = 7; nomb = 0; virgule = 0; nest=0;
1934 while(compt != lchain) {
1936 if (chaine(compt-1,1) ==
"\"") {
1937 inString = !inString;
1938 }
else if (!inString) {
1939 if (chaine(compt-1,1) ==
"(") nest++;
1940 else if (chaine(compt-1,1) ==
")") nest--;
1941 else if (chaine(compt-1,1) ==
"," && nest==0) {
1943 if (nomb == 1 && virgule == 0) virgule = compt;
1947 if (nomb != 1) err = 28;
1949 ctemp = chaine(7,virgule-8);
1953 ctemp = chaine(virgule,lchain-virgule-1);
1962 chaine_error =
"strstr";
1965 }
else if (chaine(0,4) ==
"min(") {
1966 compt = 4; nomb = 0; virgule = 0; nest=0;
1967 while(compt != lchain) {
1969 if (chaine(compt-1,1) ==
"(") nest++;
1970 else if (chaine(compt-1,1) ==
")") nest--;
1971 else if (chaine(compt-1,1) ==
"," && nest==0) {
1973 if (nomb == 1 && virgule == 0) virgule = compt;
1981 ctemp = chaine(4,virgule-5);
1984 ctemp = chaine(virgule,lchain-virgule-1);
1992 }
else if (chaine(0,4) ==
"max(") {
1993 compt = 4; nomb = 0; virgule = 0; nest=0;
1994 while(compt != lchain) {
1996 if (chaine(compt-1,1) ==
"(") nest++;
1997 else if (chaine(compt-1,1) ==
")") nest--;
1998 else if (chaine(compt-1,1) ==
"," && nest==0) {
2000 if (nomb == 1 && virgule == 0) virgule = compt;
2008 ctemp = chaine(4,virgule-5);
2011 ctemp = chaine(virgule,lchain-virgule-1);
2020 }
else if (chaine(0,6) ==
"atan2(") {
2021 compt = 6; nomb = 0; virgule = 0; nest=0;
2022 while(compt != lchain) {
2024 if (chaine(compt-1,1) ==
"(") nest++;
2025 else if (chaine(compt-1,1) ==
")") nest--;
2026 else if (chaine(compt-1,1) ==
"," && nest==0) {
2028 if (nomb == 1 && virgule == 0) virgule = compt;
2031 if (nomb != 1) err = 21;
2033 ctemp = chaine(6,virgule-7);
2036 ctemp = chaine(virgule,lchain-virgule-1);
2044 }
else if (chaine(0,5) ==
"fmod(") {
2045 compt = 5; nomb = 0; virgule = 0; nest=0;
2046 while(compt != lchain) {
2048 if (chaine(compt-1,1) ==
"(") nest++;
2049 else if (chaine(compt-1,1) ==
")") nest--;
2050 else if (chaine(compt-1,1) ==
"," && nest==0) {
2052 if (nomb == 1 && virgule == 0) virgule = compt;
2060 ctemp = chaine(5,virgule-6);
2063 ctemp = chaine(virgule,lchain-virgule-1);
2073 chaine_error = chaine;
2079 }
else if (chaine(0,1) ==
"[" && chaine(lchain-1,1) ==
"]") {
2082 ctemp = chaine(1,lchain-2);
2083 for (j=0; j<ctemp.
Length(); j++) {
2085 if (strchr(
"0123456789",t)==
nullptr && (ctemp(j,1)!=
"+" || j!=0)) {
2087 chaine_error=chaine1ST;
2091 sscanf(ctemp.
Data(),
"%d",&valeur);
2093 actionParam =
offset + valeur;
2098 }
else if (chaine ==
"pi") {
2125 chaine_error =
"\""+chaine_error+
"\"";
2127 case 2 : er =
" Invalid Floating Point Operation";
break;
2128 case 4 : er =
" Empty String";
break;
2129 case 5 : er =
" Invalid Syntax " + chaine_error;
break;
2130 case 6 : er =
" Too many operators !";
break;
2131 case 7 : er =
" Too many parameters !";
break;
2132 case 10 : er =
" z specified but not x and y";
break;
2133 case 11 : er =
" z and y specified but not x";
break;
2134 case 12 : er =
" y specified but not x";
break;
2135 case 13 : er =
" z and x specified but not y";
break;
2136 case 20 : er =
" Non integer value for parameter number : " + chaine_error;
break;
2137 case 21 : er =
" ATAN2 requires two arguments";
break;
2138 case 22 : er =
" POW requires two arguments";
break;
2139 case 23 : er =
" Degree of polynomial not specified";
break;
2140 case 24 : er =
" Degree of polynomial must be positive";
break;
2141 case 25 : er =
" Degree of polynomial must be less than 20";
break;
2142 case 26 : er =
" Unknown name : " + chaine_error;
break;
2143 case 27 : er =
" Too many constants in expression";
break;
2144 case 28 : er =
" strstr requires two arguments";
break;
2145 case 29 : er =
" TFormula can only call interpreted and compiled functions that return a numerical type: " + chaine_error;
break;
2146 case 30 : er =
" Bad numerical expression : " + chaine_error;
break;
2147 case 31 : er =
" Part of the Variable " + chaine_error; er +=
" exists but some of it is not accessible or useable";
break;
2148 case 40 : er =
" '(' is expected";
break;
2149 case 41 : er =
" ')' is expected";
break;
2150 case 42 : er =
" '[' is expected";
break;
2151 case 43 : er =
" ']' is expected";
break;
2152 case 44 : er =
" The function '" + chaine(0,err_hint) +
"' requires two arguments.";
break;
2153 case 45 : er =
"The operator " + chaine_error +
" requires a numerical operand.";
break;
2154 case 46 : er =
"Both operands of the operator " + chaine_error +
" have to be either numbers or strings.";
break;
2155 case 47 : er = chaine_error +
" requires 2 string arguments";
break;
2170 Error(
"Compile",
"\"%s\" requires a numerical operand.",
fExpr[oper].Data());
2190 Error(
"Compile",
"\"%s\" requires two numerical operands.",
fExpr[oper].Data());
2252 inline static void ResizeArrayIfAllocated(T*& oldArray,
int newSize){
2255 if (!oldArray || newSize <=0)
return;
2257 T* newArray =
new T[newSize];
2258 std::copy(oldArray, oldArray+newSize, newArray);
2260 oldArray = newArray;
2293 Int_t i,j,lc,valeur,err;
2299 if (strlen(expression))
SetTitle(expression);
2304 char *sctemp =
new char[chaine.
Length()+1];
2305 strlcpy(sctemp,chaine.
Data(),chaine.
Length()+1);
2306 char *semicol = (
char*)strstr(sctemp,
";");
2307 if (semicol) *semicol = 0;
2327 for (i=0; i<
gMAXOP; i++) {
2336 for (i=1; i<=chaine.
Length(); i++) {
2338 if (chaine(i-1,1) ==
"\"") inString = !inString;
2339 if (inString)
continue;
2340 if (chaine(i-1,2) ==
"**") {
2341 chaine = chaine(0,i-1) +
"^" + chaine(i+1,lc-i-1);
2343 }
else if (chaine(i-1,2) ==
"++") {
2344 chaine = chaine(0,i) + chaine(i+1,lc-i-1);
2346 }
else if (chaine(i-1,2) ==
"+-" || chaine(i-1,2) ==
"-+") {
2347 chaine = chaine(0,i-1) +
"-" + chaine(i+1,lc-i-1);
2349 }
else if (chaine(i-1,2) ==
"--") {
2350 chaine = chaine(0,i-1) +
"+" + chaine(i+1,lc-i-1);
2352 }
else if (chaine(i-1,2) ==
"->") {
2353 chaine = chaine(0,i-1) +
"." + chaine(i+1,lc-i-1);
2355 }
else if (chaine(i-1,1) ==
"[") {
2356 for (j=1;j<=chaine.
Length()-i;j++) {
2357 if (chaine(j+i-1,1) ==
"]" || j+i > chaine.
Length())
break;
2359 ctemp = chaine(i,j-1);
2361 sscanf(ctemp.
Data(),
"%d",&valeur);
2363 }
else if (chaine(i-1,1) ==
" ") {
2364 chaine = chaine(0,i-1)+chaine(i,lc-i);
2369 Analyze((
const char*)chaine,err);
2412 for (i=0;i<
fNpar;i++)
2447 if (err) {
fNdim = 0;
return 1; }
2451 if (!
IsA()->GetBaseClass(
"TTreeFormula")) {
2474 ((
TFormula&)obj).fParams =
nullptr;
2499 while ( (fobj = next()) ) {
2624 if (chaine ==
"x") {
2627 }
else if (chaine ==
"y") {
2630 }
else if (chaine ==
"z") {
2633 }
else if (chaine ==
"t") {
2640 if (chaine.
Data()[0]==
'x'){
2641 if (chaine.
Data()[1]==
'[' && chaine.
Data()[3]==
']'){
2642 const char ch0 =
'0';
2644 if (dim<0)
return -1;
2645 if (dim>9)
return -1;
2649 if (chaine.
Data()[1]==
'[' && chaine.
Data()[4]==
']'){
2650 const char ch0 =
'0';
2651 Int_t dim = (chaine.
Data()[2]-ch0)*10+(chaine.
Data()[3]-ch0);
2652 if (dim<0)
return -1;
2653 if (dim>99)
return -1;
2675 return ((
TFormula*)
this)->EvalPar(xx);
2695 Int_t precalculated = 0;
2696 Int_t precalculated_str = 0;
2700 params =
const_cast<Double_t*
>(uparams);
2707 for (i=0; i<
fNoper; ++i) {
2709 const int oper =
fOper[i];
2717 case kStringConst: { strpos++; stringStack[strpos-1] = (
char*)
fExpr[i].Data(); pos++; tab[pos-1] = 0;
continue; }
2719 case kAdd : pos--; tab[pos-1] += tab[pos];
continue;
2720 case kSubstract : pos--; tab[pos-1] -= tab[pos];
continue;
2721 case kMultiply : pos--; tab[pos-1] *= tab[pos];
continue;
2722 case kDivide : pos--;
if (tab[pos] == 0) tab[pos-1] = 0;
2723 else tab[pos-1] /= tab[pos];
2748 case kacosh:
if (tab[pos-1] < 1) {tab[pos-1] = 0;}
2757 case kfmod : pos--; tab[pos-1] = fmod(tab[pos-1],tab[pos]);
continue;
2758 case kpow : pos--; tab[pos-1] =
TMath::Power(tab[pos-1],tab[pos]);
continue;
2759 case ksq : tab[pos-1] = tab[pos-1]*tab[pos-1];
continue;
2762 case kstrstr : strpos -= 2; pos-=2; pos++;
2763 if (strstr(stringStack[strpos],stringStack[strpos+1])) tab[pos-1]=1;
2767 case kmin : pos--; tab[pos-1] =
TMath::Min(tab[pos-1],tab[pos]);
continue;
2768 case kmax : pos--; tab[pos-1] =
TMath::Max(tab[pos-1],tab[pos]);
continue;
2770 case klog :
if (tab[pos-1] > 0) tab[pos-1] =
TMath::Log(tab[pos-1]);
2771 else {tab[pos-1] = 0;}
2774 if (dexp < -700) {tab[pos-1] = 0;
continue;}
2775 if (dexp > 700) {tab[pos-1] =
TMath::Exp(700);
continue;}
2778 else {tab[pos-1] = 0;}
2784 case ksign :
if (tab[pos-1] < 0) tab[pos-1] = -1;
else tab[pos-1] = 1;
continue;
2787 case kSignInv: tab[pos-1] = -1 * tab[pos-1];
continue;
2791 case kAnd : pos--;
if (tab[pos-1]!=0 && tab[pos]!=0) tab[pos-1]=1;
2794 case kOr : pos--;
if (tab[pos-1]!=0 || tab[pos]!=0) tab[pos-1]=1;
2797 case kEqual: pos--;
if (tab[pos-1] == tab[pos]) tab[pos-1]=1;
2800 case kNotEqual : pos--;
if (tab[pos-1] != tab[pos]) tab[pos-1]=1;
2803 case kLess : pos--;
if (tab[pos-1] < tab[pos]) tab[pos-1]=1;
2806 case kGreater : pos--;
if (tab[pos-1] > tab[pos]) tab[pos-1]=1;
2810 case kLessThan: pos--;
if (tab[pos-1]<=tab[pos]) tab[pos-1]=1;
2813 case kGreaterThan: pos--;
if (tab[pos-1]>=tab[pos]) tab[pos-1]=1;
2816 case kNot :
if (tab[pos-1]!=0) tab[pos-1] = 0;
else tab[pos-1] = 1;
2820 if (!strcmp(stringStack[strpos+1],stringStack[strpos])) tab[pos-1]=1;
2824 if (strcmp(stringStack[strpos+1],stringStack[strpos])) tab[pos-1]=1;
2828 case kBitAnd : pos--; tab[pos-1]= ((
Int_t) tab[pos-1]) & ((
Int_t) tab[pos]);
continue;
2829 case kBitOr : pos--; tab[pos-1]= ((
Int_t) tab[pos-1]) | ((
Int_t) tab[pos]);
continue;
2841 int op = param % 10;
2843 if (op == 1 && (!tab[pos-1]) ) {
2852 }
else if (op == 2 && tab[pos-1] ) {
2864 int toskip = param / 10;
2874 #define R__EXPO(var) \
2876 pos++; int param = (oper & kTFOperMask); \
2877 tab[pos-1] = TMath::Exp(params[param]+params[param+1]*x[var]); \
2885 tab[pos-1] =
TMath::Exp(params[param]+params[param+1]*
x[0]+params[param+2]*
x[1]);
2888 #define R__GAUS(var) \
2890 pos++; int param = (oper & kTFOperMask); \
2891 tab[pos-1] = params[param]*TMath::Gaus(x[var],params[param+1],params[param+2],IsNormalized()); \
2901 if (params[param+2] == 0) {
2904 intermede1=
Double_t((
x[0]-params[param+1])/params[param+2]);
2907 if (params[param+4] == 0) {
2910 intermede2=
Double_t((
x[1]-params[param+3])/params[param+4]);
2912 tab[pos-1] = params[param]*
TMath::Exp(-0.5*(intermede1*intermede1+intermede2*intermede2));
2915 #define R__LANDAU(var) \
2917 pos++; const int param = (oper & kTFOperMask); \
2918 tab[pos-1] = params[param]*TMath::Landau(x[var],params[param+1],params[param+2],IsNormalized()); \
2925 case kxylandau: { pos++;
int param = oper&0x7fffff ;
2928 tab[pos-1] = params[param]*intermede1*intermede2;
2932 #define R__POLY(var) \
2934 pos++; int param = (oper & kTFOperMask); \
2935 tab[pos-1] = 0; Double_t intermede = 1; \
2936 Int_t inter = param/100; \
2937 Int_t int1= param-inter*100-1; \
2938 for (j=0 ;j<inter+1;j++) { \
2939 tab[pos-1] += intermede*params[j+int1]; \
2940 intermede *= x[var]; \
2950 if (!precalculated) {
2954 pos++; tab[pos-1] = param_calc[(oper &
kTFOperMask)];
2960 if (!precalculated_str) {
2961 precalculated_str=1;
2964 strpos++; stringStack[strpos-1] = string_calc[param];
2965 pos++; tab[pos-1] = 0;
2973 int fno = param / 1000;
2974 int nargs = param % 1000;
2982 UInt_t argloc = pos-nargs;
2983 for(j=0;j<nargs;j++,argloc++,pos--) {
3032 Int_t ternaryend = -1;
3036 if (ternaryend==i) {
3038 if(ismulti[spos-1]){
3039 tab[spos-2]=tab[spos-2]+
"("+tab[spos-1]+
")";
3041 tab[spos-2]=tab[spos-2]+tab[spos-1];
3055 tab[spos-1]=
"-("+tab[spos-1]+
")";
3069 if ((optype<=151 && optype>=140 && optype!=145) || (optype == 40)) {
3077 if(((optype>0 && optype<6) || optype==20 ||
3078 (((optype>59 && optype<69) || (optype >75 && optype<82)) && spos>=2))) {
3080 if(ismulti[spos-2]){
3081 tab[spos-2]=
"("+tab[spos-2]+
")";
3083 if(ismulti[spos-1]){
3084 tab[spos-2]+=
fExpr[i]+(
"("+tab[spos-1]+
")");
3086 tab[spos-2]+=
fExpr[i]+tab[spos-1];
3088 ismulti[spos-2]=
kTRUE;
3094 if(ismulti[spos-1]){
3095 tab[spos-1]=
"("+tab[spos-1]+
")?";
3097 tab[spos-1]=tab[spos-1]+
"?";
3101 if (optype==
kJump) {
3102 if(ismulti[spos-1]){
3103 tab[spos-2]=tab[spos-2]+
"("+tab[spos-1]+
"):";
3105 tab[spos-2]=tab[spos-2]+tab[spos-1]+
":";
3115 if((optype>9 && optype<16) ||
3116 (optype>20 && optype<23) ||
3117 (optype>29 && optype<34) ||
3118 (optype>40 && optype<44) ||
3119 (optype>69 && optype<76) ||
3125 if((optype>15 && optype<20) ||
3126 (optype>22 && optype<26)) {
3133 int nargs = param % 1000;
3138 for(j=0, depth=0;j<funcname.
Length();++j) {
3139 switch (funcname[j]) {
3156 Error(
"GetExpFormula",
"Internal error, number of argument found is %d",-
offset);
3157 }
else if (
offset == 0) {
3158 tab[spos]=funcname+
"()";
3164 for (j=
offset+1; j<0; j++){
3165 tab[spos+
offset]+=
","+tab[spos+j];
3173 if (ternaryend==
fNoper) {
3175 if(ismulti[spos-1]){
3176 tab[spos-2]=tab[spos-2]+
"("+tab[spos-1]+
")";
3178 tab[spos-2]=tab[spos-2]+tab[spos-1];
3184 if (spos > 0) ret = tab[spos-1];
3194 for (j=0;j<
fNpar;j++) {
3224 if (ipar <0 || ipar >=
fNpar)
return 0;
3236 Error(
"TFormula",
"Parameter %s not found", parName);
3247 if (ipar <0 || ipar >=
fNpar)
return "";
3248 if (
fNames[ipar].Length() > 0)
return (
const char*)
fNames[ipar];
3249 return Form(
"p%d",ipar);
3261 if (!strcmp(
GetParName(i),parName))
return i;
3282 Printf(
" fExpr[%d] = %s action = %d action param = %d ",
3288 Printf(
"Optimized expression");
3290 Printf(
" fExpr[%d] = %s\t\t action = %d action param = %d ",
3297 for (i=0;i<
fNpar;i++) {
3313 pch= (
char*)strstr(formula.
Data(),
"++");
3315 formula.
Insert(0,
"[0]*(");
3316 pch= (
char*)strstr(formula.
Data(),
"++");
3323 if (nf<10) replsize = 7;
3324 else if (nf<100) replsize = 8;
3326 formula.
Replace(pch-formula.
Data(), 2, repl, replsize);
3327 pch = (
char*)strstr(formula.
Data()+
offset,
"++");
3333 formula2=formula2(4, formula2.
Length()-4);
3334 pch= (
char*)strchr(formula2.
Data(),
'[');
3339 if (nf<10) replsize = 5;
3341 formula2.
Replace(pch-formula2.
Data()-1, replsize, repl, 2);
3342 pch = (
char*)strchr(formula2.
Data()+
offset,
'[');
3350 formula2 = formula2.
ReplaceAll(
"++", 2,
"|", 1);
3353 for (
Int_t i=0; i<nf; i++) {
3355 replaceformula_name =
"f_linear_";
3356 replaceformula_name.
Append(replaceformula);
3359 Error(
"TFormula",
"f_linear not allocated");
3364 gROOT->GetListOfFunctions()->Remove(
f);
3378 if (ipar <0 || ipar >=
fNpar)
return;
3388 if (ipar <0 || ipar >=
fNpar)
return;
3434 if (ipar <0 || ipar >=
fNpar)
return;
3442 const char*name5,
const char*name6,
const char*name7,
const char*name8,
const char*name9,
const char*name10)
3462 if (
b.IsReading()) {
3466 Error(
"Streamer",
"version 6 is not supported");
3481 if (
b.IsReading()) {
3485 Error(
"Streamer",
"version 6 is not supported");
3506 gROOT->GetListOfFunctions()->Add(
this);
3519 Error(
"Streamer",
"error compiling formula");
3554 if (
gROOT->GetListOfFunctions()->FindObject(
GetName()))
return;
3555 gROOT->GetListOfFunctions()->Add(
this);
3572 kOldxylandau = 4500,
3573 kOldConstants = 50000,
3574 kOldStrings = 80000,
3575 kOldVariable = 100000,
3576 kOldTreeString = 105000,
3577 kOldFormulaVar = 110000,
3578 kOldBoolOptimize = 120000,
3579 kOldFunctionCall = 200000
3583 for (i=0,j=0; i<
fNoper; ++i,++j) {
3585 Int_t newActionCode = 0;
3586 Int_t newActionParam = 0;
3594 sscanf((
const char*)
fExpr[i],
"%g",&aresult);
3601 for (
int z=i; z<
fNoper; ++z) {
3605 }
else if ( action < 100 ) {
3608 newActionCode = action;
3610 }
else if (action >= kOldFunctionCall) {
3614 newActionParam = action-kOldFunctionCall;
3616 }
else if (action >= kOldBoolOptimize) {
3620 newActionParam = action-kOldBoolOptimize;
3622 }
else if (action >= kOldFormulaVar) {
3626 newActionParam = action-kOldFormulaVar;
3628 }
else if (action >= kOldTreeString) {
3632 newActionParam = action-kOldTreeString;
3634 }
else if (action >= kOldVariable) {
3638 newActionParam = action-kOldVariable;
3640 }
else if (action == kOldStrings) {
3645 }
else if (action >= kOldConstants) {
3649 newActionParam = action-kOldConstants;
3651 }
else if (action > 10000 && action < kOldConstants) {
3654 int var = action/10000;
3655 newActionCode =
kpol + (var-1);
3656 newActionParam = action - var*10000;
3658 }
else if (action >= 4600) {
3660 Error(
"Convert",
"Unsupported value %d",action);
3662 }
else if (action > kOldxylandau) {
3666 newActionParam = action - (kOldxylandau+1);
3668 }
else if (action > kOldlandau) {
3672 int var = action/100-40;
3673 if (var) newActionCode += var;
3674 newActionParam = action - var*100 - (kOldlandau+1);
3676 }
else if (action > 2500 && action < 2600) {
3680 newActionParam = action-2501;
3682 }
else if (action > 2000 && action < 2500) {
3685 newActionCode =
kgaus;
3686 int var = action/100-20;
3687 if (var) newActionCode += var;
3688 newActionParam = action - var*100 - (kOldgaus+1);
3690 }
else if (action > 1500 && action < 1600) {
3694 newActionParam = action-1501;
3696 }
else if (action > 1000 && action < 1500) {
3699 newActionCode =
kexpo;
3700 int var = action/100-10;
3701 if (var) newActionCode += var;
3702 newActionParam = action - var*100 - (kOldexpo+1);
3704 }
else if (action > 100 && action < 200) {
3708 newActionParam = action - 101;
3711 SetAction( j, newActionCode, newActionParam );
3750 int paran = cbase.
First(
"(");
3757 if (cbase==
"<") cbase=
"XlY";
3758 if (cbase==
"<=") cbase=
"XleY";
3759 if (cbase==
">") cbase=
"XgY";
3760 if (cbase==
">=") cbase=
"XgeY";
3767 if (prim->
fType==10) {
3770 if (prim->
fType==110) {
3773 if (prim->
fType==1110) {
3776 if (prim->
fType==-1) {
3779 if (prim->
fType==0){
3835 for (i=0; i<
fNoper; i++) {
3869 for (i=0;i<
fNoper;i++) optimized[i]=0;
3929 if ((i+1) >=
fNoper)
continue;
3956 if ((i+2) >=
fNoper)
continue;
3993 if ((i+3) >=
fNoper)
continue;
4061 if (optimized[i]==0){
4108 delete [] optimized;
4198 Int_t precalculated = 0;
4199 Int_t precalculated_str = 0;
4205 params =
const_cast<Double_t*
>(uparams);
4225 case kAdd : pos--; tab[pos-1] += tab[pos];
continue;
4226 case kSubstract : pos--; tab[pos-1] -= tab[pos];
continue;
4227 case kMultiply : pos--; tab[pos-1] *= tab[pos];
continue;
4228 case kDivide : pos--;
if (tab[pos] == 0) tab[pos-1] = 0;
4229 else tab[pos-1] /= tab[pos];
4254 case kAnd : pos--; tab[pos-1] = (
bool)tab[pos];
continue;
4255 case kOr : pos--; tab[pos-1] = (
bool)tab[pos];
continue;
4259 case kabs :
if (tab[pos-1]<0) tab[pos-1]=-tab[pos-1];
continue;
4260 case ksign :
if (tab[pos-1] < 0) tab[pos-1] = -1;
else tab[pos-1] = 1;
continue;
4262 case kpow : pos--; tab[pos-1] =
TMath::Power(tab[pos-1],tab[pos]);
continue;
4272 case kfmod : pos--; tab[pos-1] = fmod(tab[pos-1],tab[pos]);
continue;
4274 case kstrstr : strpos -= 2; pos-=2; pos++;
4275 if (strstr(stringStack[strpos],stringStack[strpos+1])) tab[pos-1]=1;
4281 case kSignInv: tab[pos-1] = -1 * tab[pos-1];
continue;
4286 case kEqual: pos--;
if (tab[pos-1] == tab[pos]) tab[pos-1]=1;
4289 case kNotEqual : pos--;
if (tab[pos-1] != tab[pos]) tab[pos-1]=1;
4292 case kNot :
if (tab[pos-1]!=0) tab[pos-1] = 0;
else tab[pos-1] = 1;
4296 if (!strcmp(stringStack[strpos+1],stringStack[strpos])) tab[pos-1]=1;
4300 if (strcmp(stringStack[strpos+1],stringStack[strpos])) tab[pos-1]=1;
4304 case kBitAnd : pos--; tab[pos-1]= ((
Int_t) tab[pos-1]) & ((
Int_t) tab[pos]);
continue;
4305 case kBitOr : pos--; tab[pos-1]= ((
Int_t) tab[pos-1]) | ((
Int_t) tab[pos]);
continue;
4316 int op = param % 10;
4318 if (op == 1 && (!tab[pos-1]) ) {
4327 }
else if (op == 2 && tab[pos-1] ) {
4344#define R__EXPO(var) \
4346 pos++; int param = (oper & kTFOperMask); \
4347 tab[pos-1] = TMath::Exp(params[param]+params[param+1]*x[var]); \
4355 tab[pos-1] =
TMath::Exp(params[param]+params[param+1]*
x[0]+params[param+2]*
x[1]);
4360#define R__GAUS(var) \
4362 pos++; int param = (oper & kTFOperMask); \
4363 tab[pos-1] = params[param]*TMath::Gaus(x[var],params[param+1], \
4364 params[param+2],IsNormalized()); \
4374 if (params[param+2] == 0) {
4377 intermede1=
Double_t((
x[0]-params[param+1])/params[param+2]);
4380 if (params[param+4] == 0) {
4383 intermede2=
Double_t((
x[1]-params[param+3])/params[param+4]);
4385 tab[pos-1] = params[param]*
TMath::Exp(-0.5*(intermede1*intermede1+intermede2*intermede2));
4388#define R__LANDAU(var) \
4390 pos++; const int param = (oper & kTFOperMask); \
4391 tab[pos-1] = params[param]*TMath::Landau(x[var],params[param+1],params[param+2],IsNormalized()); \
4398 case kxylandau: { pos++;
int param = oper&0x7fffff ;
4401 tab[pos-1] = params[param]*intermede1*intermede2;
4405#define R__POLY(var) \
4407 pos++; int param = (oper & kTFOperMask); \
4408 tab[pos-1] = 0; Double_t intermede = 1; \
4409 Int_t inter = param/100; \
4410 Int_t int1= param-inter*100-1; \
4411 for (j=0 ;j<inter+1;j++) { \
4412 tab[pos-1] += intermede*params[j+int1]; \
4413 intermede *= x[var]; \
4423 if (!precalculated) {
4427 pos++; tab[pos-1] = param_calc[(oper &
kTFOperMask)];
4433 if (!precalculated_str) {
4434 precalculated_str=1;
4437 strpos++; stringStack[strpos-1] = string_calc[param];
4438 pos++; tab[pos-1] = 0;
4446 int fno = param / 1000;
4447 int nargs = param % 1000;
4455 UInt_t argloc = pos-nargs;
4456 for(j=0;j<nargs;j++,argloc++,pos--) {
4484 if (str.
Length()<3)
return 1;
4485 if (str[str.
Length()-1]!=
'+'&&str[str.
Length()-2]!=
'+')
return 1;
4487 TString funName(
"preformula_");
4491 fileName.
Form(
"/tmp/%s.C",funName.
Data());
4494 hf = fopen(fileName.
Data(),
"w");
4495 if (hf ==
nullptr) {
4496 Error(
"PreCompile",
"Unable to open the file %s for writing.",fileName.
Data());
4499 fprintf(hf,
"/////////////////////////////////////////////////////////////////////////\n");
4500 fprintf(hf,
"// This code has been automatically generated \n");
4502 fprintf(hf,
"Double_t %s(Double_t *x, Double_t *p){",funName.
Data());
4503 fprintf(hf,
"return (%s);\n}",str.
Data());
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
R__EXTERN TVirtualMutex * gROOTMutex
R__EXTERN TRandom * gRandom
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
void Printf(const char *fmt,...)
Formats a string in a circular formatting buffer and prints the string.
#define R__LOCKGUARD(mutex)
TOperOffset()
TOper offset - helper class for TFormula* specify type of operand fTypeX = kVariable = kParameter = k...
Bool_t TestBitNumber(UInt_t bitnumber) const
void SetBitNumber(UInt_t bitnumber, Bool_t value=kTRUE)
Buffer base class used for serializing objects.
TClass instances represent classes, structs and namespaces in the ROOT type system.
ClassInfo_t * GetClassInfo() const
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 void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual const char * GetPrototype() const
Returns the prototype of a function as defined by CINT, or 0 in case of error.
Method or function calling interface.
EReturnType ReturnType()
Returns the return type of the method.
void ResetParam()
Reset parameter list. To be used before the first call the SetParam().
static const EReturnType kOther
TFunction * GetMethod()
Returns the TMethod describing the method to be executed.
void Execute(const char *, const char *, int *=nullptr) override
Execute method on this object with the given parameter string, e.g.
Bool_t IsValid() const
Return true if the method call has been properly initialized and is usable.
void SetParam(Long_t l)
Add a long method parameter.
The TNamed class is the base class for all named ROOT classes.
void Copy(TObject &named) const override
Copy this to obj.
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
const char * GetName() const override
Returns name of object.
void Streamer(TBuffer &) override
Stream an object of class TObject.
const char * GetTitle() const override
Returns title of object.
virtual void Expand(Int_t newSize)
Expand or shrink the array to newSize elements.
void Delete(Option_t *option="") override
Remove all objects from the array AND delete all heap based objects.
TObject * At(Int_t idx) const override
TObject * UncheckedAt(Int_t i) const
Bool_t IsEmpty() const override
Int_t GetLast() const override
Return index of last object in array.
void Add(TObject *obj) override
Collectable string class.
Mother of all ROOT objects.
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
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.
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.
Double_t Rndm() override
Machine independent random number generator.
void ToLower()
Change string to lower-case.
TString & Insert(Ssiz_t pos, const char *s)
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
Ssiz_t First(char c) const
Find first occurrence of a character c.
const char * Data() const
TString & ReplaceAll(const TString &s1, const TString &s2)
Ssiz_t Last(char c) const
Find last occurrence of a character c.
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
TString & Remove(Ssiz_t pos)
TString & Append(const char *cs)
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Double_t CosH(Double_t)
Returns the hyperbolic cosine of x.
Double_t ACos(Double_t)
Returns the principal value of the arc cosine of x, expressed in radians.
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Double_t ASin(Double_t)
Returns the principal value of the arc sine of x, expressed in radians.
Double_t Exp(Double_t x)
Returns the base-e exponential function of x, which is e raised to the power x.
Double_t ATan(Double_t)
Returns the principal value of the arc tangent of x, expressed in radians.
Double_t ASinH(Double_t)
Returns the area hyperbolic sine of x.
Double_t Landau(Double_t x, Double_t mpv=0, Double_t sigma=1, Bool_t norm=kFALSE)
The LANDAU function.
Double_t TanH(Double_t)
Returns the hyperbolic tangent of x.
Double_t ACosH(Double_t)
Returns the nonnegative area hyperbolic cosine of x.
Double_t ATan2(Double_t y, Double_t x)
Returns the principal value of the arc tangent of y/x, expressed in radians.
Double_t Log(Double_t x)
Returns the natural logarithm of x.
Double_t Sqrt(Double_t x)
Returns the square root of x.
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Double_t Cos(Double_t)
Returns the cosine of an angle of x radians.
Double_t Sin(Double_t)
Returns the sine of an angle of x radians.
Double_t Tan(Double_t)
Returns the tangent of an angle of x radians.
Double_t ATanH(Double_t)
Returns the area hyperbolic tangent of x.
Double_t Log10(Double_t x)
Returns the common (base-10) logarithm of x.
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Double_t SinH(Double_t)
Returns the hyperbolic sine of `x.