31#pragma optimize("",off)
187 if (!expression || !*expression) {
188 Error(
"TFormula",
"expression may not be 0 or have 0 length");
194 nch = strlen(expression);
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++;
222 Warning(
"TFormula",
"Cannot use both gaus and gausn - gaus will be treated as gausn");
224 Warning(
"TFormula",
"Cannot use both gausn and landau - landau will be treated as landaun");
233 Warning(
"TFormula",
"Cannot use both gaus and landaun - gaus will be treated as gausn");
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 ((
TFormula&)formula).TFormula::Copy(*
this);
318 gROOT->GetListOfFunctions()->Remove(
this);
355 if (argStart<0)
return false;
357 TString functionName = chaine(0,argStart);
363 if (scopeEnd>0 && functionName[scopeEnd-1]==
':') {
364 spaceName = functionName(0,scopeEnd-1);
365 functionName.
Remove(0,scopeEnd+1);
370 if (chaine[chaine.
Length()-1] !=
')') {
371 Error(
"AnalyzeFunction",
"We thought we had a function but we dont (in %s)\n",chaine.
Data());
374 TString args = chaine(argStart+1,chaine.
Length()-2-argStart);
384 for(i=0; i<args.
Length(); i++) {
385 if (args[i]==
'"') inString = !inString;
386 if (inString)
continue;
391 case '(': paran++;
break;
392 case ')': paran--;
break;
393 case '[': brack++;
break;
394 case ']': brack--;
break;
396 case ',':
if (paran==0 && brack==0) { foundArg =
true; }
break;
398 if ((i+1)==args.
Length()) {
399 foundArg =
true; i++;
402 TString arg = args(prevComma,i-prevComma);
423 ClassInfo_t *cinfo = 0;
432 static TypeInfo_t *
const doubletype {
gInterpreter->TypeInfo_Factory(
"double") };
434 std::vector<TypeInfo_t*>
proto(nargs,doubletype);
436 CallFunc_t *callfunc =
gInterpreter->CallFunc_Factory();
483 if (prim && (!IsA()->GetBaseClass(
"TTreeFormula"))) {
492 Error(
"Compile",
"%s requires %d arguments",
497 if (prim->
fType==10){
500 if (prim->
fType==110){
503 if (prim->
fType==1110){
506 if (prim->
fType==-1){
717 Int_t valeur,find,
n,i,j,k,lchain,nomb,virgule,inter,nest;
718 valeur=find=
n=i=j=k=lchain=nomb=virgule=inter=nest = 0;
719 Int_t compt,compt2,compt3,compt4;
724 TString s,chaine_error,chaine1ST;
729 Int_t modulo,plus,puiss10,puiss10bis,moins,multi,divi,puiss,et,ou,petit,grand,egal,diff,peteg,grdeg,etx,oux,rshift,lshift,tercond,terelse;
734 Int_t actionCode,actionParam;
742 while (parenthese && lchain>0 && err==0){
747 if (lchain==0) err=4;
749 for (i=1; i<=lchain; ++i) {
750 if (chaine(i-1,1) ==
"\"") inString = !inString;
752 if (chaine(i-1,1) ==
"[") compt2++;
753 if (chaine(i-1,1) ==
"]") compt2--;
754 if (chaine(i-1,1) ==
"(") compt++;
755 if (chaine(i-1,1) ==
")") compt--;
757 if (compt < 0) err = 40;
758 if (compt2< 0) err = 42;
759 if (compt==0 && (i!=lchain || lchain==1)) parenthese =
kFALSE;
762 if (compt > 0) err = 41;
763 if (compt2> 0) err = 43;
764 if (parenthese) chaine = chaine(1,lchain-2);
768 if (lchain==0) err=4;
769 modulo=plus=moins=multi=divi=puiss=et=ou=petit=grand=egal=diff=peteg=grdeg=etx=oux=rshift=lshift=tercond=terelse=0;
774 compt = compt2 = compt3 = compt4 = 0;puiss10=0;puiss10bis = 0;
779 for (i=1;i<=lchain; i++) {
781 puiss10=puiss10bis=0;
784 isdecimal = isdecimal && (strchr(
"0123456789.",t)!=0);
786 if ( chaine[i-2] ==
'e' || chaine[i-2] ==
'E' ) puiss10 = 1;
787 }
else if ( strchr(
"+-/[]()&|><=!*/%^\\",t) ) {
792 if (chaine[j-2] ==
'e' || chaine[j-2] ==
'E') {
793 Bool_t isrightdecimal = 1;
795 for(k=j-3; k>=0 && isrightdecimal; --k) {
797 isrightdecimal = isrightdecimal && (strchr(
"0123456789.",t)!=0);
798 if (!isrightdecimal) {
799 if (strchr(
"+-/[]()&|><=!*/%^\\",t)!=0) {
804 if (k<0 && isrightdecimal) puiss10bis = 1;
807 if (puiss10 && (i<=lchain)) {
809 puiss10 = (strchr(
"0123456789.",t)!=0);
811 if (puiss10bis && (j<=lchain)) {
813 puiss10bis = (strchr(
"0123456789.",t)!=0);
816 if (chaine(i-1,1) ==
"\"") inString = !inString;
817 if (inString)
continue;
818 if (chaine(i-1,1) ==
"[") compt2++;
819 if (chaine(i-1,1) ==
"]") compt2--;
820 if (chaine(i-1,1) ==
"(") compt++;
821 if (chaine(i-1,1) ==
")") compt--;
822 if (chaine(j-1,1) ==
"[") compt3++;
823 if (chaine(j-1,1) ==
"]") compt3--;
824 if (chaine(j-1,1) ==
"(") compt4++;
825 if (chaine(j-1,1) ==
")") compt4--;
826 if (chaine(i-1,2)==
"&&" && !inString && compt==0 && compt2==0 && et==0) {et=i;puiss=0;}
827 if (chaine(i-1,2)==
"||" && compt==0 && compt2==0 && ou==0) {puiss10=0; ou=i;}
828 if (chaine(i-1,1)==
"&" && compt==0 && compt2==0 && etx==0) {etx=i;puiss=0;}
829 if (chaine(i-1,1)==
"|" && compt==0 && compt2==0 && oux==0) {puiss10=0; oux=i;}
830 if (chaine(i-1,2)==
">>" && compt==0 && compt2==0 && rshift==0) {puiss10=0; rshift=i;}
831 if (chaine(i-1,1)==
">" && compt==0 && compt2==0 && rshift==0 && grand==0)
832 {puiss10=0; grand=i;}
833 if (chaine(i-1,2)==
"<<" && compt==0 && compt2==0 && lshift==0) {puiss10=0; lshift=i;}
834 if (chaine(i-1,1)==
"<" && compt==0 && compt2==0 && lshift==0 && petit==0)
838 for(
int ip = i,depth=0; ip < lchain; ++ip) {
842 if (isalnum(
c) ||
c==
'_' ||
c==
',')
continue;
843 if (
c==
':' && chaine(ip+1)==
':') { ++ip;
continue; }
844 if (
c==
'<') { ++depth;
continue; }
846 if (depth) { --depth;
continue; }
862 if ((chaine(i-1,2)==
"<=" || chaine(i-1,2)==
"=<") && compt==0 && compt2==0
863 && peteg==0) {peteg=i; puiss10=0; petit=0;}
864 if ((chaine(i-1,2)==
"=>" || chaine(i-1,2)==
">=") && compt==0 && compt2==0
865 && grdeg==0) {puiss10=0; grdeg=i; grand=0;}
866 if (chaine(i-1,2) ==
"==" && compt == 0 && compt2 == 0 && egal == 0) {puiss10=0; egal=i;}
867 if (chaine(i-1,2) ==
"!=" && compt == 0 && compt2 == 0 && diff == 0) {puiss10=0; diff=i;}
868 if (i>1 && chaine(i-1,1) ==
"+" && compt == 0 && compt2 == 0 && puiss10==0) plus=i;
869 if (chaine(j-1,1) ==
"-" && chaine(j-2,1) !=
"*" && chaine(j-2,1) !=
"/"
870 && chaine(j-2,1)!=
"^" && compt3==0 && compt4==0 && moins==0 && puiss10bis==0) moins=j;
871 if (chaine(i-1,1)==
"%" && compt==0 && compt2==0 && modulo==0) {puiss10=0; modulo=i;}
872 if (chaine(i-1,1)==
"*" && compt==0 && compt2==0 && multi==0) {puiss10=0; multi=i;}
873 if (chaine(j-1,1)==
"/" && chaine(j-2,1)!=
"\\"
874 && compt4==0 && compt3==0 && divi==0)
878 if (chaine(j-1)==
'^' && compt4==0 && compt3==0 && puiss==0) {puiss10=0; puiss=j;}
879 if (chaine(i-1)==
'?' && compt == 0 && compt2 == 0 && tercond == 0) {puiss10=0; tercond=i;}
880 if (chaine(i-1)==
':' && tercond && compt == 0 && compt2 == 0 && terelse == 0) {
881 if (i>2 && chaine(i-2)!=
':' && chaine(i)!=
':') {
882 puiss10=0; terelse=i;
892 if (tercond && terelse) {
893 if (tercond == 1 || terelse == lchain || tercond == (terelse-1) ) {
898 ctemp = chaine(0,tercond-1);
908 ctemp = chaine(tercond,terelse-tercond-1);
911 SetAction(optloc, actionCode, actionParam);
921 ctemp = chaine(terelse,lchain-terelse);
925 SetAction(optloc, actionCode, actionParam);
932 }
else if (ou != 0) {
933 if (ou==1 || ou==lchain-1) {
938 ctemp = chaine(0,ou-1);
947 ctemp = chaine(ou+1,lchain-ou-1);
958 if (et==1 || et==lchain-1) {
963 ctemp = chaine(0,et-1);
973 ctemp = chaine(et+1,lchain-et-1);
984 if (oux==1 || oux==lchain) {
989 ctemp = chaine(0,oux-1);
992 ctemp = chaine(oux,lchain-oux);
1000 }
else if (etx!=0) {
1001 if (etx==1 || etx==lchain) {
1006 ctemp = chaine(0,etx-1);
1007 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1009 ctemp = chaine(etx,lchain-etx);
1010 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1017 }
else if (petit != 0) {
1018 if (petit==1 || petit==lchain) {
1023 ctemp = chaine(0,petit-1);
1024 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1026 ctemp = chaine(petit,lchain-petit);
1027 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1034 }
else if (grand != 0) {
1035 if (grand==1 || grand==lchain) {
1040 ctemp = chaine(0,grand-1);
1041 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1043 ctemp = chaine(grand,lchain-grand);
1044 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1051 }
else if (peteg != 0) {
1052 if (peteg==1 || peteg==lchain-1) {
1057 ctemp = chaine(0,peteg-1);
1058 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1059 ctemp = chaine(peteg+1,lchain-peteg-1);
1061 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1068 }
else if (grdeg != 0) {
1069 if (grdeg==1 || grdeg==lchain-1) {
1074 ctemp = chaine(0,grdeg-1);
1075 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1077 ctemp = chaine(grdeg+1,lchain-grdeg-1);
1078 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1085 }
else if (egal != 0) {
1086 if (egal==1 || egal==lchain-1) {
1091 ctemp = chaine(0,egal-1);
1092 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1095 ctemp = chaine(egal+1,lchain-egal-1);
1096 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1101 if (
IsString(optloc) != isstring) {
1103 chaine_error =
"==";
1104 }
else if (isstring) {
1110 }
else if (diff != 0) {
1111 if (diff==1 || diff==lchain-1) {
1113 chaine_error =
"!=";
1116 ctemp = chaine(0,diff-1);
1117 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1120 ctemp = chaine(diff+1,lchain-diff-1);
1121 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1126 if (
IsString(optloc) != isstring) {
1128 chaine_error =
"!=";
1129 }
else if (isstring) {
1135 }
else if (plus != 0) {
1141 ctemp = chaine(0,plus-1);
1142 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1144 ctemp = chaine(plus,lchain-plus);
1145 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1155 ctemp = chaine(moins,lchain-moins);
1156 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1163 if (moins == lchain) {
1167 ctemp = chaine(0,moins-1);
1168 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1170 ctemp = chaine(moins,lchain-moins);
1171 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1179 }
else if (modulo != 0) {
1180 if (modulo == 1 || modulo == lchain) {
1184 ctemp = chaine(0,modulo-1);
1185 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1187 ctemp = chaine(modulo,lchain-modulo);
1188 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1195 }
else if (rshift != 0) {
1196 if (rshift == 1 || rshift == lchain) {
1200 ctemp = chaine(0,rshift-1);
1201 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1203 ctemp = chaine(rshift+1,lchain-rshift-1);
1204 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1211 }
else if (lshift != 0) {
1212 if (lshift == 1 || lshift == lchain) {
1216 ctemp = chaine(0,lshift-1);
1217 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1219 ctemp = chaine(lshift+1,lchain-lshift-1);
1220 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1229 if (multi == 1 || multi == lchain) {
1234 ctemp = chaine(0,multi-1);
1235 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1237 ctemp = chaine(multi,lchain-multi);
1238 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1247 if (divi == 1 || divi == lchain) {
1252 ctemp = chaine(0,divi-1);
1253 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1255 ctemp = chaine(divi,lchain-divi);
1256 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1265 if (puiss == 1 || puiss == lchain) {
1267 chaine_error =
"**";
1270 if (chaine(lchain-2,2) ==
"^2") {
1271 ctemp =
"sq(" + chaine(0,lchain-2) +
")";
1272 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1274 ctemp = chaine(0,puiss-1);
1275 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1277 ctemp = chaine(puiss,lchain-puiss);
1278 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1295 if ((chaine(0,2)==
"0x")||(chaine(0,2)==
"0X")) isHexa=
kTRUE;
1296 for (j=0; j<chaine.
Length() && err==0; j++) {
1299 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-")) {
1302 chaine_error=chaine;
1309 if (chaine(j,2)==
"e+" || chaine(j,2)==
"e-" || chaine(j,2)==
"E+" || chaine(j,2)==
"E-") j++;
1312 if (chaine(j,1) ==
"." && !hasDot) hasDot =
kTRUE;
1317 if (!strchr(
"0123456789",t) && (chaine(j,1)!=
"+" || j!=0)) {
1319 chaine_error=chaine;
1325 if (!strchr(
"0123456789abcdefABCDEF",t) && (j>1)) {
1327 chaine_error=chaine;
1333 if (!isHexa) {
if (sscanf((
const char*)chaine,
"%lg",&vafConst) > 0) err = 0;
else err =1;}
1334 else {
if (sscanf((
const char*)chaine,
"%lx",&vafConst2) > 0) err = 0;
else err=1;
1339 if (vafConst ==
fConst[j] ) k= j;
1358 if (oldformula && strcmp(schain,oldformula->
GetTitle())) {
1369 for (
Int_t ipar=0;ipar<npold;ipar++) {
1389 chaine_error = ctemp;
1390 }
else if ( k >= 0 ) {
1392 actionCode = action;
1401 }
else if (chaine(0,1) ==
"!") {
1402 ctemp = chaine(1,lchain-1);
1403 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1409 }
else if (chaine(0,1)==
"\"" && chaine(chaine.
Length()-1,1)==
"\"") {
1415 }
else if (chaine(0,4) ==
"cos(") {
1416 ctemp = chaine(3,lchain-3);
1417 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1423 }
else if (chaine(0,4) ==
"sin(") {
1424 ctemp = chaine(3,lchain-3);
1425 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1431 }
else if (chaine(0,4) ==
"tan(") {
1432 ctemp = chaine(3,lchain-3);
1433 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1439 }
else if (chaine(0,5) ==
"acos(") {
1440 ctemp = chaine(4,lchain-4);
1441 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1447 }
else if (chaine(0,5) ==
"asin(") {
1448 ctemp = chaine(4,lchain-4);
1449 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1455 }
else if (chaine(0,5) ==
"atan(") {
1456 ctemp = chaine(4,lchain-4);
1457 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1463 }
else if (chaine(0,5) ==
"cosh(") {
1464 ctemp = chaine(4,lchain-4);
1465 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1471 }
else if (chaine(0,5) ==
"sinh(") {
1472 ctemp = chaine(4,lchain-4);
1473 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1479 }
else if (chaine(0,5) ==
"tanh(") {
1480 ctemp = chaine(4,lchain-4);
1481 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1487 }
else if (chaine(0,6) ==
"acosh(") {
1488 ctemp = chaine(5,lchain-5);
1489 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1495 }
else if (chaine(0,6) ==
"asinh(") {
1496 ctemp = chaine(5,lchain-5);
1497 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1503 }
else if (chaine(0,6) ==
"atanh(") {
1504 ctemp = chaine(5,lchain-5);
1505 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1511 }
else if (chaine(0,3) ==
"sq(") {
1512 ctemp = chaine(2,lchain-2);
1513 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1519 }
else if (chaine(0,4) ==
"log(") {
1520 ctemp = chaine(3,lchain-3);
1521 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1527 }
else if (chaine(0,6) ==
"log10(") {
1528 ctemp = chaine(5,lchain-5);
1529 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1535 }
else if (chaine(0,4) ==
"exp(") {
1536 ctemp = chaine(3,lchain-3);
1537 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1543 }
else if (chaine(0,4) ==
"abs(") {
1544 ctemp = chaine(3,lchain-3);
1545 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1551 }
else if (chaine(0,5) ==
"sign(") {
1552 ctemp = chaine(4,lchain-4);
1553 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1559 }
else if (chaine(0,4) ==
"int(") {
1560 ctemp = chaine(3,lchain-3);
1561 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1567 }
else if (chaine ==
"rndm" || chaine(0,5) ==
"rndm(") {
1572 }
else if (chaine(0,5) ==
"sqrt(") {
1573 ctemp = chaine(4,lchain-4);
1574 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1583 }
else if ( chaine ==
"expo" || chaine(0,5)==
"expo("
1584 || (lchain==5 && chaine(1,4)==
"expo")
1585 || (lchain==6 && chaine(2,4)==
"expo")
1586 || chaine(1,5)==
"expo(" || chaine(2,5)==
"expo(" ) {
1588 if (chaine(1,4) ==
"expo") {
1593 else if (ctemp==
"y") {
1596 else if (ctemp==
"z") {
1599 else if (ctemp==
"t") {
1604 chaine_error=chaine1ST;
1606 chaine=chaine(1,lchain-1);
1609 if (chaine(2,4) ==
"expo") {
1610 if (chaine(0,2) !=
"xy") {
1612 chaine_error=chaine1ST;
1617 chaine=chaine(2,lchain-2);
1625 actionCode =
kexpo + inter2;
1626 actionParam = offset;
1628 if (inter2 == 5+offset &&
fNpar < 3+offset)
fNpar = 3+offset;
1637 }
else if (chaine(4,1) ==
"(") {
1638 ctemp = chaine(5,lchain-6);
1640 for (j=0; j<ctemp.
Length(); j++) {
1642 if (strchr(
"0123456789",t)==0 && (ctemp(j,1)!=
"+" || j!=0)) {
1644 chaine_error=chaine1ST;
1648 sscanf(ctemp.
Data(),
"%d",&inter);
1651 actionCode =
kexpo + inter2;
1652 actionParam = inter;
1654 if (inter2 == 5) inter++;
1663 chaine_error=chaine;
1668 }
else if (chaine==
"gaus"
1669 || (lchain==5 && chaine(1,4)==
"gaus")
1670 || (lchain==6 && chaine(2,4)==
"gaus")
1671 || chaine(0,5)==
"gaus(" || chaine(1,5)==
"gaus(" || chaine(2,5)==
"gaus(") {
1673 if (chaine(1,4) ==
"gaus") {
1678 else if (ctemp==
"y") {
1681 else if (ctemp==
"z") {
1684 else if (ctemp==
"t") {
1689 chaine_error=chaine1ST;
1691 chaine=chaine(1,lchain-1);
1694 if (chaine(2,4) ==
"gaus") {
1695 if (chaine(0,2) !=
"xy") {
1697 chaine_error=chaine1ST;
1702 chaine=chaine(2,lchain-2);
1707 if (lchain == 4 && err==0) {
1711 actionCode =
kgaus + inter2;
1712 actionParam = offset;
1714 if (inter2 == 5+offset &&
fNpar < 5+offset)
fNpar = 5+offset;
1723 }
else if (chaine(4,1) ==
"(" && err==0) {
1724 ctemp = chaine(5,lchain-6);
1726 for (j=0; j<ctemp.
Length(); j++) {
1728 if (strchr(
"0123456789",t)==0 && (ctemp(j,1)!=
"+" || j!=0)) {
1730 chaine_error=chaine1ST;
1734 sscanf(ctemp.
Data(),
"%d",&inter);
1737 actionCode =
kgaus + inter2;
1738 actionParam = inter;
1740 if (inter2 == 5) inter += 2;
1747 }
else if (err==0) {
1749 chaine_error=chaine1ST;
1754 }
else if (chaine==
"landau" || (lchain==7 && chaine(1,6)==
"landau")
1755 || (lchain==8 && chaine(2,6)==
"landau")
1756 || chaine(0,7)==
"landau(" || chaine(1,7)==
"landau(" || chaine(2,7)==
"landau(") {
1758 if (chaine(1,6) ==
"landau") {
1763 else if (ctemp==
"y") {
1766 else if (ctemp==
"z") {
1769 else if (ctemp==
"t") {
1774 chaine_error=chaine1ST;
1776 chaine=chaine(1,lchain-1);
1779 if (chaine(2,6) ==
"landau") {
1780 if (chaine(0,2) !=
"xy") {
1782 chaine_error=chaine1ST;
1787 chaine=chaine(2,lchain-2);
1792 if (lchain == 6 && err==0) {
1796 actionCode =
klandau + inter2;
1797 actionParam = offset;
1799 if (inter2 == 5+offset &&
fNpar < 5+offset)
fNpar = 5+offset;
1808 }
else if (chaine(6,1) ==
"(" && err==0) {
1809 ctemp = chaine(7,lchain-8);
1811 for (j=0; j<ctemp.
Length(); j++) {
1813 if (strchr(
"0123456789",t)==0 && (ctemp(j,1)!=
"+" || j!=0)) {
1815 chaine_error=chaine1ST;
1819 sscanf(ctemp.
Data(),
"%d",&inter);
1822 actionCode =
klandau + inter2;
1823 actionParam = inter;
1825 if (inter2 == 5) inter += 2;
1832 }
else if (err==0) {
1834 chaine_error=chaine1ST;
1839 }
else if (chaine(0,3) ==
"pol" || chaine(1,3) ==
"pol") {
1841 if (chaine(1,3) ==
"pol") {
1846 else if (ctemp==
"y") {
1849 else if (ctemp==
"z") {
1852 else if (ctemp==
"t") {
1857 chaine_error=chaine1ST;
1859 chaine=chaine(1,lchain-1);
1862 if (chaine(lchain-1,1) ==
")") {
1864 for (j=3;j<lchain;j++)
if (chaine(j,1)==
"(" && nomb == 0) nomb = j;
1865 if (nomb == 3) err = 23;
1866 if (nomb == 0) err = 40;
1867 ctemp = chaine(nomb+1,lchain-nomb-2);
1868 for (j=0; j<ctemp.
Length(); j++) {
1870 if (strchr(
"0123456789",t)==0 && (ctemp(j,1)!=
"+" || j!=0)) {
1872 chaine_error=chaine1ST;
1876 sscanf(ctemp.
Data(),
"%d",&inter);
1877 if (inter < 0) err = 20;
1886 ctemp = chaine(3,nomb-3);
1887 if (sscanf(ctemp.
Data(),
"%d",&
n) > 0) {
1888 if (
n < 0 ) err = 24;
1889 if (
n >= 20) err = 25;
1894 actionCode =
kpol+(inter2-1);
1895 actionParam =
n*100+inter+2;
1908 }
else if (chaine(0,4) ==
"pow(") {
1909 compt = 4; nomb = 0; virgule = 0; nest=0;
1910 while(compt != lchain) {
1912 if (chaine(compt-1,1) ==
"(") nest++;
1913 else if (chaine(compt-1,1) ==
")") nest--;
1914 else if (chaine(compt-1,1) ==
"," && nest==0) {
1916 if (nomb == 1 && virgule == 0) virgule = compt;
1919 if (nomb != 1) err = 22;
1921 ctemp = chaine(4,virgule-5);
1922 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1924 ctemp = chaine(virgule,lchain-virgule-1);
1925 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1932 }
else if (chaine(0,7) ==
"strstr(") {
1933 compt = 7; nomb = 0; virgule = 0; nest=0;
1935 while(compt != lchain) {
1937 if (chaine(compt-1,1) ==
"\"") {
1938 inString = !inString;
1939 }
else if (!inString) {
1940 if (chaine(compt-1,1) ==
"(") nest++;
1941 else if (chaine(compt-1,1) ==
")") nest--;
1942 else if (chaine(compt-1,1) ==
"," && nest==0) {
1944 if (nomb == 1 && virgule == 0) virgule = compt;
1948 if (nomb != 1) err = 28;
1950 ctemp = chaine(7,virgule-8);
1951 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1954 ctemp = chaine(virgule,lchain-virgule-1);
1955 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1963 chaine_error =
"strstr";
1966 }
else if (chaine(0,4) ==
"min(") {
1967 compt = 4; nomb = 0; virgule = 0; nest=0;
1968 while(compt != lchain) {
1970 if (chaine(compt-1,1) ==
"(") nest++;
1971 else if (chaine(compt-1,1) ==
")") nest--;
1972 else if (chaine(compt-1,1) ==
"," && nest==0) {
1974 if (nomb == 1 && virgule == 0) virgule = compt;
1982 ctemp = chaine(4,virgule-5);
1983 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1985 ctemp = chaine(virgule,lchain-virgule-1);
1986 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1993 }
else if (chaine(0,4) ==
"max(") {
1994 compt = 4; nomb = 0; virgule = 0; nest=0;
1995 while(compt != lchain) {
1997 if (chaine(compt-1,1) ==
"(") nest++;
1998 else if (chaine(compt-1,1) ==
")") nest--;
1999 else if (chaine(compt-1,1) ==
"," && nest==0) {
2001 if (nomb == 1 && virgule == 0) virgule = compt;
2009 ctemp = chaine(4,virgule-5);
2010 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
2012 ctemp = chaine(virgule,lchain-virgule-1);
2013 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
2021 }
else if (chaine(0,6) ==
"atan2(") {
2022 compt = 6; nomb = 0; virgule = 0; nest=0;
2023 while(compt != lchain) {
2025 if (chaine(compt-1,1) ==
"(") nest++;
2026 else if (chaine(compt-1,1) ==
")") nest--;
2027 else if (chaine(compt-1,1) ==
"," && nest==0) {
2029 if (nomb == 1 && virgule == 0) virgule = compt;
2032 if (nomb != 1) err = 21;
2034 ctemp = chaine(6,virgule-7);
2035 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
2037 ctemp = chaine(virgule,lchain-virgule-1);
2038 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
2045 }
else if (chaine(0,5) ==
"fmod(") {
2046 compt = 5; nomb = 0; virgule = 0; nest=0;
2047 while(compt != lchain) {
2049 if (chaine(compt-1,1) ==
"(") nest++;
2050 else if (chaine(compt-1,1) ==
")") nest--;
2051 else if (chaine(compt-1,1) ==
"," && nest==0) {
2053 if (nomb == 1 && virgule == 0) virgule = compt;
2061 ctemp = chaine(5,virgule-6);
2062 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
2064 ctemp = chaine(virgule,lchain-virgule-1);
2065 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
2074 chaine_error = chaine;
2080 }
else if (chaine(0,1) ==
"[" && chaine(lchain-1,1) ==
"]") {
2083 ctemp = chaine(1,lchain-2);
2084 for (j=0; j<ctemp.
Length(); j++) {
2086 if (strchr(
"0123456789",t)==0 && (ctemp(j,1)!=
"+" || j!=0)) {
2088 chaine_error=chaine1ST;
2092 sscanf(ctemp.
Data(),
"%d",&valeur);
2094 actionParam = offset + valeur;
2099 }
else if (chaine ==
"pi") {
2126 chaine_error =
"\""+chaine_error+
"\"";
2128 case 2 : er =
" Invalid Floating Point Operation";
break;
2129 case 4 : er =
" Empty String";
break;
2130 case 5 : er =
" Invalid Syntax " + chaine_error;
break;
2131 case 6 : er =
" Too many operators !";
break;
2132 case 7 : er =
" Too many parameters !";
break;
2133 case 10 : er =
" z specified but not x and y";
break;
2134 case 11 : er =
" z and y specified but not x";
break;
2135 case 12 : er =
" y specified but not x";
break;
2136 case 13 : er =
" z and x specified but not y";
break;
2137 case 20 : er =
" Non integer value for parameter number : " + chaine_error;
break;
2138 case 21 : er =
" ATAN2 requires two arguments";
break;
2139 case 22 : er =
" POW requires two arguments";
break;
2140 case 23 : er =
" Degree of polynomial not specified";
break;
2141 case 24 : er =
" Degree of polynomial must be positive";
break;
2142 case 25 : er =
" Degree of polynomial must be less than 20";
break;
2143 case 26 : er =
" Unknown name : " + chaine_error;
break;
2144 case 27 : er =
" Too many constants in expression";
break;
2145 case 28 : er =
" strstr requires two arguments";
break;
2146 case 29 : er =
" TFormula can only call interpreted and compiled functions that return a numerical type: " + chaine_error;
break;
2147 case 30 : er =
" Bad numerical expression : " + chaine_error;
break;
2148 case 31 : er =
" Part of the Variable " + chaine_error; er +=
" exists but some of it is not accessible or useable";
break;
2149 case 40 : er =
" '(' is expected";
break;
2150 case 41 : er =
" ')' is expected";
break;
2151 case 42 : er =
" '[' is expected";
break;
2152 case 43 : er =
" ']' is expected";
break;
2153 case 44 : er =
" The function '" + chaine(0,err_hint) +
"' requires two arguments.";
break;
2154 case 45 : er =
"The operator " + chaine_error +
" requires a numerical operand.";
break;
2155 case 46 : er =
"Both operands of the operator " + chaine_error +
" have to be either numbers or strings.";
break;
2156 case 47 : er = chaine_error +
" requires 2 string arguments";
break;
2171 Error(
"Compile",
"\"%s\" requires a numerical operand.",
fExpr[oper].Data());
2191 Error(
"Compile",
"\"%s\" requires two numerical operands.",
fExpr[oper].Data());
2253 inline static void ResizeArrayIfAllocated(T*& oldArray,
int newSize){
2256 if (!oldArray || newSize <=0)
return;
2258 T* newArray =
new T[newSize];
2259 std::copy(oldArray, oldArray+newSize, newArray);
2261 oldArray = newArray;
2294 Int_t i,j,lc,valeur,err;
2300 if (strlen(expression))
SetTitle(expression);
2305 char *sctemp =
new char[chaine.
Length()+1];
2306 strlcpy(sctemp,chaine.
Data(),chaine.
Length()+1);
2307 char *semicol = (
char*)strstr(sctemp,
";");
2308 if (semicol) *semicol = 0;
2328 for (i=0; i<
gMAXOP; i++) {
2337 for (i=1; i<=chaine.
Length(); i++) {
2339 if (chaine(i-1,1) ==
"\"") inString = !inString;
2340 if (inString)
continue;
2341 if (chaine(i-1,2) ==
"**") {
2342 chaine = chaine(0,i-1) +
"^" + chaine(i+1,lc-i-1);
2344 }
else if (chaine(i-1,2) ==
"++") {
2345 chaine = chaine(0,i) + chaine(i+1,lc-i-1);
2347 }
else if (chaine(i-1,2) ==
"+-" || chaine(i-1,2) ==
"-+") {
2348 chaine = chaine(0,i-1) +
"-" + chaine(i+1,lc-i-1);
2350 }
else if (chaine(i-1,2) ==
"--") {
2351 chaine = chaine(0,i-1) +
"+" + chaine(i+1,lc-i-1);
2353 }
else if (chaine(i-1,2) ==
"->") {
2354 chaine = chaine(0,i-1) +
"." + chaine(i+1,lc-i-1);
2356 }
else if (chaine(i-1,1) ==
"[") {
2357 for (j=1;j<=chaine.
Length()-i;j++) {
2358 if (chaine(j+i-1,1) ==
"]" || j+i > chaine.
Length())
break;
2360 ctemp = chaine(i,j-1);
2362 sscanf(ctemp.
Data(),
"%d",&valeur);
2364 }
else if (chaine(i-1,1) ==
" ") {
2365 chaine = chaine(0,i-1)+chaine(i,lc-i);
2370 Analyze((
const char*)chaine,err);
2447 if (err) {
fNdim = 0;
return 1; }
2451 if (!IsA()->GetBaseClass(
"TTreeFormula")) {
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+
"()";
3162 }
else if (offset<=0 && (spos+offset>=0)) {
3163 tab[spos+offset]=funcname+(
"("+tab[spos+offset]);
3164 for (j=offset+1; j<0; j++){
3165 tab[spos+offset]+=
","+tab[spos+j];
3167 tab[spos+offset]+=
")";
3168 ismulti[spos+offset]=
kFALSE;
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++) {
3311 Int_t nf, offset, replsize;
3313 pch= (
char*)strstr(formula.
Data(),
"++");
3315 formula.
Insert(0,
"[0]*(");
3316 pch= (
char*)strstr(formula.
Data(),
"++");
3322 offset = pch-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(),
'[');
3338 offset = pch-formula2.
Data()-1;
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");
3472 b.WriteClassBuffer(TFormula::Class(),
this);
3481 if (
b.IsReading()) {
3485 Error(
"Streamer",
"version 6 is not supported");
3491 b.WriteClassBuffer(TFormula::Class(),
this);
3503 b.ReadClassBuffer(TFormula::Class(),
this,
v, R__s, R__c, onfile_class);
3506 gROOT->GetListOfFunctions()->Add(
this);
3519 Error(
"Streamer",
"error compiling formula");
3534 TNamed::Streamer(
b);
3554 if (
gROOT->GetListOfFunctions()->FindObject(
GetName()))
return;
3555 gROOT->GetListOfFunctions()->Add(
this);
3557 b.CheckByteCount(R__s, R__c, TFormula::IsA());
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;
3980 if (offset[0]==offset[2]&&offset[1]==offset[3]) {
3993 if ((i+3) >=
fNoper)
continue;
4026 if (offset[0]==offset[2]&&offset[1]==offset[3]&&offset[0]==offset[4]&&offset[1]==offset[5]){
4061 if (optimized[i]==0){
4108 delete [] optimized;
4119 case kData :
return result;
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");
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());
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.
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.
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.
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.
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...
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)