29 #pragma optimize("",off)
182 if (!expression || !*expression) {
183 Error(
"TFormula",
"expression may not be 0 or have 0 length");
189 nch = strlen(expression);
190 char *expr =
new char[nch+1];
192 for (i=0;i<nch;i++) {
193 if (expression[i] ==
' ')
continue;
194 if (i > 0 && (expression[i] ==
'*') && (expression[i-1] ==
'*')) {
198 expr[j] = expression[i]; j++;
217 Warning(
"TFormula",
"Cannot use both gaus and gausn - gaus will be treated as gausn");
219 Warning(
"TFormula",
"Cannot use both gausn and landau - landau will be treated as landaun");
228 Warning(
"TFormula",
"Cannot use both gaus and landaun - gaus will be treated as gausn");
231 Warning(
"TFormula",
"Cannot use both landau and landaun - landau will be treated as landaun");
239 SetTitle(chaine.
Data());
243 if (linear) SetBit(kLinear);
245 if (Compile())
return;
247 if (gausNorm) SetBit(kNormalized);
248 if (landauNorm) SetBit(kNormalized);
253 if (strcmp(name,
"x")==0 || strcmp(name,
"y")==0 ||
254 strcmp(name,
"z")==0 || strcmp(name,
"t")==0 )
256 Error(
"TFormula",
"The name \'%s\' is reserved as a TFormula variable name.\n"
257 "\tThis function will not be registered in the list of functions",name);
262 gROOT->GetListOfFunctions()->Remove(old);
264 gROOT->GetListOfFunctions()->Add(
this);
292 ((
TFormula&)formula).TFormula::Copy(*
this);
315 gROOT->GetListOfFunctions()->Remove(
this);
349 if (argStart<0)
return false;
351 TString functionName = chaine(0,argStart);
357 if (scopeEnd>0 && functionName[scopeEnd-1]==
':') {
358 spaceName = functionName(0,scopeEnd-1);
359 functionName.
Remove(0,scopeEnd+1);
364 if (chaine[chaine.
Length()-1] !=
')') {
365 Error(
"AnalyzeFunction",
"We thought we had a function but we dont (in %s)\n",chaine.
Data());
368 TString args = chaine(argStart+1,chaine.
Length()-2-argStart);
378 for(i=0; i<args.
Length(); i++) {
379 if (args[i]==
'"') inString = !inString;
380 if (inString)
continue;
385 case '(': paran++;
break;
386 case ')': paran--;
break;
387 case '[': brack++;
break;
388 case ']': brack--;
break;
390 case ',':
if (paran==0 && brack==0) { foundArg =
true; }
break;
392 if ((i+1)==args.
Length()) {
393 foundArg =
true; i++;
396 TString arg = args(prevComma,i-prevComma);
417 ClassInfo_t *cinfo = 0;
426 static TypeInfo_t *
const doubletype {
gInterpreter->TypeInfo_Factory(
"double") };
428 std::vector<TypeInfo_t*> proto(nargs,doubletype);
430 CallFunc_t *callfunc =
gInterpreter->CallFunc_Factory();
457 fFunctions.Add(method);
459 SetAction(fNoper, kFunctionCall, fFunctions.GetLast()*1000 + nargs);
477 if (prim && (!
IsA()->GetBaseClass(
"TTreeFormula"))) {
486 Error(
"Compile",
"%s requires %d arguments",
490 fExpr[fNoper] = prim->
GetName();
491 if (prim->
fType==10){
492 SetAction(fNoper, kFD1);
494 if (prim->
fType==110){
495 SetAction(fNoper, kFD2);
497 if (prim->
fType==1110){
498 SetAction(fNoper, kFD3);
500 if (prim->
fType==-1){
501 SetAction(fNoper, kFDM);
502 if (fNpar<prim->fNParameters) fNpar+=prim->
fNParameters;
664 void TFormula::Analyze(
const char *schain,
Int_t &err,
Int_t offset)
701 Int_t valeur,find,
n,i,j,k,lchain,nomb,virgule,inter,nest;
702 valeur=find=n=i=j=k=lchain=nomb=virgule=inter=nest = 0;
703 Int_t compt,compt2,compt3,compt4;
708 TString s,chaine_error,chaine1ST;
713 Int_t modulo,plus,puiss10,puiss10bis,moins,multi,divi,puiss,et,ou,petit,grand,egal,diff,peteg,grdeg,etx,oux,rshift,lshift,tercond,terelse;
718 Int_t actionCode,actionParam;
726 while (parenthese && lchain>0 && err==0){
731 if (lchain==0) err=4;
733 for (i=1; i<=lchain; ++i) {
734 if (chaine(i-1,1) ==
"\"") inString = !inString;
736 if (chaine(i-1,1) ==
"[") compt2++;
737 if (chaine(i-1,1) ==
"]") compt2--;
738 if (chaine(i-1,1) ==
"(") compt++;
739 if (chaine(i-1,1) ==
")") compt--;
741 if (compt < 0) err = 40;
742 if (compt2< 0) err = 42;
743 if (compt==0 && (i!=lchain || lchain==1)) parenthese =
kFALSE;
746 if (compt > 0) err = 41;
747 if (compt2> 0) err = 43;
748 if (parenthese) chaine = chaine(1,lchain-2);
752 if (lchain==0) err=4;
753 modulo=plus=moins=multi=divi=puiss=et=ou=petit=grand=egal=diff=peteg=grdeg=etx=oux=rshift=lshift=tercond=terelse=0;
758 compt = compt2 = compt3 = compt4 = 0;puiss10=0;puiss10bis = 0;
763 for (i=1;i<=lchain; i++) {
765 puiss10=puiss10bis=0;
768 isdecimal = isdecimal && (strchr(
"0123456789.",t)!=0);
770 if ( chaine[i-2] ==
'e' || chaine[i-2] ==
'E' ) puiss10 = 1;
771 }
else if ( strchr(
"+-/[]()&|><=!*/%^\\",t) ) {
776 if (chaine[j-2] ==
'e' || chaine[j-2] ==
'E') {
777 Bool_t isrightdecimal = 1;
779 for(k=j-3; k>=0 && isrightdecimal; --k) {
781 isrightdecimal = isrightdecimal && (strchr(
"0123456789.",t)!=0);
782 if (!isrightdecimal) {
783 if (strchr(
"+-/[]()&|><=!*/%^\\",t)!=0) {
788 if (k<0 && isrightdecimal) puiss10bis = 1;
791 if (puiss10 && (i<=lchain)) {
793 puiss10 = (strchr(
"0123456789.",t)!=0);
795 if (puiss10bis && (j<=lchain)) {
797 puiss10bis = (strchr(
"0123456789.",t)!=0);
800 if (chaine(i-1,1) ==
"\"") inString = !inString;
801 if (inString)
continue;
802 if (chaine(i-1,1) ==
"[") compt2++;
803 if (chaine(i-1,1) ==
"]") compt2--;
804 if (chaine(i-1,1) ==
"(") compt++;
805 if (chaine(i-1,1) ==
")") compt--;
806 if (chaine(j-1,1) ==
"[") compt3++;
807 if (chaine(j-1,1) ==
"]") compt3--;
808 if (chaine(j-1,1) ==
"(") compt4++;
809 if (chaine(j-1,1) ==
")") compt4--;
810 if (chaine(i-1,2)==
"&&" && !inString && compt==0 && compt2==0 && et==0) {et=i;puiss=0;}
811 if (chaine(i-1,2)==
"||" && compt==0 && compt2==0 && ou==0) {puiss10=0; ou=i;}
812 if (chaine(i-1,1)==
"&" && compt==0 && compt2==0 && etx==0) {etx=i;puiss=0;}
813 if (chaine(i-1,1)==
"|" && compt==0 && compt2==0 && oux==0) {puiss10=0; oux=i;}
814 if (chaine(i-1,2)==
">>" && compt==0 && compt2==0 && rshift==0) {puiss10=0; rshift=i;}
815 if (chaine(i-1,1)==
">" && compt==0 && compt2==0 && rshift==0 && grand==0)
816 {puiss10=0; grand=i;}
817 if (chaine(i-1,2)==
"<<" && compt==0 && compt2==0 && lshift==0) {puiss10=0; lshift=i;}
818 if (chaine(i-1,1)==
"<" && compt==0 && compt2==0 && lshift==0 && petit==0)
822 for(
int ip = i,depth=0; ip < lchain; ++ip) {
826 if (isalnum(c) || c==
'_' || c==
',')
continue;
827 if (c==
':' && chaine(ip+1)==
':') { ++ip;
continue; }
828 if (c==
'<') { ++depth;
continue; }
830 if (depth) { --depth;
continue; }
846 if ((chaine(i-1,2)==
"<=" || chaine(i-1,2)==
"=<") && compt==0 && compt2==0
847 && peteg==0) {peteg=i; puiss10=0; petit=0;}
848 if ((chaine(i-1,2)==
"=>" || chaine(i-1,2)==
">=") && compt==0 && compt2==0
849 && grdeg==0) {puiss10=0; grdeg=i; grand=0;}
850 if (chaine(i-1,2) ==
"==" && compt == 0 && compt2 == 0 && egal == 0) {puiss10=0; egal=i;}
851 if (chaine(i-1,2) ==
"!=" && compt == 0 && compt2 == 0 && diff == 0) {puiss10=0; diff=i;}
852 if (i>1 && chaine(i-1,1) ==
"+" && compt == 0 && compt2 == 0 && puiss10==0) plus=i;
853 if (chaine(j-1,1) ==
"-" && chaine(j-2,1) !=
"*" && chaine(j-2,1) !=
"/"
854 && chaine(j-2,1)!=
"^" && compt3==0 && compt4==0 && moins==0 && puiss10bis==0) moins=j;
855 if (chaine(i-1,1)==
"%" && compt==0 && compt2==0 && modulo==0) {puiss10=0; modulo=i;}
856 if (chaine(i-1,1)==
"*" && compt==0 && compt2==0 && multi==0) {puiss10=0; multi=i;}
857 if (chaine(j-1,1)==
"/" && chaine(j-2,1)!=
"\\"
858 && compt4==0 && compt3==0 && divi==0)
862 if (chaine(j-1)==
'^' && compt4==0 && compt3==0 && puiss==0) {puiss10=0; puiss=j;}
863 if (chaine(i-1)==
'?' && compt == 0 && compt2 == 0 && tercond == 0) {puiss10=0; tercond=i;}
864 if (chaine(i-1)==
':' && tercond && compt == 0 && compt2 == 0 && terelse == 0) {
865 if (i>2 && chaine(i-2)!=
':' && chaine(i)!=
':') {
866 puiss10=0; terelse=i;
876 if (tercond && terelse) {
877 if (tercond == 1 || terelse == lchain || tercond == (terelse-1) ) {
882 ctemp = chaine(0,tercond-1);
883 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
885 fExpr[fNoper] =
"?: condition jump";
886 actionCode = kJumpIf;
888 SetAction(fNoper,actionCode, actionParam);
889 Int_t optloc = fNoper++;
892 ctemp = chaine(tercond,terelse-tercond-1);
893 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
894 actionParam = fNoper;
895 SetAction(optloc, actionCode, actionParam);
897 fExpr[fNoper] =
"?: else jump";
901 SetAction(fNoper,actionCode, actionParam);
905 ctemp = chaine(terelse,lchain-terelse);
906 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
908 actionParam = fNoper - 1;
909 SetAction(optloc, actionCode, actionParam);
911 if (IsString(optloc-1) != IsString(fNoper-1)) {
916 }
else if (ou != 0) {
917 if (ou==1 || ou==lchain-1) {
922 ctemp = chaine(0,ou-1);
923 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
925 fExpr[fNoper] =
"|| checkpoint";
926 actionCode = kBoolOptimize;
928 SetAction(fNoper,actionCode, actionParam);
929 Int_t optloc = fNoper++;
931 ctemp = chaine(ou+1,lchain-ou-1);
932 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
933 fExpr[fNoper] =
"||";
935 SetAction(fNoper,actionCode, 0);
937 SetAction( optloc, GetAction(optloc), GetActionParam(optloc) + (fNoper-optloc) * 10);
939 if (!CheckOperands(optloc-1,fNoper-1,err))
return;
942 if (et==1 || et==lchain-1) {
947 ctemp = chaine(0,et-1);
948 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
950 fExpr[fNoper] =
"&& checkpoint";
951 actionCode = kBoolOptimize;
953 SetAction(fNoper,actionCode,actionParam);
955 Int_t optloc = fNoper++;
957 ctemp = chaine(et+1,lchain-et-1);
958 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
959 fExpr[fNoper] =
"&&";
961 SetAction(fNoper,actionCode,0);
963 SetAction(optloc, GetAction(optloc), GetActionParam(optloc) + (fNoper-optloc) * 10);
965 if (!CheckOperands(optloc-1,fNoper-1,err))
return;
968 if (oux==1 || oux==lchain) {
973 ctemp = chaine(0,oux-1);
974 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
975 UInt_t leftopr = fNoper-1;
976 ctemp = chaine(oux,lchain-oux);
977 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
980 SetAction(fNoper,actionCode,actionParam);
982 if (!CheckOperands(leftopr,fNoper-1,err))
return;
985 if (etx==1 || etx==lchain) {
990 ctemp = chaine(0,etx-1);
991 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
992 UInt_t leftopr = fNoper-1;
993 ctemp = chaine(etx,lchain-etx);
994 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
996 actionCode = kBitAnd;
997 SetAction(fNoper,actionCode,actionParam);
999 if (!CheckOperands(leftopr,fNoper-1,err))
return;
1001 }
else if (petit != 0) {
1002 if (petit==1 || petit==lchain) {
1007 ctemp = chaine(0,petit-1);
1008 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1009 UInt_t leftopr = fNoper-1;
1010 ctemp = chaine(petit,lchain-petit);
1011 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1012 fExpr[fNoper] =
"<";
1014 SetAction(fNoper,actionCode,actionParam);
1016 if (!CheckOperands(leftopr,fNoper-1,err))
return;
1018 }
else if (grand != 0) {
1019 if (grand==1 || grand==lchain) {
1024 ctemp = chaine(0,grand-1);
1025 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1026 UInt_t leftopr = fNoper-1;
1027 ctemp = chaine(grand,lchain-grand);
1028 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1029 fExpr[fNoper] =
">";
1030 actionCode = kGreater;
1031 SetAction(fNoper,actionCode,actionParam);
1033 if (!CheckOperands(leftopr,fNoper-1,err))
return;
1035 }
else if (peteg != 0) {
1036 if (peteg==1 || peteg==lchain-1) {
1041 ctemp = chaine(0,peteg-1);
1042 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1043 ctemp = chaine(peteg+1,lchain-peteg-1);
1044 UInt_t leftopr = fNoper-1;
1045 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1046 fExpr[fNoper] =
"<=";
1047 actionCode = kLessThan;
1048 SetAction(fNoper,actionCode,actionParam);
1050 if (!CheckOperands(leftopr,fNoper-1,err))
return;
1052 }
else if (grdeg != 0) {
1053 if (grdeg==1 || grdeg==lchain-1) {
1058 ctemp = chaine(0,grdeg-1);
1059 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1060 UInt_t leftopr = fNoper-1;
1061 ctemp = chaine(grdeg+1,lchain-grdeg-1);
1062 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1063 fExpr[fNoper] =
">=";
1064 actionCode = kGreaterThan;
1065 SetAction(fNoper,actionCode,actionParam);
1067 if (!CheckOperands(leftopr,fNoper-1,err))
return;
1069 }
else if (egal != 0) {
1070 if (egal==1 || egal==lchain-1) {
1075 ctemp = chaine(0,egal-1);
1076 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1077 Int_t optloc = fNoper-1;
1079 ctemp = chaine(egal+1,lchain-egal-1);
1080 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1081 fExpr[fNoper] =
"==";
1082 actionCode = kEqual;
1084 Bool_t isstring = IsString(fNoper-1);
1085 if (IsString(optloc) != isstring) {
1087 chaine_error =
"==";
1088 }
else if (isstring) {
1089 actionCode = kStringEqual;
1091 SetAction(fNoper,actionCode,actionParam);
1094 }
else if (diff != 0) {
1095 if (diff==1 || diff==lchain-1) {
1097 chaine_error =
"!=";
1100 ctemp = chaine(0,diff-1);
1101 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1102 Int_t optloc = fNoper-1;
1104 ctemp = chaine(diff+1,lchain-diff-1);
1105 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1106 fExpr[fNoper] =
"!=";
1107 actionCode = kNotEqual;
1109 Bool_t isstring = IsString(fNoper-1);
1110 if (IsString(optloc) != isstring) {
1112 chaine_error =
"!=";
1113 }
else if (isstring) {
1114 actionCode = kStringNotEqual;
1116 SetAction(fNoper,actionCode,actionParam);
1119 }
else if (plus != 0) {
1125 ctemp = chaine(0,plus-1);
1126 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1127 UInt_t leftopr = fNoper-1;
1128 ctemp = chaine(plus,lchain-plus);
1129 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1130 fExpr[fNoper] =
"+";
1132 SetAction(fNoper,actionCode,actionParam);
1134 if (!CheckOperands(leftopr,fNoper-1,err))
return;
1139 ctemp = chaine(moins,lchain-moins);
1140 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1141 fExpr[fNoper] =
"-";
1142 actionCode = kSignInv;
1143 SetAction(fNoper,actionCode,actionParam);
1145 if (!CheckOperands(fNoper-1,err))
return;
1147 if (moins == lchain) {
1151 ctemp = chaine(0,moins-1);
1152 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1153 UInt_t leftopr = fNoper-1;
1154 ctemp = chaine(moins,lchain-moins);
1155 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1156 fExpr[fNoper] =
"-";
1157 actionCode = kSubstract;
1158 SetAction(fNoper,actionCode,actionParam);
1160 if (!CheckOperands(leftopr,fNoper-1,err))
return;
1163 }
else if (modulo != 0) {
1164 if (modulo == 1 || modulo == lchain) {
1168 ctemp = chaine(0,modulo-1);
1169 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1170 UInt_t leftopr = fNoper-1;
1171 ctemp = chaine(modulo,lchain-modulo);
1172 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1173 fExpr[fNoper] =
"%";
1174 actionCode = kModulo;
1175 SetAction(fNoper,actionCode,actionParam);
1177 if (!CheckOperands(leftopr,fNoper-1,err))
return;
1179 }
else if (rshift != 0) {
1180 if (rshift == 1 || rshift == lchain) {
1184 ctemp = chaine(0,rshift-1);
1185 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1186 UInt_t leftopr = fNoper-1;
1187 ctemp = chaine(rshift+1,lchain-rshift-1);
1188 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1189 fExpr[fNoper] =
">>";
1190 actionCode = kRightShift;
1191 SetAction(fNoper,actionCode,actionParam);
1193 if (!CheckOperands(leftopr,fNoper-1,err))
return;
1195 }
else if (lshift != 0) {
1196 if (lshift == 1 || lshift == lchain) {
1200 ctemp = chaine(0,lshift-1);
1201 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1202 UInt_t leftopr = fNoper-1;
1203 ctemp = chaine(lshift+1,lchain-lshift-1);
1204 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1205 fExpr[fNoper] =
">>";
1206 actionCode = kLeftShift;
1207 SetAction(fNoper,actionCode,actionParam);
1209 if (!CheckOperands(leftopr,fNoper-1,err))
return;
1213 if (multi == 1 || multi == lchain) {
1218 ctemp = chaine(0,multi-1);
1219 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1220 UInt_t leftopr = fNoper-1;
1221 ctemp = chaine(multi,lchain-multi);
1222 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1223 fExpr[fNoper] =
"*";
1225 SetAction(fNoper,actionCode,actionParam);
1227 if (!CheckOperands(leftopr,fNoper-1,err))
return;
1231 if (divi == 1 || divi == lchain) {
1236 ctemp = chaine(0,divi-1);
1237 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1238 UInt_t leftopr = fNoper-1;
1239 ctemp = chaine(divi,lchain-divi);
1240 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1241 fExpr[fNoper] =
"/";
1242 actionCode = kDivide;
1243 SetAction(fNoper,actionCode,actionParam);
1245 if (!CheckOperands(leftopr,fNoper-1,err))
return;
1249 if (puiss == 1 || puiss == lchain) {
1251 chaine_error =
"**";
1254 if (chaine(lchain-2,2) ==
"^2") {
1255 ctemp =
"sq(" + chaine(0,lchain-2) +
")";
1256 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1258 ctemp = chaine(0,puiss-1);
1259 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1260 UInt_t leftopr = fNoper-1;
1261 ctemp = chaine(puiss,lchain-puiss);
1262 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1263 fExpr[fNoper] =
"^";
1265 SetAction(fNoper,actionCode,actionParam);
1267 if (!CheckOperands(leftopr,fNoper-1,err))
return;
1279 if ((chaine(0,2)==
"0x")||(chaine(0,2)==
"0X")) isHexa=
kTRUE;
1280 for (j=0; j<chaine.
Length() && err==0; j++) {
1283 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-")) {
1286 chaine_error=chaine;
1293 if (chaine(j,2)==
"e+" || chaine(j,2)==
"e-" || chaine(j,2)==
"E+" || chaine(j,2)==
"E-") j++;
1296 if (chaine(j,1) ==
"." && !hasDot) hasDot =
kTRUE;
1301 if (!strchr(
"0123456789",t) && (chaine(j,1)!=
"+" || j!=0)) {
1303 chaine_error=chaine;
1309 if (!strchr(
"0123456789abcdefABCDEF",t) && (j>1)) {
1311 chaine_error=chaine;
1317 if (!isHexa) {
if (sscanf((
const char*)chaine,
"%lg",&vafConst) > 0) err = 0;
else err =1;}
1318 else {
if (sscanf((
const char*)chaine,
"%lx",&vafConst2) > 0) err = 0;
else err=1;
1320 fExpr[fNoper] = chaine;
1322 for (j=0;j<fNconst;j++) {
1323 if (vafConst == fConst[j] ) k= j;
1325 if ( k < 0) { k = fNconst; fNconst++; fConst[k] = vafConst; }
1326 actionCode = kConstant;
1328 SetAction(fNoper,actionCode,actionParam);
1340 oldformula = (
const TFormula*)
gROOT->GetListOfFunctions()->FindObject((
const char*)chaine);
1342 if (oldformula && strcmp(schain,oldformula->
GetTitle())) {
1343 Int_t nprior = fNpar;
1346 if (oldformula->IsNormalized()) SetBit(kNormalized);
1353 for (
Int_t ipar=0;ipar<npold;ipar++) {
1354 fParams[ipar+fNpar-npold] = oldformula->
GetParameter(ipar);
1367 k = DefinedVariable(ctemp,action);
1373 chaine_error = ctemp;
1374 }
else if ( k >= 0 ) {
1375 fExpr[fNoper] = ctemp;
1376 actionCode = action;
1378 SetAction(fNoper,actionCode,actionParam);
1379 if (action==kDefinedString) fNstring++;
1380 else if (k <
kMAXFOUND && !fAlreadyFound.TestBitNumber(k)) {
1381 fAlreadyFound.SetBitNumber(k);
1385 }
else if (chaine(0,1) ==
"!") {
1386 ctemp = chaine(1,lchain-1);
1387 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1388 fExpr[fNoper] =
"!";
1390 SetAction(fNoper,actionCode,actionParam);
1392 if (!CheckOperands(fNoper-1,err))
return;
1393 }
else if (chaine(0,1)==
"\"" && chaine(chaine.
Length()-1,1)==
"\"") {
1395 fExpr[fNoper] = chaine(1,chaine.
Length()-2);
1396 actionCode = kStringConst;
1397 SetAction(fNoper,actionCode,actionParam);
1399 }
else if (chaine(0,4) ==
"cos(") {
1400 ctemp = chaine(3,lchain-3);
1401 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1402 fExpr[fNoper] =
"cos";
1404 SetAction(fNoper,actionCode,actionParam);
1406 if (!CheckOperands(fNoper-1,err))
return;
1407 }
else if (chaine(0,4) ==
"sin(") {
1408 ctemp = chaine(3,lchain-3);
1409 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1410 fExpr[fNoper] =
"sin";
1412 SetAction(fNoper,actionCode,actionParam);
1414 if (!CheckOperands(fNoper-1,err))
return;
1415 }
else if (chaine(0,4) ==
"tan(") {
1416 ctemp = chaine(3,lchain-3);
1417 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1418 fExpr[fNoper] =
"tan";
1420 SetAction(fNoper,actionCode,actionParam);
1422 if (!CheckOperands(fNoper-1,err))
return;
1423 }
else if (chaine(0,5) ==
"acos(") {
1424 ctemp = chaine(4,lchain-4);
1425 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1426 fExpr[fNoper] =
"acos";
1428 SetAction(fNoper,actionCode,actionParam);
1430 if (!CheckOperands(fNoper-1,err))
return;
1431 }
else if (chaine(0,5) ==
"asin(") {
1432 ctemp = chaine(4,lchain-4);
1433 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1434 fExpr[fNoper] =
"asin";
1436 SetAction(fNoper,actionCode,actionParam);
1438 if (!CheckOperands(fNoper-1,err))
return;
1439 }
else if (chaine(0,5) ==
"atan(") {
1440 ctemp = chaine(4,lchain-4);
1441 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1442 fExpr[fNoper] =
"atan";
1444 SetAction(fNoper,actionCode,actionParam);
1446 if (!CheckOperands(fNoper-1,err))
return;
1447 }
else if (chaine(0,5) ==
"cosh(") {
1448 ctemp = chaine(4,lchain-4);
1449 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1450 fExpr[fNoper] =
"cosh";
1452 SetAction(fNoper,actionCode,actionParam);
1454 if (!CheckOperands(fNoper-1,err))
return;
1455 }
else if (chaine(0,5) ==
"sinh(") {
1456 ctemp = chaine(4,lchain-4);
1457 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1458 fExpr[fNoper] =
"sinh";
1460 SetAction(fNoper,actionCode,actionParam);
1462 if (!CheckOperands(fNoper-1,err))
return;
1463 }
else if (chaine(0,5) ==
"tanh(") {
1464 ctemp = chaine(4,lchain-4);
1465 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1466 fExpr[fNoper] =
"tanh";
1468 SetAction(fNoper,actionCode,actionParam);
1470 if (!CheckOperands(fNoper-1,err))
return;
1471 }
else if (chaine(0,6) ==
"acosh(") {
1472 ctemp = chaine(5,lchain-5);
1473 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1474 fExpr[fNoper] =
"acosh";
1475 actionCode = kacosh;
1476 SetAction(fNoper,actionCode,actionParam);
1478 if (!CheckOperands(fNoper-1,err))
return;
1479 }
else if (chaine(0,6) ==
"asinh(") {
1480 ctemp = chaine(5,lchain-5);
1481 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1482 fExpr[fNoper] =
"asinh";
1483 actionCode = kasinh;
1484 SetAction(fNoper,actionCode,actionParam);
1486 if (!CheckOperands(fNoper-1,err))
return;
1487 }
else if (chaine(0,6) ==
"atanh(") {
1488 ctemp = chaine(5,lchain-5);
1489 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1490 fExpr[fNoper] =
"atanh";
1491 actionCode = katanh;
1492 SetAction(fNoper,actionCode,actionParam);
1494 if (!CheckOperands(fNoper-1,err))
return;
1495 }
else if (chaine(0,3) ==
"sq(") {
1496 ctemp = chaine(2,lchain-2);
1497 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1498 fExpr[fNoper] =
"sq";
1500 SetAction(fNoper,actionCode,actionParam);
1502 if (!CheckOperands(fNoper-1,err))
return;
1503 }
else if (chaine(0,4) ==
"log(") {
1504 ctemp = chaine(3,lchain-3);
1505 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1506 fExpr[fNoper] =
"log";
1508 SetAction(fNoper,actionCode,actionParam);
1510 if (!CheckOperands(fNoper-1,err))
return;
1511 }
else if (chaine(0,6) ==
"log10(") {
1512 ctemp = chaine(5,lchain-5);
1513 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1514 fExpr[fNoper] =
"log10";
1515 actionCode = klog10;
1516 SetAction(fNoper,actionCode,actionParam);
1518 if (!CheckOperands(fNoper-1,err))
return;
1519 }
else if (chaine(0,4) ==
"exp(") {
1520 ctemp = chaine(3,lchain-3);
1521 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1522 fExpr[fNoper] =
"exp";
1524 SetAction(fNoper,actionCode,actionParam);
1526 if (!CheckOperands(fNoper-1,err))
return;
1527 }
else if (chaine(0,4) ==
"abs(") {
1528 ctemp = chaine(3,lchain-3);
1529 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1530 fExpr[fNoper] =
"abs";
1532 SetAction(fNoper,actionCode,actionParam);
1534 if (!CheckOperands(fNoper-1,err))
return;
1535 }
else if (chaine(0,5) ==
"sign(") {
1536 ctemp = chaine(4,lchain-4);
1537 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1538 fExpr[fNoper] =
"sign";
1540 SetAction(fNoper,actionCode,actionParam);
1542 if (!CheckOperands(fNoper-1,err))
return;
1543 }
else if (chaine(0,4) ==
"int(") {
1544 ctemp = chaine(3,lchain-3);
1545 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1546 fExpr[fNoper] =
"int";
1548 SetAction(fNoper,actionCode,actionParam);
1550 if (!CheckOperands(fNoper-1,err))
return;
1551 }
else if (chaine ==
"rndm" || chaine(0,5) ==
"rndm(") {
1552 fExpr[fNoper] =
"rndm";
1554 SetAction(fNoper,actionCode,actionParam);
1556 }
else if (chaine(0,5) ==
"sqrt(") {
1557 ctemp = chaine(4,lchain-4);
1558 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1559 fExpr[fNoper] =
"sqrt";
1561 SetAction(fNoper,actionCode,actionParam);
1563 if (!CheckOperands(fNoper-1,err))
return;
1567 }
else if ( chaine ==
"expo" || chaine(0,5)==
"expo("
1568 || (lchain==5 && chaine(1,4)==
"expo")
1569 || (lchain==6 && chaine(2,4)==
"expo")
1570 || chaine(1,5)==
"expo(" || chaine(2,5)==
"expo(" ) {
1572 if (chaine(1,4) ==
"expo") {
1576 if (fNdim < 1) fNdim = 1; }
1577 else if (ctemp==
"y") {
1579 if (fNdim < 2) fNdim = 2; }
1580 else if (ctemp==
"z") {
1582 if (fNdim < 3) fNdim = 3; }
1583 else if (ctemp==
"t") {
1585 if (fNdim < 4) fNdim = 4; }
1588 chaine_error=chaine1ST;
1590 chaine=chaine(1,lchain-1);
1593 if (chaine(2,4) ==
"expo") {
1594 if (chaine(0,2) !=
"xy") {
1596 chaine_error=chaine1ST;
1600 if (fNdim < 2) fNdim = 2;
1601 chaine=chaine(2,lchain-2);
1608 fExpr[fNoper] = chaine1ST;
1609 actionCode = kexpo + inter2;
1611 SetAction(fNoper,actionCode,actionParam);
1612 if (inter2 == 5+offset && fNpar < 3+offset) fNpar = 3+
offset;
1613 if (fNpar < 2+offset) fNpar = 2+
offset;
1617 if (fNdim < 1) fNdim = 1;
1618 if (fNpar == 2) SetNumber(200);
1621 }
else if (chaine(4,1) ==
"(") {
1622 ctemp = chaine(5,lchain-6);
1623 fExpr[fNoper] = chaine1ST;
1624 for (j=0; j<ctemp.
Length(); j++) {
1626 if (strchr(
"0123456789",t)==0 && (ctemp(j,1)!=
"+" || j!=0)) {
1628 chaine_error=chaine1ST;
1632 sscanf(ctemp.
Data(),
"%d",&inter);
1635 actionCode = kexpo + inter2;
1636 actionParam = inter;
1637 SetAction(fNoper,actionCode,actionParam);
1638 if (inter2 == 5) inter++;
1639 if (inter+2>fNpar) fNpar = inter+2;
1642 if (fNpar == 2) SetNumber(200);
1647 chaine_error=chaine;
1652 }
else if (chaine==
"gaus"
1653 || (lchain==5 && chaine(1,4)==
"gaus")
1654 || (lchain==6 && chaine(2,4)==
"gaus")
1655 || chaine(0,5)==
"gaus(" || chaine(1,5)==
"gaus(" || chaine(2,5)==
"gaus(") {
1657 if (chaine(1,4) ==
"gaus") {
1661 if (fNdim < 1) fNdim = 1; }
1662 else if (ctemp==
"y") {
1664 if (fNdim < 2) fNdim = 2; }
1665 else if (ctemp==
"z") {
1667 if (fNdim < 3) fNdim = 3; }
1668 else if (ctemp==
"t") {
1670 if (fNdim < 4) fNdim = 4; }
1673 chaine_error=chaine1ST;
1675 chaine=chaine(1,lchain-1);
1678 if (chaine(2,4) ==
"gaus") {
1679 if (chaine(0,2) !=
"xy") {
1681 chaine_error=chaine1ST;
1685 if (fNdim < 2) fNdim = 2;
1686 chaine=chaine(2,lchain-2);
1691 if (lchain == 4 && err==0) {
1694 fExpr[fNoper] = chaine1ST;
1695 actionCode = kgaus + inter2;
1697 SetAction(fNoper,actionCode,actionParam);
1698 if (inter2 == 5+offset && fNpar < 5+offset) fNpar = 5+
offset;
1699 if (3+offset>fNpar) fNpar = 3+
offset;
1703 if (fNdim < 1) fNdim = 1;
1704 if (fNpar == 3) SetNumber(100);
1707 }
else if (chaine(4,1) ==
"(" && err==0) {
1708 ctemp = chaine(5,lchain-6);
1709 fExpr[fNoper] = chaine1ST;
1710 for (j=0; j<ctemp.
Length(); j++) {
1712 if (strchr(
"0123456789",t)==0 && (ctemp(j,1)!=
"+" || j!=0)) {
1714 chaine_error=chaine1ST;
1718 sscanf(ctemp.
Data(),
"%d",&inter);
1721 actionCode = kgaus + inter2;
1722 actionParam = inter;
1723 SetAction(fNoper,actionCode,actionParam);
1724 if (inter2 == 5) inter += 2;
1725 if (inter+3>fNpar) fNpar = inter+3;
1728 if(fNpar == 3) SetNumber(100);
1731 }
else if (err==0) {
1733 chaine_error=chaine1ST;
1738 }
else if (chaine==
"landau" || (lchain==7 && chaine(1,6)==
"landau")
1739 || (lchain==8 && chaine(2,6)==
"landau")
1740 || chaine(0,7)==
"landau(" || chaine(1,7)==
"landau(" || chaine(2,7)==
"landau(") {
1742 if (chaine(1,6) ==
"landau") {
1746 if (fNdim < 1) fNdim = 1; }
1747 else if (ctemp==
"y") {
1749 if (fNdim < 2) fNdim = 2; }
1750 else if (ctemp==
"z") {
1752 if (fNdim < 3) fNdim = 3; }
1753 else if (ctemp==
"t") {
1755 if (fNdim < 4) fNdim = 4; }
1758 chaine_error=chaine1ST;
1760 chaine=chaine(1,lchain-1);
1763 if (chaine(2,6) ==
"landau") {
1764 if (chaine(0,2) !=
"xy") {
1766 chaine_error=chaine1ST;
1770 if (fNdim < 2) fNdim = 2;
1771 chaine=chaine(2,lchain-2);
1776 if (lchain == 6 && err==0) {
1779 fExpr[fNoper] = chaine1ST;
1780 actionCode = klandau + inter2;
1782 SetAction(fNoper,actionCode,actionParam);
1783 if (inter2 == 5+offset && fNpar < 5+offset) fNpar = 5+
offset;
1784 if (3+offset>fNpar) fNpar = 3+
offset;
1788 if (fNdim < 1) fNdim = 1;
1789 if (fNpar == 3) SetNumber(400);
1792 }
else if (chaine(6,1) ==
"(" && err==0) {
1793 ctemp = chaine(7,lchain-8);
1794 fExpr[fNoper] = chaine1ST;
1795 for (j=0; j<ctemp.
Length(); j++) {
1797 if (strchr(
"0123456789",t)==0 && (ctemp(j,1)!=
"+" || j!=0)) {
1799 chaine_error=chaine1ST;
1803 sscanf(ctemp.
Data(),
"%d",&inter);
1806 actionCode = klandau + inter2;
1807 actionParam = inter;
1808 SetAction(fNoper,actionCode,actionParam);
1809 if (inter2 == 5) inter += 2;
1810 if (inter+3>fNpar) fNpar = inter+3;
1813 if (fNpar == 3) SetNumber(400);
1816 }
else if (err==0) {
1818 chaine_error=chaine1ST;
1823 }
else if (chaine(0,3) ==
"pol" || chaine(1,3) ==
"pol") {
1825 if (chaine(1,3) ==
"pol") {
1829 if (fNdim < 1) fNdim = 1; }
1830 else if (ctemp==
"y") {
1832 if (fNdim < 2) fNdim = 2; }
1833 else if (ctemp==
"z") {
1835 if (fNdim < 3) fNdim = 3; }
1836 else if (ctemp==
"t") {
1838 if (fNdim < 4) fNdim = 4; }
1841 chaine_error=chaine1ST;
1843 chaine=chaine(1,lchain-1);
1846 if (chaine(lchain-1,1) ==
")") {
1848 for (j=3;j<lchain;j++)
if (chaine(j,1)==
"(" && nomb == 0) nomb = j;
1849 if (nomb == 3) err = 23;
1850 if (nomb == 0) err = 40;
1851 ctemp = chaine(nomb+1,lchain-nomb-2);
1852 for (j=0; j<ctemp.
Length(); j++) {
1854 if (strchr(
"0123456789",t)==0 && (ctemp(j,1)!=
"+" || j!=0)) {
1856 chaine_error=chaine1ST;
1860 sscanf(ctemp.
Data(),
"%d",&inter);
1861 if (inter < 0) err = 20;
1870 ctemp = chaine(3,nomb-3);
1871 if (sscanf(ctemp.
Data(),
"%d",&
n) > 0) {
1872 if (n < 0 ) err = 24;
1873 if (n >= 20) err = 25;
1877 fExpr[fNoper] = chaine1ST;
1878 actionCode = kpol+(inter2-1);
1879 actionParam = n*100+inter+2;
1880 SetAction(fNoper,actionCode,actionParam);
1881 if (inter+n+1>=fNpar) fNpar = inter + n + 2;
1885 if (fNdim < 1) fNdim = 1;
1892 }
else if (chaine(0,4) ==
"pow(") {
1893 compt = 4; nomb = 0; virgule = 0; nest=0;
1894 while(compt != lchain) {
1896 if (chaine(compt-1,1) ==
"(") nest++;
1897 else if (chaine(compt-1,1) ==
")") nest--;
1898 else if (chaine(compt-1,1) ==
"," && nest==0) {
1900 if (nomb == 1 && virgule == 0) virgule = compt;
1903 if (nomb != 1) err = 22;
1905 ctemp = chaine(4,virgule-5);
1906 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1907 UInt_t leftopr = fNoper-1;
1908 ctemp = chaine(virgule,lchain-virgule-1);
1909 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1910 fExpr[fNoper] =
"^";
1912 SetAction(fNoper,actionCode,actionParam);
1914 if (!CheckOperands(leftopr,fNoper-1,err))
return;
1916 }
else if (chaine(0,7) ==
"strstr(") {
1917 compt = 7; nomb = 0; virgule = 0; nest=0;
1919 while(compt != lchain) {
1921 if (chaine(compt-1,1) ==
"\"") {
1922 inString = !inString;
1923 }
else if (!inString) {
1924 if (chaine(compt-1,1) ==
"(") nest++;
1925 else if (chaine(compt-1,1) ==
")") nest--;
1926 else if (chaine(compt-1,1) ==
"," && nest==0) {
1928 if (nomb == 1 && virgule == 0) virgule = compt;
1932 if (nomb != 1) err = 28;
1934 ctemp = chaine(7,virgule-8);
1935 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1936 Int_t optloc = fNoper-1;
1938 ctemp = chaine(virgule,lchain-virgule-1);
1939 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1940 fExpr[fNoper] =
"strstr";
1941 actionCode = kstrstr;
1942 SetAction(fNoper,actionCode,actionParam);
1945 if ( !IsString(optloc) || !IsString(fNoper-2) ) {
1947 chaine_error =
"strstr";
1950 }
else if (chaine(0,4) ==
"min(") {
1951 compt = 4; nomb = 0; virgule = 0; nest=0;
1952 while(compt != lchain) {
1954 if (chaine(compt-1,1) ==
"(") nest++;
1955 else if (chaine(compt-1,1) ==
")") nest--;
1956 else if (chaine(compt-1,1) ==
"," && nest==0) {
1958 if (nomb == 1 && virgule == 0) virgule = compt;
1966 ctemp = chaine(4,virgule-5);
1967 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1968 UInt_t leftopr = fNoper-1;
1969 ctemp = chaine(virgule,lchain-virgule-1);
1970 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1971 fExpr[fNoper] =
"min";
1973 SetAction(fNoper,actionCode,actionParam);
1975 if (!CheckOperands(leftopr,fNoper-1,err))
return;
1977 }
else if (chaine(0,4) ==
"max(") {
1978 compt = 4; nomb = 0; virgule = 0; nest=0;
1979 while(compt != lchain) {
1981 if (chaine(compt-1,1) ==
"(") nest++;
1982 else if (chaine(compt-1,1) ==
")") nest--;
1983 else if (chaine(compt-1,1) ==
"," && nest==0) {
1985 if (nomb == 1 && virgule == 0) virgule = compt;
1993 ctemp = chaine(4,virgule-5);
1994 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1995 UInt_t leftopr = fNoper-1;
1996 ctemp = chaine(virgule,lchain-virgule-1);
1997 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
1998 fExpr[fNoper] =
"max";
2000 SetAction(fNoper,actionCode,actionParam);
2002 if (!CheckOperands(leftopr,fNoper-1,err))
return;
2005 }
else if (chaine(0,6) ==
"atan2(") {
2006 compt = 6; nomb = 0; virgule = 0; nest=0;
2007 while(compt != lchain) {
2009 if (chaine(compt-1,1) ==
"(") nest++;
2010 else if (chaine(compt-1,1) ==
")") nest--;
2011 else if (chaine(compt-1,1) ==
"," && nest==0) {
2013 if (nomb == 1 && virgule == 0) virgule = compt;
2016 if (nomb != 1) err = 21;
2018 ctemp = chaine(6,virgule-7);
2019 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
2020 UInt_t leftopr = fNoper-1;
2021 ctemp = chaine(virgule,lchain-virgule-1);
2022 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
2023 fExpr[fNoper] =
"atan2";
2024 actionCode = katan2;
2025 SetAction(fNoper,actionCode,actionParam);
2027 if (!CheckOperands(leftopr,fNoper-1,err))
return;
2029 }
else if (chaine(0,5) ==
"fmod(") {
2030 compt = 5; nomb = 0; virgule = 0; nest=0;
2031 while(compt != lchain) {
2033 if (chaine(compt-1,1) ==
"(") nest++;
2034 else if (chaine(compt-1,1) ==
")") nest--;
2035 else if (chaine(compt-1,1) ==
"," && nest==0) {
2037 if (nomb == 1 && virgule == 0) virgule = compt;
2045 ctemp = chaine(5,virgule-6);
2046 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
2047 UInt_t leftopr = fNoper-1;
2048 ctemp = chaine(virgule,lchain-virgule-1);
2049 Analyze(ctemp.
Data(),err,
offset);
if (err)
return;
2050 fExpr[fNoper] =
"fmod";
2052 SetAction(fNoper,actionCode,actionParam);
2054 if (!CheckOperands(leftopr,fNoper-1,err))
return;
2056 }
else if (AnalyzeFunction(chaine,err,offset) || err) {
2058 chaine_error = chaine;
2064 }
else if (chaine(0,1) ==
"[" && chaine(lchain-1,1) ==
"]") {
2065 fExpr[fNoper] = chaine;
2067 ctemp = chaine(1,lchain-2);
2068 for (j=0; j<ctemp.
Length(); j++) {
2070 if (strchr(
"0123456789",t)==0 && (ctemp(j,1)!=
"+" || j!=0)) {
2072 chaine_error=chaine1ST;
2076 sscanf(ctemp.
Data(),
"%d",&valeur);
2077 actionCode = kParameter;
2078 actionParam = offset + valeur;
2079 SetAction(fNoper-1, actionCode, actionParam);
2080 fExpr[fNoper-1] =
"[";
2081 fExpr[fNoper-1] = (fExpr[fNoper-1] + (
long int)(valeur+offset)) +
"]";
2083 }
else if (chaine ==
"pi") {
2084 fExpr[fNoper] =
"pi";
2086 SetAction(fNoper,actionCode,actionParam);
2103 if (fNoper>=gMAXOP) err=6;
2110 chaine_error =
"\""+chaine_error+
"\"";
2112 case 2 : er =
" Invalid Floating Point Operation";
break;
2113 case 4 : er =
" Empty String";
break;
2114 case 5 : er =
" Invalid Syntax " + chaine_error;
break;
2115 case 6 : er =
" Too many operators !";
break;
2116 case 7 : er =
" Too many parameters !";
break;
2117 case 10 : er =
" z specified but not x and y";
break;
2118 case 11 : er =
" z and y specified but not x";
break;
2119 case 12 : er =
" y specified but not x";
break;
2120 case 13 : er =
" z and x specified but not y";
break;
2121 case 20 : er =
" Non integer value for parameter number : " + chaine_error;
break;
2122 case 21 : er =
" ATAN2 requires two arguments";
break;
2123 case 22 : er =
" POW requires two arguments";
break;
2124 case 23 : er =
" Degree of polynomial not specified";
break;
2125 case 24 : er =
" Degree of polynomial must be positive";
break;
2126 case 25 : er =
" Degree of polynomial must be less than 20";
break;
2127 case 26 : er =
" Unknown name : " + chaine_error;
break;
2128 case 27 : er =
" Too many constants in expression";
break;
2129 case 28 : er =
" strstr requires two arguments";
break;
2130 case 29 : er =
" TFormula can only call interpreted and compiled functions that return a numerical type: " + chaine_error;
break;
2131 case 30 : er =
" Bad numerical expression : " + chaine_error;
break;
2132 case 31 : er =
" Part of the Variable " + chaine_error; er +=
" exists but some of it is not accessible or useable";
break;
2133 case 40 : er =
" '(' is expected";
break;
2134 case 41 : er =
" ')' is expected";
break;
2135 case 42 : er =
" '[' is expected";
break;
2136 case 43 : er =
" ']' is expected";
break;
2137 case 44 : er =
" The function '" + chaine(0,err_hint) +
"' requires two arguments.";
break;
2138 case 45 : er =
"The operator " + chaine_error +
" requires a numerical operand.";
break;
2139 case 46 : er =
"Both operands of the operator " + chaine_error +
" have to be either numbers or strings.";
break;
2140 case 47 : er = chaine_error +
" requires 2 string arguments";
break;
2155 if ( IsString(oper-1) && !StringToNumber(oper-1) ) {
2156 Error(
"Compile",
"\"%s\" requires a numerical operand.",fExpr[oper].
Data());
2170 if ( IsString(oper-1) || IsString(leftoper) ) {
2171 if (IsString(oper-1) && StringToNumber(oper-1)) {
2174 if (IsString(leftoper) && StringToNumber(leftoper)) {
2177 Error(
"Compile",
"\"%s\" requires two numerical operands.",fExpr[oper].
Data());
2212 void TFormula::ClearFormula(
Option_t * )
2222 if (fExpr) {
delete [] fExpr; fExpr = 0;}
2223 if (fNames) {
delete [] fNames; fNames = 0;}
2224 if (fOper) {
delete [] fOper; fOper = 0;}
2225 if (fConst) {
delete [] fConst; fConst = 0;}
2226 if (fParams) {
delete [] fParams; fParams = 0;}
2227 fFunctions.Delete();
2228 fLinearParts.Delete();
2231 if (fPredefined) {
delete [] fPredefined; fPredefined = 0;}
2232 if (fOperOffset) {
delete [] fOperOffset; fOperOffset = 0;}
2233 if (fExprOptimized) {
delete [] fExprOptimized; fExprOptimized = 0;}
2234 if (fOperOptimized) {
delete [] fOperOptimized; fOperOptimized = 0;}
2242 inline static void ResizeArrayIfAllocated(
T*& oldArray,
int newSize){
2245 if (!oldArray || newSize <=0)
return;
2247 T* newArray =
new T[newSize];
2248 std::copy(oldArray, oldArray+newSize, newArray);
2250 oldArray = newArray;
2284 Int_t i,j,lc,valeur,err;
2290 if (strlen(expression)) SetTitle(expression);
2295 char *sctemp =
new char[chaine.
Length()+1];
2296 strlcpy(sctemp,chaine.
Data(),chaine.
Length()+1);
2297 char *semicol = (
char*)strstr(sctemp,
";");
2298 if (semicol) *semicol = 0;
2304 if (TestBit(kLinear)){
2305 ProcessLinear(chaine);
2318 for (i=0; i<
gMAXOP; i++) {
2327 for (i=1; i<=chaine.
Length(); i++) {
2329 if (chaine(i-1,1) ==
"\"") inString = !inString;
2330 if (inString)
continue;
2331 if (chaine(i-1,2) ==
"**") {
2332 chaine = chaine(0,i-1) +
"^" + chaine(i+1,lc-i-1);
2334 }
else if (chaine(i-1,2) ==
"++") {
2335 chaine = chaine(0,i) + chaine(i+1,lc-i-1);
2337 }
else if (chaine(i-1,2) ==
"+-" || chaine(i-1,2) ==
"-+") {
2338 chaine = chaine(0,i-1) +
"-" + chaine(i+1,lc-i-1);
2340 }
else if (chaine(i-1,2) ==
"--") {
2341 chaine = chaine(0,i-1) +
"+" + chaine(i+1,lc-i-1);
2343 }
else if (chaine(i-1,2) ==
"->") {
2344 chaine = chaine(0,i-1) +
"." + chaine(i+1,lc-i-1);
2346 }
else if (chaine(i-1,1) ==
"[") {
2347 for (j=1;j<=chaine.
Length()-i;j++) {
2348 if (chaine(j+i-1,1) ==
"]" || j+i > chaine.
Length())
break;
2350 ctemp = chaine(i,j-1);
2352 sscanf(ctemp.
Data(),
"%d",&valeur);
2353 if (valeur >= fNpar) fNpar = valeur+1;
2354 }
else if (chaine(i-1,1) ==
" ") {
2355 chaine = chaine(0,i-1)+chaine(i,lc-i);
2360 Analyze((
const char*)chaine,err);
2364 delete [] fParams; fParams = 0;
2365 delete [] fNames; fNames = 0;
2370 if (fNdim <= 0) fNdim = 1;
2373 if ( GetNumber() != 400 &&
2374 GetNumber() != 410 &&
2375 GetNumber() != 110 )
2377 else if ( GetNumber() == 110 && chaine.
Length() > 6 )
2379 else if ( GetNumber() == 410 && chaine.
Length() > 8 )
2383 if (GetNumber() == 100) {
2384 SetParName(0,
"Constant");
2385 SetParName(1,
"Mean");
2386 SetParName(2,
"Sigma");
2389 if (GetNumber() == 110){
2390 SetParName(0,
"Constant");
2391 SetParName(1,
"MeanX");
2392 SetParName(2,
"SigmaX");
2393 SetParName(3,
"MeanY");
2394 SetParName(4,
"SigmaY");
2397 if (GetNumber() == 200) {
2398 SetParName(0,
"Constant");
2399 SetParName(1,
"Slope");
2402 if (GetNumber() == 300+fNpar) {
2403 for (i=0;i<fNpar;i++) SetParName(i,
Form(
"p%d",i));
2406 if (GetNumber() == 400) {
2407 SetParName(0,
"Constant");
2408 SetParName(1,
"MPV");
2409 SetParName(2,
"Sigma");
2412 if (GetNumber() == 410) {
2413 SetParName(0,
"Constant");
2414 SetParName(1,
"MPVX");
2415 SetParName(2,
"SigmaX");
2416 SetParName(3,
"MPVY");
2417 SetParName(4,
"SigmaY");
2429 ResizeArrayIfAllocated(fExpr, fNoper);
2430 ResizeArrayIfAllocated(fConst, fNconst);
2431 ResizeArrayIfAllocated(fParams, fNpar);
2432 ResizeArrayIfAllocated(fNames, fNpar);
2433 ResizeArrayIfAllocated(fOper, fNoper);
2437 if (err) { fNdim = 0;
return 1; }
2441 if (!
IsA()->GetBaseClass(
"TTreeFormula")) {
2460 ((
TFormula&)obj).fNconst = fNconst;
2461 ((
TFormula&)obj).fNumber = fNumber;
2467 if (fExpr && fNoper) {
2469 for (i=0;i<fNoper;i++) ((
TFormula&)
obj).fExpr[i] = fExpr[i];
2471 if (fOper && fNoper) {
2473 for (i=0;i<fNoper;i++) ((
TFormula&)
obj).fOper[i] = fOper[i];
2475 if (fConst && fNconst) {
2477 for (i=0;i<fNconst;i++) ((
TFormula&)
obj).fConst[i] = fConst[i];
2479 if (fParams && fNpar) {
2481 for (i=0;i<fNpar;i++) ((
TFormula&)
obj).fParams[i] = fParams[i];
2483 if (fNames && fNpar) {
2485 for (i=0;i<fNpar;i++) ((
TFormula&)
obj).fNames[i] = fNames[i];
2490 while ( (fobj =
next()) ) {
2498 if(fExprOptimized) {
2500 for (i=0;i<fNoper;i++) ((
TFormula&)
obj).fExprOptimized[i] = fExprOptimized[i];
2502 if (fOperOptimized) {
2504 for (i=0;i<fNoper;i++) ((
TFormula&)
obj).fOperOptimized[i] = fOperOptimized[i];
2508 for (i=0;i<fNoper;i++) {((
TFormula&)obj).fPredefined[i] = fPredefined[i];}
2511 ((
TFormula&)obj).fOperOffset =
new TOperOffset[fNoper];
2512 for (i=0;i<fNoper;i++) {((
TFormula&)obj).fOperOffset[i] = fOperOffset[i];}
2515 ((
TFormula&)obj).fNOperOptimized = fNOperOptimized;
2516 ((
TFormula&)obj).fOptimal = fOptimal;
2543 char *TFormula::DefinedString(
Int_t)
2606 if (chaine ==
"x") {
2607 if (fNdim < 1) fNdim = 1;
2609 }
else if (chaine ==
"y") {
2610 if (fNdim < 2) fNdim = 2;
2612 }
else if (chaine ==
"z") {
2613 if (fNdim < 3) fNdim = 3;
2615 }
else if (chaine ==
"t") {
2616 if (fNdim < 4) fNdim = 4;
2622 if (chaine.
Data()[0]==
'x'){
2623 if (chaine.
Data()[1]==
'[' && chaine.
Data()[3]==
']'){
2624 const char ch0 =
'0';
2626 if (dim<0)
return -1;
2627 if (dim>9)
return -1;
2628 if (fNdim<=dim) fNdim = dim+1;
2631 if (chaine.
Data()[1]==
'[' && chaine.
Data()[4]==
']'){
2632 const char ch0 =
'0';
2633 Int_t dim = (chaine.
Data()[2]-ch0)*10+(chaine.
Data()[3]-ch0);
2634 if (dim<0)
return -1;
2635 if (dim>99)
return -1;
2636 if (fNdim<=dim) fNdim = dim+1;
2658 return ((
TFormula*)
this)->EvalPar(xx);
2683 Int_t precalculated = 0;
2684 Int_t precalculated_str = 0;
2688 params =
const_cast<Double_t*
>(uparams);
2695 for (i=0; i<fNoper; ++i) {
2697 const int oper = fOper[i];
2702 case kParameter : { pos++; tab[pos-1] = params[ oper &
kTFOperMask ];
continue; }
2703 case kConstant : { pos++; tab[pos-1] = fConst[ oper &
kTFOperMask ];
continue; }
2704 case kVariable : { pos++; tab[pos-1] = x[ oper &
kTFOperMask ];
continue; }
2705 case kStringConst: { strpos++; stringStack[strpos-1] = (
char*)fExpr[i].
Data(); pos++; tab[pos-1] = 0;
continue; }
2707 case kAdd : pos--; tab[pos-1] += tab[pos];
continue;
2708 case kSubstract : pos--; tab[pos-1] -= tab[pos];
continue;
2709 case kMultiply : pos--; tab[pos-1] *= tab[pos];
continue;
2710 case kDivide : pos--;
if (tab[pos] == 0) tab[pos-1] = 0;
2711 else tab[pos-1] /= tab[pos];
2713 case kModulo : {pos--;
2719 case kcos : tab[pos-1] =
TMath::Cos(tab[pos-1]);
continue;
2720 case ksin : tab[pos-1] =
TMath::Sin(tab[pos-1]);
continue;
2721 case ktan :
if (
TMath::Cos(tab[pos-1]) == 0) {tab[pos-1] = 0;}
2724 case kacos :
if (
TMath::Abs(tab[pos-1]) > 1) {tab[pos-1] = 0;}
2727 case kasin :
if (
TMath::Abs(tab[pos-1]) > 1) {tab[pos-1] = 0;}
2730 case katan : tab[pos-1] =
TMath::ATan(tab[pos-1]);
continue;
2731 case kcosh : tab[pos-1] =
TMath::CosH(tab[pos-1]);
continue;
2732 case ksinh : tab[pos-1] =
TMath::SinH(tab[pos-1]);
continue;
2733 case ktanh :
if (
TMath::CosH(tab[pos-1]) == 0) {tab[pos-1] = 0;}
2736 case kacosh:
if (tab[pos-1] < 1) {tab[pos-1] = 0;}
2739 case kasinh: tab[pos-1] =
TMath::ASinH(tab[pos-1]);
continue;
2740 case katanh:
if (
TMath::Abs(tab[pos-1]) > 1) {tab[pos-1] = 0;}
2742 case katan2: pos--; tab[pos-1] =
TMath::ATan2(tab[pos-1],tab[pos]);
continue;
2744 case kfmod : pos--; tab[pos-1] = fmod(tab[pos-1],tab[pos]);
continue;
2745 case kpow : pos--; tab[pos-1] =
TMath::Power(tab[pos-1],tab[pos]);
continue;
2746 case ksq : tab[pos-1] = tab[pos-1]*tab[pos-1];
continue;
2749 case kstrstr : strpos -= 2; pos-=2; pos++;
2750 if (strstr(stringStack[strpos],stringStack[strpos+1])) tab[pos-1]=1;
2751 else tab[pos-1]=0;
continue;
2753 case kmin : pos--; tab[pos-1] =
TMath::Min(tab[pos-1],tab[pos]);
continue;
2754 case kmax : pos--; tab[pos-1] =
TMath::Max(tab[pos-1],tab[pos]);
continue;
2756 case klog :
if (tab[pos-1] > 0) tab[pos-1] =
TMath::Log(tab[pos-1]);
2757 else {tab[pos-1] = 0;}
2759 case kexp : {
Double_t dexp = tab[pos-1];
2760 if (dexp < -700) {tab[pos-1] = 0;
continue;}
2761 if (dexp > 700) {tab[pos-1] =
TMath::Exp(700);
continue;}
2763 case klog10:
if (tab[pos-1] > 0) tab[pos-1] =
TMath::Log10(tab[pos-1]);
2764 else {tab[pos-1] = 0;}
2767 case kpi : pos++; tab[pos-1] =
TMath::ACos(-1);
continue;
2769 case kabs : tab[pos-1] =
TMath::Abs(tab[pos-1]);
continue;
2770 case ksign :
if (tab[pos-1] < 0) tab[pos-1] = -1;
else tab[pos-1] = 1;
continue;
2773 case kSignInv: tab[pos-1] = -1 * tab[pos-1];
continue;
2775 case krndm : pos++; tab[pos-1] =
gRandom->
Rndm(1);
continue;
2777 case kAnd : pos--;
if (tab[pos-1]!=0 && tab[pos]!=0) tab[pos-1]=1;
2778 else tab[pos-1]=0;
continue;
2779 case kOr : pos--;
if (tab[pos-1]!=0 || tab[pos]!=0) tab[pos-1]=1;
2780 else tab[pos-1]=0;
continue;
2781 case kEqual: pos--;
if (tab[pos-1] == tab[pos]) tab[pos-1]=1;
2782 else tab[pos-1]=0;
continue;
2783 case kNotEqual : pos--;
if (tab[pos-1] != tab[pos]) tab[pos-1]=1;
2784 else tab[pos-1]=0;
continue;
2785 case kLess : pos--;
if (tab[pos-1] < tab[pos]) tab[pos-1]=1;
2786 else tab[pos-1]=0;
continue;
2787 case kGreater : pos--;
if (tab[pos-1] > tab[pos]) tab[pos-1]=1;
2788 else tab[pos-1]=0;
continue;
2790 case kLessThan: pos--;
if (tab[pos-1]<=tab[pos]) tab[pos-1]=1;
2791 else tab[pos-1]=0;
continue;
2792 case kGreaterThan: pos--;
if (tab[pos-1]>=tab[pos]) tab[pos-1]=1;
2793 else tab[pos-1]=0;
continue;
2794 case kNot :
if (tab[pos-1]!=0) tab[pos-1] = 0;
else tab[pos-1] = 1;
continue;
2796 case kStringEqual : strpos -= 2; pos -=2 ; pos++;
2797 if (!strcmp(stringStack[strpos+1],stringStack[strpos])) tab[pos-1]=1;
2798 else tab[pos-1]=0;
continue;
2799 case kStringNotEqual: strpos -= 2; pos -= 2; pos++;
2800 if (strcmp(stringStack[strpos+1],stringStack[strpos])) tab[pos-1]=1;
2801 else tab[pos-1]=0;
continue;
2803 case kBitAnd : pos--; tab[pos-1]= ((
Int_t) tab[pos-1]) & ((
Int_t) tab[pos]);
continue;
2804 case kBitOr : pos--; tab[pos-1]= ((
Int_t) tab[pos-1]) | ((
Int_t) tab[pos]);
continue;
2805 case kLeftShift : pos--; tab[pos-1]= ((
Int_t) tab[pos-1]) <<((
Int_t) tab[pos]);
continue;
2806 case kRightShift: pos--; tab[pos-1]= ((
Int_t) tab[pos-1]) >>((
Int_t) tab[pos]);
continue;
2809 case kJumpIf : pos--;
if (!tab[pos]) i = (oper &
kTFOperMask);
continue;
2811 case kBoolOptimize: {
2816 int op = param % 10;
2818 if (op == 1 && (!tab[pos-1]) ) {
2827 }
else if (op == 2 && tab[pos-1] ) {
2839 int toskip = param / 10;
2849 #define R__EXPO(var) \
2851 pos++; int param = (oper & kTFOperMask); \
2852 tab[pos-1] = TMath::Exp(params[param]+params[param+1]*x[var]); \
2859 case kxyexpo:{ pos++;
int param = (oper &
kTFOperMask);
2860 tab[pos-1] =
TMath::Exp(params[param]+params[param+1]*x[0]+params[param+2]*x[1]);
2863 #define R__GAUS(var) \
2865 pos++; int param = (oper & kTFOperMask); \
2866 tab[pos-1] = params[param]*TMath::Gaus(x[var],params[param+1],params[param+2],IsNormalized()); \
2874 case kxygaus: {pos++;
int param = (oper &
kTFOperMask);
2876 if (params[param+2] == 0) {
2879 intermede1=
Double_t((x[0]-params[param+1])/params[param+2]);
2882 if (params[param+4] == 0) {
2885 intermede2=
Double_t((x[1]-params[param+3])/params[param+4]);
2887 tab[pos-1] = params[param]*
TMath::Exp(-0.5*(intermede1*intermede1+intermede2*intermede2));
2890 #define R__LANDAU(var) \
2892 pos++; const int param = (oper & kTFOperMask); \
2893 tab[pos-1] = params[param]*TMath::Landau(x[var],params[param+1],params[param+2],IsNormalized()); \
2900 case kxylandau: { pos++;
int param = oper&0x7fffff ;
2903 tab[pos-1] = params[param]*intermede1*intermede2;
2907 #define R__POLY(var) \
2909 pos++; int param = (oper & kTFOperMask); \
2910 tab[pos-1] = 0; Double_t intermede = 1; \
2911 Int_t inter = param/100; \
2912 Int_t int1= param-inter*100-1; \
2913 for (j=0 ;j<inter+1;j++) { \
2914 tab[pos-1] += intermede*params[j+int1]; \
2915 intermede *= x[var]; \
2924 case kDefinedVariable : {
2925 if (!precalculated) {
2927 for(j=0;j<fNval;j++) param_calc[j]=DefinedValue(j);
2929 pos++; tab[pos-1] = param_calc[(oper &
kTFOperMask)];
2933 case kDefinedString : {
2935 if (!precalculated_str) {
2936 precalculated_str=1;
2937 for (j=0;j<fNstring;j++) string_calc[j]=DefinedString(j);
2939 strpos++; stringStack[strpos-1] = string_calc[param];
2940 pos++; tab[pos-1] = 0;
2944 case kFunctionCall: {
2948 int fno = param / 1000;
2949 int nargs = param % 1000;
2957 UInt_t argloc = pos-nargs;
2958 for(j=0;j<nargs;j++,argloc++,pos--) {
2970 if (!TestBit(kOptimizationError)) {
2971 SetBit(kOptimizationError);
2972 Warning(
"EvalParOld",
"Found an unsupported opcode (%d)",oper >> kTFOperShift);
3007 Int_t ternaryend = -1;
3008 for(
Int_t i=0;i<fNoper;i++){
3009 optype = GetAction(i);
3011 if (ternaryend==i) {
3013 if(ismulti[spos-1]){
3014 tab[spos-2]=tab[spos-2]+
"("+tab[spos-1]+
")";
3016 tab[spos-2]=tab[spos-2]+tab[spos-1];
3024 if (optype==kBoolOptimize) {
3029 if (optype==kSignInv) {
3030 tab[spos-1]=
"-("+tab[spos-1]+
")";
3036 if (kexpo<=optype && optype<=kzpol) {
3044 if ((optype<=151 && optype>=140 && optype!=145) || (optype == 40)) {
3052 if(((optype>0 && optype<6) || optype==20 ||
3053 (((optype>59 && optype<69) || (optype >75 && optype<82)) && spos>=2))) {
3055 if(ismulti[spos-2]){
3056 tab[spos-2]=
"("+tab[spos-2]+
")";
3058 if(ismulti[spos-1]){
3059 tab[spos-2]+=fExpr[i]+(
"("+tab[spos-1]+
")");
3061 tab[spos-2]+=fExpr[i]+tab[spos-1];
3063 ismulti[spos-2]=
kTRUE;
3068 if (optype==kJumpIf) {
3069 if(ismulti[spos-1]){
3070 tab[spos-1]=
"("+tab[spos-1]+
")?";
3072 tab[spos-1]=tab[spos-1]+
"?";
3076 if (optype==kJump) {
3077 if(ismulti[spos-1]){
3078 tab[spos-2]=tab[spos-2]+
"("+tab[spos-1]+
"):";
3080 tab[spos-2]=tab[spos-2]+tab[spos-1]+
":";
3082 ternaryend = GetActionParam(i) + 1;
3090 if((optype>9 && optype<16) ||
3091 (optype>20 && optype<23) ||
3092 (optype>29 && optype<34) ||
3093 (optype>40 && optype<44) ||
3094 (optype>69 && optype<76) ||
3100 if((optype>15 && optype<20) ||
3101 (optype>22 && optype<26)) {
3108 int nargs = param % 1000;
3113 for(j=0, depth=0;j<funcname.
Length();++j) {
3114 switch (funcname[j]) {
3131 Error(
"GetExpFormula",
"Internal error, number of argument found is %d",-offset);
3132 }
else if (offset == 0) {
3133 tab[spos]=funcname+
"()";
3137 }
else if (offset<=0 && (spos+offset>=0)) {
3139 for (j=offset+1; j<0; j++){
3140 tab[spos+
offset]+=
","+tab[spos+j];
3148 if (ternaryend==fNoper) {
3150 if(ismulti[spos-1]){
3151 tab[spos-2]=tab[spos-2]+
"("+tab[spos-1]+
")";
3153 tab[spos-2]=tab[spos-2]+tab[spos-1];
3159 if (spos > 0) ret = tab[spos-1];
3169 for (j=0;j<fNpar;j++) {
3170 snprintf(pb,10,
"[%d]",j);
3171 snprintf(pbv,100,
"%g",fParams[j]);
3190 if (!fLinearParts.IsEmpty())
3191 return fLinearParts.UncheckedAt(i);
3201 if (ipar <0 || ipar >= fNpar)
return 0;
3202 return fParams[ipar];
3212 Int_t index = GetParNumber(parName);
3214 Error(
"TFormula",
"Parameter %s not found", parName);
3217 return GetParameter(index);
3226 if (ipar <0 || ipar >= fNpar)
return "";
3227 if (fNames[ipar].Length() > 0)
return (
const char*)fNames[ipar];
3228 return Form(
"p%d",ipar);
3240 for (
Int_t i=0; i<fNpar; i++) {
3241 if (!strcmp(GetParName(i),parName))
return i;
3252 return GetAction(oper) == kStringConst;
3262 Printf(
" %20s : %s Ndim= %d, Npar= %d, Noper= %d",GetName(),GetTitle(), fNdim,fNpar,fNoper);
3263 for (i=0;i<fNoper;i++) {
3264 Printf(
" fExpr[%d] = %s action = %d action param = %d ",
3265 i,(
const char*)fExpr[i],GetAction(i),GetActionParam(i));
3269 if (fNOperOptimized>0){
3270 Printf(
"Optimized expression");
3271 for (i=0;i<fNOperOptimized;i++) {
3272 Printf(
" fExpr[%d] = %s\t\t action = %d action param = %d ",
3273 i,(
const char*)fExprOptimized[i],GetActionOptimized(i),GetActionParamOptimized(i));
3277 if (!fNames)
return;
3278 if (!fParams)
return;
3279 for (i=0;i<fNpar;i++) {
3280 Printf(
" Par%3d %20s = %g",i,GetParName(i),fParams[i]);
3289 void TFormula::ProcessLinear(
TString &formula)
3296 pch= (
char*)strstr(formula.
Data(),
"++");
3298 formula.
Insert(0,
"[0]*(");
3299 pch= (
char*)strstr(formula.
Data(),
"++");
3304 snprintf(repl,20,
")+[%d]*(", nf);
3305 offset = pch-formula.
Data();
3306 if (nf<10) replsize = 7;
3307 else if (nf<100) replsize = 8;
3309 formula.
Replace(pch-formula.
Data(), 2, repl, replsize);
3310 pch = (
char*)strstr(formula.
Data()+
offset,
"++");
3316 formula2=formula2(4, formula2.
Length()-4);
3317 pch= (
char*)strchr(formula2.
Data(),
'[');
3318 snprintf(repl,20,
"++");
3321 offset = pch-formula2.
Data()-1;
3322 if (nf<10) replsize = 5;
3324 formula2.
Replace(pch-formula2.
Data()-1, replsize, repl, 2);
3325 pch = (
char*)strchr(formula2.
Data()+
offset,
'[');
3330 fLinearParts.Expand(nf);
3333 formula2 = formula2.
ReplaceAll(
"++", 2,
"|", 1);
3336 for (
Int_t i=0; i<nf; i++) {
3338 replaceformula_name =
"f_linear_";
3339 replaceformula_name.
Append(replaceformula);
3342 Error(
"TFormula",
"f_linear not allocated");
3347 gROOT->GetListOfFunctions()->Remove(f);
3349 f->
SetBit(kNotGlobal, 1);
3350 fLinearParts.Add(f);
3361 Int_t ipar = GetParNumber(name);
3362 if (ipar <0 || ipar >= fNpar)
return;
3363 fParams[ipar] =
value;
3373 if (ipar <0 || ipar >= fNpar)
return;
3374 fParams[ipar] =
value;
3385 for (
Int_t i=0; i<fNpar;i++) {
3386 fParams[i] = params[i];
3402 if (fNpar > 0) fParams[0] = p0;
3403 if (fNpar > 1) fParams[1] =
p1;
3404 if (fNpar > 2) fParams[2] =
p2;
3405 if (fNpar > 3) fParams[3] =
p3;
3406 if (fNpar > 4) fParams[4] = p4;
3407 if (fNpar > 5) fParams[5] = p5;
3408 if (fNpar > 6) fParams[6] = p6;
3409 if (fNpar > 7) fParams[7] = p7;
3410 if (fNpar > 8) fParams[8] = p8;
3411 if (fNpar > 9) fParams[9] = p9;
3412 if (fNpar >10) fParams[10]= p10;
3422 if (ipar <0 || ipar >= fNpar)
return;
3423 fNames[ipar] =
name;
3430 void TFormula::SetParNames(
const char*name0,
const char*name1,
const char*name2,
const char*name3,
const char*name4,
3431 const char*name5,
const char*name6,
const char*name7,
const char*name8,
const char*name9,
const char*name10)
3433 if (fNpar > 0) fNames[0] = name0;
3434 if (fNpar > 1) fNames[1] = name1;
3435 if (fNpar > 2) fNames[2] = name2;
3436 if (fNpar > 3) fNames[3] = name3;
3437 if (fNpar > 4) fNames[4] = name4;
3438 if (fNpar > 5) fNames[5] = name5;
3439 if (fNpar > 6) fNames[6] = name6;
3440 if (fNpar > 7) fNames[7] = name7;
3441 if (fNpar > 8) fNames[8] = name8;
3442 if (fNpar > 9) fNames[9] = name9;
3443 if (fNpar >10) fNames[10]= name10;
3449 void TFormula::Streamer(
TBuffer &b,
const TClass *onfile_class)
3455 Error(
"Streamer",
"version 6 is not supported");
3458 Streamer(b, v, R__s, R__c, onfile_class);
3468 void TFormula::Streamer(
TBuffer &b)
3474 Error(
"Streamer",
"version 6 is not supported");
3477 Streamer(b, v, R__s, R__c,
nullptr);
3493 if (!TestBit(kNotGlobal)) {
3495 gROOT->GetListOfFunctions()->Add(
this);
3499 if (fFunctions.GetLast()>=0) {
3508 Error(
"Streamer",
"error compiling formula");
3511 for (
Int_t i = 0; i<npar && i<fNpar; ++i) fParams[i] = param[i];
3523 TNamed::Streamer(b);
3526 if (v > 1) b >> fNval;
3527 if (v > 2) b >> fNstring;
3539 for (i=0;i<fNoper;i++) fExpr[i].Streamer(b);
3540 for (i=0;i<fNpar;i++) fNames[i].Streamer(b);
3543 if (
gROOT->GetListOfFunctions()->FindObject(GetName()))
return;
3544 gROOT->GetListOfFunctions()->Add(
this);
3553 void TFormula::Convert(
UInt_t )
3561 kOldxylandau = 4500,
3562 kOldConstants = 50000,
3563 kOldStrings = 80000,
3564 kOldVariable = 100000,
3565 kOldTreeString = 105000,
3566 kOldFormulaVar = 110000,
3567 kOldBoolOptimize = 120000,
3568 kOldFunctionCall = 200000
3572 for (i=0,j=0; i<fNoper; ++i,++j) {
3573 Int_t action = fOper[i];
3574 Int_t newActionCode = 0;
3575 Int_t newActionParam = 0;
3580 newActionCode = kSignInv;
3583 sscanf((
const char*)fExpr[i],
"%g",&aresult);
3590 for (
int z=i; z<fNoper; ++
z) {
3591 fExpr[z-1] = fExpr[
z];
3594 }
else if ( action < 100 ) {
3597 newActionCode = action;
3599 }
else if (action >= kOldFunctionCall) {
3602 newActionCode = kFunctionCall;
3603 newActionParam = action-kOldFunctionCall;
3605 }
else if (action >= kOldBoolOptimize) {
3608 newActionCode = kBoolOptimize;
3609 newActionParam = action-kOldBoolOptimize;
3611 }
else if (action >= kOldFormulaVar) {
3614 newActionCode = kVariable;
3615 newActionParam = action-kOldFormulaVar;
3617 }
else if (action >= kOldTreeString) {
3620 newActionCode = kDefinedString;
3621 newActionParam = action-kOldTreeString;
3623 }
else if (action >= kOldVariable) {
3626 newActionCode = kDefinedVariable;
3627 newActionParam = action-kOldVariable;
3629 }
else if (action == kOldStrings) {
3632 newActionCode = kStringConst;
3634 }
else if (action >= kOldConstants) {
3637 newActionCode = kConstant;
3638 newActionParam = action-kOldConstants;
3640 }
else if (action > 10000 && action < kOldConstants) {
3643 int var = action/10000;
3644 newActionCode = kpol + (var-1);
3645 newActionParam = action - var*10000;
3647 }
else if (action >= 4600) {
3649 Error(
"Convert",
"Unsupported value %d",action);
3651 }
else if (action > kOldxylandau) {
3654 newActionCode = kxylandau;
3655 newActionParam = action - (kOldxylandau+1);
3657 }
else if (action > kOldlandau) {
3660 newActionCode = klandau;
3661 int var = action/100-40;
3662 if (var) newActionCode += var;
3663 newActionParam = action - var*100 - (kOldlandau+1);
3665 }
else if (action > 2500 && action < 2600) {
3668 newActionCode = kxygaus;
3669 newActionParam = action-2501;
3671 }
else if (action > 2000 && action < 2500) {
3674 newActionCode = kgaus;
3675 int var = action/100-20;
3676 if (var) newActionCode += var;
3677 newActionParam = action - var*100 - (kOldgaus+1);
3679 }
else if (action > 1500 && action < 1600) {
3682 newActionCode = kxyexpo;
3683 newActionParam = action-1501;
3685 }
else if (action > 1000 && action < 1500) {
3688 newActionCode = kexpo;
3689 int var = action/100-10;
3690 if (var) newActionCode += var;
3691 newActionParam = action - var*100 - (kOldexpo+1);
3693 }
if (action > 100 && action < 200) {
3696 newActionCode = kParameter;
3697 newActionParam = action - 101;
3700 SetAction( j, newActionCode, newActionParam );
3721 TOperOffset::TOperOffset()
3740 void TFormula::MakePrimitive(
const char *expr,
Int_t pos)
3744 int paran = cbase.
First(
"(");
3751 if (cbase==
"<") cbase=
"XlY";
3752 if (cbase==
"<=") cbase=
"XleY";
3753 if (cbase==
">") cbase=
"XgY";
3754 if (cbase==
">=") cbase=
"XgeY";
3755 if (cbase==
"==" && GetActionOptimized(pos)!=kStringEqual) cbase=
"XeY";
3756 if (cbase==
"!=" && GetActionOptimized(pos)!=kStringNotEqual) cbase=
"XneY";
3760 fPredefined[pos] = prim;
3761 if (prim->
fType==10) {
3762 SetActionOptimized(pos, kFD1);
3764 if (prim->
fType==110) {
3765 SetActionOptimized(pos, kFD2);
3767 if (prim->
fType==1110) {
3768 SetActionOptimized(pos, kFD3);
3770 if (prim->
fType==-1) {
3771 SetActionOptimized(pos, kFDM);
3773 if (prim->
fType==0){
3774 SetActionOptimized(pos,kConstant,fNconst);
3775 fConst[fNconst] = prim->
Eval(0);
3818 if (fPredefined) {
delete [] fPredefined; fPredefined = 0;}
3819 if (fOperOffset) {
delete [] fOperOffset; fOperOffset = 0;}
3820 if (fExprOptimized) {
delete [] fExprOptimized; fExprOptimized = 0;}
3821 if (fOperOptimized) {
delete [] fOperOptimized; fOperOptimized = 0;}
3823 fExprOptimized =
new TString[fNoper];
3824 fOperOptimized =
new Int_t[fNoper];
3826 fOperOffset =
new TOperOffset[fNoper];
3827 for (i=0; i<fNoper; i++) {
3828 fExprOptimized[i] = fExpr[i] ;
3829 fOperOptimized[i] = fOper[i];
3836 for (i=0;i<fNoper;i++){
3837 if (fExprOptimized[i].
Data()) {
3838 MakePrimitive(fExprOptimized[i].
Data(), i);
3842 Int_t maxfound = fNoper+1;
3861 for (i=0;i<fNoper;i++) optimized[i]=0;
3863 for (i=0;i<fNoper;i++){
3864 Int_t actionparam = GetActionParamOptimized(i);
3865 Int_t action = GetActionOptimized(i);
3867 if (action==kBoolOptimize){
3871 fOperOffset[i].fType1 = actionparam/10;
3872 fOperOffset[i].fOffset0 = actionparam%10;
3873 fOperOffset[i].fToJump = i+fOperOffset[i].fType1;
3876 if (action==kJump || action==kJumpIf) {
3878 fOperOffset[i].fType1 = action;
3879 fOperOffset[i].fToJump = actionparam;
3882 if (action==kConstant&&i<fNoper-2){
3886 if (GetActionOptimized(i+1)==kConstant && GetActionOptimized(i+2)==kFDM){
3890 fOperOffset[i].fType0=actionparam;
3891 fOperOffset[i].fOffset0=GetActionParamOptimized(i-1);
3892 Int_t offset2 = int(fConst[fOperOffset[i].fOffset0]+0.4);
3893 fOperOffset[i].fOffset0=offset2;
3894 Int_t nparmax = offset2+fPredefined[i]->fNParameters;
3902 case kVariable : {action=kData; fOperOffset[i].fType0=0;
break;}
3903 case kParameter: {action=kData; fOperOffset[i].fType0=1;
break;}
3904 case kConstant : {action=kData; fOperOffset[i].fType0=2;
break;}
3907 fOperOffset[i].fOffset0 = GetActionParamOptimized(i);
3908 SetActionOptimized(i,action, actionparam);
3912 fNOperOptimized = fNoper;
3914 for (i=0; i<fNoper; ++i)
3917 if (!(GetActionOptimized(i)== kData))
continue;
3918 offset[0] = fOperOffset[i].fType0;
3921 if ((i+1) >= fNoper)
continue;
3923 if (GetActionOptimized(i+1)==kFD1){
3926 fOperOffset[i].fType0 = offset[0];
3927 fOperOffset[i].fOffset0 = offset[1];
3928 SetActionOptimized(i ,kUnary);
3931 if (GetActionOptimized(i+1)==kAdd){
3934 fOperOffset[i].fType0 = offset[0];
3935 fOperOffset[i].fOffset0 = offset[1];
3936 SetActionOptimized(i ,kPlusD);
3939 if (GetActionOptimized(i+1)==
kMultiply){
3942 fOperOffset[i].fType0 = offset[0];
3943 fOperOffset[i].fOffset0 = offset[1];
3944 SetActionOptimized(i,kMultD);
3948 if ((i+2) >= fNoper)
continue;
3952 if (!(GetActionOptimized(i+1)== kData))
continue;
3953 offset[2] = fOperOffset[i+1].fType0;
3956 if (GetActionOptimized(i+2)==kFD2 || GetActionOptimized(i+2)==kAdd ||GetActionOptimized(i+2)==kSubstract||
3957 GetActionOptimized(i+2)==
kMultiply || GetActionOptimized(i+2)==kDivide){
3963 fOperOffset[i].fType0 = offset[0];
3964 fOperOffset[i].fOffset0 = offset[1];
3965 fOperOffset[i].fType1 = offset[2];
3966 fOperOffset[i].fOffset1 = offset[3];
3967 fOperOffset[i].fType2 = GetActionOptimized(i);
3968 if (GetActionOptimized(i)==kAdd) {fPredefined[i] = primitive[0];}
3969 if (GetActionOptimized(i)==kSubstract) {fPredefined[i] = primitive[1];}
3971 fPredefined[i]=primitive[2];
3972 if (offset[0]==offset[2]&&offset[1]==offset[3]) {
3973 fPredefined[i] = primitive[8];
3974 SetActionOptimized(i,kUnary);
3978 if (GetActionOptimized(i)==kDivide) {
3979 fPredefined[i] = primitive[3];
3981 SetActionOptimized(i,kBinary);
3985 if ((i+3) >= fNoper)
continue;
3990 if (!(GetActionOptimized(i+2)== kData))
continue;
3991 offset[4] = fOperOffset[i+2].fType0;
3994 if (GetActionOptimized(i+3)==kFD3|| ( (GetActionOptimized(i+3)==kAdd||GetActionOptimized(i+3)==
kMultiply) &&
3995 (GetActionOptimized(i+4)==kAdd||GetActionOptimized(i+4)==
kMultiply) ) ){
4001 fOperOffset[i].fType0 = offset[0];
4002 fOperOffset[i].fOffset0 = offset[1];
4003 fOperOffset[i].fType1 = offset[2];
4004 fOperOffset[i].fOffset1 = offset[3];
4005 fOperOffset[i].fType2 = offset[4];
4006 fOperOffset[i].fOffset2 = offset[5];
4008 fOperOffset[i].fOldAction = GetActionOptimized(i);
4009 if (GetActionOptimized(i)==kFD3) {
4010 SetActionOptimized(i,kThree);
4014 Int_t action2=kThree;
4015 if (GetActionOptimized(i)==kAdd&&GetActionOptimized(i+1)==kAdd) action=4;
4018 if (offset[0]==offset[2]&&offset[1]==offset[3]&&offset[0]==offset[4]&&offset[1]==offset[5]){
4019 fPredefined[i]=primitive[9];
4024 if (GetActionOptimized(i)==kAdd&&GetActionOptimized(i+1)==
kMultiply) action=6;
4025 if (GetActionOptimized(i)==
kMultiply&&GetActionOptimized(i+1)==kAdd) action=7;
4029 fOperOffset[i].fType0 = offset[0];
4030 fOperOffset[i].fOffset0 = offset[1];
4031 fOperOffset[i].fType1 = offset[2];
4032 fOperOffset[i].fOffset1 = offset[3];
4033 fOperOffset[i].fType2 = offset[4];
4034 fOperOffset[i].fOffset2 = offset[5];
4035 fPredefined[i]=primitive[action];
4036 SetActionOptimized(i,action2);
4046 for (i=0;i<fNoper;i++){
4049 fOperOptimized[operO] = fOperOptimized[i];
4050 fPredefined[operO] = fPredefined[i];
4051 fOperOffset[operO] = fOperOffset[i];
4052 expr += fExprOptimized[i];
4053 if (optimized[i]==0){
4054 fExprOptimized[operO] = expr;
4064 for (i=0; i<fNOperOptimized; i++){
4065 Int_t optaction = GetActionOptimized(i);
4066 if (optaction==kBoolOptimize){
4067 Int_t oldpos = fOperOffset[i].fToJump;
4068 Int_t newpos = oldpos==fNoper ? fNOperOptimized : map0[oldpos];
4069 fOperOffset[i].fToJump = newpos;
4070 Int_t actionop = GetActionParamOptimized(i) % 10;
4072 case 1: SetActionOptimized(i,kBoolOptimizeAnd,newpos);
break;
4073 case 2: SetActionOptimized(i,kBoolOptimizeOr,newpos);
break;
4075 }
else if (optaction==kJump || optaction==kJumpIf) {
4076 Int_t oldpos = fOperOffset[i].fToJump;
4077 Int_t newpos = oldpos==fNoper ? fNOperOptimized : map0[oldpos];
4078 fOperOffset[i].fToJump = newpos;
4079 SetActionOptimized(i,optaction,newpos);
4084 fNOperOptimized = operO;
4087 if (fNOperOptimized==1) {
4088 switch(GetActionOptimized(0)){
4100 delete [] optimized;
4109 const Double_t *pdata[3] = {
x,(params!=0)?params:fParams, fConst};
4110 Double_t result = pdata[fOperOffset->fType0][fOperOffset->fOffset0];
4112 case kData :
return result;
4113 case kUnary :
return (fPredefined[0]->fFunc10)(pdata[fOperOffset->fType0][fOperOffset->fOffset0]);
4114 case kBinary :
return (fPredefined[0]->fFunc110)(
result,
4115 pdata[fOperOffset->fType1][fOperOffset->fOffset1]);
4117 case kThree :
return (fPredefined[0]->fFunc1110)(
result, pdata[fOperOffset->fType1][fOperOffset->fOffset1],
4118 pdata[fOperOffset->fType2][fOperOffset->fOffset2]);
4119 case kFDM :
return (fPredefined[0]->fFuncG)((
Double_t*)&x[fOperOffset->fType0],
4120 (
Double_t*)¶ms[fOperOffset->fOffset0]);
4131 const Double_t *pdata[3] = {
x,(params!=0)?params:fParams, fConst};
4132 return pdata[fOperOffset->fType0][fOperOffset->fOffset0];
4141 const Double_t *pdata[3] = {
x,(params!=0)?params:fParams, fConst};
4142 return (fPredefined[0]->fFunc10)(pdata[fOperOffset->fType0][fOperOffset->fOffset0]);
4151 const Double_t *pdata[3] = {
x,(params!=0)?params:fParams, fConst};
4152 return (fPredefined[0]->fFunc110)(pdata[fOperOffset->fType0][fOperOffset->fOffset0],
4153 pdata[fOperOffset->fType1][fOperOffset->fOffset1]);
4162 const Double_t *pdata[3] = {
x,(params!=0)?params:fParams, fConst};
4163 return (fPredefined[0]->fFunc1110)(pdata[fOperOffset->fType0][fOperOffset->fOffset0], pdata[fOperOffset->fType1][fOperOffset->fOffset1],
4164 pdata[fOperOffset->fType2][fOperOffset->fOffset2]);
4174 return (fPredefined[0]->fFuncG)((
Double_t*)&x[fOperOffset->fType0],
4175 (
Double_t*)&par[fOperOffset->fOffset0]);
4194 const Double_t *pdata[3] = {
x,(uparams!=0)?uparams:fParams, fConst};
4201 Int_t precalculated = 0;
4202 Int_t precalculated_str = 0;
4208 params =
const_cast<Double_t*
>(uparams);
4219 for (i=0; i<fNOperOptimized; ++i) {
4221 const int oper = fOperOptimized[i];
4225 case kData : tab[pos] = pdata[fOperOffset[i].fType0][fOperOffset[i].fOffset0]; pos++;
continue;
4226 case kPlusD : tab[pos-1]+= pdata[fOperOffset[i].fType0][fOperOffset[i].fOffset0];
continue;
4227 case kMultD : tab[pos-1]*= pdata[fOperOffset[i].fType0][fOperOffset[i].fOffset0];
continue;
4228 case kAdd : pos--; tab[pos-1] += tab[pos];
continue;
4229 case kSubstract : pos--; tab[pos-1] -= tab[pos];
continue;
4230 case kMultiply : pos--; tab[pos-1] *= tab[pos];
continue;
4231 case kDivide : pos--;
if (tab[pos] == 0) tab[pos-1] = 0;
4232 else tab[pos-1] /= tab[pos];
4234 case kUnary : tab[pos] = (fPredefined[i]->fFunc10)(pdata[fOperOffset[i].fType0][fOperOffset[i].fOffset0]); pos++;
continue;
4235 case kBinary : tab[pos] = (fPredefined[i]->fFunc110)(pdata[fOperOffset[i].fType0][fOperOffset[i].fOffset0],
4236 pdata[fOperOffset[i].fType1][fOperOffset[i].fOffset1]);pos++;
continue;
4238 case kThree : tab[pos] = (fPredefined[i]->fFunc1110)(pdata[fOperOffset[i].fType0][fOperOffset[i].fOffset0],
4239 pdata[fOperOffset[i].fType1][fOperOffset[i].fOffset1],
4240 pdata[fOperOffset[i].fType2][fOperOffset[i].fOffset2]); pos++;
continue;
4242 case kFDM : tab[pos] = (fPredefined[i]->fFuncG)(&x[fOperOffset[i].fType0],¶ms[fOperOffset[i].fOffset0]); pos++;
continue;
4243 case kFD1 : tab[pos-1] =(fPredefined[i]->fFunc10)(tab[pos-1]);
continue;
4244 case kFD2 : pos--; tab[pos-1] = (fPredefined[i]->fFunc110)(tab[pos-1],tab[pos]);
continue;
4245 case kFD3 : pos-=2; tab[pos-1] = (fPredefined[i]->fFunc1110)(tab[pos-1],tab[pos],tab[pos+1]);
continue;
4249 case kBoolOptimizeAnd: {
4250 if (!tab[pos-1]) i=fOperOffset[i].fToJump;
continue;
4252 case kBoolOptimizeOr: {
4253 if (tab[pos-1]) i=fOperOffset[i].fToJump;
continue;
4255 case kAnd : pos--; tab[pos-1] = (bool)tab[pos];
continue;
4256 case kOr : pos--; tab[pos-1] = (bool)tab[pos];
continue;
4260 case kabs :
if (tab[pos-1]<0) tab[pos-1]=-tab[pos-1];
continue;
4261 case ksign :
if (tab[pos-1] < 0) tab[pos-1] = -1;
else tab[pos-1] = 1;
continue;
4263 case kpow : pos--; tab[pos-1] =
TMath::Power(tab[pos-1],tab[pos]);
continue;
4265 case kModulo : {pos--;
4272 case kStringConst: { strpos++; stringStack[strpos-1] = (
char*)fExprOptimized[i].
Data(); pos++; tab[pos-1] = 0;
continue; }
4273 case kfmod : pos--; tab[pos-1] = fmod(tab[pos-1],tab[pos]);
continue;
4275 case kstrstr : strpos -= 2; pos-=2; pos++;
4276 if (strstr(stringStack[strpos],stringStack[strpos+1])) tab[pos-1]=1;
4277 else tab[pos-1]=0;
continue;
4278 case kpi : pos++; tab[pos-1] =
TMath::ACos(-1);
continue;
4281 case kSignInv: tab[pos-1] = -1 * tab[pos-1];
continue;
4283 case krndm : pos++; tab[pos-1] =
gRandom->
Rndm(1);
continue;
4286 case kEqual: pos--;
if (tab[pos-1] == tab[pos]) tab[pos-1]=1;
4287 else tab[pos-1]=0;
continue;
4288 case kNotEqual : pos--;
if (tab[pos-1] != tab[pos]) tab[pos-1]=1;
4289 else tab[pos-1]=0;
continue;
4290 case kNot :
if (tab[pos-1]!=0) tab[pos-1] = 0;
else tab[pos-1] = 1;
continue;
4292 case kStringEqual : strpos -= 2; pos -=2 ; pos++;
4293 if (!strcmp(stringStack[strpos+1],stringStack[strpos])) tab[pos-1]=1;
4294 else tab[pos-1]=0;
continue;
4295 case kStringNotEqual: strpos -= 2; pos -= 2; pos++;
4296 if (strcmp(stringStack[strpos+1],stringStack[strpos])) tab[pos-1]=1;
4297 else tab[pos-1]=0;
continue;
4299 case kBitAnd : pos--; tab[pos-1]= ((
Int_t) tab[pos-1]) & ((
Int_t) tab[pos]);
continue;
4300 case kBitOr : pos--; tab[pos-1]= ((
Int_t) tab[pos-1]) | ((
Int_t) tab[pos]);
continue;
4301 case kLeftShift : pos--; tab[pos-1]= ((
Int_t) tab[pos-1]) <<((
Int_t) tab[pos]);
continue;
4302 case kRightShift: pos--; tab[pos-1]= ((
Int_t) tab[pos-1]) >>((
Int_t) tab[pos]);
continue;
4305 case kJumpIf : pos--;
if (!tab[pos]) i = (oper &
kTFOperMask);
continue;
4307 case kBoolOptimize: {
4311 int op = param % 10;
4313 if (op == 1 && (!tab[pos-1]) ) {
4322 }
else if (op == 2 && tab[pos-1] ) {
4339 #define R__EXPO(var) \
4341 pos++; int param = (oper & kTFOperMask); \
4342 tab[pos-1] = TMath::Exp(params[param]+params[param+1]*x[var]); \
4349 case kxyexpo:{ pos++;
int param = (oper &
kTFOperMask);
4350 tab[pos-1] =
TMath::Exp(params[param]+params[param+1]*x[0]+params[param+2]*x[1]);
4355 #define R__GAUS(var) \
4357 pos++; int param = (oper & kTFOperMask); \
4358 tab[pos-1] = params[param]*TMath::Gaus(x[var],params[param+1], \
4359 params[param+2],IsNormalized()); \
4367 case kxygaus: { pos++;
int param = (oper &
kTFOperMask);
4369 if (params[param+2] == 0) {
4372 intermede1=
Double_t((x[0]-params[param+1])/params[param+2]);
4375 if (params[param+4] == 0) {
4378 intermede2=
Double_t((x[1]-params[param+3])/params[param+4]);
4380 tab[pos-1] = params[param]*
TMath::Exp(-0.5*(intermede1*intermede1+intermede2*intermede2));
4383 #define R__LANDAU(var) \
4385 pos++; const int param = (oper & kTFOperMask); \
4386 tab[pos-1] = params[param]*TMath::Landau(x[var],params[param+1],params[param+2],IsNormalized()); \
4393 case kxylandau: { pos++;
int param = oper&0x7fffff ;
4396 tab[pos-1] = params[param]*intermede1*intermede2;
4400 #define R__POLY(var) \
4402 pos++; int param = (oper & kTFOperMask); \
4403 tab[pos-1] = 0; Double_t intermede = 1; \
4404 Int_t inter = param/100; \
4405 Int_t int1= param-inter*100-1; \
4406 for (j=0 ;j<inter+1;j++) { \
4407 tab[pos-1] += intermede*params[j+int1]; \
4408 intermede *= x[var]; \
4417 case kDefinedVariable : {
4418 if (!precalculated) {
4420 for(j=0;j<fNval;j++) param_calc[j]=DefinedValue(j);
4422 pos++; tab[pos-1] = param_calc[(oper &
kTFOperMask)];
4426 case kDefinedString : {
4428 if (!precalculated_str) {
4429 precalculated_str=1;
4430 for (j=0;j<fNstring;j++) string_calc[j]=DefinedString(j);
4432 strpos++; stringStack[strpos-1] = string_calc[param];
4433 pos++; tab[pos-1] = 0;
4437 case kFunctionCall: {
4441 int fno = param / 1000;
4442 int nargs = param % 1000;
4450 UInt_t argloc = pos-nargs;
4451 for(j=0;j<nargs;j++,argloc++,pos--) {
4463 if (!TestBit(kOptimizationError)) {
4464 SetBit(kOptimizationError);
4465 Warning(
"EvalParFast",
"Found an unsupported optmized opcode (%d)",oper >> kTFOperShift);
4477 Int_t TFormula::PreCompile()
4480 if (str.
Length()<3)
return 1;
4481 if (str[str.
Length()-1]!=
'+'&&str[str.
Length()-2]!=
'+')
return 1;
4483 TString funName(
"preformula_");
4487 fileName.
Form(
"/tmp/%s.C",funName.
Data());
4490 hf = fopen(fileName.
Data(),
"w");
4492 Error(
"PreCompile",
"Unable to open the file %s for writing.",fileName.
Data());
4495 fprintf(hf,
"/////////////////////////////////////////////////////////////////////////\n");
4496 fprintf(hf,
"// This code has been automatically generated \n");
4498 fprintf(hf,
"Double_t %s(Double_t *x, Double_t *p){",funName.
Data());
4499 fprintf(hf,
"return (%s);\n}",str.
Data());
4535 void TFormula::GetMaxima(
Int_t& maxop,
Int_t& maxpar,
Int_t& maxconst)
virtual const char * GetTitle() const
Returns title of object.
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Double_t Landau(Double_t x, Double_t mpv=0, Double_t sigma=1, Bool_t norm=kFALSE)
The LANDAU function.
RooCmdArg Optimize(Int_t flag=2)
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
static double p3(double t, double a, double b, double c, double d)
ClassImp(TSeqCollection) Int_t TSeqCollection TIter next(this)
Return index of object in collection.
Collectable string class.
virtual Double_t Rndm(Int_t i=0)
Machine independent random number generator.
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)
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
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)
const char * Data() const
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
The TNamed class is the base class for all named ROOT classes.
UChar_t mod R__LOCKGUARD2(gSrvAuthenticateMutex)
virtual void Copy(TObject &named) const
Copy this to obj.
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
Double_t ATan2(Double_t, Double_t)
Method or function calling interface.
void Error(const char *location, const char *msgfmt,...)
TObject * UncheckedAt(Int_t i) const
ClassInfo_t * GetClassInfo() const
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
char * Form(const char *fmt,...)
virtual const char * GetName() const
Returns name of object.
The ROOT global object gROOT contains a list of all defined classes.
static double p1(double t, double a, double b)
void Warning(const char *location, const char *msgfmt,...)
R__EXTERN TRandom * gRandom
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
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.
virtual const char * GetPrototype() const
Returns the prototype of a function as defined by CINT, or 0 in case of error.
void ResetParam()
Reset parameter list. To be used before the first call the SetParam().
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.
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)
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
void SetParam(Long_t l)
Add a long method parameter.
Double_t Sqrt(Double_t x)
static char * skip(char **buf, const char *delimiters)
Bool_t IsValid() const
Return true if the method call has been properly initialized and is usable.
Ssiz_t First(char c) const
Find first occurrence of a character c.
EReturnType ReturnType()
Returns the return type of the method.
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
virtual Int_t ReadArray(Bool_t *&b)=0