29#pragma optimize("",off)
185 if (!expression || !*expression) {
186 Error(
"TFormula",
"expression may not be 0 or have 0 length");
192 nch = strlen(expression);
193 char *expr =
new char[nch+1];
195 for (i=0;i<nch;i++) {
196 if (expression[i] ==
' ')
continue;
197 if (i > 0 && (expression[i] ==
'*') && (expression[i-1] ==
'*')) {
201 expr[j] = expression[i]; j++;
220 Warning(
"TFormula",
"Cannot use both gaus and gausn - gaus will be treated as gausn");
222 Warning(
"TFormula",
"Cannot use both gausn and landau - landau will be treated as landaun");
231 Warning(
"TFormula",
"Cannot use both gaus and landaun - gaus will be treated as gausn");
234 Warning(
"TFormula",
"Cannot use both landau and landaun - landau will be treated as landaun");
256 if (strcmp(
name,
"x")==0 || strcmp(
name,
"y")==0 ||
257 strcmp(
name,
"z")==0 || strcmp(
name,
"t")==0 )
259 Error(
"TFormula",
"The name \'%s\' is reserved as a TFormula variable name.\n"
260 "\tThis function will not be registered in the list of functions",
name);
265 gROOT->GetListOfFunctions()->Remove(old);
267 gROOT->GetListOfFunctions()->Add(
this);
295 ((
TFormula&)formula).TFormula::Copy(*
this);
316 gROOT->GetListOfFunctions()->Remove(
this);
353 if (argStart<0)
return false;
355 TString functionName = chaine(0,argStart);
361 if (scopeEnd>0 && functionName[scopeEnd-1]==
':') {
362 spaceName = functionName(0,scopeEnd-1);
363 functionName.
Remove(0,scopeEnd+1);
368 if (chaine[chaine.
Length()-1] !=
')') {
369 Error(
"AnalyzeFunction",
"We thought we had a function but we dont (in %s)\n",chaine.
Data());
372 TString args = chaine(argStart+1,chaine.
Length()-2-argStart);
382 for(i=0; i<args.
Length(); i++) {
383 if (args[i]==
'"') inString = !inString;
384 if (inString)
continue;
389 case '(': paran++;
break;
390 case ')': paran--;
break;
391 case '[': brack++;
break;
392 case ']': brack--;
break;
394 case ',':
if (paran==0 && brack==0) { foundArg =
true; }
break;
396 if ((i+1)==args.
Length()) {
397 foundArg =
true; i++;
400 TString arg = args(prevComma,i-prevComma);
421 ClassInfo_t *cinfo = 0;
423 cinfo =
ns->GetClassInfo();
430 static TypeInfo_t *
const doubletype {
gInterpreter->TypeInfo_Factory(
"double") };
432 std::vector<TypeInfo_t*>
proto(nargs,doubletype);
434 CallFunc_t *callfunc =
gInterpreter->CallFunc_Factory();
481 if (prim && (!IsA()->GetBaseClass(
"TTreeFormula"))) {
490 Error(
"Compile",
"%s requires %d arguments",
495 if (prim->
fType==10){
498 if (prim->
fType==110){
501 if (prim->
fType==1110){
504 if (prim->
fType==-1){
715 Int_t valeur,find,
n,i,j,k,lchain,nomb,virgule,inter,nest;
716 valeur=find=
n=i=j=k=lchain=nomb=virgule=inter=nest = 0;
717 Int_t compt,compt2,compt3,compt4;
727 Int_t modulo,plus,puiss10,puiss10bis,moins,multi,divi,puiss,et,ou,petit,grand,egal,diff,peteg,grdeg,etx,oux,rshift,lshift,tercond,terelse;
732 Int_t actionCode,actionParam;
740 while (parenthese && lchain>0 && err==0){
745 if (lchain==0) err=4;
747 for (i=1; i<=lchain; ++i) {
748 if (chaine(i-1,1) ==
"\"") inString = !inString;
750 if (chaine(i-1,1) ==
"[") compt2++;
751 if (chaine(i-1,1) ==
"]") compt2--;
752 if (chaine(i-1,1) ==
"(") compt++;
753 if (chaine(i-1,1) ==
")") compt--;
755 if (compt < 0) err = 40;
756 if (compt2< 0) err = 42;
757 if (compt==0 && (i!=lchain || lchain==1)) parenthese =
kFALSE;
760 if (compt > 0) err = 41;
761 if (compt2> 0) err = 43;
762 if (parenthese) chaine = chaine(1,lchain-2);
766 if (lchain==0) err=4;
767 modulo=plus=moins=multi=divi=puiss=et=ou=petit=grand=egal=diff=peteg=grdeg=etx=oux=rshift=lshift=tercond=terelse=0;
772 compt = compt2 = compt3 = compt4 = 0;puiss10=0;puiss10bis = 0;
777 for (i=1;i<=lchain; i++) {
779 puiss10=puiss10bis=0;
782 isdecimal = isdecimal && (strchr(
"0123456789.",t)!=0);
784 if ( chaine[i-2] ==
'e' || chaine[i-2] ==
'E' ) puiss10 = 1;
785 }
else if ( strchr(
"+-/[]()&|><=!*/%^\\",t) ) {
790 if (chaine[j-2] ==
'e' || chaine[j-2] ==
'E') {
791 Bool_t isrightdecimal = 1;
793 for(k=j-3; k>=0 && isrightdecimal; --k) {
795 isrightdecimal = isrightdecimal && (strchr(
"0123456789.",t)!=0);
796 if (!isrightdecimal) {
797 if (strchr(
"+-/[]()&|><=!*/%^\\",t)!=0) {
802 if (k<0 && isrightdecimal) puiss10bis = 1;
805 if (puiss10 && (i<=lchain)) {
807 puiss10 = (strchr(
"0123456789.",t)!=0);
809 if (puiss10bis && (j<=lchain)) {
811 puiss10bis = (strchr(
"0123456789.",t)!=0);
814 if (chaine(i-1,1) ==
"\"") inString = !inString;
815 if (inString)
continue;
816 if (chaine(i-1,1) ==
"[") compt2++;
817 if (chaine(i-1,1) ==
"]") compt2--;
818 if (chaine(i-1,1) ==
"(") compt++;
819 if (chaine(i-1,1) ==
")") compt--;
820 if (chaine(j-1,1) ==
"[") compt3++;
821 if (chaine(j-1,1) ==
"]") compt3--;
822 if (chaine(j-1,1) ==
"(") compt4++;
823 if (chaine(j-1,1) ==
")") compt4--;
824 if (chaine(i-1,2)==
"&&" && !inString && compt==0 && compt2==0 && et==0) {et=i;puiss=0;}
825 if (chaine(i-1,2)==
"||" && compt==0 && compt2==0 && ou==0) {puiss10=0; ou=i;}
826 if (chaine(i-1,1)==
"&" && compt==0 && compt2==0 && etx==0) {etx=i;puiss=0;}
827 if (chaine(i-1,1)==
"|" && compt==0 && compt2==0 && oux==0) {puiss10=0; oux=i;}
828 if (chaine(i-1,2)==
">>" && compt==0 && compt2==0 && rshift==0) {puiss10=0; rshift=i;}
829 if (chaine(i-1,1)==
">" && compt==0 && compt2==0 && rshift==0 && grand==0)
830 {puiss10=0; grand=i;}
831 if (chaine(i-1,2)==
"<<" && compt==0 && compt2==0 && lshift==0) {puiss10=0; lshift=i;}
832 if (chaine(i-1,1)==
"<" && compt==0 && compt2==0 && lshift==0 && petit==0)
836 for(
int ip = i,depth=0; ip < lchain; ++ip) {
840 if (isalnum(
c) ||
c==
'_' ||
c==
',')
continue;
841 if (
c==
':' && chaine(ip+1)==
':') { ++ip;
continue; }
842 if (
c==
'<') { ++depth;
continue; }
844 if (depth) { --depth;
continue; }
860 if ((chaine(i-1,2)==
"<=" || chaine(i-1,2)==
"=<") && compt==0 && compt2==0
861 && peteg==0) {peteg=i; puiss10=0; petit=0;}
862 if ((chaine(i-1,2)==
"=>" || chaine(i-1,2)==
">=") && compt==0 && compt2==0
863 && grdeg==0) {puiss10=0; grdeg=i; grand=0;}
864 if (chaine(i-1,2) ==
"==" && compt == 0 && compt2 == 0 && egal == 0) {puiss10=0; egal=i;}
865 if (chaine(i-1,2) ==
"!=" && compt == 0 && compt2 == 0 && diff == 0) {puiss10=0; diff=i;}
866 if (i>1 && chaine(i-1,1) ==
"+" && compt == 0 && compt2 == 0 && puiss10==0) plus=i;
867 if (chaine(j-1,1) ==
"-" && chaine(j-2,1) !=
"*" && chaine(j-2,1) !=
"/"
868 && chaine(j-2,1)!=
"^" && compt3==0 && compt4==0 && moins==0 && puiss10bis==0) moins=j;
869 if (chaine(i-1,1)==
"%" && compt==0 && compt2==0 && modulo==0) {puiss10=0; modulo=i;}
870 if (chaine(i-1,1)==
"*" && compt==0 && compt2==0 && multi==0) {puiss10=0; multi=i;}
871 if (chaine(j-1,1)==
"/" && chaine(j-2,1)!=
"\\"
872 && compt4==0 && compt3==0 && divi==0)
876 if (chaine(j-1)==
'^' && compt4==0 && compt3==0 && puiss==0) {puiss10=0; puiss=j;}
877 if (chaine(i-1)==
'?' && compt == 0 && compt2 == 0 && tercond == 0) {puiss10=0; tercond=i;}
878 if (chaine(i-1)==
':' && tercond && compt == 0 && compt2 == 0 && terelse == 0) {
879 if (i>2 && chaine(i-2)!=
':' && chaine(i)!=
':') {
880 puiss10=0; terelse=i;
890 if (tercond && terelse) {
891 if (tercond == 1 || terelse == lchain || tercond == (terelse-1) ) {
896 ctemp = chaine(0,tercond-1);
906 ctemp = chaine(tercond,terelse-tercond-1);
909 SetAction(optloc, actionCode, actionParam);
919 ctemp = chaine(terelse,lchain-terelse);
923 SetAction(optloc, actionCode, actionParam);
930 }
else if (ou != 0) {
931 if (ou==1 || ou==lchain-1) {
936 ctemp = chaine(0,ou-1);
945 ctemp = chaine(ou+1,lchain-ou-1);
956 if (et==1 || et==lchain-1) {
961 ctemp = chaine(0,et-1);
971 ctemp = chaine(et+1,lchain-et-1);
982 if (oux==1 || oux==lchain) {
987 ctemp = chaine(0,oux-1);
990 ctemp = chaine(oux,lchain-oux);
999 if (etx==1 || etx==lchain) {
1004 ctemp = chaine(0,etx-1);
1005 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1007 ctemp = chaine(etx,lchain-etx);
1008 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1015 }
else if (petit != 0) {
1016 if (petit==1 || petit==lchain) {
1021 ctemp = chaine(0,petit-1);
1022 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1024 ctemp = chaine(petit,lchain-petit);
1025 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1032 }
else if (grand != 0) {
1033 if (grand==1 || grand==lchain) {
1038 ctemp = chaine(0,grand-1);
1039 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1041 ctemp = chaine(grand,lchain-grand);
1042 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1049 }
else if (peteg != 0) {
1050 if (peteg==1 || peteg==lchain-1) {
1055 ctemp = chaine(0,peteg-1);
1056 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1057 ctemp = chaine(peteg+1,lchain-peteg-1);
1059 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1066 }
else if (grdeg != 0) {
1067 if (grdeg==1 || grdeg==lchain-1) {
1072 ctemp = chaine(0,grdeg-1);
1073 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1075 ctemp = chaine(grdeg+1,lchain-grdeg-1);
1076 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1083 }
else if (egal != 0) {
1084 if (egal==1 || egal==lchain-1) {
1089 ctemp = chaine(0,egal-1);
1090 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1093 ctemp = chaine(egal+1,lchain-egal-1);
1094 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1099 if (
IsString(optloc) != isstring) {
1101 chaine_error =
"==";
1102 }
else if (isstring) {
1108 }
else if (diff != 0) {
1109 if (diff==1 || diff==lchain-1) {
1111 chaine_error =
"!=";
1114 ctemp = chaine(0,diff-1);
1115 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1118 ctemp = chaine(diff+1,lchain-diff-1);
1119 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1124 if (
IsString(optloc) != isstring) {
1126 chaine_error =
"!=";
1127 }
else if (isstring) {
1133 }
else if (plus != 0) {
1139 ctemp = chaine(0,plus-1);
1140 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1142 ctemp = chaine(plus,lchain-plus);
1143 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1153 ctemp = chaine(moins,lchain-moins);
1154 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1161 if (moins == lchain) {
1165 ctemp = chaine(0,moins-1);
1166 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1168 ctemp = chaine(moins,lchain-moins);
1169 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1177 }
else if (modulo != 0) {
1178 if (modulo == 1 || modulo == lchain) {
1182 ctemp = chaine(0,modulo-1);
1183 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1185 ctemp = chaine(modulo,lchain-modulo);
1186 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1193 }
else if (rshift != 0) {
1194 if (rshift == 1 || rshift == lchain) {
1198 ctemp = chaine(0,rshift-1);
1199 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1201 ctemp = chaine(rshift+1,lchain-rshift-1);
1202 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1209 }
else if (lshift != 0) {
1210 if (lshift == 1 || lshift == lchain) {
1214 ctemp = chaine(0,lshift-1);
1215 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1217 ctemp = chaine(lshift+1,lchain-lshift-1);
1218 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1227 if (multi == 1 || multi == lchain) {
1232 ctemp = chaine(0,multi-1);
1233 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1235 ctemp = chaine(multi,lchain-multi);
1236 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1245 if (divi == 1 || divi == lchain) {
1250 ctemp = chaine(0,divi-1);
1251 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1253 ctemp = chaine(divi,lchain-divi);
1254 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1263 if (puiss == 1 || puiss == lchain) {
1265 chaine_error =
"**";
1268 if (chaine(lchain-2,2) ==
"^2") {
1269 ctemp =
"sq(" + chaine(0,lchain-2) +
")";
1270 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1272 ctemp = chaine(0,puiss-1);
1273 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1275 ctemp = chaine(puiss,lchain-puiss);
1276 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1293 if ((chaine(0,2)==
"0x")||(chaine(0,2)==
"0X")) isHexa=
kTRUE;
1294 for (j=0; j<chaine.
Length() && err==0; j++) {
1297 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-")) {
1300 chaine_error=chaine;
1307 if (chaine(j,2)==
"e+" || chaine(j,2)==
"e-" || chaine(j,2)==
"E+" || chaine(j,2)==
"E-") j++;
1310 if (chaine(j,1) ==
"." && !hasDot) hasDot =
kTRUE;
1315 if (!strchr(
"0123456789",t) && (chaine(j,1)!=
"+" || j!=0)) {
1317 chaine_error=chaine;
1323 if (!strchr(
"0123456789abcdefABCDEF",t) && (j>1)) {
1325 chaine_error=chaine;
1331 if (!isHexa) {
if (sscanf((
const char*)chaine,
"%lg",&vafConst) > 0) err = 0;
else err =1;}
1332 else {
if (sscanf((
const char*)chaine,
"%lx",&vafConst2) > 0) err = 0;
else err=1;
1337 if (vafConst ==
fConst[j] ) k= j;
1354 oldformula = (
const TFormula*)
gROOT->GetListOfFunctions()->FindObject((
const char*)chaine);
1356 if (oldformula && strcmp(schain,oldformula->
GetTitle())) {
1367 for (
Int_t ipar=0;ipar<npold;ipar++) {
1387 chaine_error = ctemp;
1388 }
else if ( k >= 0 ) {
1390 actionCode = action;
1399 }
else if (chaine(0,1) ==
"!") {
1400 ctemp = chaine(1,lchain-1);
1401 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1407 }
else if (chaine(0,1)==
"\"" && chaine(chaine.
Length()-1,1)==
"\"") {
1413 }
else if (chaine(0,4) ==
"cos(") {
1414 ctemp = chaine(3,lchain-3);
1415 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1421 }
else if (chaine(0,4) ==
"sin(") {
1422 ctemp = chaine(3,lchain-3);
1423 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1429 }
else if (chaine(0,4) ==
"tan(") {
1430 ctemp = chaine(3,lchain-3);
1431 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1437 }
else if (chaine(0,5) ==
"acos(") {
1438 ctemp = chaine(4,lchain-4);
1439 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1445 }
else if (chaine(0,5) ==
"asin(") {
1446 ctemp = chaine(4,lchain-4);
1447 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1453 }
else if (chaine(0,5) ==
"atan(") {
1454 ctemp = chaine(4,lchain-4);
1455 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1461 }
else if (chaine(0,5) ==
"cosh(") {
1462 ctemp = chaine(4,lchain-4);
1463 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1469 }
else if (chaine(0,5) ==
"sinh(") {
1470 ctemp = chaine(4,lchain-4);
1471 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1477 }
else if (chaine(0,5) ==
"tanh(") {
1478 ctemp = chaine(4,lchain-4);
1479 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1485 }
else if (chaine(0,6) ==
"acosh(") {
1486 ctemp = chaine(5,lchain-5);
1487 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1493 }
else if (chaine(0,6) ==
"asinh(") {
1494 ctemp = chaine(5,lchain-5);
1495 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1501 }
else if (chaine(0,6) ==
"atanh(") {
1502 ctemp = chaine(5,lchain-5);
1503 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1509 }
else if (chaine(0,3) ==
"sq(") {
1510 ctemp = chaine(2,lchain-2);
1511 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1517 }
else if (chaine(0,4) ==
"log(") {
1518 ctemp = chaine(3,lchain-3);
1519 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1525 }
else if (chaine(0,6) ==
"log10(") {
1526 ctemp = chaine(5,lchain-5);
1527 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1533 }
else if (chaine(0,4) ==
"exp(") {
1534 ctemp = chaine(3,lchain-3);
1535 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1541 }
else if (chaine(0,4) ==
"abs(") {
1542 ctemp = chaine(3,lchain-3);
1543 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1549 }
else if (chaine(0,5) ==
"sign(") {
1550 ctemp = chaine(4,lchain-4);
1551 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1557 }
else if (chaine(0,4) ==
"int(") {
1558 ctemp = chaine(3,lchain-3);
1559 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1565 }
else if (chaine ==
"rndm" || chaine(0,5) ==
"rndm(") {
1570 }
else if (chaine(0,5) ==
"sqrt(") {
1571 ctemp = chaine(4,lchain-4);
1572 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1581 }
else if ( chaine ==
"expo" || chaine(0,5)==
"expo("
1582 || (lchain==5 && chaine(1,4)==
"expo")
1583 || (lchain==6 && chaine(2,4)==
"expo")
1584 || chaine(1,5)==
"expo(" || chaine(2,5)==
"expo(" ) {
1586 if (chaine(1,4) ==
"expo") {
1591 else if (ctemp==
"y") {
1594 else if (ctemp==
"z") {
1597 else if (ctemp==
"t") {
1602 chaine_error=chaine1ST;
1604 chaine=chaine(1,lchain-1);
1607 if (chaine(2,4) ==
"expo") {
1608 if (chaine(0,2) !=
"xy") {
1610 chaine_error=chaine1ST;
1615 chaine=chaine(2,lchain-2);
1623 actionCode =
kexpo + inter2;
1624 actionParam = offset;
1626 if (inter2 == 5+offset &&
fNpar < 3+offset)
fNpar = 3+offset;
1635 }
else if (chaine(4,1) ==
"(") {
1636 ctemp = chaine(5,lchain-6);
1638 for (j=0; j<ctemp.
Length(); j++) {
1640 if (strchr(
"0123456789",t)==0 && (ctemp(j,1)!=
"+" || j!=0)) {
1642 chaine_error=chaine1ST;
1646 sscanf(ctemp.
Data(),
"%d",&inter);
1649 actionCode =
kexpo + inter2;
1650 actionParam = inter;
1652 if (inter2 == 5) inter++;
1661 chaine_error=chaine;
1666 }
else if (chaine==
"gaus"
1667 || (lchain==5 && chaine(1,4)==
"gaus")
1668 || (lchain==6 && chaine(2,4)==
"gaus")
1669 || chaine(0,5)==
"gaus(" || chaine(1,5)==
"gaus(" || chaine(2,5)==
"gaus(") {
1671 if (chaine(1,4) ==
"gaus") {
1676 else if (ctemp==
"y") {
1679 else if (ctemp==
"z") {
1682 else if (ctemp==
"t") {
1687 chaine_error=chaine1ST;
1689 chaine=chaine(1,lchain-1);
1692 if (chaine(2,4) ==
"gaus") {
1693 if (chaine(0,2) !=
"xy") {
1695 chaine_error=chaine1ST;
1700 chaine=chaine(2,lchain-2);
1705 if (lchain == 4 && err==0) {
1709 actionCode =
kgaus + inter2;
1710 actionParam = offset;
1712 if (inter2 == 5+offset &&
fNpar < 5+offset)
fNpar = 5+offset;
1721 }
else if (chaine(4,1) ==
"(" && err==0) {
1722 ctemp = chaine(5,lchain-6);
1724 for (j=0; j<ctemp.
Length(); j++) {
1726 if (strchr(
"0123456789",t)==0 && (ctemp(j,1)!=
"+" || j!=0)) {
1728 chaine_error=chaine1ST;
1732 sscanf(ctemp.
Data(),
"%d",&inter);
1735 actionCode =
kgaus + inter2;
1736 actionParam = inter;
1738 if (inter2 == 5) inter += 2;
1745 }
else if (err==0) {
1747 chaine_error=chaine1ST;
1752 }
else if (chaine==
"landau" || (lchain==7 && chaine(1,6)==
"landau")
1753 || (lchain==8 && chaine(2,6)==
"landau")
1754 || chaine(0,7)==
"landau(" || chaine(1,7)==
"landau(" || chaine(2,7)==
"landau(") {
1756 if (chaine(1,6) ==
"landau") {
1761 else if (ctemp==
"y") {
1764 else if (ctemp==
"z") {
1767 else if (ctemp==
"t") {
1772 chaine_error=chaine1ST;
1774 chaine=chaine(1,lchain-1);
1777 if (chaine(2,6) ==
"landau") {
1778 if (chaine(0,2) !=
"xy") {
1780 chaine_error=chaine1ST;
1785 chaine=chaine(2,lchain-2);
1790 if (lchain == 6 && err==0) {
1794 actionCode =
klandau + inter2;
1795 actionParam = offset;
1797 if (inter2 == 5+offset &&
fNpar < 5+offset)
fNpar = 5+offset;
1806 }
else if (chaine(6,1) ==
"(" && err==0) {
1807 ctemp = chaine(7,lchain-8);
1809 for (j=0; j<ctemp.
Length(); j++) {
1811 if (strchr(
"0123456789",t)==0 && (ctemp(j,1)!=
"+" || j!=0)) {
1813 chaine_error=chaine1ST;
1817 sscanf(ctemp.
Data(),
"%d",&inter);
1820 actionCode =
klandau + inter2;
1821 actionParam = inter;
1823 if (inter2 == 5) inter += 2;
1830 }
else if (err==0) {
1832 chaine_error=chaine1ST;
1837 }
else if (chaine(0,3) ==
"pol" || chaine(1,3) ==
"pol") {
1839 if (chaine(1,3) ==
"pol") {
1844 else if (ctemp==
"y") {
1847 else if (ctemp==
"z") {
1850 else if (ctemp==
"t") {
1855 chaine_error=chaine1ST;
1857 chaine=chaine(1,lchain-1);
1860 if (chaine(lchain-1,1) ==
")") {
1862 for (j=3;j<lchain;j++)
if (chaine(j,1)==
"(" && nomb == 0) nomb = j;
1863 if (nomb == 3) err = 23;
1864 if (nomb == 0) err = 40;
1865 ctemp = chaine(nomb+1,lchain-nomb-2);
1866 for (j=0; j<ctemp.
Length(); j++) {
1868 if (strchr(
"0123456789",t)==0 && (ctemp(j,1)!=
"+" || j!=0)) {
1870 chaine_error=chaine1ST;
1874 sscanf(ctemp.
Data(),
"%d",&inter);
1875 if (inter < 0) err = 20;
1884 ctemp = chaine(3,nomb-3);
1885 if (sscanf(ctemp.
Data(),
"%d",&
n) > 0) {
1886 if (
n < 0 ) err = 24;
1887 if (
n >= 20) err = 25;
1892 actionCode =
kpol+(inter2-1);
1893 actionParam =
n*100+inter+2;
1906 }
else if (chaine(0,4) ==
"pow(") {
1907 compt = 4; nomb = 0; virgule = 0; nest=0;
1908 while(compt != lchain) {
1910 if (chaine(compt-1,1) ==
"(") nest++;
1911 else if (chaine(compt-1,1) ==
")") nest--;
1912 else if (chaine(compt-1,1) ==
"," && nest==0) {
1914 if (nomb == 1 && virgule == 0) virgule = compt;
1917 if (nomb != 1) err = 22;
1919 ctemp = chaine(4,virgule-5);
1920 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1922 ctemp = chaine(virgule,lchain-virgule-1);
1923 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1930 }
else if (chaine(0,7) ==
"strstr(") {
1931 compt = 7; nomb = 0; virgule = 0; nest=0;
1933 while(compt != lchain) {
1935 if (chaine(compt-1,1) ==
"\"") {
1936 inString = !inString;
1937 }
else if (!inString) {
1938 if (chaine(compt-1,1) ==
"(") nest++;
1939 else if (chaine(compt-1,1) ==
")") nest--;
1940 else if (chaine(compt-1,1) ==
"," && nest==0) {
1942 if (nomb == 1 && virgule == 0) virgule = compt;
1946 if (nomb != 1) err = 28;
1948 ctemp = chaine(7,virgule-8);
1949 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1952 ctemp = chaine(virgule,lchain-virgule-1);
1953 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1961 chaine_error =
"strstr";
1964 }
else if (chaine(0,4) ==
"min(") {
1965 compt = 4; nomb = 0; virgule = 0; nest=0;
1966 while(compt != lchain) {
1968 if (chaine(compt-1,1) ==
"(") nest++;
1969 else if (chaine(compt-1,1) ==
")") nest--;
1970 else if (chaine(compt-1,1) ==
"," && nest==0) {
1972 if (nomb == 1 && virgule == 0) virgule = compt;
1980 ctemp = chaine(4,virgule-5);
1981 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1983 ctemp = chaine(virgule,lchain-virgule-1);
1984 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1991 }
else if (chaine(0,4) ==
"max(") {
1992 compt = 4; nomb = 0; virgule = 0; nest=0;
1993 while(compt != lchain) {
1995 if (chaine(compt-1,1) ==
"(") nest++;
1996 else if (chaine(compt-1,1) ==
")") nest--;
1997 else if (chaine(compt-1,1) ==
"," && nest==0) {
1999 if (nomb == 1 && virgule == 0) virgule = compt;
2007 ctemp = chaine(4,virgule-5);
2008 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
2010 ctemp = chaine(virgule,lchain-virgule-1);
2011 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
2019 }
else if (chaine(0,6) ==
"atan2(") {
2020 compt = 6; nomb = 0; virgule = 0; nest=0;
2021 while(compt != lchain) {
2023 if (chaine(compt-1,1) ==
"(") nest++;
2024 else if (chaine(compt-1,1) ==
")") nest--;
2025 else if (chaine(compt-1,1) ==
"," && nest==0) {
2027 if (nomb == 1 && virgule == 0) virgule = compt;
2030 if (nomb != 1) err = 21;
2032 ctemp = chaine(6,virgule-7);
2033 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
2035 ctemp = chaine(virgule,lchain-virgule-1);
2036 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
2043 }
else if (chaine(0,5) ==
"fmod(") {
2044 compt = 5; nomb = 0; virgule = 0; nest=0;
2045 while(compt != lchain) {
2047 if (chaine(compt-1,1) ==
"(") nest++;
2048 else if (chaine(compt-1,1) ==
")") nest--;
2049 else if (chaine(compt-1,1) ==
"," && nest==0) {
2051 if (nomb == 1 && virgule == 0) virgule = compt;
2059 ctemp = chaine(5,virgule-6);
2060 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
2062 ctemp = chaine(virgule,lchain-virgule-1);
2063 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
2072 chaine_error = chaine;
2078 }
else if (chaine(0,1) ==
"[" && chaine(lchain-1,1) ==
"]") {
2081 ctemp = chaine(1,lchain-2);
2082 for (j=0; j<ctemp.
Length(); j++) {
2084 if (strchr(
"0123456789",t)==0 && (ctemp(j,1)!=
"+" || j!=0)) {
2086 chaine_error=chaine1ST;
2090 sscanf(ctemp.
Data(),
"%d",&valeur);
2092 actionParam = offset + valeur;
2097 }
else if (chaine ==
"pi") {
2124 chaine_error =
"\""+chaine_error+
"\"";
2126 case 2 : er =
" Invalid Floating Point Operation";
break;
2127 case 4 : er =
" Empty String";
break;
2128 case 5 : er =
" Invalid Syntax " + chaine_error;
break;
2129 case 6 : er =
" Too many operators !";
break;
2130 case 7 : er =
" Too many parameters !";
break;
2131 case 10 : er =
" z specified but not x and y";
break;
2132 case 11 : er =
" z and y specified but not x";
break;
2133 case 12 : er =
" y specified but not x";
break;
2134 case 13 : er =
" z and x specified but not y";
break;
2135 case 20 : er =
" Non integer value for parameter number : " + chaine_error;
break;
2136 case 21 : er =
" ATAN2 requires two arguments";
break;
2137 case 22 : er =
" POW requires two arguments";
break;
2138 case 23 : er =
" Degree of polynomial not specified";
break;
2139 case 24 : er =
" Degree of polynomial must be positive";
break;
2140 case 25 : er =
" Degree of polynomial must be less than 20";
break;
2141 case 26 : er =
" Unknown name : " + chaine_error;
break;
2142 case 27 : er =
" Too many constants in expression";
break;
2143 case 28 : er =
" strstr requires two arguments";
break;
2144 case 29 : er =
" TFormula can only call interpreted and compiled functions that return a numerical type: " + chaine_error;
break;
2145 case 30 : er =
" Bad numerical expression : " + chaine_error;
break;
2146 case 31 : er =
" Part of the Variable " + chaine_error; er +=
" exists but some of it is not accessible or useable";
break;
2147 case 40 : er =
" '(' is expected";
break;
2148 case 41 : er =
" ')' is expected";
break;
2149 case 42 : er =
" '[' is expected";
break;
2150 case 43 : er =
" ']' is expected";
break;
2151 case 44 : er =
" The function '" + chaine(0,err_hint) +
"' requires two arguments.";
break;
2152 case 45 : er =
"The operator " + chaine_error +
" requires a numerical operand.";
break;
2153 case 46 : er =
"Both operands of the operator " + chaine_error +
" have to be either numbers or strings.";
break;
2154 case 47 : er = chaine_error +
" requires 2 string arguments";
break;
2169 Error(
"Compile",
"\"%s\" requires a numerical operand.",
fExpr[oper].Data());
2189 Error(
"Compile",
"\"%s\" requires two numerical operands.",
fExpr[oper].Data());
2251 inline static void ResizeArrayIfAllocated(
T*& oldArray,
int newSize){
2254 if (!oldArray || newSize <=0)
return;
2256 T* newArray =
new T[newSize];
2257 std::copy(oldArray, oldArray+newSize, newArray);
2259 oldArray = newArray;
2292 Int_t i,j,lc,valeur,err;
2298 if (strlen(expression))
SetTitle(expression);
2303 char *sctemp =
new char[chaine.
Length()+1];
2304 strlcpy(sctemp,chaine.
Data(),chaine.
Length()+1);
2305 char *semicol = (
char*)strstr(sctemp,
";");
2306 if (semicol) *semicol = 0;
2326 for (i=0; i<
gMAXOP; i++) {
2335 for (i=1; i<=chaine.
Length(); i++) {
2337 if (chaine(i-1,1) ==
"\"") inString = !inString;
2338 if (inString)
continue;
2339 if (chaine(i-1,2) ==
"**") {
2340 chaine = chaine(0,i-1) +
"^" + chaine(i+1,lc-i-1);
2342 }
else if (chaine(i-1,2) ==
"++") {
2343 chaine = chaine(0,i) + chaine(i+1,lc-i-1);
2345 }
else if (chaine(i-1,2) ==
"+-" || chaine(i-1,2) ==
"-+") {
2346 chaine = chaine(0,i-1) +
"-" + chaine(i+1,lc-i-1);
2348 }
else if (chaine(i-1,2) ==
"--") {
2349 chaine = chaine(0,i-1) +
"+" + chaine(i+1,lc-i-1);
2351 }
else if (chaine(i-1,2) ==
"->") {
2352 chaine = chaine(0,i-1) +
"." + chaine(i+1,lc-i-1);
2354 }
else if (chaine(i-1,1) ==
"[") {
2355 for (j=1;j<=chaine.
Length()-i;j++) {
2356 if (chaine(j+i-1,1) ==
"]" || j+i > chaine.
Length())
break;
2358 ctemp = chaine(i,j-1);
2360 sscanf(ctemp.
Data(),
"%d",&valeur);
2362 }
else if (chaine(i-1,1) ==
" ") {
2363 chaine = chaine(0,i-1)+chaine(i,lc-i);
2368 Analyze((
const char*)chaine,err);
2445 if (err) {
fNdim = 0;
return 1; }
2449 if (!IsA()->GetBaseClass(
"TTreeFormula")) {
2497 while ( (fobj = next()) ) {
2622 if (chaine ==
"x") {
2625 }
else if (chaine ==
"y") {
2628 }
else if (chaine ==
"z") {
2631 }
else if (chaine ==
"t") {
2638 if (chaine.
Data()[0]==
'x'){
2639 if (chaine.
Data()[1]==
'[' && chaine.
Data()[3]==
']'){
2640 const char ch0 =
'0';
2642 if (dim<0)
return -1;
2643 if (dim>9)
return -1;
2647 if (chaine.
Data()[1]==
'[' && chaine.
Data()[4]==
']'){
2648 const char ch0 =
'0';
2649 Int_t dim = (chaine.
Data()[2]-ch0)*10+(chaine.
Data()[3]-ch0);
2650 if (dim<0)
return -1;
2651 if (dim>99)
return -1;
2673 return ((
TFormula*)
this)->EvalPar(xx);
2693 Int_t precalculated = 0;
2694 Int_t precalculated_str = 0;
2698 params =
const_cast<Double_t*
>(uparams);
2705 for (i=0; i<
fNoper; ++i) {
2707 const int oper =
fOper[i];
2715 case kStringConst: { strpos++; stringStack[strpos-1] = (
char*)
fExpr[i].Data(); pos++; tab[pos-1] = 0;
continue; }
2717 case kAdd : pos--; tab[pos-1] += tab[pos];
continue;
2718 case kSubstract : pos--; tab[pos-1] -= tab[pos];
continue;
2719 case kMultiply : pos--; tab[pos-1] *= tab[pos];
continue;
2720 case kDivide : pos--;
if (tab[pos] == 0) tab[pos-1] = 0;
2721 else tab[pos-1] /= tab[pos];
2746 case kacosh:
if (tab[pos-1] < 1) {tab[pos-1] = 0;}
2755 case kfmod : pos--; tab[pos-1] = fmod(tab[pos-1],tab[pos]);
continue;
2756 case kpow : pos--; tab[pos-1] =
TMath::Power(tab[pos-1],tab[pos]);
continue;
2757 case ksq : tab[pos-1] = tab[pos-1]*tab[pos-1];
continue;
2760 case kstrstr : strpos -= 2; pos-=2; pos++;
2761 if (strstr(stringStack[strpos],stringStack[strpos+1])) tab[pos-1]=1;
2765 case kmin : pos--; tab[pos-1] =
TMath::Min(tab[pos-1],tab[pos]);
continue;
2766 case kmax : pos--; tab[pos-1] =
TMath::Max(tab[pos-1],tab[pos]);
continue;
2768 case klog :
if (tab[pos-1] > 0) tab[pos-1] =
TMath::Log(tab[pos-1]);
2769 else {tab[pos-1] = 0;}
2772 if (dexp < -700) {tab[pos-1] = 0;
continue;}
2773 if (dexp > 700) {tab[pos-1] =
TMath::Exp(700);
continue;}
2776 else {tab[pos-1] = 0;}
2782 case ksign :
if (tab[pos-1] < 0) tab[pos-1] = -1;
else tab[pos-1] = 1;
continue;
2785 case kSignInv: tab[pos-1] = -1 * tab[pos-1];
continue;
2789 case kAnd : pos--;
if (tab[pos-1]!=0 && tab[pos]!=0) tab[pos-1]=1;
2792 case kOr : pos--;
if (tab[pos-1]!=0 || tab[pos]!=0) tab[pos-1]=1;
2795 case kEqual: pos--;
if (tab[pos-1] == tab[pos]) tab[pos-1]=1;
2798 case kNotEqual : pos--;
if (tab[pos-1] != tab[pos]) tab[pos-1]=1;
2801 case kLess : pos--;
if (tab[pos-1] < tab[pos]) tab[pos-1]=1;
2804 case kGreater : pos--;
if (tab[pos-1] > tab[pos]) tab[pos-1]=1;
2808 case kLessThan: pos--;
if (tab[pos-1]<=tab[pos]) tab[pos-1]=1;
2811 case kGreaterThan: pos--;
if (tab[pos-1]>=tab[pos]) tab[pos-1]=1;
2814 case kNot :
if (tab[pos-1]!=0) tab[pos-1] = 0;
else tab[pos-1] = 1;
2818 if (!strcmp(stringStack[strpos+1],stringStack[strpos])) tab[pos-1]=1;
2822 if (strcmp(stringStack[strpos+1],stringStack[strpos])) tab[pos-1]=1;
2826 case kBitAnd : pos--; tab[pos-1]= ((
Int_t) tab[pos-1]) & ((
Int_t) tab[pos]);
continue;
2827 case kBitOr : pos--; tab[pos-1]= ((
Int_t) tab[pos-1]) | ((
Int_t) tab[pos]);
continue;
2839 int op = param % 10;
2841 if (op == 1 && (!tab[pos-1]) ) {
2850 }
else if (op == 2 && tab[pos-1] ) {
2862 int toskip = param / 10;
2872 #define R__EXPO(var) \
2874 pos++; int param = (oper & kTFOperMask); \
2875 tab[pos-1] = TMath::Exp(params[param]+params[param+1]*x[var]); \
2883 tab[pos-1] =
TMath::Exp(params[param]+params[param+1]*
x[0]+params[param+2]*
x[1]);
2886 #define R__GAUS(var) \
2888 pos++; int param = (oper & kTFOperMask); \
2889 tab[pos-1] = params[param]*TMath::Gaus(x[var],params[param+1],params[param+2],IsNormalized()); \
2899 if (params[param+2] == 0) {
2902 intermede1=
Double_t((
x[0]-params[param+1])/params[param+2]);
2905 if (params[param+4] == 0) {
2908 intermede2=
Double_t((
x[1]-params[param+3])/params[param+4]);
2910 tab[pos-1] = params[param]*
TMath::Exp(-0.5*(intermede1*intermede1+intermede2*intermede2));
2913 #define R__LANDAU(var) \
2915 pos++; const int param = (oper & kTFOperMask); \
2916 tab[pos-1] = params[param]*TMath::Landau(x[var],params[param+1],params[param+2],IsNormalized()); \
2923 case kxylandau: { pos++;
int param = oper&0x7fffff ;
2926 tab[pos-1] = params[param]*intermede1*intermede2;
2930 #define R__POLY(var) \
2932 pos++; int param = (oper & kTFOperMask); \
2933 tab[pos-1] = 0; Double_t intermede = 1; \
2934 Int_t inter = param/100; \
2935 Int_t int1= param-inter*100-1; \
2936 for (j=0 ;j<inter+1;j++) { \
2937 tab[pos-1] += intermede*params[j+int1]; \
2938 intermede *= x[var]; \
2948 if (!precalculated) {
2952 pos++; tab[pos-1] = param_calc[(oper &
kTFOperMask)];
2958 if (!precalculated_str) {
2959 precalculated_str=1;
2962 strpos++; stringStack[strpos-1] = string_calc[param];
2963 pos++; tab[pos-1] = 0;
2971 int fno = param / 1000;
2972 int nargs = param % 1000;
2980 UInt_t argloc = pos-nargs;
2981 for(j=0;j<nargs;j++,argloc++,pos--) {
3030 Int_t ternaryend = -1;
3034 if (ternaryend==i) {
3036 if(ismulti[spos-1]){
3037 tab[spos-2]=tab[spos-2]+
"("+tab[spos-1]+
")";
3039 tab[spos-2]=tab[spos-2]+tab[spos-1];
3053 tab[spos-1]=
"-("+tab[spos-1]+
")";
3067 if ((optype<=151 && optype>=140 && optype!=145) || (optype == 40)) {
3075 if(((optype>0 && optype<6) || optype==20 ||
3076 (((optype>59 && optype<69) || (optype >75 && optype<82)) && spos>=2))) {
3078 if(ismulti[spos-2]){
3079 tab[spos-2]=
"("+tab[spos-2]+
")";
3081 if(ismulti[spos-1]){
3082 tab[spos-2]+=
fExpr[i]+(
"("+tab[spos-1]+
")");
3084 tab[spos-2]+=
fExpr[i]+tab[spos-1];
3086 ismulti[spos-2]=
kTRUE;
3092 if(ismulti[spos-1]){
3093 tab[spos-1]=
"("+tab[spos-1]+
")?";
3095 tab[spos-1]=tab[spos-1]+
"?";
3099 if (optype==
kJump) {
3100 if(ismulti[spos-1]){
3101 tab[spos-2]=tab[spos-2]+
"("+tab[spos-1]+
"):";
3103 tab[spos-2]=tab[spos-2]+tab[spos-1]+
":";
3113 if((optype>9 && optype<16) ||
3114 (optype>20 && optype<23) ||
3115 (optype>29 && optype<34) ||
3116 (optype>40 && optype<44) ||
3117 (optype>69 && optype<76) ||
3123 if((optype>15 && optype<20) ||
3124 (optype>22 && optype<26)) {
3131 int nargs = param % 1000;
3136 for(j=0, depth=0;j<funcname.
Length();++j) {
3137 switch (funcname[j]) {
3154 Error(
"GetExpFormula",
"Internal error, number of argument found is %d",-offset);
3155 }
else if (offset == 0) {
3156 tab[spos]=funcname+
"()";
3160 }
else if (offset<=0 && (spos+offset>=0)) {
3161 tab[spos+offset]=funcname+(
"("+tab[spos+offset]);
3162 for (j=offset+1; j<0; j++){
3163 tab[spos+offset]+=
","+tab[spos+j];
3165 tab[spos+offset]+=
")";
3166 ismulti[spos+offset]=
kFALSE;
3171 if (ternaryend==
fNoper) {
3173 if(ismulti[spos-1]){
3174 tab[spos-2]=tab[spos-2]+
"("+tab[spos-1]+
")";
3176 tab[spos-2]=tab[spos-2]+tab[spos-1];
3182 if (spos > 0) ret = tab[spos-1];
3192 for (j=0;j<
fNpar;j++) {
3222 if (ipar <0 || ipar >=
fNpar)
return 0;
3234 Error(
"TFormula",
"Parameter %s not found", parName);
3245 if (ipar <0 || ipar >=
fNpar)
return "";
3246 if (
fNames[ipar].Length() > 0)
return (
const char*)
fNames[ipar];
3247 return Form(
"p%d",ipar);
3259 if (!strcmp(
GetParName(i),parName))
return i;
3280 Printf(
" fExpr[%d] = %s action = %d action param = %d ",
3286 Printf(
"Optimized expression");
3288 Printf(
" fExpr[%d] = %s\t\t action = %d action param = %d ",
3295 for (i=0;i<
fNpar;i++) {
3309 Int_t nf, offset, replsize;
3311 pch= (
char*)strstr(formula.
Data(),
"++");
3313 formula.
Insert(0,
"[0]*(");
3314 pch= (
char*)strstr(formula.
Data(),
"++");
3320 offset = pch-formula.
Data();
3321 if (nf<10) replsize = 7;
3322 else if (nf<100) replsize = 8;
3324 formula.
Replace(pch-formula.
Data(), 2, repl, replsize);
3325 pch = (
char*)strstr(formula.
Data()+offset,
"++");
3331 formula2=formula2(4, formula2.
Length()-4);
3332 pch= (
char*)strchr(formula2.
Data(),
'[');
3336 offset = pch-formula2.
Data()-1;
3337 if (nf<10) replsize = 5;
3339 formula2.
Replace(pch-formula2.
Data()-1, replsize, repl, 2);
3340 pch = (
char*)strchr(formula2.
Data()+offset,
'[');
3348 formula2 = formula2.
ReplaceAll(
"++", 2,
"|", 1);
3351 for (
Int_t i=0; i<nf; i++) {
3353 replaceformula_name =
"f_linear_";
3354 replaceformula_name.
Append(replaceformula);
3357 Error(
"TFormula",
"f_linear not allocated");
3362 gROOT->GetListOfFunctions()->Remove(
f);
3376 if (ipar <0 || ipar >=
fNpar)
return;
3386 if (ipar <0 || ipar >=
fNpar)
return;
3432 if (ipar <0 || ipar >=
fNpar)
return;
3440 const char*name5,
const char*name6,
const char*name7,
const char*name8,
const char*name9,
const char*name10)
3460 if (
b.IsReading()) {
3464 Error(
"Streamer",
"version 6 is not supported");
3479 if (
b.IsReading()) {
3483 Error(
"Streamer",
"version 6 is not supported");
3504 gROOT->GetListOfFunctions()->Add(
this);
3517 Error(
"Streamer",
"error compiling formula");
3532 TNamed::Streamer(
b);
3552 if (
gROOT->GetListOfFunctions()->FindObject(
GetName()))
return;
3553 gROOT->GetListOfFunctions()->Add(
this);
3555 b.CheckByteCount(R__s, R__c, TFormula::IsA());
3570 kOldxylandau = 4500,
3571 kOldConstants = 50000,
3572 kOldStrings = 80000,
3573 kOldVariable = 100000,
3574 kOldTreeString = 105000,
3575 kOldFormulaVar = 110000,
3576 kOldBoolOptimize = 120000,
3577 kOldFunctionCall = 200000
3581 for (i=0,j=0; i<
fNoper; ++i,++j) {
3583 Int_t newActionCode = 0;
3584 Int_t newActionParam = 0;
3592 sscanf((
const char*)
fExpr[i],
"%g",&aresult);
3599 for (
int z=i; z<
fNoper; ++z) {
3603 }
else if ( action < 100 ) {
3606 newActionCode = action;
3608 }
else if (action >= kOldFunctionCall) {
3612 newActionParam = action-kOldFunctionCall;
3614 }
else if (action >= kOldBoolOptimize) {
3618 newActionParam = action-kOldBoolOptimize;
3620 }
else if (action >= kOldFormulaVar) {
3624 newActionParam = action-kOldFormulaVar;
3626 }
else if (action >= kOldTreeString) {
3630 newActionParam = action-kOldTreeString;
3632 }
else if (action >= kOldVariable) {
3636 newActionParam = action-kOldVariable;
3638 }
else if (action == kOldStrings) {
3643 }
else if (action >= kOldConstants) {
3647 newActionParam = action-kOldConstants;
3649 }
else if (action > 10000 && action < kOldConstants) {
3652 int var = action/10000;
3653 newActionCode =
kpol + (var-1);
3654 newActionParam = action - var*10000;
3656 }
else if (action >= 4600) {
3658 Error(
"Convert",
"Unsupported value %d",action);
3660 }
else if (action > kOldxylandau) {
3664 newActionParam = action - (kOldxylandau+1);
3666 }
else if (action > kOldlandau) {
3670 int var = action/100-40;
3671 if (var) newActionCode += var;
3672 newActionParam = action - var*100 - (kOldlandau+1);
3674 }
else if (action > 2500 && action < 2600) {
3678 newActionParam = action-2501;
3680 }
else if (action > 2000 && action < 2500) {
3683 newActionCode =
kgaus;
3684 int var = action/100-20;
3685 if (var) newActionCode += var;
3686 newActionParam = action - var*100 - (kOldgaus+1);
3688 }
else if (action > 1500 && action < 1600) {
3692 newActionParam = action-1501;
3694 }
else if (action > 1000 && action < 1500) {
3697 newActionCode =
kexpo;
3698 int var = action/100-10;
3699 if (var) newActionCode += var;
3700 newActionParam = action - var*100 - (kOldexpo+1);
3702 }
if (action > 100 && action < 200) {
3706 newActionParam = action - 101;
3709 SetAction( j, newActionCode, newActionParam );
3748 int paran = cbase.
First(
"(");
3755 if (cbase==
"<") cbase=
"XlY";
3756 if (cbase==
"<=") cbase=
"XleY";
3757 if (cbase==
">") cbase=
"XgY";
3758 if (cbase==
">=") cbase=
"XgeY";
3765 if (prim->
fType==10) {
3768 if (prim->
fType==110) {
3771 if (prim->
fType==1110) {
3774 if (prim->
fType==-1) {
3777 if (prim->
fType==0){
3833 for (i=0; i<
fNoper; i++) {
3867 for (i=0;i<
fNoper;i++) optimized[i]=0;
3927 if ((i+1) >=
fNoper)
continue;
3954 if ((i+2) >=
fNoper)
continue;
3978 if (offset[0]==offset[2]&&offset[1]==offset[3]) {
3991 if ((i+3) >=
fNoper)
continue;
4024 if (offset[0]==offset[2]&&offset[1]==offset[3]&&offset[0]==offset[4]&&offset[1]==offset[5]){
4059 if (optimized[i]==0){
4106 delete [] optimized;
4117 case kData :
return result;
4196 Int_t precalculated = 0;
4197 Int_t precalculated_str = 0;
4203 params =
const_cast<Double_t*
>(uparams);
4223 case kAdd : pos--; tab[pos-1] += tab[pos];
continue;
4224 case kSubstract : pos--; tab[pos-1] -= tab[pos];
continue;
4225 case kMultiply : pos--; tab[pos-1] *= tab[pos];
continue;
4226 case kDivide : pos--;
if (tab[pos] == 0) tab[pos-1] = 0;
4227 else tab[pos-1] /= tab[pos];
4252 case kAnd : pos--; tab[pos-1] = (bool)tab[pos];
continue;
4253 case kOr : pos--; tab[pos-1] = (bool)tab[pos];
continue;
4257 case kabs :
if (tab[pos-1]<0) tab[pos-1]=-tab[pos-1];
continue;
4258 case ksign :
if (tab[pos-1] < 0) tab[pos-1] = -1;
else tab[pos-1] = 1;
continue;
4260 case kpow : pos--; tab[pos-1] =
TMath::Power(tab[pos-1],tab[pos]);
continue;
4270 case kfmod : pos--; tab[pos-1] = fmod(tab[pos-1],tab[pos]);
continue;
4272 case kstrstr : strpos -= 2; pos-=2; pos++;
4273 if (strstr(stringStack[strpos],stringStack[strpos+1])) tab[pos-1]=1;
4279 case kSignInv: tab[pos-1] = -1 * tab[pos-1];
continue;
4284 case kEqual: pos--;
if (tab[pos-1] == tab[pos]) tab[pos-1]=1;
4287 case kNotEqual : pos--;
if (tab[pos-1] != tab[pos]) tab[pos-1]=1;
4290 case kNot :
if (tab[pos-1]!=0) tab[pos-1] = 0;
else tab[pos-1] = 1;
4294 if (!strcmp(stringStack[strpos+1],stringStack[strpos])) tab[pos-1]=1;
4298 if (strcmp(stringStack[strpos+1],stringStack[strpos])) tab[pos-1]=1;
4302 case kBitAnd : pos--; tab[pos-1]= ((
Int_t) tab[pos-1]) & ((
Int_t) tab[pos]);
continue;
4303 case kBitOr : pos--; tab[pos-1]= ((
Int_t) tab[pos-1]) | ((
Int_t) tab[pos]);
continue;
4314 int op = param % 10;
4316 if (op == 1 && (!tab[pos-1]) ) {
4325 }
else if (op == 2 && tab[pos-1] ) {
4342#define R__EXPO(var) \
4344 pos++; int param = (oper & kTFOperMask); \
4345 tab[pos-1] = TMath::Exp(params[param]+params[param+1]*x[var]); \
4353 tab[pos-1] =
TMath::Exp(params[param]+params[param+1]*
x[0]+params[param+2]*
x[1]);
4358#define R__GAUS(var) \
4360 pos++; int param = (oper & kTFOperMask); \
4361 tab[pos-1] = params[param]*TMath::Gaus(x[var],params[param+1], \
4362 params[param+2],IsNormalized()); \
4372 if (params[param+2] == 0) {
4375 intermede1=
Double_t((
x[0]-params[param+1])/params[param+2]);
4378 if (params[param+4] == 0) {
4381 intermede2=
Double_t((
x[1]-params[param+3])/params[param+4]);
4383 tab[pos-1] = params[param]*
TMath::Exp(-0.5*(intermede1*intermede1+intermede2*intermede2));
4386#define R__LANDAU(var) \
4388 pos++; const int param = (oper & kTFOperMask); \
4389 tab[pos-1] = params[param]*TMath::Landau(x[var],params[param+1],params[param+2],IsNormalized()); \
4396 case kxylandau: { pos++;
int param = oper&0x7fffff ;
4399 tab[pos-1] = params[param]*intermede1*intermede2;
4403#define R__POLY(var) \
4405 pos++; int param = (oper & kTFOperMask); \
4406 tab[pos-1] = 0; Double_t intermede = 1; \
4407 Int_t inter = param/100; \
4408 Int_t int1= param-inter*100-1; \
4409 for (j=0 ;j<inter+1;j++) { \
4410 tab[pos-1] += intermede*params[j+int1]; \
4411 intermede *= x[var]; \
4421 if (!precalculated) {
4425 pos++; tab[pos-1] = param_calc[(oper &
kTFOperMask)];
4431 if (!precalculated_str) {
4432 precalculated_str=1;
4435 strpos++; stringStack[strpos-1] = string_calc[param];
4436 pos++; tab[pos-1] = 0;
4444 int fno = param / 1000;
4445 int nargs = param % 1000;
4453 UInt_t argloc = pos-nargs;
4454 for(j=0;j<nargs;j++,argloc++,pos--) {
4482 if (str.
Length()<3)
return 1;
4483 if (str[str.
Length()-1]!=
'+'&&str[str.
Length()-2]!=
'+')
return 1;
4485 TString funName(
"preformula_");
4489 fileName.
Form(
"/tmp/%s.C",funName.
Data());
4492 hf = fopen(fileName.
Data(),
"w");
4494 Error(
"PreCompile",
"Unable to open the file %s for writing.",fileName.
Data());
4497 fprintf(hf,
"/////////////////////////////////////////////////////////////////////////\n");
4498 fprintf(hf,
"// This code has been automatically generated \n");
4500 fprintf(hf,
"Double_t %s(Double_t *x, Double_t *p){",funName.
Data());
4501 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
Namespace for new ROOT classes and functions.
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, Double_t)
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)