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
416static void mdfHelper(
int&,
double*,
double&,
double*,
int);
508:
TNamed(
"multidimfit",
"Multi-dimensional fit object"),
511fVariables(dimension*100),
512fMeanVariables(dimension),
513fMaxVariables(dimension),
514fMinVariables(dimension)
722 Warning(
"AddTestRow",
"variable %d (row: %d) too large: %f > %f",
725 Warning(
"AddTestRow",
"variable %d (row: %d) too small: %f < %f",
739 while ((
h = (
TH1*)next()))
740 b->Add(
h,
h->GetName());
829 for (i = 0; i <
n; i++) {
832 for (j = 0; j <
m; j++)
922 returnValue += term*term;
925 returnValue =
sqrt(returnValue);
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;
1044 Warning(
"Fit",
"test sample is very small");
1047 Error(
"Fit",
"invalid option");
1054 Error(
"Fit",
"Cannot 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;
1149 control[numberFunctions-1] =
Int_t(1.0e+6*
s);
1173 for (j = 0; j < i; j++)
1204 if (control[j] <=
x) {
1212 control[k] = control[i];
1214 order[k] = order[i];
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++)
1471 for (j = 0; j < i; j++) {
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",
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)
1927 std::cout << std::endl;
1959 const char *classname,
1965 const char *prefix = (isMethod ?
Form(
"%s::", classname) :
"");
1966 const char *cv_qual = (isMethod ?
"" :
"static ");
1968 std::ofstream outFile(filename,std::ios::out|std::ios::trunc);
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 <<
" ";
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;
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)");
2493 double* coeffs,
int )
TMatrixTRow< Double_t > TMatrixDRow
TMatrixTDiag_const< Double_t > TMatrixDDiag_const
static void mdfHelper(int &, double *, double &, double *, int)
Helper function for doing the minimisation of Chi2 using Minuit.
char * Form(const char *fmt,...)
Using a TBrowser one can browse all ROOT objects.
This class stores the date and time with a precision of one second in an unsigned 32 bit word (950130...
const char * AsString() const
Return the date & time as a string (ctime() format).
Cholesky Decomposition class.
Bool_t Invert(TMatrixDSym &inv)
For a symmetric matrix A(m,m), its inverse A_inv(m,m) is returned .
virtual Bool_t Decompose()
Matrix A is decomposed in component U so that A = U^T * U If the decomposition succeeds,...
1-D histogram with a double per channel (see TH1 documentation)}
2-D histogram with a double per channel (see TH1 documentation)}
virtual void Add(TObject *obj)
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
virtual void Clear(Option_t *option="")
Remove all objects from the list.
void Print(Option_t *name="") const
Print the matrix as a table of elements.
virtual TMatrixTBase< Element > & Zero()
Set matrix elements to zero.
virtual TMatrixTBase< Element > & NormByDiag(const TVectorT< Element > &v, Option_t *option="D")
option:
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...
Multidimensional Fits in ROOT.
virtual void MakeCorrelation()
PRIVATE METHOD: Compute the correlation matrix.
virtual void MakeCoefficientErrors()
PRIVATE METHOD: Compute the errors on the coefficients.
TMatrixD fOrthCurvatureMatrix
virtual Double_t Eval(const Double_t *x, const Double_t *coeff=0) const
Evaluate parameterization at point x.
Double_t fSumSqAvgQuantity
virtual void MakeNormalized()
PRIVATE METHOD: Normalize data to the interval [-1;1].
static TMultiDimFit * Instance()
Return the static instance.
virtual ~TMultiDimFit()
Destructor.
virtual void MakeCode(const char *functionName="MDF", Option_t *option="")
Generate the file <filename> with .C appended if argument doesn't end in .cxx or ....
virtual void MakeCandidates()
PRIVATE METHOD: Create list of candidate functions for the parameterisation.
void SetPowerLimit(Double_t limit=1e-3)
Set the user parameter for the function selection.
virtual void FindParameterization(Option_t *option="")
Find the parameterization.
virtual Double_t MakeGramSchmidt(Int_t function)
PRIVATE METHOD: Make Gram-Schmidt orthogonalisation.
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,...
TVectorD fOrthCoefficients
virtual Bool_t TestFunction(Double_t squareResidual, Double_t dResidur)
PRIVATE METHOD: Test whether the currently considered function contributes to the fit.
Double_t fCorrelationCoeff
void SetMaxPowers(const Int_t *powers)
Set the maximum power to be considered in the fit for each variable.
virtual void SetPowers(const Int_t *powers, Int_t terms)
Define a user function.
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 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,...
Int_t fParameterisationCode
virtual void Fit(Option_t *option="")
Try to fit the found parameterisation to the test sample.
TMultiDimFit()
Empty CTOR. Do not use.
Double_t fTestCorrelationCoeff
void SetMinRelativeError(Double_t error)
Set the acceptable relative error for when sum of square residuals is considered minimized.
virtual void MakeMethod(const Char_t *className="MDF", Option_t *option="")
Generate the file <classname>MDF.cxx which contains the implementation of the method:
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 MakeCoefficients()
PRIVATE METHOD: Invert the model matrix B, and compute final coefficients.
TMatrixD fCorrelationMatrix
virtual void Clear(Option_t *option="")
Clear internal structures and variables.
virtual Double_t EvalControl(const Int_t *powers) const
PRIVATE METHOD: Calculate the control parameter from the passed powers.
virtual void Browse(TBrowser *b)
Browse the TMultiDimFit object in the TBrowser.
virtual void MakeParameterization()
PRIVATE METHOD: Find the parameterization over the training sample.
EMDFPolyType fPolyType
Fit object (MINUIT)
virtual Bool_t Select(const Int_t *iv)
Selection method.
virtual Double_t EvalError(const Double_t *x, const Double_t *coeff=0) const
Evaluate parameterization error at point x.
virtual Double_t EvalFactor(Int_t p, Double_t x) const
PRIVATE METHOD: Evaluate function with power p at variable value x.
void SetMinAngle(Double_t angle=1)
Set the min angle (in degrees) between a new candidate function and the subspace spanned by the previ...
virtual void Print(Option_t *option="ps") const
Print statistics etc.
TVectorD fOrthFunctionNorms
TVectorD fCoefficientsRMS
static TMultiDimFit * fgInstance
virtual void MakeHistograms(Option_t *option="A")
Make histograms of the result of the analysis.
Double_t fMinRelativeError
virtual Double_t MakeChi2(const Double_t *coeff=0)
Calculate Chi square over either the test sample.
The TNamed class is the base class for all named ROOT classes.
virtual const char * GetName() const
Returns name of object.
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
void ToLower()
Change string to lower-case.
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
const char * Data() const
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
TVectorT< Element > & Zero()
Set vector elements to zero.
TVectorT< Element > & ResizeTo(Int_t lwb, Int_t upb)
Resize the vector to [lwb:upb] .
virtual void PrintResults(Int_t level, Double_t amin) const =0
virtual void SetFCN(void(*fcn)(Int_t &, Double_t *, Double_t &f, Double_t *, Int_t))
To set the address of the minimization objective function called by the native compiler (see function...
virtual Int_t SetParameter(Int_t ipar, const char *parname, Double_t value, Double_t verr, Double_t vlow, Double_t vhigh)=0
virtual Int_t ExecuteCommand(const char *command, Double_t *args, Int_t nargs)=0
virtual Double_t GetParameter(Int_t ipar) const =0
static TVirtualFitter * Fitter(TObject *obj, Int_t maxpar=25)
Static function returning a pointer to the current fitter.
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
static constexpr double s
Short_t Max(Short_t a, Short_t b)
constexpr Double_t E()
Base of natural log:
Double_t Sqrt(Double_t x)
static long int sum(long int i)