401#define RADDEG (180. / TMath::Pi())
402#define DEGRAD (TMath::Pi() / 180.)
411#define PARAM_MAXSTUDY 1
412#define PARAM_SEVERAL 2
413#define PARAM_RELERR 3
414#define PARAM_MAXTERMS 4
419static void mdfHelper(
int&,
double*,
double&,
double*,
int);
511:
TNamed(
"multidimfit",
"Multi-dimensional fit object"),
514fVariables(dimension*100),
515fMeanVariables(dimension),
516fMaxVariables(dimension),
517fMinVariables(dimension)
725 Warning(
"AddTestRow",
"variable %d (row: %d) too large: %f > %f",
728 Warning(
"AddTestRow",
"variable %d (row: %d) too small: %f < %f",
742 while ((
h = (
TH1*)next()))
832 for (i = 0; i <
n; i++) {
835 for (j = 0; j <
m; j++)
925 returnValue += term*term;
928 returnValue =
sqrt(returnValue);
969 for (i = 3; i <= p; i++) {
972 p3 = ((2 * i - 3) * p2 *
x - (i - 2) * p1) / (i - 1);
974 p3 = 2 *
x * p2 - p1;
1030 sumSqR += res * res;
1047 Warning(
"Fit",
"test sample is very small");
1050 Error(
"Fit",
"invalid option");
1057 Error(
"Fit",
"Cannot create Fitter");
1063 const Int_t maxArgs = 16;
1073 startVal, startErr, 0, 0);
1082 Double_t val = 0, err = 0, low = 0, high = 0;
1084 val, err, low, high);
1127 Int_t numberFunctions = 0;
1130 Int_t maxNumberFunctions = 1;
1152 control[numberFunctions-1] =
Int_t(1.0e+6*s);
1176 for (j = 0; j < i; j++)
1207 if (control[j] <=
x) {
1215 control[k] = control[i];
1217 order[k] = order[i];
1321 for (j = 0; j <= i; j++) {
1324 curvatureMatrix(i,j) +=
1326 curvatureMatrix(j,i) = curvatureMatrix(i,j);
1346 Error(
"MakeCoefficientErrors",
"curvature matrix is singular");
1347 chol.
Invert(curvatureMatrix);
1368 Int_t col = 0, row = 0;
1372 for (row = col - 1; row > -1; row--) {
1374 for (i = row; i <= col ; i++)
1474 for (j = 0; j < i; j++) {
1617 Form(
"Original variable # %d",i),
1636 Form(
"Normalized variable # %d",i),
1655 Form(
"Computed residual versus x_%d", i),
1667 "Computed residuals vs Quantity",
1681 "Computed residuals over training sample",
1690 "Distribution of residuals from test",
1869 std::cout <<
"Coeff SumSqRes Contrib Angle QM Func"
1870 <<
" Value W^2 Powers" << std::endl;
1875 if (dResidur == 0) {
1904 squareResidual -= dResidur;
1918 << std::setw(10) << std::setprecision(4) << squareResidual <<
" "
1919 << std::setw(10) << std::setprecision(4) << dResidur <<
" "
1920 << std::setw(7) << std::setprecision(3) <<
fMaxAngle <<
" "
1921 << std::setw(7) << std::setprecision(3) << s <<
" "
1922 << std::setw(5) << i <<
" "
1923 << std::setw(10) << std::setprecision(4)
1925 << std::setw(10) << std::setprecision(4)
1930 std::cout << std::endl;
1962 const char *classname,
1968 const char *prefix = (isMethod ?
Form(
"%s::", classname) :
"");
1969 const char *cv_qual = (isMethod ?
"" :
"static ");
1971 std::ofstream outFile(filename,std::ios::out|std::ios::trunc);
1973 Error(
"MakeRealCode",
"couldn't open output file '%s'",filename);
1978 std::cout <<
"Writing on file \"" << filename <<
"\" ... " << std::flush;
1983 outFile <<
"// -*- mode: c++ -*-" << std::endl;
1985 outFile <<
"// " << std::endl
1986 <<
"// File " << filename
1987 <<
" generated by TMultiDimFit::MakeRealCode" << std::endl;
1990 outFile <<
"// on " << date.
AsString() << std::endl;
1992 outFile <<
"// ROOT version " <<
gROOT->GetVersion()
1993 << std::endl <<
"//" << std::endl;
1995 outFile <<
"// This file contains the function " << std::endl
1996 <<
"//" << std::endl
1997 <<
"// double " << prefix <<
"MDF(double *x); " << std::endl
1998 <<
"//" << std::endl
1999 <<
"// For evaluating the parameterization obtained" << std::endl
2000 <<
"// from TMultiDimFit and the point x" << std::endl
2001 <<
"// " << std::endl
2002 <<
"// See TMultiDimFit class documentation for more "
2003 <<
"information " << std::endl <<
"// " << std::endl;
2007 outFile <<
"#include \"" << classname <<
".h\"" << std::endl;
2012 outFile <<
"//" << std::endl
2013 <<
"// Static data variables" << std::endl
2014 <<
"//" << std::endl;
2015 outFile << cv_qual <<
"int " << prefix <<
"gNVariables = "
2017 outFile << cv_qual <<
"int " << prefix <<
"gNCoefficients = "
2019 outFile << cv_qual <<
"double " << prefix <<
"gDMean = "
2023 outFile <<
"// Assignment to mean vector." << std::endl;
2024 outFile << cv_qual <<
"double " << prefix
2025 <<
"gXMean[] = {" << std::endl;
2027 outFile << (i != 0 ?
", " :
" ") <<
fMeanVariables(i) << std::flush;
2028 outFile <<
" };" << std::endl << std::endl;
2031 outFile <<
"// Assignment to minimum vector." << std::endl;
2032 outFile << cv_qual <<
"double " << prefix
2033 <<
"gXMin[] = {" << std::endl;
2035 outFile << (i != 0 ?
", " :
" ") <<
fMinVariables(i) << std::flush;
2036 outFile <<
" };" << std::endl << std::endl;
2039 outFile <<
"// Assignment to maximum vector." << std::endl;
2040 outFile << cv_qual <<
"double " << prefix
2041 <<
"gXMax[] = {" << std::endl;
2043 outFile << (i != 0 ?
", " :
" ") <<
fMaxVariables(i) << std::flush;
2044 outFile <<
" };" << std::endl << std::endl;
2047 outFile <<
"// Assignment to coefficients vector." << std::endl;
2048 outFile << cv_qual <<
"double " << prefix
2049 <<
"gCoefficient[] = {" << std::flush;
2051 outFile << (i != 0 ?
"," :
"") << std::endl
2053 outFile << std::endl <<
" };" << std::endl << std::endl;
2056 outFile <<
"// Assignment to error coefficients vector." << std::endl;
2057 outFile << cv_qual <<
"double " << prefix
2058 <<
"gCoefficientRMS[] = {" << std::flush;
2060 outFile << (i != 0 ?
"," :
"") << std::endl
2062 outFile << std::endl <<
" };" << std::endl << std::endl;
2065 outFile <<
"// Assignment to powers vector." << std::endl
2066 <<
"// The powers are stored row-wise, that is" << std::endl
2067 <<
"// p_ij = " << prefix
2068 <<
"gPower[i * NVariables + j];" << std::endl;
2069 outFile << cv_qual <<
"int " << prefix
2070 <<
"gPower[] = {" << std::flush;
2073 if (j != 0) outFile << std::flush <<
" ";
2074 else outFile << std::endl <<
" ";
2080 outFile << std::endl <<
"};" << std::endl << std::endl;
2086 outFile <<
"// " << std::endl
2088 << (isMethod ?
"method " :
"function ")
2089 <<
" double " << prefix
2091 << std::endl <<
"// " << std::endl;
2092 outFile <<
"double " << prefix
2093 <<
"MDF(double *x) {" << std::endl
2094 <<
" double returnValue = " << prefix <<
"gDMean;" << std::endl
2095 <<
" int i = 0, j = 0, k = 0;" << std::endl
2096 <<
" for (i = 0; i < " << prefix <<
"gNCoefficients ; i++) {"
2098 <<
" // Evaluate the ith term in the expansion" << std::endl
2099 <<
" double term = " << prefix <<
"gCoefficient[i];"
2101 <<
" for (j = 0; j < " << prefix <<
"gNVariables; j++) {"
2103 <<
" // Evaluate the polynomial in the jth variable." << std::endl
2104 <<
" int power = "<< prefix <<
"gPower["
2105 << prefix <<
"gNVariables * i + j]; " << std::endl
2106 <<
" double p1 = 1, p2 = 0, p3 = 0, r = 0;" << std::endl
2107 <<
" double v = 1 + 2. / ("
2108 << prefix <<
"gXMax[j] - " << prefix
2109 <<
"gXMin[j]) * (x[j] - " << prefix <<
"gXMax[j]);" << std::endl
2110 <<
" // what is the power to use!" << std::endl
2111 <<
" switch(power) {" << std::endl
2112 <<
" case 1: r = 1; break; " << std::endl
2113 <<
" case 2: r = v; break; " << std::endl
2114 <<
" default: " << std::endl
2115 <<
" p2 = v; " << std::endl
2116 <<
" for (k = 3; k <= power; k++) { " << std::endl
2117 <<
" p3 = p2 * v;" << std::endl;
2119 outFile <<
" p3 = ((2 * i - 3) * p2 * v - (i - 2) * p1)"
2120 <<
" / (i - 1);" << std::endl;
2122 outFile <<
" p3 = 2 * v * p2 - p1; " << std::endl;
2123 outFile <<
" p1 = p2; p2 = p3; " << std::endl <<
" }" << std::endl
2124 <<
" r = p3;" << std::endl <<
" }" << std::endl
2125 <<
" // multiply this term by the poly in the jth var" << std::endl
2126 <<
" term *= r; " << std::endl <<
" }" << std::endl
2127 <<
" // Add this term to the final result" << std::endl
2128 <<
" returnValue += term;" << std::endl <<
" }" << std::endl
2129 <<
" return returnValue;" << std::endl <<
"}" << std::endl << std::endl;
2132 outFile <<
"// EOF for " << filename << std::endl;
2138 std::cout <<
"done" << std::endl;
2164 std::cout <<
"User parameters:" << std::endl
2165 <<
"----------------" << std::endl
2168 <<
" Max Terms: " <<
fMaxTerms << std::endl
2169 <<
" Power Limit Parameter: " <<
fPowerLimit << std::endl
2171 <<
" Max functions to study: " <<
fMaxStudy << std::endl
2172 <<
" Max angle (optional): " <<
fMaxAngle << std::endl
2173 <<
" Min angle: " <<
fMinAngle << std::endl
2175 <<
" Maximum Powers: " << std::flush;
2177 std::cout <<
" " <<
fMaxPowers[i] - 1 << std::flush;
2178 std::cout << std::endl << std::endl
2179 <<
" Parameterisation will be done using " << std::flush;
2181 std::cout <<
"Chebyshev polynomials" << std::endl;
2183 std::cout <<
"Legendre polynomials" << std::endl;
2185 std::cout <<
"Monomials" << std::endl;
2186 std::cout << std::endl;
2191 std::cout <<
"Sample statistics:" << std::endl
2192 <<
"------------------" << std::endl
2193 <<
" D" << std::flush;
2195 std::cout <<
" " << std::setw(10) << i+1 << std::flush;
2196 std::cout << std::endl <<
" Max: " << std::setw(10) << std::setprecision(7)
2199 std::cout <<
" " << std::setw(10) << std::setprecision(4)
2201 std::cout << std::endl <<
" Min: " << std::setw(10) << std::setprecision(7)
2204 std::cout <<
" " << std::setw(10) << std::setprecision(4)
2206 std::cout << std::endl <<
" Mean: " << std::setw(10) << std::setprecision(7)
2209 std::cout <<
" " << std::setw(10) << std::setprecision(4)
2211 std::cout << std::endl <<
" Function Sum Squares: " <<
fSumSqQuantity
2212 << std::endl << std::endl;
2216 std::cout <<
"Results of Parameterisation:" << std::endl
2217 <<
"----------------------------" << std::endl
2218 <<
" Total reduction of square residuals "
2220 <<
" Relative precision obtained: "
2222 <<
" Error obtained: "
2224 <<
" Multiple correlation coefficient: "
2226 <<
" Reduced Chi square over sample: "
2228 <<
" Maximum residual value: "
2230 <<
" Minimum residual value: "
2232 <<
" Estimated root mean square: "
2233 <<
fRMS << std::endl
2234 <<
" Maximum powers used: " << std::flush;
2237 std::cout << std::endl
2238 <<
" Function codes of candidate functions." << std::endl
2239 <<
" 1: considered,"
2240 <<
" 2: too little contribution,"
2241 <<
" 3: accepted." << std::flush;
2244 std::cout << std::endl <<
" " << std::flush;
2245 else if (i % 10 == 0)
2246 std::cout <<
" " << std::flush;
2249 std::cout << std::endl <<
" Loop over candidates stopped because " << std::flush;
2252 std::cout <<
"max allowed studies reached" << std::endl;
break;
2254 std::cout <<
"all candidates considered several times" << std::endl;
break;
2256 std::cout <<
"wanted relative error obtained" << std::endl;
break;
2258 std::cout <<
"max number of terms reached" << std::endl;
break;
2260 std::cout <<
"some unknown reason" << std::endl;
2263 std::cout << std::endl;
2267 std::cout <<
"Results of Fit:" << std::endl
2268 <<
"---------------" << std::endl
2269 <<
" Test sample size: "
2271 <<
" Multiple correlation coefficient: "
2273 <<
" Relative precision obtained: "
2275 <<
" Error obtained: "
2277 <<
" Reduced Chi square over sample: "
2282 std::cout << std::endl;
2287 std::cout <<
"Coefficients:" << std::endl
2288 <<
"-------------" << std::endl
2289 <<
" # Value Error Powers" << std::endl
2290 <<
" ---------------------------------------" << std::endl;
2292 std::cout <<
" " << std::setw(3) << i <<
" "
2296 std::cout <<
" " << std::setw(3)
2298 std::cout << std::endl;
2300 std::cout << std::endl;
2303 std::cout <<
"Correlation Matrix:" << std::endl
2304 <<
"-------------------";
2309 std::cout <<
"Parameterization:" << std::endl
2310 <<
"-----------------" << std::endl
2311 <<
" Normalised variables: " << std::endl;
2313 std::cout <<
"\ty_" << i <<
"\t= 1 + 2 * (x_" << i <<
" - "
2317 std::cout << std::endl
2320 std::cout <<
"y_" << i;
2323 std::cout <<
") = ";
2326 std::cout << std::endl <<
"\t" << (
fCoefficients(i) < 0 ?
"- " :
"+ ")
2334 case 2: std::cout <<
" * y_" << j;
break;
2337 case kLegendre: std::cout <<
" * L_" << p-1 <<
"(y_" << j <<
")";
break;
2338 case kChebyshev: std::cout <<
" * C_" << p-1 <<
"(y_" << j <<
")";
break;
2339 default: std::cout <<
" * y_" << j <<
"^" << p-1;
break;
2345 std::cout << std::endl;
2375 if (ang >= 90 || ang < 0) {
2376 Warning(
"SetMaxAngle",
"angle must be in [0,90)");
2391 if (ang > 90 || ang <= 0) {
2392 Warning(
"SetMinAngle",
"angle must be in [0,90)");
2496 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)}
TH1 is the base class of all histogram classes in ROOT.
virtual Bool_t Add(TF1 *h1, Double_t c1=1, Option_t *option="")
Performs the operation: this = this + c1*f1 if errors are defined (see TH1::Sumw2),...
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.
Short_t Max(Short_t a, Short_t b)
Double_t Sqrt(Double_t x)
static uint64_t sum(uint64_t i)