30#pragma optimize("",off)
186 if (!expression || !*expression) {
187 Error(
"TFormula",
"expression may not be 0 or have 0 length");
193 nch = strlen(expression);
194 char *expr =
new char[nch+1];
196 for (i=0;i<nch;i++) {
197 if (expression[i] ==
' ')
continue;
198 if (i > 0 && (expression[i] ==
'*') && (expression[i-1] ==
'*')) {
202 expr[j] = expression[i]; j++;
221 Warning(
"TFormula",
"Cannot use both gaus and gausn - gaus will be treated as gausn");
223 Warning(
"TFormula",
"Cannot use both gausn and landau - landau will be treated as landaun");
232 Warning(
"TFormula",
"Cannot use both gaus and landaun - gaus will be treated as gausn");
235 Warning(
"TFormula",
"Cannot use both landau and landaun - landau will be treated as landaun");
257 if (strcmp(
name,
"x")==0 || strcmp(
name,
"y")==0 ||
258 strcmp(
name,
"z")==0 || strcmp(
name,
"t")==0 )
260 Error(
"TFormula",
"The name \'%s\' is reserved as a TFormula variable name.\n"
261 "\tThis function will not be registered in the list of functions",
name);
266 gROOT->GetListOfFunctions()->Remove(old);
268 gROOT->GetListOfFunctions()->Add(
this);
296 ((
TFormula&)formula).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 = 0;
424 cinfo =
ns->GetClassInfo();
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;
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)!=0);
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 = 1;
794 for(k=j-3; k>=0 && isrightdecimal; --k) {
796 isrightdecimal = isrightdecimal && (strchr(
"0123456789.",t)!=0);
797 if (!isrightdecimal) {
798 if (strchr(
"+-/[]()&|><=!*/%^\\",t)!=0) {
803 if (k<0 && isrightdecimal) puiss10bis = 1;
806 if (puiss10 && (i<=lchain)) {
808 puiss10 = (strchr(
"0123456789.",t)!=0);
810 if (puiss10bis && (j<=lchain)) {
812 puiss10bis = (strchr(
"0123456789.",t)!=0);
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);
1006 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1008 ctemp = chaine(etx,lchain-etx);
1009 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1016 }
else if (petit != 0) {
1017 if (petit==1 || petit==lchain) {
1022 ctemp = chaine(0,petit-1);
1023 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1025 ctemp = chaine(petit,lchain-petit);
1026 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1033 }
else if (grand != 0) {
1034 if (grand==1 || grand==lchain) {
1039 ctemp = chaine(0,grand-1);
1040 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1042 ctemp = chaine(grand,lchain-grand);
1043 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1050 }
else if (peteg != 0) {
1051 if (peteg==1 || peteg==lchain-1) {
1056 ctemp = chaine(0,peteg-1);
1057 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1058 ctemp = chaine(peteg+1,lchain-peteg-1);
1060 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1067 }
else if (grdeg != 0) {
1068 if (grdeg==1 || grdeg==lchain-1) {
1073 ctemp = chaine(0,grdeg-1);
1074 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1076 ctemp = chaine(grdeg+1,lchain-grdeg-1);
1077 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1084 }
else if (egal != 0) {
1085 if (egal==1 || egal==lchain-1) {
1090 ctemp = chaine(0,egal-1);
1091 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1094 ctemp = chaine(egal+1,lchain-egal-1);
1095 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
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);
1116 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1119 ctemp = chaine(diff+1,lchain-diff-1);
1120 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1125 if (
IsString(optloc) != isstring) {
1127 chaine_error =
"!=";
1128 }
else if (isstring) {
1134 }
else if (plus != 0) {
1140 ctemp = chaine(0,plus-1);
1141 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1143 ctemp = chaine(plus,lchain-plus);
1144 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1154 ctemp = chaine(moins,lchain-moins);
1155 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1162 if (moins == lchain) {
1166 ctemp = chaine(0,moins-1);
1167 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1169 ctemp = chaine(moins,lchain-moins);
1170 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1178 }
else if (modulo != 0) {
1179 if (modulo == 1 || modulo == lchain) {
1183 ctemp = chaine(0,modulo-1);
1184 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1186 ctemp = chaine(modulo,lchain-modulo);
1187 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1194 }
else if (rshift != 0) {
1195 if (rshift == 1 || rshift == lchain) {
1199 ctemp = chaine(0,rshift-1);
1200 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1202 ctemp = chaine(rshift+1,lchain-rshift-1);
1203 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1210 }
else if (lshift != 0) {
1211 if (lshift == 1 || lshift == lchain) {
1215 ctemp = chaine(0,lshift-1);
1216 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1218 ctemp = chaine(lshift+1,lchain-lshift-1);
1219 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1228 if (multi == 1 || multi == lchain) {
1233 ctemp = chaine(0,multi-1);
1234 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1236 ctemp = chaine(multi,lchain-multi);
1237 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1246 if (divi == 1 || divi == lchain) {
1251 ctemp = chaine(0,divi-1);
1252 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1254 ctemp = chaine(divi,lchain-divi);
1255 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1264 if (puiss == 1 || puiss == lchain) {
1266 chaine_error =
"**";
1269 if (chaine(lchain-2,2) ==
"^2") {
1270 ctemp =
"sq(" + chaine(0,lchain-2) +
")";
1271 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1273 ctemp = chaine(0,puiss-1);
1274 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1276 ctemp = chaine(puiss,lchain-puiss);
1277 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
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;
1355 oldformula = (
const TFormula*)
gROOT->GetListOfFunctions()->FindObject((
const char*)chaine);
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);
1402 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1408 }
else if (chaine(0,1)==
"\"" && chaine(chaine.
Length()-1,1)==
"\"") {
1414 }
else if (chaine(0,4) ==
"cos(") {
1415 ctemp = chaine(3,lchain-3);
1416 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1422 }
else if (chaine(0,4) ==
"sin(") {
1423 ctemp = chaine(3,lchain-3);
1424 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1430 }
else if (chaine(0,4) ==
"tan(") {
1431 ctemp = chaine(3,lchain-3);
1432 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1438 }
else if (chaine(0,5) ==
"acos(") {
1439 ctemp = chaine(4,lchain-4);
1440 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1446 }
else if (chaine(0,5) ==
"asin(") {
1447 ctemp = chaine(4,lchain-4);
1448 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1454 }
else if (chaine(0,5) ==
"atan(") {
1455 ctemp = chaine(4,lchain-4);
1456 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1462 }
else if (chaine(0,5) ==
"cosh(") {
1463 ctemp = chaine(4,lchain-4);
1464 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1470 }
else if (chaine(0,5) ==
"sinh(") {
1471 ctemp = chaine(4,lchain-4);
1472 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1478 }
else if (chaine(0,5) ==
"tanh(") {
1479 ctemp = chaine(4,lchain-4);
1480 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1486 }
else if (chaine(0,6) ==
"acosh(") {
1487 ctemp = chaine(5,lchain-5);
1488 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1494 }
else if (chaine(0,6) ==
"asinh(") {
1495 ctemp = chaine(5,lchain-5);
1496 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1502 }
else if (chaine(0,6) ==
"atanh(") {
1503 ctemp = chaine(5,lchain-5);
1504 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1510 }
else if (chaine(0,3) ==
"sq(") {
1511 ctemp = chaine(2,lchain-2);
1512 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1518 }
else if (chaine(0,4) ==
"log(") {
1519 ctemp = chaine(3,lchain-3);
1520 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1526 }
else if (chaine(0,6) ==
"log10(") {
1527 ctemp = chaine(5,lchain-5);
1528 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1534 }
else if (chaine(0,4) ==
"exp(") {
1535 ctemp = chaine(3,lchain-3);
1536 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1542 }
else if (chaine(0,4) ==
"abs(") {
1543 ctemp = chaine(3,lchain-3);
1544 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1550 }
else if (chaine(0,5) ==
"sign(") {
1551 ctemp = chaine(4,lchain-4);
1552 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1558 }
else if (chaine(0,4) ==
"int(") {
1559 ctemp = chaine(3,lchain-3);
1560 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1566 }
else if (chaine ==
"rndm" || chaine(0,5) ==
"rndm(") {
1571 }
else if (chaine(0,5) ==
"sqrt(") {
1572 ctemp = chaine(4,lchain-4);
1573 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
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;
1625 actionParam = offset;
1627 if (inter2 == 5+offset &&
fNpar < 3+offset)
fNpar = 3+offset;
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)==0 && (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;
1711 actionParam = offset;
1713 if (inter2 == 5+offset &&
fNpar < 5+offset)
fNpar = 5+offset;
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)==0 && (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;
1796 actionParam = offset;
1798 if (inter2 == 5+offset &&
fNpar < 5+offset)
fNpar = 5+offset;
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)==0 && (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)==0 && (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);
1921 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1923 ctemp = chaine(virgule,lchain-virgule-1);
1924 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
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);
1950 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1953 ctemp = chaine(virgule,lchain-virgule-1);
1954 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
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);
1982 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1984 ctemp = chaine(virgule,lchain-virgule-1);
1985 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
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);
2009 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
2011 ctemp = chaine(virgule,lchain-virgule-1);
2012 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
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);
2034 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
2036 ctemp = chaine(virgule,lchain-virgule-1);
2037 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
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);
2061 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
2063 ctemp = chaine(virgule,lchain-virgule-1);
2064 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
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)==0 && (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);
2446 if (err) {
fNdim = 0;
return 1; }
2450 if (!IsA()->GetBaseClass(
"TTreeFormula")) {
2498 while ( (fobj = next()) ) {
2623 if (chaine ==
"x") {
2626 }
else if (chaine ==
"y") {
2629 }
else if (chaine ==
"z") {
2632 }
else if (chaine ==
"t") {
2639 if (chaine.
Data()[0]==
'x'){
2640 if (chaine.
Data()[1]==
'[' && chaine.
Data()[3]==
']'){
2641 const char ch0 =
'0';
2643 if (dim<0)
return -1;
2644 if (dim>9)
return -1;
2648 if (chaine.
Data()[1]==
'[' && chaine.
Data()[4]==
']'){
2649 const char ch0 =
'0';
2650 Int_t dim = (chaine.
Data()[2]-ch0)*10+(chaine.
Data()[3]-ch0);
2651 if (dim<0)
return -1;
2652 if (dim>99)
return -1;
2674 return ((
TFormula*)
this)->EvalPar(xx);
2694 Int_t precalculated = 0;
2695 Int_t precalculated_str = 0;
2699 params =
const_cast<Double_t*
>(uparams);
2706 for (i=0; i<
fNoper; ++i) {
2708 const int oper =
fOper[i];
2716 case kStringConst: { strpos++; stringStack[strpos-1] = (
char*)
fExpr[i].Data(); pos++; tab[pos-1] = 0;
continue; }
2718 case kAdd : pos--; tab[pos-1] += tab[pos];
continue;
2719 case kSubstract : pos--; tab[pos-1] -= tab[pos];
continue;
2720 case kMultiply : pos--; tab[pos-1] *= tab[pos];
continue;
2721 case kDivide : pos--;
if (tab[pos] == 0) tab[pos-1] = 0;
2722 else tab[pos-1] /= tab[pos];
2747 case kacosh:
if (tab[pos-1] < 1) {tab[pos-1] = 0;}
2756 case kfmod : pos--; tab[pos-1] = fmod(tab[pos-1],tab[pos]);
continue;
2757 case kpow : pos--; tab[pos-1] =
TMath::Power(tab[pos-1],tab[pos]);
continue;
2758 case ksq : tab[pos-1] = tab[pos-1]*tab[pos-1];
continue;
2761 case kstrstr : strpos -= 2; pos-=2; pos++;
2762 if (strstr(stringStack[strpos],stringStack[strpos+1])) tab[pos-1]=1;
2766 case kmin : pos--; tab[pos-1] =
TMath::Min(tab[pos-1],tab[pos]);
continue;
2767 case kmax : pos--; tab[pos-1] =
TMath::Max(tab[pos-1],tab[pos]);
continue;
2769 case klog :
if (tab[pos-1] > 0) tab[pos-1] =
TMath::Log(tab[pos-1]);
2770 else {tab[pos-1] = 0;}
2773 if (dexp < -700) {tab[pos-1] = 0;
continue;}
2774 if (dexp > 700) {tab[pos-1] =
TMath::Exp(700);
continue;}
2777 else {tab[pos-1] = 0;}
2783 case ksign :
if (tab[pos-1] < 0) tab[pos-1] = -1;
else tab[pos-1] = 1;
continue;
2786 case kSignInv: tab[pos-1] = -1 * tab[pos-1];
continue;
2790 case kAnd : pos--;
if (tab[pos-1]!=0 && tab[pos]!=0) tab[pos-1]=1;
2793 case kOr : pos--;
if (tab[pos-1]!=0 || tab[pos]!=0) tab[pos-1]=1;
2796 case kEqual: pos--;
if (tab[pos-1] == tab[pos]) tab[pos-1]=1;
2799 case kNotEqual : pos--;
if (tab[pos-1] != tab[pos]) tab[pos-1]=1;
2802 case kLess : pos--;
if (tab[pos-1] < tab[pos]) tab[pos-1]=1;
2805 case kGreater : pos--;
if (tab[pos-1] > tab[pos]) tab[pos-1]=1;
2809 case kLessThan: pos--;
if (tab[pos-1]<=tab[pos]) tab[pos-1]=1;
2812 case kGreaterThan: pos--;
if (tab[pos-1]>=tab[pos]) tab[pos-1]=1;
2815 case kNot :
if (tab[pos-1]!=0) tab[pos-1] = 0;
else tab[pos-1] = 1;
2819 if (!strcmp(stringStack[strpos+1],stringStack[strpos])) tab[pos-1]=1;
2823 if (strcmp(stringStack[strpos+1],stringStack[strpos])) tab[pos-1]=1;
2827 case kBitAnd : pos--; tab[pos-1]= ((
Int_t) tab[pos-1]) & ((
Int_t) tab[pos]);
continue;
2828 case kBitOr : pos--; tab[pos-1]= ((
Int_t) tab[pos-1]) | ((
Int_t) tab[pos]);
continue;
2840 int op = param % 10;
2842 if (op == 1 && (!tab[pos-1]) ) {
2851 }
else if (op == 2 && tab[pos-1] ) {
2863 int toskip = param / 10;
2873 #define R__EXPO(var) \
2875 pos++; int param = (oper & kTFOperMask); \
2876 tab[pos-1] = TMath::Exp(params[param]+params[param+1]*x[var]); \
2884 tab[pos-1] =
TMath::Exp(params[param]+params[param+1]*
x[0]+params[param+2]*
x[1]);
2887 #define R__GAUS(var) \
2889 pos++; int param = (oper & kTFOperMask); \
2890 tab[pos-1] = params[param]*TMath::Gaus(x[var],params[param+1],params[param+2],IsNormalized()); \
2900 if (params[param+2] == 0) {
2903 intermede1=
Double_t((
x[0]-params[param+1])/params[param+2]);
2906 if (params[param+4] == 0) {
2909 intermede2=
Double_t((
x[1]-params[param+3])/params[param+4]);
2911 tab[pos-1] = params[param]*
TMath::Exp(-0.5*(intermede1*intermede1+intermede2*intermede2));
2914 #define R__LANDAU(var) \
2916 pos++; const int param = (oper & kTFOperMask); \
2917 tab[pos-1] = params[param]*TMath::Landau(x[var],params[param+1],params[param+2],IsNormalized()); \
2924 case kxylandau: { pos++;
int param = oper&0x7fffff ;
2927 tab[pos-1] = params[param]*intermede1*intermede2;
2931 #define R__POLY(var) \
2933 pos++; int param = (oper & kTFOperMask); \
2934 tab[pos-1] = 0; Double_t intermede = 1; \
2935 Int_t inter = param/100; \
2936 Int_t int1= param-inter*100-1; \
2937 for (j=0 ;j<inter+1;j++) { \
2938 tab[pos-1] += intermede*params[j+int1]; \
2939 intermede *= x[var]; \
2949 if (!precalculated) {
2953 pos++; tab[pos-1] = param_calc[(oper &
kTFOperMask)];
2959 if (!precalculated_str) {
2960 precalculated_str=1;
2963 strpos++; stringStack[strpos-1] = string_calc[param];
2964 pos++; tab[pos-1] = 0;
2972 int fno = param / 1000;
2973 int nargs = param % 1000;
2981 UInt_t argloc = pos-nargs;
2982 for(j=0;j<nargs;j++,argloc++,pos--) {
3031 Int_t ternaryend = -1;
3035 if (ternaryend==i) {
3037 if(ismulti[spos-1]){
3038 tab[spos-2]=tab[spos-2]+
"("+tab[spos-1]+
")";
3040 tab[spos-2]=tab[spos-2]+tab[spos-1];
3054 tab[spos-1]=
"-("+tab[spos-1]+
")";
3068 if ((optype<=151 && optype>=140 && optype!=145) || (optype == 40)) {
3076 if(((optype>0 && optype<6) || optype==20 ||
3077 (((optype>59 && optype<69) || (optype >75 && optype<82)) && spos>=2))) {
3079 if(ismulti[spos-2]){
3080 tab[spos-2]=
"("+tab[spos-2]+
")";
3082 if(ismulti[spos-1]){
3083 tab[spos-2]+=
fExpr[i]+(
"("+tab[spos-1]+
")");
3085 tab[spos-2]+=
fExpr[i]+tab[spos-1];
3087 ismulti[spos-2]=
kTRUE;
3093 if(ismulti[spos-1]){
3094 tab[spos-1]=
"("+tab[spos-1]+
")?";
3096 tab[spos-1]=tab[spos-1]+
"?";
3100 if (optype==
kJump) {
3101 if(ismulti[spos-1]){
3102 tab[spos-2]=tab[spos-2]+
"("+tab[spos-1]+
"):";
3104 tab[spos-2]=tab[spos-2]+tab[spos-1]+
":";
3114 if((optype>9 && optype<16) ||
3115 (optype>20 && optype<23) ||
3116 (optype>29 && optype<34) ||
3117 (optype>40 && optype<44) ||
3118 (optype>69 && optype<76) ||
3124 if((optype>15 && optype<20) ||
3125 (optype>22 && optype<26)) {
3132 int nargs = param % 1000;
3137 for(j=0, depth=0;j<funcname.
Length();++j) {
3138 switch (funcname[j]) {
3155 Error(
"GetExpFormula",
"Internal error, number of argument found is %d",-offset);
3156 }
else if (offset == 0) {
3157 tab[spos]=funcname+
"()";
3161 }
else if (offset<=0 && (spos+offset>=0)) {
3162 tab[spos+offset]=funcname+(
"("+tab[spos+offset]);
3163 for (j=offset+1; j<0; j++){
3164 tab[spos+offset]+=
","+tab[spos+j];
3166 tab[spos+offset]+=
")";
3167 ismulti[spos+offset]=
kFALSE;
3172 if (ternaryend==
fNoper) {
3174 if(ismulti[spos-1]){
3175 tab[spos-2]=tab[spos-2]+
"("+tab[spos-1]+
")";
3177 tab[spos-2]=tab[spos-2]+tab[spos-1];
3183 if (spos > 0) ret = tab[spos-1];
3193 for (j=0;j<
fNpar;j++) {
3223 if (ipar <0 || ipar >=
fNpar)
return 0;
3235 Error(
"TFormula",
"Parameter %s not found", parName);
3246 if (ipar <0 || ipar >=
fNpar)
return "";
3247 if (
fNames[ipar].Length() > 0)
return (
const char*)
fNames[ipar];
3248 return Form(
"p%d",ipar);
3260 if (!strcmp(
GetParName(i),parName))
return i;
3281 Printf(
" fExpr[%d] = %s action = %d action param = %d ",
3287 Printf(
"Optimized expression");
3289 Printf(
" fExpr[%d] = %s\t\t action = %d action param = %d ",
3296 for (i=0;i<
fNpar;i++) {
3310 Int_t nf, offset, replsize;
3312 pch= (
char*)strstr(formula.
Data(),
"++");
3314 formula.
Insert(0,
"[0]*(");
3315 pch= (
char*)strstr(formula.
Data(),
"++");
3321 offset = pch-formula.
Data();
3322 if (nf<10) replsize = 7;
3323 else if (nf<100) replsize = 8;
3325 formula.
Replace(pch-formula.
Data(), 2, repl, replsize);
3326 pch = (
char*)strstr(formula.
Data()+offset,
"++");
3332 formula2=formula2(4, formula2.
Length()-4);
3333 pch= (
char*)strchr(formula2.
Data(),
'[');
3337 offset = pch-formula2.
Data()-1;
3338 if (nf<10) replsize = 5;
3340 formula2.
Replace(pch-formula2.
Data()-1, replsize, repl, 2);
3341 pch = (
char*)strchr(formula2.
Data()+offset,
'[');
3349 formula2 = formula2.
ReplaceAll(
"++", 2,
"|", 1);
3352 for (
Int_t i=0; i<nf; i++) {
3354 replaceformula_name =
"f_linear_";
3355 replaceformula_name.
Append(replaceformula);
3358 Error(
"TFormula",
"f_linear not allocated");
3363 gROOT->GetListOfFunctions()->Remove(
f);
3377 if (ipar <0 || ipar >=
fNpar)
return;
3387 if (ipar <0 || ipar >=
fNpar)
return;
3433 if (ipar <0 || ipar >=
fNpar)
return;
3441 const char*name5,
const char*name6,
const char*name7,
const char*name8,
const char*name9,
const char*name10)
3461 if (
b.IsReading()) {
3465 Error(
"Streamer",
"version 6 is not supported");
3480 if (
b.IsReading()) {
3484 Error(
"Streamer",
"version 6 is not supported");
3505 gROOT->GetListOfFunctions()->Add(
this);
3518 Error(
"Streamer",
"error compiling formula");
3533 TNamed::Streamer(
b);
3553 if (
gROOT->GetListOfFunctions()->FindObject(
GetName()))
return;
3554 gROOT->GetListOfFunctions()->Add(
this);
3556 b.CheckByteCount(R__s, R__c, TFormula::IsA());
3571 kOldxylandau = 4500,
3572 kOldConstants = 50000,
3573 kOldStrings = 80000,
3574 kOldVariable = 100000,
3575 kOldTreeString = 105000,
3576 kOldFormulaVar = 110000,
3577 kOldBoolOptimize = 120000,
3578 kOldFunctionCall = 200000
3582 for (i=0,j=0; i<
fNoper; ++i,++j) {
3584 Int_t newActionCode = 0;
3585 Int_t newActionParam = 0;
3593 sscanf((
const char*)
fExpr[i],
"%g",&aresult);
3600 for (
int z=i; z<
fNoper; ++z) {
3604 }
else if ( action < 100 ) {
3607 newActionCode = action;
3609 }
else if (action >= kOldFunctionCall) {
3613 newActionParam = action-kOldFunctionCall;
3615 }
else if (action >= kOldBoolOptimize) {
3619 newActionParam = action-kOldBoolOptimize;
3621 }
else if (action >= kOldFormulaVar) {
3625 newActionParam = action-kOldFormulaVar;
3627 }
else if (action >= kOldTreeString) {
3631 newActionParam = action-kOldTreeString;
3633 }
else if (action >= kOldVariable) {
3637 newActionParam = action-kOldVariable;
3639 }
else if (action == kOldStrings) {
3644 }
else if (action >= kOldConstants) {
3648 newActionParam = action-kOldConstants;
3650 }
else if (action > 10000 && action < kOldConstants) {
3653 int var = action/10000;
3654 newActionCode =
kpol + (var-1);
3655 newActionParam = action - var*10000;
3657 }
else if (action >= 4600) {
3659 Error(
"Convert",
"Unsupported value %d",action);
3661 }
else if (action > kOldxylandau) {
3665 newActionParam = action - (kOldxylandau+1);
3667 }
else if (action > kOldlandau) {
3671 int var = action/100-40;
3672 if (var) newActionCode += var;
3673 newActionParam = action - var*100 - (kOldlandau+1);
3675 }
else if (action > 2500 && action < 2600) {
3679 newActionParam = action-2501;
3681 }
else if (action > 2000 && action < 2500) {
3684 newActionCode =
kgaus;
3685 int var = action/100-20;
3686 if (var) newActionCode += var;
3687 newActionParam = action - var*100 - (kOldgaus+1);
3689 }
else if (action > 1500 && action < 1600) {
3693 newActionParam = action-1501;
3695 }
else if (action > 1000 && action < 1500) {
3698 newActionCode =
kexpo;
3699 int var = action/100-10;
3700 if (var) newActionCode += var;
3701 newActionParam = action - var*100 - (kOldexpo+1);
3703 }
else if (action > 100 && action < 200) {
3707 newActionParam = action - 101;
3710 SetAction( j, newActionCode, newActionParam );
3749 int paran = cbase.
First(
"(");
3756 if (cbase==
"<") cbase=
"XlY";
3757 if (cbase==
"<=") cbase=
"XleY";
3758 if (cbase==
">") cbase=
"XgY";
3759 if (cbase==
">=") cbase=
"XgeY";
3766 if (prim->
fType==10) {
3769 if (prim->
fType==110) {
3772 if (prim->
fType==1110) {
3775 if (prim->
fType==-1) {
3778 if (prim->
fType==0){
3834 for (i=0; i<
fNoper; i++) {
3868 for (i=0;i<
fNoper;i++) optimized[i]=0;
3928 if ((i+1) >=
fNoper)
continue;
3955 if ((i+2) >=
fNoper)
continue;
3979 if (offset[0]==offset[2]&&offset[1]==offset[3]) {
3992 if ((i+3) >=
fNoper)
continue;
4025 if (offset[0]==offset[2]&&offset[1]==offset[3]&&offset[0]==offset[4]&&offset[1]==offset[5]){
4060 if (optimized[i]==0){
4107 delete [] optimized;
4118 case kData :
return result;
4197 Int_t precalculated = 0;
4198 Int_t precalculated_str = 0;
4204 params =
const_cast<Double_t*
>(uparams);
4224 case kAdd : pos--; tab[pos-1] += tab[pos];
continue;
4225 case kSubstract : pos--; tab[pos-1] -= tab[pos];
continue;
4226 case kMultiply : pos--; tab[pos-1] *= tab[pos];
continue;
4227 case kDivide : pos--;
if (tab[pos] == 0) tab[pos-1] = 0;
4228 else tab[pos-1] /= tab[pos];
4253 case kAnd : pos--; tab[pos-1] = (
bool)tab[pos];
continue;
4254 case kOr : pos--; tab[pos-1] = (
bool)tab[pos];
continue;
4258 case kabs :
if (tab[pos-1]<0) tab[pos-1]=-tab[pos-1];
continue;
4259 case ksign :
if (tab[pos-1] < 0) tab[pos-1] = -1;
else tab[pos-1] = 1;
continue;
4261 case kpow : pos--; tab[pos-1] =
TMath::Power(tab[pos-1],tab[pos]);
continue;
4271 case kfmod : pos--; tab[pos-1] = fmod(tab[pos-1],tab[pos]);
continue;
4273 case kstrstr : strpos -= 2; pos-=2; pos++;
4274 if (strstr(stringStack[strpos],stringStack[strpos+1])) tab[pos-1]=1;
4280 case kSignInv: tab[pos-1] = -1 * tab[pos-1];
continue;
4285 case kEqual: pos--;
if (tab[pos-1] == tab[pos]) tab[pos-1]=1;
4288 case kNotEqual : pos--;
if (tab[pos-1] != tab[pos]) tab[pos-1]=1;
4291 case kNot :
if (tab[pos-1]!=0) tab[pos-1] = 0;
else tab[pos-1] = 1;
4295 if (!strcmp(stringStack[strpos+1],stringStack[strpos])) tab[pos-1]=1;
4299 if (strcmp(stringStack[strpos+1],stringStack[strpos])) tab[pos-1]=1;
4303 case kBitAnd : pos--; tab[pos-1]= ((
Int_t) tab[pos-1]) & ((
Int_t) tab[pos]);
continue;
4304 case kBitOr : pos--; tab[pos-1]= ((
Int_t) tab[pos-1]) | ((
Int_t) tab[pos]);
continue;
4315 int op = param % 10;
4317 if (op == 1 && (!tab[pos-1]) ) {
4326 }
else if (op == 2 && tab[pos-1] ) {
4343#define R__EXPO(var) \
4345 pos++; int param = (oper & kTFOperMask); \
4346 tab[pos-1] = TMath::Exp(params[param]+params[param+1]*x[var]); \
4354 tab[pos-1] =
TMath::Exp(params[param]+params[param+1]*
x[0]+params[param+2]*
x[1]);
4359#define R__GAUS(var) \
4361 pos++; int param = (oper & kTFOperMask); \
4362 tab[pos-1] = params[param]*TMath::Gaus(x[var],params[param+1], \
4363 params[param+2],IsNormalized()); \
4373 if (params[param+2] == 0) {
4376 intermede1=
Double_t((
x[0]-params[param+1])/params[param+2]);
4379 if (params[param+4] == 0) {
4382 intermede2=
Double_t((
x[1]-params[param+3])/params[param+4]);
4384 tab[pos-1] = params[param]*
TMath::Exp(-0.5*(intermede1*intermede1+intermede2*intermede2));
4387#define R__LANDAU(var) \
4389 pos++; const int param = (oper & kTFOperMask); \
4390 tab[pos-1] = params[param]*TMath::Landau(x[var],params[param+1],params[param+2],IsNormalized()); \
4397 case kxylandau: { pos++;
int param = oper&0x7fffff ;
4400 tab[pos-1] = params[param]*intermede1*intermede2;
4404#define R__POLY(var) \
4406 pos++; int param = (oper & kTFOperMask); \
4407 tab[pos-1] = 0; Double_t intermede = 1; \
4408 Int_t inter = param/100; \
4409 Int_t int1= param-inter*100-1; \
4410 for (j=0 ;j<inter+1;j++) { \
4411 tab[pos-1] += intermede*params[j+int1]; \
4412 intermede *= x[var]; \
4422 if (!precalculated) {
4426 pos++; tab[pos-1] = param_calc[(oper &
kTFOperMask)];
4432 if (!precalculated_str) {
4433 precalculated_str=1;
4436 strpos++; stringStack[strpos-1] = string_calc[param];
4437 pos++; tab[pos-1] = 0;
4445 int fno = param / 1000;
4446 int nargs = param % 1000;
4454 UInt_t argloc = pos-nargs;
4455 for(j=0;j<nargs;j++,argloc++,pos--) {
4483 if (str.
Length()<3)
return 1;
4484 if (str[str.
Length()-1]!=
'+'&&str[str.
Length()-2]!=
'+')
return 1;
4486 TString funName(
"preformula_");
4490 fileName.
Form(
"/tmp/%s.C",funName.
Data());
4493 hf = fopen(fileName.
Data(),
"w");
4495 Error(
"PreCompile",
"Unable to open the file %s for writing.",fileName.
Data());
4498 fprintf(hf,
"/////////////////////////////////////////////////////////////////////////\n");
4499 fprintf(hf,
"// This code has been automatically generated \n");
4501 fprintf(hf,
"Double_t %s(Double_t *x, Double_t *p){",funName.
Data());
4502 fprintf(hf,
"return (%s);\n}",str.
Data());
R__EXTERN TVirtualMutex * gROOTMutex
R__EXTERN TRandom * gRandom
char * Form(const char *fmt,...)
void Printf(const char *fmt,...)
#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.
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.
Bool_t IsValid() const
Return true if the method call has been properly initialized and is usable.
void Execute(const char *, const char *, int *=0)
Execute method on this object with the given parameter string, e.g.
void SetParam(Long_t l)
Add a long method parameter.
The TNamed class is the base class for all named ROOT classes.
virtual void Copy(TObject &named) const
Copy this to obj.
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
virtual const char * GetTitle() const
Returns title of object.
virtual const char * GetName() const
Returns name of object.
virtual void Expand(Int_t newSize)
Expand or shrink the array to newSize elements.
TObject * UncheckedAt(Int_t i) const
virtual void Delete(Option_t *option="")
Remove all objects from the array AND delete all heap based objects.
Int_t GetLast() const
Return index of last object in array.
TObject * At(Int_t idx) const
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.
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 Double_t Rndm()
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)
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...
static constexpr double s
static constexpr double ns
Short_t Max(Short_t a, Short_t b)
Double_t Landau(Double_t x, Double_t mpv=0, Double_t sigma=1, Bool_t norm=kFALSE)
The LANDAU function.
Double_t ATan2(Double_t y, Double_t x)
Double_t Sqrt(Double_t x)
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Short_t Min(Short_t a, Short_t b)
Double_t Log10(Double_t x)