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);
294 ((
TFormula&)formula).TFormula::Copy(*
this);
315 gROOT->GetListOfFunctions()->Remove(
this);
352 if (argStart<0)
return false;
354 TString functionName = chaine(0,argStart);
360 if (scopeEnd>0 && functionName[scopeEnd-1]==
':') {
361 spaceName = functionName(0,scopeEnd-1);
362 functionName.
Remove(0,scopeEnd+1);
367 if (chaine[chaine.
Length()-1] !=
')') {
368 Error(
"AnalyzeFunction",
"We thought we had a function but we dont (in %s)\n",chaine.
Data());
371 TString args = chaine(argStart+1,chaine.
Length()-2-argStart);
381 for(i=0; i<args.Length(); i++) {
382 if (args[i]==
'"') inString = !inString;
383 if (inString)
continue;
388 case '(': paran++;
break;
389 case ')': paran--;
break;
390 case '[': brack++;
break;
391 case ']': brack--;
break;
393 case ',':
if (paran==0 && brack==0) { foundArg =
true; }
break;
395 if ((i+1)==args.Length()) {
396 foundArg =
true; i++;
399 TString arg = args(prevComma,i-prevComma);
420 ClassInfo_t *cinfo = 0;
429 static TypeInfo_t *
const doubletype {
gInterpreter->TypeInfo_Factory(
"double") };
431 std::vector<TypeInfo_t*>
proto(nargs,doubletype);
433 CallFunc_t *callfunc =
gInterpreter->CallFunc_Factory();
480 if (prim && (!IsA()->GetBaseClass(
"TTreeFormula"))) {
489 Error(
"Compile",
"%s requires %d arguments",
494 if (prim->
fType==10){
497 if (prim->
fType==110){
500 if (prim->
fType==1110){
503 if (prim->
fType==-1){
714 Int_t valeur,find,
n,i,j,k,lchain,nomb,virgule,inter,nest;
715 valeur=find=n=i=j=k=lchain=nomb=virgule=inter=nest = 0;
716 Int_t compt,compt2,compt3,compt4;
721 TString s,chaine_error,chaine1ST;
726 Int_t modulo,plus,puiss10,puiss10bis,moins,multi,divi,puiss,et,ou,petit,grand,egal,diff,peteg,grdeg,etx,oux,rshift,lshift,tercond,terelse;
731 Int_t actionCode,actionParam;
739 while (parenthese && lchain>0 && err==0){
744 if (lchain==0) err=4;
746 for (i=1; i<=lchain; ++i) {
747 if (chaine(i-1,1) ==
"\"") inString = !inString;
749 if (chaine(i-1,1) ==
"[") compt2++;
750 if (chaine(i-1,1) ==
"]") compt2--;
751 if (chaine(i-1,1) ==
"(") compt++;
752 if (chaine(i-1,1) ==
")") compt--;
754 if (compt < 0) err = 40;
755 if (compt2< 0) err = 42;
756 if (compt==0 && (i!=lchain || lchain==1)) parenthese =
kFALSE;
759 if (compt > 0) err = 41;
760 if (compt2> 0) err = 43;
761 if (parenthese) chaine = chaine(1,lchain-2);
765 if (lchain==0) err=4;
766 modulo=plus=moins=multi=divi=puiss=et=ou=petit=grand=egal=diff=peteg=grdeg=etx=oux=rshift=lshift=tercond=terelse=0;
771 compt = compt2 = compt3 = compt4 = 0;puiss10=0;puiss10bis = 0;
776 for (i=1;i<=lchain; i++) {
778 puiss10=puiss10bis=0;
781 isdecimal = isdecimal && (strchr(
"0123456789.",t)!=0);
783 if ( chaine[i-2] ==
'e' || chaine[i-2] ==
'E' ) puiss10 = 1;
784 }
else if ( strchr(
"+-/[]()&|><=!*/%^\\",t) ) {
789 if (chaine[j-2] ==
'e' || chaine[j-2] ==
'E') {
790 Bool_t isrightdecimal = 1;
792 for(k=j-3; k>=0 && isrightdecimal; --k) {
794 isrightdecimal = isrightdecimal && (strchr(
"0123456789.",t)!=0);
795 if (!isrightdecimal) {
796 if (strchr(
"+-/[]()&|><=!*/%^\\",t)!=0) {
801 if (k<0 && isrightdecimal) puiss10bis = 1;
804 if (puiss10 && (i<=lchain)) {
806 puiss10 = (strchr(
"0123456789.",t)!=0);
808 if (puiss10bis && (j<=lchain)) {
810 puiss10bis = (strchr(
"0123456789.",t)!=0);
813 if (chaine(i-1,1) ==
"\"") inString = !inString;
814 if (inString)
continue;
815 if (chaine(i-1,1) ==
"[") compt2++;
816 if (chaine(i-1,1) ==
"]") compt2--;
817 if (chaine(i-1,1) ==
"(") compt++;
818 if (chaine(i-1,1) ==
")") compt--;
819 if (chaine(j-1,1) ==
"[") compt3++;
820 if (chaine(j-1,1) ==
"]") compt3--;
821 if (chaine(j-1,1) ==
"(") compt4++;
822 if (chaine(j-1,1) ==
")") compt4--;
823 if (chaine(i-1,2)==
"&&" && !inString && compt==0 && compt2==0 && et==0) {et=i;puiss=0;}
824 if (chaine(i-1,2)==
"||" && compt==0 && compt2==0 && ou==0) {puiss10=0; ou=i;}
825 if (chaine(i-1,1)==
"&" && compt==0 && compt2==0 && etx==0) {etx=i;puiss=0;}
826 if (chaine(i-1,1)==
"|" && compt==0 && compt2==0 && oux==0) {puiss10=0; oux=i;}
827 if (chaine(i-1,2)==
">>" && compt==0 && compt2==0 && rshift==0) {puiss10=0; rshift=i;}
828 if (chaine(i-1,1)==
">" && compt==0 && compt2==0 && rshift==0 && grand==0)
829 {puiss10=0; grand=i;}
830 if (chaine(i-1,2)==
"<<" && compt==0 && compt2==0 && lshift==0) {puiss10=0; lshift=i;}
831 if (chaine(i-1,1)==
"<" && compt==0 && compt2==0 && lshift==0 && petit==0)
835 for(
int ip = i,depth=0; ip < lchain; ++ip) {
839 if (isalnum(c) || c==
'_' || c==
',')
continue;
840 if (c==
':' && chaine(ip+1)==
':') { ++ip;
continue; }
841 if (c==
'<') { ++depth;
continue; }
843 if (depth) { --depth;
continue; }
859 if ((chaine(i-1,2)==
"<=" || chaine(i-1,2)==
"=<") && compt==0 && compt2==0
860 && peteg==0) {peteg=i; puiss10=0; petit=0;}
861 if ((chaine(i-1,2)==
"=>" || chaine(i-1,2)==
">=") && compt==0 && compt2==0
862 && grdeg==0) {puiss10=0; grdeg=i; grand=0;}
863 if (chaine(i-1,2) ==
"==" && compt == 0 && compt2 == 0 && egal == 0) {puiss10=0; egal=i;}
864 if (chaine(i-1,2) ==
"!=" && compt == 0 && compt2 == 0 && diff == 0) {puiss10=0; diff=i;}
865 if (i>1 && chaine(i-1,1) ==
"+" && compt == 0 && compt2 == 0 && puiss10==0) plus=i;
866 if (chaine(j-1,1) ==
"-" && chaine(j-2,1) !=
"*" && chaine(j-2,1) !=
"/" 867 && chaine(j-2,1)!=
"^" && compt3==0 && compt4==0 && moins==0 && puiss10bis==0) moins=j;
868 if (chaine(i-1,1)==
"%" && compt==0 && compt2==0 && modulo==0) {puiss10=0; modulo=i;}
869 if (chaine(i-1,1)==
"*" && compt==0 && compt2==0 && multi==0) {puiss10=0; multi=i;}
870 if (chaine(j-1,1)==
"/" && chaine(j-2,1)!=
"\\" 871 && compt4==0 && compt3==0 && divi==0)
875 if (chaine(j-1)==
'^' && compt4==0 && compt3==0 && puiss==0) {puiss10=0; puiss=j;}
876 if (chaine(i-1)==
'?' && compt == 0 && compt2 == 0 && tercond == 0) {puiss10=0; tercond=i;}
877 if (chaine(i-1)==
':' && tercond && compt == 0 && compt2 == 0 && terelse == 0) {
878 if (i>2 && chaine(i-2)!=
':' && chaine(i)!=
':') {
879 puiss10=0; terelse=i;
889 if (tercond && terelse) {
890 if (tercond == 1 || terelse == lchain || tercond == (terelse-1) ) {
895 ctemp = chaine(0,tercond-1);
905 ctemp = chaine(tercond,terelse-tercond-1);
908 SetAction(optloc, actionCode, actionParam);
918 ctemp = chaine(terelse,lchain-terelse);
922 SetAction(optloc, actionCode, actionParam);
929 }
else if (ou != 0) {
930 if (ou==1 || ou==lchain-1) {
935 ctemp = chaine(0,ou-1);
944 ctemp = chaine(ou+1,lchain-ou-1);
955 if (et==1 || et==lchain-1) {
960 ctemp = chaine(0,et-1);
970 ctemp = chaine(et+1,lchain-et-1);
981 if (oux==1 || oux==lchain) {
986 ctemp = chaine(0,oux-1);
989 ctemp = chaine(oux,lchain-oux);
998 if (etx==1 || etx==lchain) {
1003 ctemp = chaine(0,etx-1);
1004 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1006 ctemp = chaine(etx,lchain-etx);
1007 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1014 }
else if (petit != 0) {
1015 if (petit==1 || petit==lchain) {
1020 ctemp = chaine(0,petit-1);
1021 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1023 ctemp = chaine(petit,lchain-petit);
1024 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1031 }
else if (grand != 0) {
1032 if (grand==1 || grand==lchain) {
1037 ctemp = chaine(0,grand-1);
1038 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1040 ctemp = chaine(grand,lchain-grand);
1041 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1048 }
else if (peteg != 0) {
1049 if (peteg==1 || peteg==lchain-1) {
1054 ctemp = chaine(0,peteg-1);
1055 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1056 ctemp = chaine(peteg+1,lchain-peteg-1);
1058 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1065 }
else if (grdeg != 0) {
1066 if (grdeg==1 || grdeg==lchain-1) {
1071 ctemp = chaine(0,grdeg-1);
1072 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1074 ctemp = chaine(grdeg+1,lchain-grdeg-1);
1075 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1082 }
else if (egal != 0) {
1083 if (egal==1 || egal==lchain-1) {
1088 ctemp = chaine(0,egal-1);
1089 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1092 ctemp = chaine(egal+1,lchain-egal-1);
1093 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1098 if (
IsString(optloc) != isstring) {
1100 chaine_error =
"==";
1101 }
else if (isstring) {
1107 }
else if (diff != 0) {
1108 if (diff==1 || diff==lchain-1) {
1110 chaine_error =
"!=";
1113 ctemp = chaine(0,diff-1);
1114 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1117 ctemp = chaine(diff+1,lchain-diff-1);
1118 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1123 if (
IsString(optloc) != isstring) {
1125 chaine_error =
"!=";
1126 }
else if (isstring) {
1132 }
else if (plus != 0) {
1138 ctemp = chaine(0,plus-1);
1139 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1141 ctemp = chaine(plus,lchain-plus);
1142 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1152 ctemp = chaine(moins,lchain-moins);
1153 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1160 if (moins == lchain) {
1164 ctemp = chaine(0,moins-1);
1165 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1167 ctemp = chaine(moins,lchain-moins);
1168 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1176 }
else if (modulo != 0) {
1177 if (modulo == 1 || modulo == lchain) {
1181 ctemp = chaine(0,modulo-1);
1182 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1184 ctemp = chaine(modulo,lchain-modulo);
1185 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1192 }
else if (rshift != 0) {
1193 if (rshift == 1 || rshift == lchain) {
1197 ctemp = chaine(0,rshift-1);
1198 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1200 ctemp = chaine(rshift+1,lchain-rshift-1);
1201 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1208 }
else if (lshift != 0) {
1209 if (lshift == 1 || lshift == lchain) {
1213 ctemp = chaine(0,lshift-1);
1214 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1216 ctemp = chaine(lshift+1,lchain-lshift-1);
1217 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1226 if (multi == 1 || multi == lchain) {
1231 ctemp = chaine(0,multi-1);
1232 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1234 ctemp = chaine(multi,lchain-multi);
1235 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1244 if (divi == 1 || divi == lchain) {
1249 ctemp = chaine(0,divi-1);
1250 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1252 ctemp = chaine(divi,lchain-divi);
1253 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1262 if (puiss == 1 || puiss == lchain) {
1264 chaine_error =
"**";
1267 if (chaine(lchain-2,2) ==
"^2") {
1268 ctemp =
"sq(" + chaine(0,lchain-2) +
")";
1269 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1271 ctemp = chaine(0,puiss-1);
1272 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1274 ctemp = chaine(puiss,lchain-puiss);
1275 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1292 if ((chaine(0,2)==
"0x")||(chaine(0,2)==
"0X")) isHexa=
kTRUE;
1293 for (j=0; j<chaine.
Length() && err==0; j++) {
1296 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-")) {
1299 chaine_error=chaine;
1306 if (chaine(j,2)==
"e+" || chaine(j,2)==
"e-" || chaine(j,2)==
"E+" || chaine(j,2)==
"E-") j++;
1309 if (chaine(j,1) ==
"." && !hasDot) hasDot =
kTRUE;
1314 if (!strchr(
"0123456789",t) && (chaine(j,1)!=
"+" || j!=0)) {
1316 chaine_error=chaine;
1322 if (!strchr(
"0123456789abcdefABCDEF",t) && (j>1)) {
1324 chaine_error=chaine;
1330 if (!isHexa) {
if (sscanf((
const char*)chaine,
"%lg",&vafConst) > 0) err = 0;
else err =1;}
1331 else {
if (sscanf((
const char*)chaine,
"%lx",&vafConst2) > 0) err = 0;
else err=1;
1336 if (vafConst ==
fConst[j] ) k= j;
1338 if ( k < 0) { k =
fNconst; fNconst++;
fConst[k] = vafConst; }
1353 oldformula = (
const TFormula*)
gROOT->GetListOfFunctions()->FindObject((
const char*)chaine);
1355 if (oldformula && strcmp(schain,oldformula->
GetTitle())) {
1366 for (
Int_t ipar=0;ipar<npold;ipar++) {
1386 chaine_error = ctemp;
1387 }
else if ( k >= 0 ) {
1389 actionCode = action;
1398 }
else if (chaine(0,1) ==
"!") {
1399 ctemp = chaine(1,lchain-1);
1400 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1406 }
else if (chaine(0,1)==
"\"" && chaine(chaine.
Length()-1,1)==
"\"") {
1412 }
else if (chaine(0,4) ==
"cos(") {
1413 ctemp = chaine(3,lchain-3);
1414 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1420 }
else if (chaine(0,4) ==
"sin(") {
1421 ctemp = chaine(3,lchain-3);
1422 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1428 }
else if (chaine(0,4) ==
"tan(") {
1429 ctemp = chaine(3,lchain-3);
1430 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1436 }
else if (chaine(0,5) ==
"acos(") {
1437 ctemp = chaine(4,lchain-4);
1438 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1444 }
else if (chaine(0,5) ==
"asin(") {
1445 ctemp = chaine(4,lchain-4);
1446 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1452 }
else if (chaine(0,5) ==
"atan(") {
1453 ctemp = chaine(4,lchain-4);
1454 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1460 }
else if (chaine(0,5) ==
"cosh(") {
1461 ctemp = chaine(4,lchain-4);
1462 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1468 }
else if (chaine(0,5) ==
"sinh(") {
1469 ctemp = chaine(4,lchain-4);
1470 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1476 }
else if (chaine(0,5) ==
"tanh(") {
1477 ctemp = chaine(4,lchain-4);
1478 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1484 }
else if (chaine(0,6) ==
"acosh(") {
1485 ctemp = chaine(5,lchain-5);
1486 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1492 }
else if (chaine(0,6) ==
"asinh(") {
1493 ctemp = chaine(5,lchain-5);
1494 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1500 }
else if (chaine(0,6) ==
"atanh(") {
1501 ctemp = chaine(5,lchain-5);
1502 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1508 }
else if (chaine(0,3) ==
"sq(") {
1509 ctemp = chaine(2,lchain-2);
1510 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1516 }
else if (chaine(0,4) ==
"log(") {
1517 ctemp = chaine(3,lchain-3);
1518 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1524 }
else if (chaine(0,6) ==
"log10(") {
1525 ctemp = chaine(5,lchain-5);
1526 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1532 }
else if (chaine(0,4) ==
"exp(") {
1533 ctemp = chaine(3,lchain-3);
1534 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1540 }
else if (chaine(0,4) ==
"abs(") {
1541 ctemp = chaine(3,lchain-3);
1542 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1548 }
else if (chaine(0,5) ==
"sign(") {
1549 ctemp = chaine(4,lchain-4);
1550 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1556 }
else if (chaine(0,4) ==
"int(") {
1557 ctemp = chaine(3,lchain-3);
1558 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1564 }
else if (chaine ==
"rndm" || chaine(0,5) ==
"rndm(") {
1569 }
else if (chaine(0,5) ==
"sqrt(") {
1570 ctemp = chaine(4,lchain-4);
1571 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1580 }
else if ( chaine ==
"expo" || chaine(0,5)==
"expo(" 1581 || (lchain==5 && chaine(1,4)==
"expo")
1582 || (lchain==6 && chaine(2,4)==
"expo")
1583 || chaine(1,5)==
"expo(" || chaine(2,5)==
"expo(" ) {
1585 if (chaine(1,4) ==
"expo") {
1590 else if (ctemp==
"y") {
1593 else if (ctemp==
"z") {
1596 else if (ctemp==
"t") {
1601 chaine_error=chaine1ST;
1603 chaine=chaine(1,lchain-1);
1606 if (chaine(2,4) ==
"expo") {
1607 if (chaine(0,2) !=
"xy") {
1609 chaine_error=chaine1ST;
1614 chaine=chaine(2,lchain-2);
1622 actionCode =
kexpo + inter2;
1623 actionParam = offset;
1625 if (inter2 == 5+offset &&
fNpar < 3+offset)
fNpar = 3+offset;
1634 }
else if (chaine(4,1) ==
"(") {
1635 ctemp = chaine(5,lchain-6);
1637 for (j=0; j<ctemp.
Length(); j++) {
1639 if (strchr(
"0123456789",t)==0 && (ctemp(j,1)!=
"+" || j!=0)) {
1641 chaine_error=chaine1ST;
1645 sscanf(ctemp.
Data(),
"%d",&inter);
1648 actionCode =
kexpo + inter2;
1649 actionParam = inter;
1651 if (inter2 == 5) inter++;
1660 chaine_error=chaine;
1665 }
else if (chaine==
"gaus" 1666 || (lchain==5 && chaine(1,4)==
"gaus")
1667 || (lchain==6 && chaine(2,4)==
"gaus")
1668 || chaine(0,5)==
"gaus(" || chaine(1,5)==
"gaus(" || chaine(2,5)==
"gaus(") {
1670 if (chaine(1,4) ==
"gaus") {
1675 else if (ctemp==
"y") {
1678 else if (ctemp==
"z") {
1681 else if (ctemp==
"t") {
1686 chaine_error=chaine1ST;
1688 chaine=chaine(1,lchain-1);
1691 if (chaine(2,4) ==
"gaus") {
1692 if (chaine(0,2) !=
"xy") {
1694 chaine_error=chaine1ST;
1699 chaine=chaine(2,lchain-2);
1704 if (lchain == 4 && err==0) {
1708 actionCode =
kgaus + inter2;
1709 actionParam = offset;
1711 if (inter2 == 5+offset &&
fNpar < 5+offset)
fNpar = 5+offset;
1720 }
else if (chaine(4,1) ==
"(" && err==0) {
1721 ctemp = chaine(5,lchain-6);
1723 for (j=0; j<ctemp.
Length(); j++) {
1725 if (strchr(
"0123456789",t)==0 && (ctemp(j,1)!=
"+" || j!=0)) {
1727 chaine_error=chaine1ST;
1731 sscanf(ctemp.
Data(),
"%d",&inter);
1734 actionCode =
kgaus + inter2;
1735 actionParam = inter;
1737 if (inter2 == 5) inter += 2;
1744 }
else if (err==0) {
1746 chaine_error=chaine1ST;
1751 }
else if (chaine==
"landau" || (lchain==7 && chaine(1,6)==
"landau")
1752 || (lchain==8 && chaine(2,6)==
"landau")
1753 || chaine(0,7)==
"landau(" || chaine(1,7)==
"landau(" || chaine(2,7)==
"landau(") {
1755 if (chaine(1,6) ==
"landau") {
1760 else if (ctemp==
"y") {
1763 else if (ctemp==
"z") {
1766 else if (ctemp==
"t") {
1771 chaine_error=chaine1ST;
1773 chaine=chaine(1,lchain-1);
1776 if (chaine(2,6) ==
"landau") {
1777 if (chaine(0,2) !=
"xy") {
1779 chaine_error=chaine1ST;
1784 chaine=chaine(2,lchain-2);
1789 if (lchain == 6 && err==0) {
1793 actionCode =
klandau + inter2;
1794 actionParam = offset;
1796 if (inter2 == 5+offset &&
fNpar < 5+offset)
fNpar = 5+offset;
1805 }
else if (chaine(6,1) ==
"(" && err==0) {
1806 ctemp = chaine(7,lchain-8);
1808 for (j=0; j<ctemp.
Length(); j++) {
1810 if (strchr(
"0123456789",t)==0 && (ctemp(j,1)!=
"+" || j!=0)) {
1812 chaine_error=chaine1ST;
1816 sscanf(ctemp.
Data(),
"%d",&inter);
1819 actionCode =
klandau + inter2;
1820 actionParam = inter;
1822 if (inter2 == 5) inter += 2;
1829 }
else if (err==0) {
1831 chaine_error=chaine1ST;
1836 }
else if (chaine(0,3) ==
"pol" || chaine(1,3) ==
"pol") {
1838 if (chaine(1,3) ==
"pol") {
1843 else if (ctemp==
"y") {
1846 else if (ctemp==
"z") {
1849 else if (ctemp==
"t") {
1854 chaine_error=chaine1ST;
1856 chaine=chaine(1,lchain-1);
1859 if (chaine(lchain-1,1) ==
")") {
1861 for (j=3;j<lchain;j++)
if (chaine(j,1)==
"(" && nomb == 0) nomb = j;
1862 if (nomb == 3) err = 23;
1863 if (nomb == 0) err = 40;
1864 ctemp = chaine(nomb+1,lchain-nomb-2);
1865 for (j=0; j<ctemp.
Length(); j++) {
1867 if (strchr(
"0123456789",t)==0 && (ctemp(j,1)!=
"+" || j!=0)) {
1869 chaine_error=chaine1ST;
1873 sscanf(ctemp.
Data(),
"%d",&inter);
1874 if (inter < 0) err = 20;
1883 ctemp = chaine(3,nomb-3);
1884 if (sscanf(ctemp.
Data(),
"%d",&
n) > 0) {
1885 if (n < 0 ) err = 24;
1886 if (n >= 20) err = 25;
1891 actionCode =
kpol+(inter2-1);
1892 actionParam = n*100+inter+2;
1905 }
else if (chaine(0,4) ==
"pow(") {
1906 compt = 4; nomb = 0; virgule = 0; nest=0;
1907 while(compt != lchain) {
1909 if (chaine(compt-1,1) ==
"(") nest++;
1910 else if (chaine(compt-1,1) ==
")") nest--;
1911 else if (chaine(compt-1,1) ==
"," && nest==0) {
1913 if (nomb == 1 && virgule == 0) virgule = compt;
1916 if (nomb != 1) err = 22;
1918 ctemp = chaine(4,virgule-5);
1919 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1921 ctemp = chaine(virgule,lchain-virgule-1);
1922 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1929 }
else if (chaine(0,7) ==
"strstr(") {
1930 compt = 7; nomb = 0; virgule = 0; nest=0;
1932 while(compt != lchain) {
1934 if (chaine(compt-1,1) ==
"\"") {
1935 inString = !inString;
1936 }
else if (!inString) {
1937 if (chaine(compt-1,1) ==
"(") nest++;
1938 else if (chaine(compt-1,1) ==
")") nest--;
1939 else if (chaine(compt-1,1) ==
"," && nest==0) {
1941 if (nomb == 1 && virgule == 0) virgule = compt;
1945 if (nomb != 1) err = 28;
1947 ctemp = chaine(7,virgule-8);
1948 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1951 ctemp = chaine(virgule,lchain-virgule-1);
1952 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1960 chaine_error =
"strstr";
1963 }
else if (chaine(0,4) ==
"min(") {
1964 compt = 4; nomb = 0; virgule = 0; nest=0;
1965 while(compt != lchain) {
1967 if (chaine(compt-1,1) ==
"(") nest++;
1968 else if (chaine(compt-1,1) ==
")") nest--;
1969 else if (chaine(compt-1,1) ==
"," && nest==0) {
1971 if (nomb == 1 && virgule == 0) virgule = compt;
1979 ctemp = chaine(4,virgule-5);
1980 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1982 ctemp = chaine(virgule,lchain-virgule-1);
1983 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
1990 }
else if (chaine(0,4) ==
"max(") {
1991 compt = 4; nomb = 0; virgule = 0; nest=0;
1992 while(compt != lchain) {
1994 if (chaine(compt-1,1) ==
"(") nest++;
1995 else if (chaine(compt-1,1) ==
")") nest--;
1996 else if (chaine(compt-1,1) ==
"," && nest==0) {
1998 if (nomb == 1 && virgule == 0) virgule = compt;
2006 ctemp = chaine(4,virgule-5);
2007 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
2009 ctemp = chaine(virgule,lchain-virgule-1);
2010 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
2018 }
else if (chaine(0,6) ==
"atan2(") {
2019 compt = 6; nomb = 0; virgule = 0; nest=0;
2020 while(compt != lchain) {
2022 if (chaine(compt-1,1) ==
"(") nest++;
2023 else if (chaine(compt-1,1) ==
")") nest--;
2024 else if (chaine(compt-1,1) ==
"," && nest==0) {
2026 if (nomb == 1 && virgule == 0) virgule = compt;
2029 if (nomb != 1) err = 21;
2031 ctemp = chaine(6,virgule-7);
2032 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
2034 ctemp = chaine(virgule,lchain-virgule-1);
2035 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
2042 }
else if (chaine(0,5) ==
"fmod(") {
2043 compt = 5; nomb = 0; virgule = 0; nest=0;
2044 while(compt != lchain) {
2046 if (chaine(compt-1,1) ==
"(") nest++;
2047 else if (chaine(compt-1,1) ==
")") nest--;
2048 else if (chaine(compt-1,1) ==
"," && nest==0) {
2050 if (nomb == 1 && virgule == 0) virgule = compt;
2058 ctemp = chaine(5,virgule-6);
2059 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
2061 ctemp = chaine(virgule,lchain-virgule-1);
2062 Analyze(ctemp.
Data(),err,offset);
if (err)
return;
2071 chaine_error = chaine;
2077 }
else if (chaine(0,1) ==
"[" && chaine(lchain-1,1) ==
"]") {
2080 ctemp = chaine(1,lchain-2);
2081 for (j=0; j<ctemp.
Length(); j++) {
2083 if (strchr(
"0123456789",t)==0 && (ctemp(j,1)!=
"+" || j!=0)) {
2085 chaine_error=chaine1ST;
2089 sscanf(ctemp.
Data(),
"%d",&valeur);
2091 actionParam = offset + valeur;
2096 }
else if (chaine ==
"pi") {
2123 chaine_error =
"\""+chaine_error+
"\"";
2125 case 2 : er =
" Invalid Floating Point Operation";
break;
2126 case 4 : er =
" Empty String";
break;
2127 case 5 : er =
" Invalid Syntax " + chaine_error;
break;
2128 case 6 : er =
" Too many operators !";
break;
2129 case 7 : er =
" Too many parameters !";
break;
2130 case 10 : er =
" z specified but not x and y";
break;
2131 case 11 : er =
" z and y specified but not x";
break;
2132 case 12 : er =
" y specified but not x";
break;
2133 case 13 : er =
" z and x specified but not y";
break;
2134 case 20 : er =
" Non integer value for parameter number : " + chaine_error;
break;
2135 case 21 : er =
" ATAN2 requires two arguments";
break;
2136 case 22 : er =
" POW requires two arguments";
break;
2137 case 23 : er =
" Degree of polynomial not specified";
break;
2138 case 24 : er =
" Degree of polynomial must be positive";
break;
2139 case 25 : er =
" Degree of polynomial must be less than 20";
break;
2140 case 26 : er =
" Unknown name : " + chaine_error;
break;
2141 case 27 : er =
" Too many constants in expression";
break;
2142 case 28 : er =
" strstr requires two arguments";
break;
2143 case 29 : er =
" TFormula can only call interpreted and compiled functions that return a numerical type: " + chaine_error;
break;
2144 case 30 : er =
" Bad numerical expression : " + chaine_error;
break;
2145 case 31 : er =
" Part of the Variable " + chaine_error; er +=
" exists but some of it is not accessible or useable";
break;
2146 case 40 : er =
" '(' is expected";
break;
2147 case 41 : er =
" ')' is expected";
break;
2148 case 42 : er =
" '[' is expected";
break;
2149 case 43 : er =
" ']' is expected";
break;
2150 case 44 : er =
" The function '" + chaine(0,err_hint) +
"' requires two arguments.";
break;
2151 case 45 : er =
"The operator " + chaine_error +
" requires a numerical operand.";
break;
2152 case 46 : er =
"Both operands of the operator " + chaine_error +
" have to be either numbers or strings.";
break;
2153 case 47 : er = chaine_error +
" requires 2 string arguments";
break;
2168 Error(
"Compile",
"\"%s\" requires a numerical operand.",
fExpr[oper].
Data());
2188 Error(
"Compile",
"\"%s\" requires two numerical operands.",
fExpr[oper].
Data());
2250 inline static void ResizeArrayIfAllocated(
T*& oldArray,
int newSize){
2253 if (!oldArray || newSize <=0)
return;
2255 T* newArray =
new T[newSize];
2256 std::copy(oldArray, oldArray+newSize, newArray);
2258 oldArray = newArray;
2291 Int_t i,j,lc,valeur,err;
2297 if (strlen(expression))
SetTitle(expression);
2302 char *sctemp =
new char[chaine.
Length()+1];
2303 strlcpy(sctemp,chaine.
Data(),chaine.
Length()+1);
2304 char *semicol = (
char*)strstr(sctemp,
";");
2305 if (semicol) *semicol = 0;
2325 for (i=0; i<
gMAXOP; i++) {
2334 for (i=1; i<=chaine.
Length(); i++) {
2336 if (chaine(i-1,1) ==
"\"") inString = !inString;
2337 if (inString)
continue;
2338 if (chaine(i-1,2) ==
"**") {
2339 chaine = chaine(0,i-1) +
"^" + chaine(i+1,lc-i-1);
2341 }
else if (chaine(i-1,2) ==
"++") {
2342 chaine = chaine(0,i) + chaine(i+1,lc-i-1);
2344 }
else if (chaine(i-1,2) ==
"+-" || chaine(i-1,2) ==
"-+") {
2345 chaine = chaine(0,i-1) +
"-" + chaine(i+1,lc-i-1);
2347 }
else if (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,1) ==
"[") {
2354 for (j=1;j<=chaine.
Length()-i;j++) {
2355 if (chaine(j+i-1,1) ==
"]" || j+i > chaine.
Length())
break;
2357 ctemp = chaine(i,j-1);
2359 sscanf(ctemp.
Data(),
"%d",&valeur);
2361 }
else if (chaine(i-1,1) ==
" ") {
2362 chaine = chaine(0,i-1)+chaine(i,lc-i);
2367 Analyze((
const char*)chaine,err);
2378 if (chaine.Length() > 4)
2384 else if (
GetNumber() == 110 && chaine.Length() > 6 )
2386 else if (
GetNumber() == 410 && chaine.Length() > 8 )
2444 if (err) {
fNdim = 0;
return 1; }
2448 if (!IsA()->GetBaseClass(
"TTreeFormula")) {
2496 while ( (fobj = next()) ) {
2621 if (chaine ==
"x") {
2624 }
else if (chaine ==
"y") {
2627 }
else if (chaine ==
"z") {
2630 }
else if (chaine ==
"t") {
2637 if (chaine.
Data()[0]==
'x'){
2638 if (chaine.
Data()[1]==
'[' && chaine.
Data()[3]==
']'){
2639 const char ch0 =
'0';
2641 if (dim<0)
return -1;
2642 if (dim>9)
return -1;
2646 if (chaine.
Data()[1]==
'[' && chaine.
Data()[4]==
']'){
2647 const char ch0 =
'0';
2648 Int_t dim = (chaine.
Data()[2]-ch0)*10+(chaine.
Data()[3]-ch0);
2649 if (dim<0)
return -1;
2650 if (dim>99)
return -1;
2672 return ((
TFormula*)
this)->EvalPar(xx);
2692 Int_t precalculated = 0;
2693 Int_t precalculated_str = 0;
2697 params =
const_cast<Double_t*
>(uparams);
2704 for (i=0; i<
fNoper; ++i) {
2706 const int oper =
fOper[i];
2714 case kStringConst: { strpos++; stringStack[strpos-1] = (
char*)
fExpr[i].
Data(); pos++; tab[pos-1] = 0;
continue; }
2716 case kAdd : pos--; tab[pos-1] += tab[pos];
continue;
2717 case kSubstract : pos--; tab[pos-1] -= tab[pos];
continue;
2718 case kMultiply : pos--; tab[pos-1] *= tab[pos];
continue;
2719 case kDivide : pos--;
if (tab[pos] == 0) tab[pos-1] = 0;
2720 else tab[pos-1] /= tab[pos];
2745 case kacosh:
if (tab[pos-1] < 1) {tab[pos-1] = 0;}
2754 case kfmod : pos--; tab[pos-1] = fmod(tab[pos-1],tab[pos]);
continue;
2755 case kpow : pos--; tab[pos-1] =
TMath::Power(tab[pos-1],tab[pos]);
continue;
2756 case ksq : tab[pos-1] = tab[pos-1]*tab[pos-1];
continue;
2759 case kstrstr : strpos -= 2; pos-=2; pos++;
2760 if (strstr(stringStack[strpos],stringStack[strpos+1])) tab[pos-1]=1;
2764 case kmin : pos--; tab[pos-1] =
TMath::Min(tab[pos-1],tab[pos]);
continue;
2765 case kmax : pos--; tab[pos-1] =
TMath::Max(tab[pos-1],tab[pos]);
continue;
2767 case klog :
if (tab[pos-1] > 0) tab[pos-1] =
TMath::Log(tab[pos-1]);
2768 else {tab[pos-1] = 0;}
2771 if (dexp < -700) {tab[pos-1] = 0;
continue;}
2772 if (dexp > 700) {tab[pos-1] =
TMath::Exp(700);
continue;}
2775 else {tab[pos-1] = 0;}
2781 case ksign :
if (tab[pos-1] < 0) tab[pos-1] = -1;
else tab[pos-1] = 1;
continue;
2784 case kSignInv: tab[pos-1] = -1 * tab[pos-1];
continue;
2788 case kAnd : pos--;
if (tab[pos-1]!=0 && tab[pos]!=0) tab[pos-1]=1;
2791 case kOr : pos--;
if (tab[pos-1]!=0 || tab[pos]!=0) tab[pos-1]=1;
2794 case kEqual: pos--;
if (tab[pos-1] == tab[pos]) tab[pos-1]=1;
2797 case kNotEqual : pos--;
if (tab[pos-1] != tab[pos]) tab[pos-1]=1;
2800 case kLess : pos--;
if (tab[pos-1] < tab[pos]) tab[pos-1]=1;
2803 case kGreater : pos--;
if (tab[pos-1] > tab[pos]) tab[pos-1]=1;
2807 case kLessThan: pos--;
if (tab[pos-1]<=tab[pos]) tab[pos-1]=1;
2810 case kGreaterThan: pos--;
if (tab[pos-1]>=tab[pos]) tab[pos-1]=1;
2813 case kNot :
if (tab[pos-1]!=0) tab[pos-1] = 0;
else tab[pos-1] = 1;
2817 if (!strcmp(stringStack[strpos+1],stringStack[strpos])) tab[pos-1]=1;
2821 if (strcmp(stringStack[strpos+1],stringStack[strpos])) tab[pos-1]=1;
2825 case kBitAnd : pos--; tab[pos-1]= ((
Int_t) tab[pos-1]) & ((
Int_t) tab[pos]);
continue;
2826 case kBitOr : pos--; tab[pos-1]= ((
Int_t) tab[pos-1]) | ((
Int_t) tab[pos]);
continue;
2838 int op = param % 10;
2840 if (op == 1 && (!tab[pos-1]) ) {
2849 }
else if (op == 2 && tab[pos-1] ) {
2861 int toskip = param / 10;
2871 #define R__EXPO(var) \ 2873 pos++; int param = (oper & kTFOperMask); \ 2874 tab[pos-1] = TMath::Exp(params[param]+params[param+1]*x[var]); \ 2882 tab[pos-1] =
TMath::Exp(params[param]+params[param+1]*x[0]+params[param+2]*x[1]);
2885 #define R__GAUS(var) \ 2887 pos++; int param = (oper & kTFOperMask); \ 2888 tab[pos-1] = params[param]*TMath::Gaus(x[var],params[param+1],params[param+2],IsNormalized()); \ 2898 if (params[param+2] == 0) {
2901 intermede1=
Double_t((x[0]-params[param+1])/params[param+2]);
2904 if (params[param+4] == 0) {
2907 intermede2=
Double_t((x[1]-params[param+3])/params[param+4]);
2909 tab[pos-1] = params[param]*
TMath::Exp(-0.5*(intermede1*intermede1+intermede2*intermede2));
2912 #define R__LANDAU(var) \ 2914 pos++; const int param = (oper & kTFOperMask); \ 2915 tab[pos-1] = params[param]*TMath::Landau(x[var],params[param+1],params[param+2],IsNormalized()); \ 2922 case kxylandau: { pos++;
int param = oper&0x7fffff ;
2925 tab[pos-1] = params[param]*intermede1*intermede2;
2929 #define R__POLY(var) \ 2931 pos++; int param = (oper & kTFOperMask); \ 2932 tab[pos-1] = 0; Double_t intermede = 1; \ 2933 Int_t inter = param/100; \ 2934 Int_t int1= param-inter*100-1; \ 2935 for (j=0 ;j<inter+1;j++) { \ 2936 tab[pos-1] += intermede*params[j+int1]; \ 2937 intermede *= x[var]; \ 2947 if (!precalculated) {
2951 pos++; tab[pos-1] = param_calc[(oper &
kTFOperMask)];
2957 if (!precalculated_str) {
2958 precalculated_str=1;
2961 strpos++; stringStack[strpos-1] = string_calc[param];
2962 pos++; tab[pos-1] = 0;
2970 int fno = param / 1000;
2971 int nargs = param % 1000;
2979 UInt_t argloc = pos-nargs;
2980 for(j=0;j<nargs;j++,argloc++,pos--) {
2994 Warning(
"EvalParOld",
"Found an unsupported opcode (%d)",oper >> kTFOperShift);
3029 Int_t ternaryend = -1;
3033 if (ternaryend==i) {
3035 if(ismulti[spos-1]){
3036 tab[spos-2]=tab[spos-2]+
"("+tab[spos-1]+
")";
3038 tab[spos-2]=tab[spos-2]+tab[spos-1];
3052 tab[spos-1]=
"-("+tab[spos-1]+
")";
3066 if ((optype<=151 && optype>=140 && optype!=145) || (optype == 40)) {
3074 if(((optype>0 && optype<6) || optype==20 ||
3075 (((optype>59 && optype<69) || (optype >75 && optype<82)) && spos>=2))) {
3077 if(ismulti[spos-2]){
3078 tab[spos-2]=
"("+tab[spos-2]+
")";
3080 if(ismulti[spos-1]){
3081 tab[spos-2]+=
fExpr[i]+(
"("+tab[spos-1]+
")");
3083 tab[spos-2]+=
fExpr[i]+tab[spos-1];
3085 ismulti[spos-2]=
kTRUE;
3091 if(ismulti[spos-1]){
3092 tab[spos-1]=
"("+tab[spos-1]+
")?";
3094 tab[spos-1]=tab[spos-1]+
"?";
3098 if (optype==
kJump) {
3099 if(ismulti[spos-1]){
3100 tab[spos-2]=tab[spos-2]+
"("+tab[spos-1]+
"):";
3102 tab[spos-2]=tab[spos-2]+tab[spos-1]+
":";
3112 if((optype>9 && optype<16) ||
3113 (optype>20 && optype<23) ||
3114 (optype>29 && optype<34) ||
3115 (optype>40 && optype<44) ||
3116 (optype>69 && optype<76) ||
3122 if((optype>15 && optype<20) ||
3123 (optype>22 && optype<26)) {
3130 int nargs = param % 1000;
3135 for(j=0, depth=0;j<funcname.
Length();++j) {
3136 switch (funcname[j]) {
3153 Error(
"GetExpFormula",
"Internal error, number of argument found is %d",-offset);
3154 }
else if (offset == 0) {
3155 tab[spos]=funcname+
"()";
3159 }
else if (offset<=0 && (spos+offset>=0)) {
3160 tab[spos+offset]=funcname+(
"("+tab[spos+offset]);
3161 for (j=offset+1; j<0; j++){
3162 tab[spos+offset]+=
","+tab[spos+j];
3164 tab[spos+offset]+=
")";
3165 ismulti[spos+offset]=
kFALSE;
3170 if (ternaryend==fNoper) {
3172 if(ismulti[spos-1]){
3173 tab[spos-2]=tab[spos-2]+
"("+tab[spos-1]+
")";
3175 tab[spos-2]=tab[spos-2]+tab[spos-1];
3181 if (spos > 0) ret = tab[spos-1];
3191 for (j=0;j<
fNpar;j++) {
3221 if (ipar <0 || ipar >=
fNpar)
return 0;
3233 Error(
"TFormula",
"Parameter %s not found", parName);
3244 if (ipar <0 || ipar >=
fNpar)
return "";
3245 if (
fNames[ipar].Length() > 0)
return (
const char*)
fNames[ipar];
3246 return Form(
"p%d",ipar);
3258 if (!strcmp(
GetParName(i),parName))
return i;
3279 Printf(
" fExpr[%d] = %s action = %d action param = %d ",
3285 Printf(
"Optimized expression");
3287 Printf(
" fExpr[%d] = %s\t\t action = %d action param = %d ",
3294 for (i=0;i<
fNpar;i++) {
3308 Int_t nf, offset, replsize;
3310 pch= (
char*)strstr(formula.
Data(),
"++");
3312 formula.
Insert(0,
"[0]*(");
3313 pch= (
char*)strstr(formula.
Data(),
"++");
3319 offset = pch-formula.
Data();
3320 if (nf<10) replsize = 7;
3321 else if (nf<100) replsize = 8;
3323 formula.
Replace(pch-formula.
Data(), 2, repl, replsize);
3324 pch = (
char*)strstr(formula.
Data()+offset,
"++");
3330 formula2=formula2(4, formula2.
Length()-4);
3331 pch= (
char*)strchr(formula2.
Data(),
'[');
3335 offset = pch-formula2.
Data()-1;
3336 if (nf<10) replsize = 5;
3338 formula2.
Replace(pch-formula2.
Data()-1, replsize, repl, 2);
3339 pch = (
char*)strchr(formula2.
Data()+offset,
'[');
3347 formula2 = formula2.
ReplaceAll(
"++", 2,
"|", 1);
3350 for (
Int_t i=0; i<nf; i++) {
3352 replaceformula_name =
"f_linear_";
3353 replaceformula_name.
Append(replaceformula);
3356 Error(
"TFormula",
"f_linear not allocated");
3361 gROOT->GetListOfFunctions()->Remove(f);
3375 if (ipar <0 || ipar >=
fNpar)
return;
3385 if (ipar <0 || ipar >=
fNpar)
return;
3431 if (ipar <0 || ipar >=
fNpar)
return;
3439 const char*name5,
const char*name6,
const char*name7,
const char*name8,
const char*name9,
const char*name10)
3463 Error(
"Streamer",
"version 6 is not supported");
3466 Streamer(b, v, R__s, R__c, onfile_class);
3482 Error(
"Streamer",
"version 6 is not supported");
3485 Streamer(b, v, R__s, R__c,
nullptr);
3503 gROOT->GetListOfFunctions()->Add(
this);
3516 Error(
"Streamer",
"error compiling formula");
3531 TNamed::Streamer(b);
3534 if (v > 1) b >>
fNval;
3551 if (
gROOT->GetListOfFunctions()->FindObject(
GetName()))
return;
3552 gROOT->GetListOfFunctions()->Add(
this);
3569 kOldxylandau = 4500,
3570 kOldConstants = 50000,
3571 kOldStrings = 80000,
3572 kOldVariable = 100000,
3573 kOldTreeString = 105000,
3574 kOldFormulaVar = 110000,
3575 kOldBoolOptimize = 120000,
3576 kOldFunctionCall = 200000
3580 for (i=0,j=0; i<
fNoper; ++i,++j) {
3582 Int_t newActionCode = 0;
3583 Int_t newActionParam = 0;
3591 sscanf((
const char*)
fExpr[i],
"%g",&aresult);
3602 }
else if ( action < 100 ) {
3605 newActionCode = action;
3607 }
else if (action >= kOldFunctionCall) {
3611 newActionParam = action-kOldFunctionCall;
3613 }
else if (action >= kOldBoolOptimize) {
3617 newActionParam = action-kOldBoolOptimize;
3619 }
else if (action >= kOldFormulaVar) {
3623 newActionParam = action-kOldFormulaVar;
3625 }
else if (action >= kOldTreeString) {
3629 newActionParam = action-kOldTreeString;
3631 }
else if (action >= kOldVariable) {
3635 newActionParam = action-kOldVariable;
3637 }
else if (action == kOldStrings) {
3642 }
else if (action >= kOldConstants) {
3646 newActionParam = action-kOldConstants;
3648 }
else if (action > 10000 && action < kOldConstants) {
3651 int var = action/10000;
3652 newActionCode =
kpol + (var-1);
3653 newActionParam = action - var*10000;
3655 }
else if (action >= 4600) {
3657 Error(
"Convert",
"Unsupported value %d",action);
3659 }
else if (action > kOldxylandau) {
3663 newActionParam = action - (kOldxylandau+1);
3665 }
else if (action > kOldlandau) {
3669 int var = action/100-40;
3670 if (var) newActionCode += var;
3671 newActionParam = action - var*100 - (kOldlandau+1);
3673 }
else if (action > 2500 && action < 2600) {
3677 newActionParam = action-2501;
3679 }
else if (action > 2000 && action < 2500) {
3682 newActionCode =
kgaus;
3683 int var = action/100-20;
3684 if (var) newActionCode += var;
3685 newActionParam = action - var*100 - (kOldgaus+1);
3687 }
else if (action > 1500 && action < 1600) {
3691 newActionParam = action-1501;
3693 }
else if (action > 1000 && action < 1500) {
3696 newActionCode =
kexpo;
3697 int var = action/100-10;
3698 if (var) newActionCode += var;
3699 newActionParam = action - var*100 - (kOldexpo+1);
3701 }
if (action > 100 && action < 200) {
3705 newActionParam = action - 101;
3708 SetAction( j, newActionCode, newActionParam );
3747 int paran = cbase.
First(
"(");
3754 if (cbase==
"<") cbase=
"XlY";
3755 if (cbase==
"<=") cbase=
"XleY";
3756 if (cbase==
">") cbase=
"XgY";
3757 if (cbase==
">=") cbase=
"XgeY";
3764 if (prim->
fType==10) {
3767 if (prim->
fType==110) {
3770 if (prim->
fType==1110) {
3773 if (prim->
fType==-1) {
3776 if (prim->
fType==0){
3832 for (i=0; i<
fNoper; i++) {
3847 Int_t maxfound = fNoper+1;
3866 for (i=0;i<
fNoper;i++) optimized[i]=0;
3926 if ((i+1) >= fNoper)
continue;
3953 if ((i+2) >= fNoper)
continue;
3977 if (offset[0]==offset[2]&&offset[1]==offset[3]) {
3990 if ((i+3) >= fNoper)
continue;
4023 if (offset[0]==offset[2]&&offset[1]==offset[3]&&offset[0]==offset[4]&&offset[1]==offset[5]){
4058 if (optimized[i]==0){
4089 fNOperOptimized = operO;
4092 if (fNOperOptimized==1) {
4105 delete [] optimized;
4195 Int_t precalculated = 0;
4196 Int_t precalculated_str = 0;
4202 params =
const_cast<Double_t*
>(uparams);
4220 case kPlusD : tab[pos-1]+= pdata[fOperOffset[i].fType0][fOperOffset[i].fOffset0];
continue;
4221 case kMultD : tab[pos-1]*= pdata[fOperOffset[i].fType0][fOperOffset[i].fOffset0];
continue;
4222 case kAdd : pos--; tab[pos-1] += tab[pos];
continue;
4223 case kSubstract : pos--; tab[pos-1] -= tab[pos];
continue;
4224 case kMultiply : pos--; tab[pos-1] *= tab[pos];
continue;
4225 case kDivide : pos--;
if (tab[pos] == 0) tab[pos-1] = 0;
4226 else tab[pos-1] /= tab[pos];
4228 case kUnary : tab[pos] = (
fPredefined[i]->
fFunc10)(pdata[fOperOffset[i].fType0][fOperOffset[i].fOffset0]); pos++;
continue;
4230 pdata[fOperOffset[i].fType1][fOperOffset[i].fOffset1]);pos++;
continue;
4233 pdata[fOperOffset[i].fType1][fOperOffset[i].fOffset1],
4234 pdata[fOperOffset[i].fType2][fOperOffset[i].fOffset2]); pos++;
continue;
4236 case kFDM : tab[pos] = (
fPredefined[i]->
fFuncG)(&x[fOperOffset[i].fType0],¶ms[fOperOffset[i].fOffset0]); pos++;
continue;
4251 case kAnd : pos--; tab[pos-1] = (bool)tab[pos];
continue;
4252 case kOr : pos--; tab[pos-1] = (bool)tab[pos];
continue;
4256 case kabs :
if (tab[pos-1]<0) tab[pos-1]=-tab[pos-1];
continue;
4257 case ksign :
if (tab[pos-1] < 0) tab[pos-1] = -1;
else tab[pos-1] = 1;
continue;
4259 case kpow : pos--; tab[pos-1] =
TMath::Power(tab[pos-1],tab[pos]);
continue;
4269 case kfmod : pos--; tab[pos-1] = fmod(tab[pos-1],tab[pos]);
continue;
4271 case kstrstr : strpos -= 2; pos-=2; pos++;
4272 if (strstr(stringStack[strpos],stringStack[strpos+1])) tab[pos-1]=1;
4278 case kSignInv: tab[pos-1] = -1 * tab[pos-1];
continue;
4283 case kEqual: pos--;
if (tab[pos-1] == tab[pos]) tab[pos-1]=1;
4286 case kNotEqual : pos--;
if (tab[pos-1] != tab[pos]) tab[pos-1]=1;
4289 case kNot :
if (tab[pos-1]!=0) tab[pos-1] = 0;
else tab[pos-1] = 1;
4293 if (!strcmp(stringStack[strpos+1],stringStack[strpos])) tab[pos-1]=1;
4297 if (strcmp(stringStack[strpos+1],stringStack[strpos])) tab[pos-1]=1;
4301 case kBitAnd : pos--; tab[pos-1]= ((
Int_t) tab[pos-1]) & ((
Int_t) tab[pos]);
continue;
4302 case kBitOr : pos--; tab[pos-1]= ((
Int_t) tab[pos-1]) | ((
Int_t) tab[pos]);
continue;
4313 int op = param % 10;
4315 if (op == 1 && (!tab[pos-1]) ) {
4324 }
else if (op == 2 && tab[pos-1] ) {
4341 #define R__EXPO(var) \ 4343 pos++; int param = (oper & kTFOperMask); \ 4344 tab[pos-1] = TMath::Exp(params[param]+params[param+1]*x[var]); \ 4352 tab[pos-1] =
TMath::Exp(params[param]+params[param+1]*x[0]+params[param+2]*x[1]);
4357 #define R__GAUS(var) \ 4359 pos++; int param = (oper & kTFOperMask); \ 4360 tab[pos-1] = params[param]*TMath::Gaus(x[var],params[param+1], \ 4361 params[param+2],IsNormalized()); \ 4371 if (params[param+2] == 0) {
4374 intermede1=
Double_t((x[0]-params[param+1])/params[param+2]);
4377 if (params[param+4] == 0) {
4380 intermede2=
Double_t((x[1]-params[param+3])/params[param+4]);
4382 tab[pos-1] = params[param]*
TMath::Exp(-0.5*(intermede1*intermede1+intermede2*intermede2));
4385 #define R__LANDAU(var) \ 4387 pos++; const int param = (oper & kTFOperMask); \ 4388 tab[pos-1] = params[param]*TMath::Landau(x[var],params[param+1],params[param+2],IsNormalized()); \ 4395 case kxylandau: { pos++;
int param = oper&0x7fffff ;
4398 tab[pos-1] = params[param]*intermede1*intermede2;
4402 #define R__POLY(var) \ 4404 pos++; int param = (oper & kTFOperMask); \ 4405 tab[pos-1] = 0; Double_t intermede = 1; \ 4406 Int_t inter = param/100; \ 4407 Int_t int1= param-inter*100-1; \ 4408 for (j=0 ;j<inter+1;j++) { \ 4409 tab[pos-1] += intermede*params[j+int1]; \ 4410 intermede *= x[var]; \ 4420 if (!precalculated) {
4424 pos++; tab[pos-1] = param_calc[(oper &
kTFOperMask)];
4430 if (!precalculated_str) {
4431 precalculated_str=1;
4434 strpos++; stringStack[strpos-1] = string_calc[param];
4435 pos++; tab[pos-1] = 0;
4443 int fno = param / 1000;
4444 int nargs = param % 1000;
4452 UInt_t argloc = pos-nargs;
4453 for(j=0;j<nargs;j++,argloc++,pos--) {
4467 Warning(
"EvalParFast",
"Found an unsupported optmized opcode (%d)",oper >> kTFOperShift);
4481 if (str.
Length()<3)
return 1;
4482 if (str[str.
Length()-1]!=
'+'&&str[str.
Length()-2]!=
'+')
return 1;
4484 TString funName(
"preformula_");
4488 fileName.
Form(
"/tmp/%s.C",funName.
Data());
4491 hf = fopen(fileName.
Data(),
"w");
4493 Error(
"PreCompile",
"Unable to open the file %s for writing.",fileName.
Data());
4496 fprintf(hf,
"/////////////////////////////////////////////////////////////////////////\n");
4497 fprintf(hf,
"// This code has been automatically generated \n");
4499 fprintf(hf,
"Double_t %s(Double_t *x, Double_t *p){",funName.
Data());
4500 fprintf(hf,
"return (%s);\n}",str.
Data());
TOperOffset()
TOper offset - helper class for TFormula* specify type of operand fTypeX = kVariable = kParameter = k...
virtual const char * GetName() const
Returns name of object.
Double_t Landau(Double_t x, Double_t mpv=0, Double_t sigma=1, Bool_t norm=kFALSE)
The LANDAU function.
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
static double p3(double t, double a, double b, double c, double d)
Namespace for new ROOT classes and functions.
Collectable string class.
static const EReturnType kOther
virtual void Delete(Option_t *option="")
Remove all objects from the array AND delete all heap based objects.
TString & ReplaceAll(const TString &s1, const TString &s2)
Bool_t TestBit(UInt_t f) const
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
Buffer base class used for serializing objects.
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
Short_t Min(Short_t a, Short_t b)
void ToLower()
Change string to lower-case.
R__EXTERN TVirtualMutex * gROOTMutex
TObject * At(Int_t idx) const
TString & Insert(Ssiz_t pos, const char *s)
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
The TNamed class is the base class for all named ROOT classes.
Double_t Log10(Double_t x)
static double p2(double t, double a, double b, double c)
TString & Append(const char *cs)
std::vector< std::vector< double > > Data
ClassInfo_t * GetClassInfo() const
Ssiz_t First(char c) const
Find first occurrence of a character c.
Double_t ATan2(Double_t, Double_t)
Method or function calling interface.
Bool_t TestBitNumber(UInt_t bitnumber) const
virtual Double_t Rndm()
Machine independent random number generator.
Int_t GetLast() const
Return index of last object in array.
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
char * Form(const char *fmt,...)
The ROOT global object gROOT contains a list of all defined classes.
static double p1(double t, double a, double b)
R__EXTERN TRandom * gRandom
Bool_t IsValid() const
Return true if the method call has been properly initialized and is usable.
#define R__LOCKGUARD2(mutex)
TString & Remove(Ssiz_t pos)
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
TFunction * GetMethod()
Returns the TMethod describing the method to be executed.
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
TObject * UncheckedAt(Int_t i) const
void ResetParam()
Reset parameter list. To be used before the first call the SetParam().
Ssiz_t Last(char c) const
Find last occurrence of a character c.
virtual void Expand(Int_t newSize)
Expand or shrink the array to newSize elements.
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
virtual const char * GetPrototype() const
Returns the prototype of a function as defined by CINT, or 0 in case of error.
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Mother of all ROOT objects.
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
you should not use this method at all Int_t Int_t z
virtual void Copy(TObject &named) const
Copy this to obj.
void Execute(const char *, const char *, int *=0)
Execute method on this object with the given parameter string, e.g.
Short_t Max(Short_t a, Short_t b)
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
void SetParam(Long_t l)
Add a long method parameter.
Double_t Sqrt(Double_t x)
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
static char * skip(char **buf, const char *delimiters)
void SetBitNumber(UInt_t bitnumber, Bool_t value=kTRUE)
EReturnType ReturnType()
Returns the return type of the method.
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
virtual const char * GetTitle() const
Returns title of object.
virtual Int_t ReadArray(Bool_t *&b)=0
const char * Data() const