398 #define RADDEG (180. / TMath::Pi())
399 #define DEGRAD (TMath::Pi() / 180.)
408 #define PARAM_MAXSTUDY 1
409 #define PARAM_SEVERAL 2
410 #define PARAM_RELERR 3
411 #define PARAM_MAXTERMS 4
416 static void mdfHelper(
int&,
double*,
double&,
double*,
int);
508 :
TNamed(
"multidimfit",
"Multi-dimensional fit object"),
509 fQuantity(dimension),
511 fVariables(dimension*100),
512 fMeanVariables(dimension),
513 fMaxVariables(dimension),
514 fMinVariables(dimension)
722 Warning(
"AddTestRow",
"variable %d (row: %d) too large: %f > %f",
725 Warning(
"AddTestRow",
"variable %d (row: %d) too small: %f < %f",
829 for (i = 0; i <
n; i++) {
832 for (j = 0; j <
m; j++)
922 returnValue += term*term;
925 returnValue =
sqrt(returnValue);
940 s += (epsilon + iv[i] - 1) / (epsilon +
fMaxPowers[i] - 1);
966 for (i = 3; i <= p; i++) {
969 p3 = ((2 * i - 3) * p2 * x - (i - 2) *
p1) / (i - 1);
971 p3 = 2 * x * p2 -
p1;
1027 sumSqR += res * res;
1031 Double_t dAvg = sumSqD - (sumD * sumD) / fTestSampleSize;
1032 Double_t rAvg = sumSqR - (sumR * sumR) / fTestSampleSize;
1044 Warning(
"Fit",
"test sample is very small");
1047 Error(
"Fit",
"invalid option");
1054 Error(
"Fit",
"Vannot create Fitter");
1060 const Int_t maxArgs = 16;
1070 startVal, startErr, 0, 0);
1079 Double_t val = 0, err = 0, low = 0, high = 0;
1081 val, err, low, high);
1124 Int_t numberFunctions = 0;
1127 Int_t maxNumberFunctions = 1;
1144 if (numberFunctions > fMaxFunctions)
1149 control[numberFunctions-1] =
Int_t(1.0e+6*s);
1153 j = (numberFunctions - 1) * fNVariables + i;
1165 if (i == fNVariables) {
1166 fMaxFunctions = numberFunctions;
1171 if (i < fNVariables) iv[i]++;
1173 for (j = 0; j < i; j++)
1182 powers[i * fNVariables + j] =
fPowers[i * fNVariables + j];
1183 iv[j] =
fPowers[i * fNVariables + j];
1204 if (control[j] <= x) {
1212 control[k] = control[i];
1214 order[k] = order[i];
1221 fPowers[i * fNVariables + j] = powers[order[i] * fNVariables + j];
1318 for (j = 0; j <= i; j++) {
1321 curvatureMatrix(i,j) +=
1323 curvatureMatrix(j,i) = curvatureMatrix(i,j);
1343 Error(
"MakeCoefficientErrors",
"curvature matrix is singular");
1344 chol.
Invert(curvatureMatrix);
1365 Int_t col = 0, row = 0;
1369 for (row = col - 1; row > -1; row--) {
1371 for (i = row; i <= col ; i++)
1464 k = j * fNVariables + i;
1471 for (j = 0; j < i; j++) {
1477 l = k * fNVariables + j;
1478 m = k * fNVariables + i;
1614 Form(
"Original variable # %d",i),
1633 Form(
"Normalized variable # %d",i),
1652 Form(
"Computed residual versus x_%d", i),
1664 "Computed residuals vs Quantity",
1678 "Computed residuals over training sample",
1687 "Distribution of residuals from test",
1769 k = i * fNVariables + j;
1851 if (i == fMaxFunctions) {
1866 std::cout <<
"Coeff SumSqRes Contrib Angle QM Func"
1867 <<
" Value W^2 Powers" << std::endl;
1872 if (dResidur == 0) {
1901 squareResidual -= dResidur;
1915 << std::setw(10) << std::setprecision(4) << squareResidual <<
" "
1916 << std::setw(10) << std::setprecision(4) << dResidur <<
" "
1917 << std::setw(7) << std::setprecision(3) <<
fMaxAngle <<
" "
1918 << std::setw(7) << std::setprecision(3) << s <<
" "
1919 << std::setw(5) << i <<
" "
1920 << std::setw(10) << std::setprecision(4)
1922 << std::setw(10) << std::setprecision(4)
1926 std::cout <<
" " <<
fPowers[i * fNVariables + j] - 1 << std::flush;
1927 std::cout << std::endl;
1959 const char *classname,
1965 const char *prefix = (isMethod ?
Form(
"%s::", classname) :
"");
1966 const char *cv_qual = (isMethod ?
"" :
"static ");
1970 Error(
"MakeRealCode",
"couldn't open output file '%s'",filename);
1975 std::cout <<
"Writing on file \"" << filename <<
"\" ... " << std::flush;
1980 outFile <<
"// -*- mode: c++ -*-" << std::endl;
1982 outFile <<
"// " << std::endl
1983 <<
"// File " << filename
1984 <<
" generated by TMultiDimFit::MakeRealCode" << std::endl;
1987 outFile <<
"// on " << date.
AsString() << std::endl;
1989 outFile <<
"// ROOT version " <<
gROOT->GetVersion()
1990 << std::endl <<
"//" << std::endl;
1992 outFile <<
"// This file contains the function " << std::endl
1993 <<
"//" << std::endl
1994 <<
"// double " << prefix <<
"MDF(double *x); " << std::endl
1995 <<
"//" << std::endl
1996 <<
"// For evaluating the parameterization obtained" << std::endl
1997 <<
"// from TMultiDimFit and the point x" << std::endl
1998 <<
"// " << std::endl
1999 <<
"// See TMultiDimFit class documentation for more "
2000 <<
"information " << std::endl <<
"// " << std::endl;
2004 outFile <<
"#include \"" << classname <<
".h\"" << std::endl;
2009 outFile <<
"//" << std::endl
2010 <<
"// Static data variables" << std::endl
2011 <<
"//" << std::endl;
2012 outFile << cv_qual <<
"int " << prefix <<
"gNVariables = "
2014 outFile << cv_qual <<
"int " << prefix <<
"gNCoefficients = "
2016 outFile << cv_qual <<
"double " << prefix <<
"gDMean = "
2020 outFile <<
"// Assignment to mean vector." << std::endl;
2021 outFile << cv_qual <<
"double " << prefix
2022 <<
"gXMean[] = {" << std::endl;
2024 outFile << (i != 0 ?
", " :
" ") <<
fMeanVariables(i) << std::flush;
2025 outFile <<
" };" << std::endl << std::endl;
2028 outFile <<
"// Assignment to minimum vector." << std::endl;
2029 outFile << cv_qual <<
"double " << prefix
2030 <<
"gXMin[] = {" << std::endl;
2032 outFile << (i != 0 ?
", " :
" ") <<
fMinVariables(i) << std::flush;
2033 outFile <<
" };" << std::endl << std::endl;
2036 outFile <<
"// Assignment to maximum vector." << std::endl;
2037 outFile << cv_qual <<
"double " << prefix
2038 <<
"gXMax[] = {" << std::endl;
2040 outFile << (i != 0 ?
", " :
" ") <<
fMaxVariables(i) << std::flush;
2041 outFile <<
" };" << std::endl << std::endl;
2044 outFile <<
"// Assignment to coefficients vector." << std::endl;
2045 outFile << cv_qual <<
"double " << prefix
2046 <<
"gCoefficient[] = {" << std::flush;
2048 outFile << (i != 0 ?
"," :
"") << std::endl
2050 outFile << std::endl <<
" };" << std::endl << std::endl;
2053 outFile <<
"// Assignment to error coefficients vector." << std::endl;
2054 outFile << cv_qual <<
"double " << prefix
2055 <<
"gCoefficientRMS[] = {" << std::flush;
2057 outFile << (i != 0 ?
"," :
"") << std::endl
2059 outFile << std::endl <<
" };" << std::endl << std::endl;
2062 outFile <<
"// Assignment to powers vector." << std::endl
2063 <<
"// The powers are stored row-wise, that is" << std::endl
2064 <<
"// p_ij = " << prefix
2065 <<
"gPower[i * NVariables + j];" << std::endl;
2066 outFile << cv_qual <<
"int " << prefix
2067 <<
"gPower[] = {" << std::flush;
2070 if (j != 0) outFile << std::flush <<
" ";
2071 else outFile << std::endl <<
" ";
2073 << (i == fNCoefficients - 1 && j == fNVariables - 1 ?
"" :
",")
2077 outFile << std::endl <<
"};" << std::endl << std::endl;
2083 outFile <<
"// " << std::endl
2085 << (isMethod ?
"method " :
"function ")
2086 <<
" double " << prefix
2088 << std::endl <<
"// " << std::endl;
2089 outFile <<
"double " << prefix
2090 <<
"MDF(double *x) {" << std::endl
2091 <<
" double returnValue = " << prefix <<
"gDMean;" << std::endl
2092 <<
" int i = 0, j = 0, k = 0;" << std::endl
2093 <<
" for (i = 0; i < " << prefix <<
"gNCoefficients ; i++) {"
2095 <<
" // Evaluate the ith term in the expansion" << std::endl
2096 <<
" double term = " << prefix <<
"gCoefficient[i];"
2098 <<
" for (j = 0; j < " << prefix <<
"gNVariables; j++) {"
2100 <<
" // Evaluate the polynomial in the jth variable." << std::endl
2101 <<
" int power = "<< prefix <<
"gPower["
2102 << prefix <<
"gNVariables * i + j]; " << std::endl
2103 <<
" double p1 = 1, p2 = 0, p3 = 0, r = 0;" << std::endl
2104 <<
" double v = 1 + 2. / ("
2105 << prefix <<
"gXMax[j] - " << prefix
2106 <<
"gXMin[j]) * (x[j] - " << prefix <<
"gXMax[j]);" << std::endl
2107 <<
" // what is the power to use!" << std::endl
2108 <<
" switch(power) {" << std::endl
2109 <<
" case 1: r = 1; break; " << std::endl
2110 <<
" case 2: r = v; break; " << std::endl
2111 <<
" default: " << std::endl
2112 <<
" p2 = v; " << std::endl
2113 <<
" for (k = 3; k <= power; k++) { " << std::endl
2114 <<
" p3 = p2 * v;" << std::endl;
2116 outFile <<
" p3 = ((2 * i - 3) * p2 * v - (i - 2) * p1)"
2117 <<
" / (i - 1);" << std::endl;
2119 outFile <<
" p3 = 2 * v * p2 - p1; " << std::endl;
2120 outFile <<
" p1 = p2; p2 = p3; " << std::endl <<
" }" << std::endl
2121 <<
" r = p3;" << std::endl <<
" }" << std::endl
2122 <<
" // multiply this term by the poly in the jth var" << std::endl
2123 <<
" term *= r; " << std::endl <<
" }" << std::endl
2124 <<
" // Add this term to the final result" << std::endl
2125 <<
" returnValue += term;" << std::endl <<
" }" << std::endl
2126 <<
" return returnValue;" << std::endl <<
"}" << std::endl << std::endl;
2129 outFile <<
"// EOF for " << filename << std::endl;
2135 std::cout <<
"done" << std::endl;
2161 std::cout <<
"User parameters:" << std::endl
2162 <<
"----------------" << std::endl
2165 <<
" Max Terms: " <<
fMaxTerms << std::endl
2166 <<
" Power Limit Parameter: " <<
fPowerLimit << std::endl
2168 <<
" Max functions to study: " <<
fMaxStudy << std::endl
2169 <<
" Max angle (optional): " <<
fMaxAngle << std::endl
2170 <<
" Min angle: " <<
fMinAngle << std::endl
2172 <<
" Maximum Powers: " << std::flush;
2174 std::cout <<
" " <<
fMaxPowers[i] - 1 << std::flush;
2175 std::cout << std::endl << std::endl
2176 <<
" Parameterisation will be done using " << std::flush;
2178 std::cout <<
"Chebyshev polynomials" << std::endl;
2180 std::cout <<
"Legendre polynomials" << std::endl;
2182 std::cout <<
"Monomials" << std::endl;
2183 std::cout << std::endl;
2188 std::cout <<
"Sample statistics:" << std::endl
2189 <<
"------------------" << std::endl
2190 <<
" D" << std::flush;
2192 std::cout <<
" " << std::setw(10) << i+1 << std::flush;
2193 std::cout << std::endl <<
" Max: " << std::setw(10) << std::setprecision(7)
2196 std::cout <<
" " << std::setw(10) << std::setprecision(4)
2198 std::cout << std::endl <<
" Min: " << std::setw(10) << std::setprecision(7)
2201 std::cout <<
" " << std::setw(10) << std::setprecision(4)
2203 std::cout << std::endl <<
" Mean: " << std::setw(10) << std::setprecision(7)
2206 std::cout <<
" " << std::setw(10) << std::setprecision(4)
2208 std::cout << std::endl <<
" Function Sum Squares: " <<
fSumSqQuantity
2209 << std::endl << std::endl;
2213 std::cout <<
"Results of Parameterisation:" << std::endl
2214 <<
"----------------------------" << std::endl
2215 <<
" Total reduction of square residuals "
2217 <<
" Relative precision obtained: "
2219 <<
" Error obtained: "
2221 <<
" Multiple correlation coefficient: "
2223 <<
" Reduced Chi square over sample: "
2225 <<
" Maximum residual value: "
2227 <<
" Minimum residual value: "
2229 <<
" Estimated root mean square: "
2230 <<
fRMS << std::endl
2231 <<
" Maximum powers used: " << std::flush;
2234 std::cout << std::endl
2235 <<
" Function codes of candidate functions." << std::endl
2236 <<
" 1: considered,"
2237 <<
" 2: too little contribution,"
2238 <<
" 3: accepted." << std::flush;
2241 std::cout << std::endl <<
" " << std::flush;
2242 else if (i % 10 == 0)
2243 std::cout <<
" " << std::flush;
2246 std::cout << std::endl <<
" Loop over candidates stopped because " << std::flush;
2249 std::cout <<
"max allowed studies reached" << std::endl;
break;
2251 std::cout <<
"all candidates considered several times" << std::endl;
break;
2253 std::cout <<
"wanted relative error obtained" << std::endl;
break;
2255 std::cout <<
"max number of terms reached" << std::endl;
break;
2257 std::cout <<
"some unknown reason" << std::endl;
2260 std::cout << std::endl;
2264 std::cout <<
"Results of Fit:" << std::endl
2265 <<
"---------------" << std::endl
2266 <<
" Test sample size: "
2268 <<
" Multiple correlation coefficient: "
2270 <<
" Relative precision obtained: "
2272 <<
" Error obtained: "
2274 <<
" Reduced Chi square over sample: "
2279 std::cout << std::endl;
2284 std::cout <<
"Coefficients:" << std::endl
2285 <<
"-------------" << std::endl
2286 <<
" # Value Error Powers" << std::endl
2287 <<
" ---------------------------------------" << std::endl;
2289 std::cout <<
" " << std::setw(3) << i <<
" "
2293 std::cout <<
" " << std::setw(3)
2295 std::cout << std::endl;
2297 std::cout << std::endl;
2300 std::cout <<
"Correlation Matrix:" << std::endl
2301 <<
"-------------------";
2306 std::cout <<
"Parameterization:" << std::endl
2307 <<
"-----------------" << std::endl
2308 <<
" Normalised variables: " << std::endl;
2310 std::cout <<
"\ty_" << i <<
"\t= 1 + 2 * (x_" << i <<
" - "
2314 std::cout << std::endl
2317 std::cout <<
"y_" << i;
2318 if (i != fNVariables-1) std::cout <<
", ";
2320 std::cout <<
") = ";
2323 std::cout << std::endl <<
"\t" << (
fCoefficients(i) < 0 ?
"- " :
"+ ")
2331 case 2: std::cout <<
" * y_" << j;
break;
2334 case kLegendre: std::cout <<
" * L_" << p-1 <<
"(y_" << j <<
")";
break;
2335 case kChebyshev: std::cout <<
" * C_" << p-1 <<
"(y_" << j <<
")";
break;
2336 default: std::cout <<
" * y_" << j <<
"^" << p-1;
break;
2342 std::cout << std::endl;
2372 if (ang >= 90 || ang < 0) {
2373 Warning(
"SetMaxAngle",
"angle must be in [0,90)");
2388 if (ang > 90 || ang <= 0) {
2389 Warning(
"SetMinAngle",
"angle must be in [0,90)");
2417 fPowers[i * fNVariables + j] = powers[i * fNVariables + j] + 1;
2493 double* coeffs,
int )
void Add(TObject *obj, const char *name=0, Int_t check=-1)
Add object with name to browser.
virtual Double_t MakeChi2(const Double_t *coeff=0)
Calculate Chi square over either the test sample.
TVectorT< Element > & ResizeTo(Int_t lwb, Int_t upb)
Resize the vector to [lwb:upb] .
static void mdfHelper(int &, double *, double &, double *, int)
Helper function for doing the minimisation of Chi2 using Minuit.
static double p3(double t, double a, double b, double c, double d)
TMatrixTDiag_const< Double_t > TMatrixDDiag_const
static Vc_ALWAYS_INLINE float_v trunc(float_v::AsArg v)
ClassImp(TSeqCollection) Int_t TSeqCollection TIter next(this)
Return index of object in collection.
virtual TMatrixTBase< Element > & Zero()
Set matrix elements to zero.
static TMultiDimFit * fgInstance
virtual Int_t SetParameter(Int_t ipar, const char *parname, Double_t value, Double_t verr, Double_t vlow, Double_t vhigh)=0
virtual void Fit(Option_t *option="")
Try to fit the found parameterisation to the test sample.
virtual ~TMultiDimFit()
Destructor.
virtual void Print(Option_t *option="ps") const
Print statistics etc.
Double_t fMinRelativeError
void SetMaxPowers(const Int_t *powers)
Set the maximum power to be considered in the fit for each variable.
virtual Double_t GetParameter(Int_t ipar) const =0
TMatrixD fOrthCurvatureMatrix
static const char * filename()
void ToLower()
Change string to lower-case.
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
virtual void SetFCN(void *fcn)
To set the address of the minimization objective function.
virtual Double_t EvalFactor(Int_t p, Double_t x) const
PRIVATE METHOD: Evaluate function with power p at variable value x.
virtual void Clear(Option_t *option="")
Clear internal structures and variables.
virtual void MakeNormalized()
PRIVATE METHOD: Normalize data to the interval [-1;1].
virtual TMatrixTBase< Element > & ResizeTo(Int_t nrows, Int_t ncols, Int_t=-1)
Set size of the matrix to nrows x ncols New dynamic elements are created, the overlapping part of the...
virtual void MakeRealCode(const char *filename, const char *classname, Option_t *option="")
PRIVATE METHOD: This is the method that actually generates the code for the evaluation the parameteri...
virtual Bool_t TestFunction(Double_t squareResidual, Double_t dResidur)
PRIVATE METHOD: Test whether the currently considered function contributes to the fit...
virtual void MakeParameterization()
PRIVATE METHOD: Find the parameterization over the training sample.
virtual void MakeCoefficientErrors()
PRIVATE METHOD: Compute the errors on the coefficients.
virtual Double_t Eval(const Double_t *x, const Double_t *coeff=0) const
Evaluate parameterization at point x.
const char * Data() const
virtual void PrintResults(Int_t level, Double_t amin) const =0
void SetPowerLimit(Double_t limit=1e-3)
Set the user parameter for the function selection.
Double_t fSumSqAvgQuantity
virtual Double_t EvalControl(const Int_t *powers) const
PRIVATE METHOD: Calculate the control parameter from the passed powers.
The TNamed class is the base class for all named ROOT classes.
static TMultiDimFit * Instance()
Return the static instance.
TMatrixD fCorrelationMatrix
static double p2(double t, double a, double b, double c)
TVectorD fOrthFunctionNorms
void SetMinAngle(Double_t angle=1)
Set the min angle (in degrees) between a new candidate function and the subspace spanned by the previ...
void SetMaxAngle(Double_t angle=0)
Set the max angle (in degrees) between the initial data vector to be fitted, and the new candidate fu...
virtual void AddRow(const Double_t *x, Double_t D, Double_t E=0)
Add a row consisting of fNVariables independent variables, the known, dependent quantity, and optionally, the square error in the dependent quantity, to the training sample to be used for the parameterization.
Bool_t Invert(TMatrixDSym &inv)
For a symmetric matrix A(m,m), its inverse A_inv(m,m) is returned .
virtual Bool_t Select(const Int_t *iv)
Selection method.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
TMatrixTRow< Double_t > TMatrixDRow
void Print(Option_t *name="") const
Print the matrix as a table of elements.
Using a TBrowser one can browse all ROOT objects.
virtual TMatrixTBase< Element > & NormByDiag(const TVectorT< Element > &v, Option_t *option="D")
option: "D" : b(i,j) = a(i,j)/sqrt(abs*(v(i)*v(j))) (default) else : b(i,j) = a(i,j)*sqrt(abs*(v(i)*v(j))) (default)
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
virtual void MakeCandidates()
PRIVATE METHOD: Create list of candidate functions for the parameterisation.
TVectorT< Element > & Zero()
Set vector elements to zero.
Multidimensional Fits in ROOT.
char * Form(const char *fmt,...)
Int_t fParameterisationCode
virtual void FindParameterization(Option_t *option="")
Find the parameterization.
virtual const char * GetName() const
Returns name of object.
virtual Int_t ExecuteCommand(const char *command, Double_t *args, Int_t nargs)=0
virtual void SetPowers(const Int_t *powers, Int_t terms)
Define a user function.
static double p1(double t, double a, double b)
virtual void AddTestRow(const Double_t *x, Double_t D, Double_t E=0)
Add a row consisting of fNVariables independent variables, the known, dependent quantity, and optionally, the square error in the dependent quantity, to the test sample to be used for the test of the parameterization.
1-D histogram with a double per channel (see TH1 documentation)}
virtual void MakeMethod(const Char_t *className="MDF", Option_t *option="")
Generate the file MDF.cxx which contains the implementation of the method: ...
virtual void MakeHistograms(Option_t *option="A")
Make histograms of the result of the analysis.
EMDFPolyType fPolyType
Fit object (MINUIT)
void SetMinRelativeError(Double_t error)
Set the acceptable relative error for when sum of square residuals is considered minimized.
TVectorD fCoefficientsRMS
virtual void MakeCode(const char *functionName="MDF", Option_t *option="")
Generate the file with .C appended if argument doesn't end in .cxx or .C.
TMultiDimFit()
Empty CTOR. Do not use.
virtual void Clear(Option_t *option="")
Remove all objects from the list.
virtual Bool_t Decompose()
Matrix A is decomposed in component U so that A = U^T * U If the decomposition succeeds, bit kDecomposed is set , otherwise kSingular.
virtual Double_t EvalError(const Double_t *x, const Double_t *coeff=0) const
Evaluate parameterization error at point x.
static TVirtualFitter * Fitter(TObject *obj, Int_t maxpar=25)
Static function returning a pointer to the current fitter.
virtual void Add(TObject *obj)
double f2(const double *x)
Short_t Max(Short_t a, Short_t b)
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
virtual void MakeCorrelation()
PRIVATE METHOD: Compute the correlation matrix.
Double_t Sqrt(Double_t x)
virtual Double_t MakeGramSchmidt(Int_t function)
PRIVATE METHOD: Make Gram-Schmidt orthogonalisation.
Double_t fCorrelationCoeff
const char * AsString() const
Return the date & time as a string (ctime() format).
TVectorD fOrthCoefficients
virtual void MakeCoefficients()
PRIVATE METHOD: Invert the model matrix B, and compute final coefficients.
This class stores the date and time with a precision of one second in an unsigned 32 bit word (950130...
virtual void Browse(TBrowser *b)
Browse the TMultiDimFit object in the TBrowser.
2-D histogram with a double per channel (see TH1 documentation)}
Double_t fTestCorrelationCoeff
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.