CMS 3D CMS Logo

TMultiDimFet.cc
Go to the documentation of this file.
1 /****************************************************************************
2 *
3 * This is a part of TOTEM ofFileline software.
4 *
5 * Based on TMultiDimFet.cc (from ROOT) by Christian Holm Christense.
6 *
7 * Authors:
8 * Hubert Niewiadomski
9 * Jan Kašpar (jan.kaspar@gmail.com)
10 *
11 ****************************************************************************/
12 
13 #include "Riostream.h"
16 #include "TMath.h"
17 #include "TH1.h"
18 #include "TH2.h"
19 #include "TROOT.h"
20 #include "TDecompChol.h"
21 #include "TDatime.h"
22 #include <iostream>
23 #include <map>
24 
25 #define RADDEG (180. / TMath::Pi())
26 #define DEGRAD (TMath::Pi() / 180.)
27 #define HIST_XORIG 0
28 #define HIST_DORIG 1
29 #define HIST_XNORM 2
30 #define HIST_DSHIF 3
31 #define HIST_RX 4
32 #define HIST_RD 5
33 #define HIST_RTRAI 6
34 #define HIST_RTEST 7
35 #define PARAM_MAXSTUDY 1
36 #define PARAM_SEVERAL 2
37 #define PARAM_RELERR 3
38 #define PARAM_MAXTERMS 4
39 
40 //____________________________________________________________________
41 //static void mdfHelper(int&, double*, double&, double*, int);
42 
43 //____________________________________________________________________
45 
46 //____________________________________________________________________
47 // Static instance. Used with mdfHelper and TMinuit
48 //TMultiDimFet* TMultiDimFet::fgInstance = nullptr;
49 
50 //____________________________________________________________________
52  // Empty CTOR. Do not use
53  fMeanQuantity = 0;
54  fMaxQuantity = 0;
55  fMinQuantity = 0;
56  fSumSqQuantity = 0;
58  fPowerLimit = 1;
59 
60  fMaxAngle = 0;
61  fMinAngle = 1;
62 
63  fNVariables = 0;
64  fMaxVariables = 0;
65  fMinVariables = 0;
66  fSampleSize = 0;
67 
68  fMaxAngle = 0;
69  fMinAngle = 0;
70 
72  fShowCorrelation = kFALSE;
73 
74  fIsUserFunction = kFALSE;
75 
76  fHistograms = nullptr;
77  fHistogramMask = 0;
78 
79  //fFitter = nullptr;
80  //fgInstance = nullptr;
81 }
82 
84  if (this == &in) {
85  return in;
86  }
87 
88  fMeanQuantity = in.fMeanQuantity; // Mean of dependent quantity
89 
90  fMaxQuantity = 0.0;
91  fMinQuantity = 0.0;
92  fSumSqQuantity = 0.0;
93  fSumSqAvgQuantity = 0.0;
94 
95  fNVariables = in.fNVariables; // Number of independent variables
96 
97  fMaxVariables.ResizeTo(in.fMaxVariables.GetLwb(), in.fMaxVariables.GetUpb());
98  fMaxVariables = in.fMaxVariables; // max value of independent variables
99 
100  fMinVariables.ResizeTo(in.fMinVariables.GetLwb(), in.fMinVariables.GetUpb());
101  fMinVariables = in.fMinVariables; // min value of independent variables
102 
103  fSampleSize = 0;
104  fTestSampleSize = 0;
105  fMinAngle = 1;
106  fMaxAngle = 0.0;
107 
108  fMaxTerms = in.fMaxTerms; // Max terms expected in final expr.
109 
110  fMinRelativeError = 0.0;
111 
112  fMaxPowers.clear();
113  fPowerLimit = 1;
114 
115  fMaxFunctions = in.fMaxFunctions; // max number of functions
116 
117  fFunctionCodes.clear();
118  fMaxStudy = 0;
119 
120  fMaxPowersFinal.clear();
121 
122  fMaxFunctionsTimesNVariables = in.fMaxFunctionsTimesNVariables; // fMaxFunctionsTimesNVariables
123  fPowers = in.fPowers;
124 
125  fPowerIndex = in.fPowerIndex; // [fMaxTerms] Index of accepted powers
126 
127  fMaxResidual = 0.0;
128  fMinResidual = 0.0;
129  fMaxResidualRow = 0;
130  fMinResidualRow = 0;
131  fSumSqResidual = 0.0;
132 
133  fNCoefficients = in.fNCoefficients; // Dimension of model coefficients
134 
135  fCoefficients.ResizeTo(in.fCoefficients.GetLwb(), in.fCoefficients.GetUpb());
136  fCoefficients = in.fCoefficients; // Vector of the final coefficients
137 
138  fRMS = 0.0;
139  fChi2 = 0.0;
141  fError = 0.0;
142  fTestError = 0.0;
143  fPrecision = 0.0;
144  fTestPrecision = 0.0;
145  fCorrelationCoeff = 0.0;
146  fTestCorrelationCoeff = 0.0;
147  fHistograms = nullptr;
148  fHistogramMask = 0;
149  //fFitter = nullptr; //! Fit object (MINUIT)
150 
151  fPolyType = in.fPolyType; // Type of polynomials to use
152  fShowCorrelation = in.fShowCorrelation; // print correlation matrix
153  fIsUserFunction = in.fIsUserFunction; // Flag for user defined function
154  fIsVerbose = in.fIsVerbose; //
155  return in;
156 }
157 
158 //____________________________________________________________________
160  : TNamed("multidimfit", "Multi-dimensional fit object"),
161  fQuantity(dimension),
162  fSqError(dimension),
163  fVariables(dimension * 100),
164  fMeanVariables(dimension),
165  fMaxVariables(dimension),
166  fMinVariables(dimension) {
167  // Constructor
168  // Second argument is the type of polynomials to use in
169  // parameterisation, one of:
170  // TMultiDimFet::kMonomials
171  // TMultiDimFet::kChebyshev
172  // TMultiDimFet::kLegendre
173  //
174  // Options:
175  // K Compute (k)correlation matrix
176  // V Be verbose
177  //
178  // Default is no options.
179  //
180 
181  //fgInstance = this;
182 
183  fMeanQuantity = 0;
184  fMaxQuantity = 0;
185  fMinQuantity = 0;
186  fSumSqQuantity = 0;
187  fSumSqAvgQuantity = 0;
188  fPowerLimit = 1;
189 
190  fMaxAngle = 0;
191  fMinAngle = 1;
192 
194  fMaxVariables = 0;
196  fMinVariables = 0;
197  fSampleSize = 0;
198  fTestSampleSize = 0;
199  fMinRelativeError = 0.01;
200  fError = 0;
201  fTestError = 0;
202  fPrecision = 0;
203  fTestPrecision = 0;
205 
206  fPolyType = type;
207  fShowCorrelation = kFALSE;
208  fIsVerbose = kFALSE;
209 
210  TString opt = option;
211  opt.ToLower();
212 
213  if (opt.Contains("k"))
214  fShowCorrelation = kTRUE;
215  if (opt.Contains("v"))
216  fIsVerbose = kTRUE;
217 
218  fIsUserFunction = kFALSE;
219 
220  fHistograms = nullptr;
221  fHistogramMask = 0;
222 
223  fMaxPowers.resize(dimension);
224  fMaxPowersFinal.resize(dimension);
225  //fFitter = nullptr;
226 }
227 
228 //____________________________________________________________________
230  if (fHistograms)
231  fHistograms->Clear("nodelete");
232  delete fHistograms;
233 }
234 
235 //____________________________________________________________________
236 void TMultiDimFet::AddRow(const Double_t *x, Double_t D, Double_t E) {
237  // Add a row consisting of fNVariables independent variables, the
238  // known, dependent quantity, and optionally, the square error in
239  // the dependent quantity, to the training sample to be used for the
240  // parameterization.
241  // The mean of the variables and quantity is calculated on the fly,
242  // as outlined in TPrincipal::AddRow.
243  // This sample should be representive of the problem at hand.
244  // Please note, that if no error is given Poisson statistics is
245  // assumed and the square error is set to the value of dependent
246  // quantity. See also the
247  // Begin_Html<a href="#TMultiDimFet:description">class description</a>End_Html
248  if (!x)
249  return;
250 
251  if (++fSampleSize == 1) {
252  fMeanQuantity = D;
253  fMaxQuantity = D;
254  fMinQuantity = D;
255  } else {
256  fMeanQuantity *= 1 - 1. / Double_t(fSampleSize);
257  fMeanQuantity += D / Double_t(fSampleSize);
258  fSumSqQuantity += D * D;
259 
260  if (D >= fMaxQuantity)
261  fMaxQuantity = D;
262  if (D <= fMinQuantity)
263  fMinQuantity = D;
264  }
265 
266  // If the vector isn't big enough to hold the new data, then
267  // expand the vector by half it's size.
268  Int_t size = fQuantity.GetNrows();
269  if (fSampleSize > size) {
270  fQuantity.ResizeTo(size + size / 2);
271  fSqError.ResizeTo(size + size / 2);
272  }
273 
274  // Store the value
275  fQuantity(fSampleSize - 1) = D;
276  fSqError(fSampleSize - 1) = (E == 0 ? D : E);
277 
278  // Store data point in internal vector
279  // If the vector isn't big enough to hold the new data, then
280  // expand the vector by half it's size
281  size = fVariables.GetNrows();
282  if (fSampleSize * fNVariables > size)
283  fVariables.ResizeTo(size + size / 2);
284 
285  // Increment the data point counter
286  Int_t i, j;
287  for (i = 0; i < fNVariables; i++) {
288  if (fSampleSize == 1) {
289  fMeanVariables(i) = x[i];
290  fMaxVariables(i) = x[i];
291  fMinVariables(i) = x[i];
292  } else {
293  fMeanVariables(i) *= 1 - 1. / Double_t(fSampleSize);
294  fMeanVariables(i) += x[i] / Double_t(fSampleSize);
295 
296  // Update the maximum value for this component
297  if (x[i] >= fMaxVariables(i))
298  fMaxVariables(i) = x[i];
299 
300  // Update the minimum value for this component
301  if (x[i] <= fMinVariables(i))
302  fMinVariables(i) = x[i];
303  }
304 
305  // Store the data.
306  j = (fSampleSize - 1) * fNVariables + i;
307  fVariables(j) = x[i];
308  }
309 }
310 
311 //____________________________________________________________________
312 void TMultiDimFet::AddTestRow(const Double_t *x, Double_t D, Double_t E) {
313  // Add a row consisting of fNVariables independent variables, the
314  // known, dependent quantity, and optionally, the square error in
315  // the dependent quantity, to the test sample to be used for the
316  // test of the parameterization.
317  // This sample needn't be representive of the problem at hand.
318  // Please note, that if no error is given Poisson statistics is
319  // assumed and the square error is set to the value of dependent
320  // quantity. See also the
321  // Begin_Html<a href="#TMultiDimFet:description">class description</a>End_Html
322  if (fTestSampleSize++ == 0) {
323  fTestQuantity.ResizeTo(fNVariables);
324  fTestSqError.ResizeTo(fNVariables);
325  fTestVariables.ResizeTo(fNVariables * 100);
326  }
327 
328  // If the vector isn't big enough to hold the new data, then
329  // expand the vector by half it's size.
330  Int_t size = fTestQuantity.GetNrows();
331  if (fTestSampleSize > size) {
332  fTestQuantity.ResizeTo(size + size / 2);
333  fTestSqError.ResizeTo(size + size / 2);
334  }
335 
336  // Store the value
338  fTestSqError(fTestSampleSize - 1) = (E == 0 ? D : E);
339 
340  // Store data point in internal vector
341  // If the vector isn't big enough to hold the new data, then
342  // expand the vector by half it's size
343  size = fTestVariables.GetNrows();
345  fTestVariables.ResizeTo(size + size / 2);
346 
347  // Increment the data point counter
348  Int_t i, j;
349  for (i = 0; i < fNVariables; i++) {
350  j = fNVariables * (fTestSampleSize - 1) + i;
351  fTestVariables(j) = x[i];
352 
353  if (x[i] > fMaxVariables(i))
354  Warning("AddTestRow", "variable %d (row: %d) too large: %f > %f", i, fTestSampleSize, x[i], fMaxVariables(i));
355  if (x[i] < fMinVariables(i))
356  Warning("AddTestRow", "variable %d (row: %d) too small: %f < %f", i, fTestSampleSize, x[i], fMinVariables(i));
357  }
358 }
359 
360 //____________________________________________________________________
361 void TMultiDimFet::Clear(Option_t *option) {
362  // Clear internal structures and variables
363  Int_t i, j, n = fNVariables, m = fMaxFunctions;
364 
365  // Training sample, dependent quantity
366  fQuantity.Zero();
367  fSqError.Zero();
368  fMeanQuantity = 0;
369  fMaxQuantity = 0;
370  fMinQuantity = 0;
371  fSumSqQuantity = 0;
372  fSumSqAvgQuantity = 0;
373 
374  // Training sample, independent variables
375  fVariables.Zero();
376  fNVariables = 0;
377  fSampleSize = 0;
378  fMeanVariables.Zero();
379  fMaxVariables.Zero();
380  fMinVariables.Zero();
381 
382  // Test sample
383  fTestQuantity.Zero();
384  fTestSqError.Zero();
385  fTestVariables.Zero();
386  fTestSampleSize = 0;
387 
388  // Functions
389  fFunctions.Zero();
390  fMaxFunctions = 0;
391  fMaxStudy = 0;
393  fOrthFunctions.Zero();
394  fOrthFunctionNorms.Zero();
395 
396  // Control parameters
397  fMinRelativeError = 0;
398  fMinAngle = 0;
399  fMaxAngle = 0;
400  fMaxTerms = 0;
401 
402  // Powers
403  for (i = 0; i < n; i++) {
404  fMaxPowers[i] = 0;
405  fMaxPowersFinal[i] = 0;
406  for (j = 0; j < m; j++)
407  fPowers[i * n + j] = 0;
408  }
409  fPowerLimit = 0;
410 
411  // Residuals
412  fMaxResidual = 0;
413  fMinResidual = 0;
414  fMaxResidualRow = 0;
415  fMinResidualRow = 0;
416  fSumSqResidual = 0;
417 
418  // Fit
419  fNCoefficients = 0;
420  fOrthCoefficients = 0;
422  fRMS = 0;
423  fCorrelationMatrix.Zero();
424  fError = 0;
425  fTestError = 0;
426  fPrecision = 0;
427  fTestPrecision = 0;
428 
429  // Coefficients
430  fCoefficients.Zero();
431  fCoefficientsRMS.Zero();
432  fResiduals.Zero();
433  fHistograms->Clear(option);
434 
435  // Options
437  fShowCorrelation = kFALSE;
438  fIsUserFunction = kFALSE;
439 }
440 
441 //____________________________________________________________________
442 Double_t TMultiDimFet::Eval(const Double_t *x, const Double_t *coeff) const {
443  // Evaluate parameterization at point x. Optional argument coeff is
444  // a vector of coefficients for the parameterisation, fNCoefficients
445  // elements long.
446  // int fMaxFunctionsTimesNVariables = fMaxFunctions * fNVariables;
447  Double_t returnValue = fMeanQuantity;
448  Double_t term = 0;
449  Int_t i, j;
450 
451  for (i = 0; i < fNCoefficients; i++) {
452  // Evaluate the ith term in the expansion
453  term = (coeff ? coeff[i] : fCoefficients(i));
454  for (j = 0; j < fNVariables; j++) {
455  // Evaluate the factor (polynomial) in the j-th variable.
456  Int_t p = fPowers[fPowerIndex[i] * fNVariables + j];
457  Double_t y = 1 + 2. / (fMaxVariables(j) - fMinVariables(j)) * (x[j] - fMaxVariables(j));
458  term *= EvalFactor(p, y);
459  }
460  // Add this term to the final result
461  returnValue += term;
462  }
463  return returnValue;
464 }
465 
467  if (error == 0.0)
468  return;
469  else {
471  }
472 }
473 
475  typedef std::multimap<double, int> cmt;
476  cmt m;
477 
478  for (int i = 0; i < fNCoefficients; i++) {
479  m.insert(std::pair<double, int>(TMath::Abs(fCoefficients(i)), i));
480  }
481 
482  double del_error_abs = 0;
483  int deleted_terms_count = 0;
484 
485  for (cmt::iterator it = m.begin(); it != m.end() && del_error_abs < error; ++it) {
486  if (TMath::Abs(it->first) + del_error_abs < error) {
487  fCoefficients(it->second) = 0.0;
488  del_error_abs = TMath::Abs(it->first) + del_error_abs;
489  deleted_terms_count++;
490  } else
491  break;
492  }
493 
494  int fNCoefficients_new = fNCoefficients - deleted_terms_count;
495  TVectorD fCoefficients_new(fNCoefficients_new);
496  std::vector<Int_t> fPowerIndex_new;
497 
498  int ind = 0;
499  for (int i = 0; i < fNCoefficients; i++) {
500  if (fCoefficients(i) != 0.0) {
501  fCoefficients_new(ind) = fCoefficients(i);
502  fPowerIndex_new.push_back(fPowerIndex[i]);
503  ind++;
504  }
505  }
506  fNCoefficients = fNCoefficients_new;
507  fCoefficients.ResizeTo(fNCoefficients);
508  fCoefficients = fCoefficients_new;
509  fPowerIndex = fPowerIndex_new;
510  edm::LogInfo("TMultiDimFet") << deleted_terms_count << " terms removed"
511  << "\n";
512 }
513 
514 //____________________________________________________________________
515 Double_t TMultiDimFet::EvalControl(const Int_t *iv) {
516  // PRIVATE METHOD:
517  // Calculate the control parameter from the passed powers
518  Double_t s = 0;
519  Double_t epsilon = 1e-6; // a small number
520  for (Int_t i = 0; i < fNVariables; i++) {
521  if (fMaxPowers[i] != 1)
522  s += (epsilon + iv[i] - 1) / (epsilon + fMaxPowers[i] - 1);
523  }
524  return s;
525 }
526 
527 //____________________________________________________________________
528 Double_t TMultiDimFet::EvalFactor(Int_t p, Double_t x) const {
529  // PRIVATE METHOD:
530  // Evaluate function with power p at variable value x
531  Int_t i = 0;
532  Double_t p1 = 1;
533  Double_t p2 = 0;
534  Double_t p3 = 0;
535  Double_t r = 0;
536 
537  switch (p) {
538  case 1:
539  r = 1;
540  break;
541  case 2:
542  r = x;
543  break;
544  default:
545  p2 = x;
546  for (i = 3; i <= p; i++) {
547  p3 = p2 * x;
548  if (fPolyType == kLegendre)
549  p3 = ((2 * i - 3) * p2 * x - (i - 2) * p1) / (i - 1);
550  else if (fPolyType == kChebyshev)
551  p3 = 2 * x * p2 - p1;
552  p1 = p2;
553  p2 = p3;
554  }
555  r = p3;
556  }
557 
558  return r;
559 }
560 
561 //____________________________________________________________________
563  // Find the parameterization
564  //
565  // Options:
566  // None so far
567  //
568  // For detailed description of what this entails, please refer to the
569  // Begin_Html<a href="#TMultiDimFet:description">class description</a>End_Html
570  MakeNormalized();
571  MakeCandidates();
575 }
576 
577 //____________________________________________________________________
578 /*
579 void TMultiDimFet::Fit(Option_t *option)
580 {
581  // Try to fit the found parameterisation to the test sample.
582  //
583  // Options
584  // M use Minuit to improve coefficients
585  //
586  // Also, refer to
587  // Begin_Html<a href="#TMultiDimFet:description">class description</a>End_Html
588 
589  //fgInstance = this;
590 
591  Int_t i, j;
592  Double_t* x = new Double_t[fNVariables];
593  Double_t sumSqD = 0;
594  Double_t sumD = 0;
595  Double_t sumSqR = 0;
596  Double_t sumR = 0;
597 
598  // Calculate the residuals over the test sample
599  for (i = 0; i < fTestSampleSize; i++) {
600  for (j = 0; j < fNVariables; j++)
601  x[j] = fTestVariables(i * fNVariables + j);
602  Double_t res = fTestQuantity(i) - Eval(x);
603  sumD += fTestQuantity(i);
604  sumSqD += fTestQuantity(i) * fTestQuantity(i);
605  sumR += res;
606  sumSqR += res * res;
607  if (TESTBIT(fHistogramMask,HIST_RTEST))
608  ((TH1D*)fHistograms->FindObject("res_test"))->Fill(res);
609  }
610  Double_t dAvg = sumSqD - (sumD * sumD) / fTestSampleSize;
611  Double_t rAvg = sumSqR - (sumR * sumR) / fTestSampleSize;
612  fTestCorrelationCoeff = (dAvg - rAvg) / dAvg;
613  fTestError = sumSqR;
614  fTestPrecision = sumSqR / sumSqD;
615 
616  TString opt(option);
617  opt.ToLower();
618 
619  if (!opt.Contains("m"))
620  MakeChi2();
621 
622  if (fNCoefficients * 50 > fTestSampleSize)
623  Warning("Fit", "test sample is very small");
624 
625  if (!opt.Contains("m"))
626  return;
627 
628  fFitter = TVirtualFitter::Fitter(nullptr,fNCoefficients);
629  fFitter->SetFCN(mdfHelper);
630 
631  const Int_t maxArgs = 16;
632  Int_t args = 1;
633  Double_t* arglist = new Double_t[maxArgs];
634  arglist[0] = -1;
635  fFitter->ExecuteCommand("SET PRINT",arglist,args);
636 
637  for (i = 0; i < fNCoefficients; i++) {
638  Double_t startVal = fCoefficients(i);
639  Double_t startErr = fCoefficientsRMS(i);
640  fFitter->SetParameter(i, Form("coeff%02d",i),
641  startVal, startErr, 0, 0);
642  }
643 
644  args = 1;
645  fFitter->ExecuteCommand("MIGRAD",arglist,args);
646 
647  for (i = 0; i < fNCoefficients; i++) {
648  Double_t val = 0, err = 0, low = 0, high = 0;
649  fFitter->GetParameter(i, Form("coeff%02d",i),
650  val, err, low, high);
651  fCoefficients(i) = val;
652  fCoefficientsRMS(i) = err;
653  }
654 }
655 */
656 
657 //____________________________________________________________________
659  // PRIVATE METHOD:
660  // Create list of candidate functions for the parameterisation. See
661  // also
662  // Begin_Html<a href="#TMultiDimFet:description">class description</a>End_Html
663  Int_t i = 0;
664  Int_t j = 0;
665  Int_t k = 0;
666 
667  // The temporary array to store the powers in. We don't need to
668  // initialize this array however.
669  Int_t *powers = new Int_t[fNVariables * fMaxFunctions];
670 
671  // store of `control variables'
672  Double_t *control = new Double_t[fMaxFunctions];
673 
674  // We've better initialize the variables
675  Int_t *iv = new Int_t[fNVariables];
676  for (i = 0; i < fNVariables; i++)
677  iv[i] = 1;
678 
679  if (!fIsUserFunction) {
680  // Number of funcs selected
681  Int_t numberFunctions = 0;
682 
683  while (kTRUE) {
684  // Get the control value for this function
685  Double_t s = EvalControl(iv);
686 
687  if (s <= fPowerLimit) {
688  // Call over-loadable method Select, as to allow the user to
689  // interfere with the selection of functions.
690  if (Select(iv)) {
691  numberFunctions++;
692 
693  // If we've reached the user defined limit of how many
694  // functions we can consider, break out of the loop
695  if (numberFunctions > fMaxFunctions)
696  break;
697 
698  // Store the control value, so we can sort array of powers
699  // later on
700  control[numberFunctions - 1] = Int_t(1.0e+6 * s);
701 
702  // Store the powers in powers array.
703  for (i = 0; i < fNVariables; i++) {
704  j = (numberFunctions - 1) * fNVariables + i;
705  powers[j] = iv[i];
706  }
707  } // if (Select())
708  } // if (s <= fPowerLimit)
709 
710  for (i = 0; i < fNVariables; i++)
711  if (iv[i] < fMaxPowers[i])
712  break;
713 
714  // If all variables have reached their maximum power, then we
715  // break out of the loop
716  if (i == fNVariables) {
717  fMaxFunctions = numberFunctions;
719  break;
720  }
721 
722  // Next power in variable i
723  iv[i]++;
724 
725  for (j = 0; j < i; j++)
726  iv[j] = 1;
727  } // while (kTRUE)
728  } else {
729  // In case the user gave an explicit function
730  for (i = 0; i < fMaxFunctions; i++) {
731  // Copy the powers to working arrays
732  for (j = 0; j < fNVariables; j++) {
733  powers[i * fNVariables + j] = fPowers[i * fNVariables + j];
734  iv[j] = fPowers[i * fNVariables + j];
735  }
736 
737  control[i] = Int_t(1.0e+6 * EvalControl(iv));
738  }
739  }
740 
741  // Now we need to sort the powers according to least `control
742  // variable'
743  Int_t *order = new Int_t[fMaxFunctions];
744  for (i = 0; i < fMaxFunctions; i++)
745  order[i] = i;
747 
748  for (i = 0; i < fMaxFunctions; i++) {
749  Double_t x = control[i];
750  Int_t l = order[i];
751  k = i;
752 
753  for (j = i; j < fMaxFunctions; j++) {
754  if (control[j] <= x) {
755  x = control[j];
756  l = order[j];
757  k = j;
758  }
759  }
760 
761  if (k != i) {
762  control[k] = control[i];
763  control[i] = x;
764  order[k] = order[i];
765  order[i] = l;
766  }
767  }
768 
769  for (i = 0; i < fMaxFunctions; i++)
770  for (j = 0; j < fNVariables; j++)
771  fPowers[i * fNVariables + j] = powers[order[i] * fNVariables + j];
772 
773  delete[] control;
774  delete[] powers;
775  delete[] order;
776  delete[] iv;
777 }
778 
779 Double_t TMultiDimFet::MakeChi2(const Double_t *coeff) {
780  // Calculate Chi square over either the test sample. The optional
781  // argument coeff is a vector of coefficients to use in the
782  // evaluation of the parameterisation. If coeff == 0, then the found
783  // coefficients is used.
784  // Used my MINUIT for fit (see TMultDimFit::Fit)
785  fChi2 = 0;
786  Int_t i, j;
787  Double_t *x = new Double_t[fNVariables];
788  for (i = 0; i < fTestSampleSize; i++) {
789  // Get the stored point
790  for (j = 0; j < fNVariables; j++)
791  x[j] = fTestVariables(i * fNVariables + j);
792 
793  // Evaluate function. Scale to shifted values
794  Double_t f = Eval(x, coeff);
795 
796  // Calculate contribution to Chic square
797  fChi2 += 1. / TMath::Max(fTestSqError(i), 1e-20) * (fTestQuantity(i) - f) * (fTestQuantity(i) - f);
798  }
799 
800  // Clean up
801  delete[] x;
802 
803  return fChi2;
804 }
805 
806 //____________________________________________________________________
807 void TMultiDimFet::MakeCode(const char *filename, Option_t *option) {
808  // Generate the file <filename> with .C appended if argument doesn't
809  // end in .cxx or .C. The contains the implementation of the
810  // function:
811  //
812  // Double_t <funcname>(Double_t *x)
813  //
814  // which does the same as TMultiDimFet::Eval. Please refer to this
815  // method.
816  //
817  // Further, the static variables:
818  //
819  // Int_t gNVariables
820  // Int_t gNCoefficients
821  // Double_t gDMean
822  // Double_t gXMean[]
823  // Double_t gXMin[]
824  // Double_t gXMax[]
825  // Double_t gCoefficient[]
826  // Int_t gPower[]
827  //
828  // are initialized. The only ROOT header file needed is Rtypes.h
829  //
830  // See TMultiDimFet::MakeRealCode for a list of options
831 
832  TString outName(filename);
833  if (!outName.EndsWith(".C") && !outName.EndsWith(".cxx"))
834  outName += ".C";
835 
836  MakeRealCode(outName.Data(), "", option);
837 }
838 
840  // PRIVATE METHOD:
841  // Compute the errors on the coefficients. For this to be done, the
842  // curvature matrix of the non-orthogonal functions, is computed.
843  Int_t i = 0;
844  Int_t j = 0;
845  Int_t k = 0;
846  TVectorD iF(fSampleSize);
847  TVectorD jF(fSampleSize);
849 
850  TMatrixDSym curvatureMatrix(fNCoefficients);
851 
852  // Build the curvature matrix
853  for (i = 0; i < fNCoefficients; i++) {
854  iF = TMatrixDRow(fFunctions, i);
855  for (j = 0; j <= i; j++) {
856  jF = TMatrixDRow(fFunctions, j);
857  for (k = 0; k < fSampleSize; k++)
858  curvatureMatrix(i, j) += 1 / TMath::Max(fSqError(k), 1e-20) * iF(k) * jF(k);
859  curvatureMatrix(j, i) = curvatureMatrix(i, j);
860  }
861  }
862 
863  // Calculate Chi Square
864  fChi2 = 0;
865  for (i = 0; i < fSampleSize; i++) {
866  Double_t f = 0;
867  for (j = 0; j < fNCoefficients; j++)
868  f += fCoefficients(j) * fFunctions(j, i);
869  fChi2 += 1. / TMath::Max(fSqError(i), 1e-20) * (fQuantity(i) - f) * (fQuantity(i) - f);
870  }
871 
872  // Invert the curvature matrix
873  const TVectorD diag = TMatrixDDiag_const(curvatureMatrix);
874  curvatureMatrix.NormByDiag(diag);
875 
876  TDecompChol chol(curvatureMatrix);
877  if (!chol.Decompose())
878  Error("MakeCoefficientErrors", "curvature matrix is singular");
879  chol.Invert(curvatureMatrix);
880 
881  curvatureMatrix.NormByDiag(diag);
882 
883  for (i = 0; i < fNCoefficients; i++)
884  fCoefficientsRMS(i) = TMath::Sqrt(curvatureMatrix(i, i));
885 }
886 
887 //____________________________________________________________________
889  // PRIVATE METHOD:
890  // Invert the model matrix B, and compute final coefficients. For a
891  // more thorough discussion of what this means, please refer to the
892  // Begin_Html<a href="#TMultiDimFet:description">class description</a>End_Html
893  //
894  // First we invert the lower triangle matrix fOrthCurvatureMatrix
895  // and store the inverted matrix in the upper triangle.
896 
897  Int_t i = 0, j = 0;
898  Int_t col = 0, row = 0;
899 
900  // Invert the B matrix
901  for (col = 1; col < fNCoefficients; col++) {
902  for (row = col - 1; row > -1; row--) {
903  fOrthCurvatureMatrix(row, col) = 0;
904  for (i = row; i <= col; i++)
906  }
907  }
908 
909  // Compute the final coefficients
910  fCoefficients.ResizeTo(fNCoefficients);
911 
912  for (i = 0; i < fNCoefficients; i++) {
913  Double_t sum = 0;
914  for (j = i; j < fNCoefficients; j++)
916  fCoefficients(i) = sum;
917  }
918 
919  // Compute the final residuals
920  fResiduals.ResizeTo(fSampleSize);
921  for (i = 0; i < fSampleSize; i++)
922  fResiduals(i) = fQuantity(i);
923 
924  for (i = 0; i < fNCoefficients; i++)
925  for (j = 0; j < fSampleSize; j++)
927 
928  // Compute the max and minimum, and squared sum of the evaluated
929  // residuals
930  fMinResidual = 10e10;
931  fMaxResidual = -10e10;
932  Double_t sqRes = 0;
933  for (i = 0; i < fSampleSize; i++) {
934  sqRes += fResiduals(i) * fResiduals(i);
935  if (fResiduals(i) <= fMinResidual) {
937  fMinResidualRow = i;
938  }
939  if (fResiduals(i) >= fMaxResidual) {
941  fMaxResidualRow = i;
942  }
943  }
944 
946  fPrecision = TMath::Sqrt(sqRes / fSumSqQuantity);
947 
948  // If we use histograms, fill some more
949  if (TESTBIT(fHistogramMask, HIST_RD) || TESTBIT(fHistogramMask, HIST_RTRAI) || TESTBIT(fHistogramMask, HIST_RX)) {
950  for (i = 0; i < fSampleSize; i++) {
951  if (TESTBIT(fHistogramMask, HIST_RD))
952  ((TH2D *)fHistograms->FindObject("res_d"))->Fill(fQuantity(i), fResiduals(i));
953  if (TESTBIT(fHistogramMask, HIST_RTRAI))
954  ((TH1D *)fHistograms->FindObject("res_train"))->Fill(fResiduals(i));
955 
956  if (TESTBIT(fHistogramMask, HIST_RX))
957  for (j = 0; j < fNVariables; j++)
958  ((TH2D *)fHistograms->FindObject(Form("res_x_%d", j)))->Fill(fVariables(i * fNVariables + j), fResiduals(i));
959  }
960  } // If histograms
961 }
962 
963 //____________________________________________________________________
965  // PRIVATE METHOD:
966  // Compute the correlation matrix
967  if (!fShowCorrelation)
968  return;
969 
971 
972  Double_t d2 = 0;
973  Double_t ddotXi = 0; // G.Q. needs to be reinitialized in the loop over i fNVariables
974  Double_t xiNorm = 0; // G.Q. needs to be reinitialized in the loop over i fNVariables
975  Double_t xidotXj = 0; // G.Q. needs to be reinitialized in the loop over j fNVariables
976  Double_t xjNorm = 0; // G.Q. needs to be reinitialized in the loop over j fNVariables
977 
978  Int_t i, j, k, l, m; // G.Q. added m variable
979  for (i = 0; i < fSampleSize; i++)
980  d2 += fQuantity(i) * fQuantity(i);
981 
982  for (i = 0; i < fNVariables; i++) {
983  ddotXi = 0.; // G.Q. reinitialisation
984  xiNorm = 0.; // G.Q. reinitialisation
985  for (j = 0; j < fSampleSize; j++) {
986  // Index of sample j of variable i
987  k = j * fNVariables + i;
988  ddotXi += fQuantity(j) * (fVariables(k) - fMeanVariables(i));
989  xiNorm += (fVariables(k) - fMeanVariables(i)) * (fVariables(k) - fMeanVariables(i));
990  }
991  fCorrelationMatrix(i, 0) = ddotXi / TMath::Sqrt(d2 * xiNorm);
992 
993  for (j = 0; j < i; j++) {
994  xidotXj = 0.; // G.Q. reinitialisation
995  xjNorm = 0.; // G.Q. reinitialisation
996  for (k = 0; k < fSampleSize; k++) {
997  // Index of sample j of variable i
998  // l = j * fNVariables + k; // G.Q.
999  l = k * fNVariables + j; // G.Q.
1000  m = k * fNVariables + i; // G.Q.
1001  // G.Q. xidotXj += (fVariables(i) - fMeanVariables(i))
1002  // G.Q. * (fVariables(l) - fMeanVariables(j));
1003  xidotXj +=
1004  (fVariables(m) - fMeanVariables(i)) * (fVariables(l) - fMeanVariables(j)); // G.Q. modified index for Xi
1005  xjNorm += (fVariables(l) - fMeanVariables(j)) * (fVariables(l) - fMeanVariables(j));
1006  }
1007  fCorrelationMatrix(i, j + 1) = xidotXj / TMath::Sqrt(xiNorm * xjNorm);
1008  }
1009  }
1010 }
1011 
1012 //____________________________________________________________________
1013 Double_t TMultiDimFet::MakeGramSchmidt(Int_t function) {
1014  // PRIVATE METHOD:
1015  // Make Gram-Schmidt orthogonalisation. The class description gives
1016  // a thorough account of this algorithm, as well as
1017  // references. Please refer to the
1018  // Begin_Html<a href="#TMultiDimFet:description">class description</a>End_Html
1019 
1020  // calculate w_i, that is, evaluate the current function at data
1021  // point i
1022  Double_t f2 = 0;
1025  Int_t j = 0;
1026  Int_t k = 0;
1027 
1028  for (j = 0; j < fSampleSize; j++) {
1029  fFunctions(fNCoefficients, j) = 1;
1031  // First, however, we need to calculate f_fNCoefficients
1032  for (k = 0; k < fNVariables; k++) {
1033  Int_t p = fPowers[function * fNVariables + k];
1034  Double_t x = fVariables(j * fNVariables + k);
1036  }
1037 
1038  // Calculate f dot f in f2
1040  // Assign to w_fNCoefficients f_fNCoefficients
1042  }
1043 
1044  // the first column of w is equal to f
1045  for (j = 0; j < fNCoefficients; j++) {
1046  Double_t fdw = 0;
1047  // Calculate (f_fNCoefficients dot w_j) / w_j^2
1048  for (k = 0; k < fSampleSize; k++) {
1050  }
1051 
1053  // and subtract it from the current value of w_ij
1054  for (k = 0; k < fSampleSize; k++)
1056  }
1057 
1058  for (j = 0; j < fSampleSize; j++) {
1059  // calculate squared length of w_fNCoefficients
1061 
1062  // calculate D dot w_fNCoefficients in A
1064  }
1065 
1066  // First test, but only if didn't user specify
1067  if (!fIsUserFunction)
1068  if (TMath::Sqrt(fOrthFunctionNorms(fNCoefficients) / (f2 + 1e-10)) < TMath::Sin(fMinAngle * DEGRAD))
1069  return 0;
1070 
1071  // The result found by this code for the first residual is always
1072  // much less then the one found be MUDIFI. That's because it's
1073  // supposed to be. The cause is the improved precision of Double_t
1074  // over DOUBLE PRECISION!
1076  Double_t b = fOrthCoefficients(fNCoefficients);
1078 
1079  // Calculate the residual from including this fNCoefficients.
1080  Double_t dResidur = fOrthCoefficients(fNCoefficients) * b;
1081 
1082  return dResidur;
1083 }
1084 
1085 //____________________________________________________________________
1087  // Make histograms of the result of the analysis. This message
1088  // should be sent after having read all data points, but before
1089  // finding the parameterization
1090  //
1091  // Options:
1092  // A All the below
1093  // X Original independent variables
1094  // D Original dependent variables
1095  // N Normalised independent variables
1096  // S Shifted dependent variables
1097  // R1 Residuals versus normalised independent variables
1098  // R2 Residuals versus dependent variable
1099  // R3 Residuals computed on training sample
1100  // R4 Residuals computed on test sample
1101  //
1102  // For a description of these quantities, refer to
1103  // Begin_Html<a href="#TMultiDimFet:description">class description</a>End_Html
1104  TString opt(option);
1105  opt.ToLower();
1106 
1107  if (opt.Length() < 1)
1108  return;
1109 
1110  if (!fHistograms)
1111  fHistograms = new TList;
1112 
1113  // Counter variable
1114  Int_t i = 0;
1115 
1116  // Histogram of original variables
1117  if (opt.Contains("x") || opt.Contains("a")) {
1118  SETBIT(fHistogramMask, HIST_XORIG);
1119  for (i = 0; i < fNVariables; i++)
1120  if (!fHistograms->FindObject(Form("x_%d_orig", i)))
1121  fHistograms->Add(
1122  new TH1D(Form("x_%d_orig", i), Form("Original variable # %d", i), 100, fMinVariables(i), fMaxVariables(i)));
1123  }
1124 
1125  // Histogram of original dependent variable
1126  if (opt.Contains("d") || opt.Contains("a")) {
1127  SETBIT(fHistogramMask, HIST_DORIG);
1128  if (!fHistograms->FindObject("d_orig"))
1129  fHistograms->Add(new TH1D("d_orig", "Original Quantity", 100, fMinQuantity, fMaxQuantity));
1130  }
1131 
1132  // Histograms of normalized variables
1133  if (opt.Contains("n") || opt.Contains("a")) {
1134  SETBIT(fHistogramMask, HIST_XNORM);
1135  for (i = 0; i < fNVariables; i++)
1136  if (!fHistograms->FindObject(Form("x_%d_norm", i)))
1137  fHistograms->Add(new TH1D(Form("x_%d_norm", i), Form("Normalized variable # %d", i), 100, -1, 1));
1138  }
1139 
1140  // Histogram of shifted dependent variable
1141  if (opt.Contains("s") || opt.Contains("a")) {
1142  SETBIT(fHistogramMask, HIST_DSHIF);
1143  if (!fHistograms->FindObject("d_shifted"))
1144  fHistograms->Add(
1145  new TH1D("d_shifted", "Shifted Quantity", 100, fMinQuantity - fMeanQuantity, fMaxQuantity - fMeanQuantity));
1146  }
1147 
1148  // Residual from training sample versus independent variables
1149  if (opt.Contains("r1") || opt.Contains("a")) {
1150  SETBIT(fHistogramMask, HIST_RX);
1151  for (i = 0; i < fNVariables; i++)
1152  if (!fHistograms->FindObject(Form("res_x_%d", i)))
1153  fHistograms->Add(new TH2D(Form("res_x_%d", i),
1154  Form("Computed residual versus x_%d", i),
1155  100,
1156  -1,
1157  1,
1158  35,
1161  }
1162 
1163  // Residual from training sample versus. dependent variable
1164  if (opt.Contains("r2") || opt.Contains("a")) {
1165  SETBIT(fHistogramMask, HIST_RD);
1166  if (!fHistograms->FindObject("res_d"))
1167  fHistograms->Add(new TH2D("res_d",
1168  "Computed residuals vs Quantity",
1169  100,
1172  35,
1175  }
1176 
1177  // Residual from training sample
1178  if (opt.Contains("r3") || opt.Contains("a")) {
1179  SETBIT(fHistogramMask, HIST_RTRAI);
1180  if (!fHistograms->FindObject("res_train"))
1181  fHistograms->Add(new TH1D("res_train",
1182  "Computed residuals over training sample",
1183  100,
1186  }
1187  if (opt.Contains("r4") || opt.Contains("a")) {
1188  SETBIT(fHistogramMask, HIST_RTEST);
1189  if (!fHistograms->FindObject("res_test"))
1190  fHistograms->Add(new TH1D("res_test",
1191  "Distribution of residuals from test",
1192  100,
1195  }
1196 }
1197 
1198 //____________________________________________________________________
1199 void TMultiDimFet::MakeMethod(const Char_t *classname, Option_t *option) {
1200  // Generate the file <classname>MDF.cxx which contains the
1201  // implementation of the method:
1202  //
1203  // Double_t <classname>::MDF(Double_t *x)
1204  //
1205  // which does the same as TMultiDimFet::Eval. Please refer to this
1206  // method.
1207  //
1208  // Further, the public static members:
1209  //
1210  // Int_t <classname>::fgNVariables
1211  // Int_t <classname>::fgNCoefficients
1212  // Double_t <classname>::fgDMean
1213  // Double_t <classname>::fgXMean[] //[fgNVariables]
1214  // Double_t <classname>::fgXMin[] //[fgNVariables]
1215  // Double_t <classname>::fgXMax[] //[fgNVariables]
1216  // Double_t <classname>::fgCoefficient[] //[fgNCoeffficents]
1217  // Int_t <classname>::fgPower[] //[fgNCoeffficents*fgNVariables]
1218  //
1219  // are initialized, and assumed to exist. The class declaration is
1220  // assumed to be in <classname>.h and assumed to be provided by the
1221  // user.
1222  //
1223  // See TMultiDimFet::MakeRealCode for a list of options
1224  //
1225  // The minimal class definition is:
1226  //
1227  // class <classname> {
1228  // public:
1229  // Int_t <classname>::fgNVariables; // Number of variables
1230  // Int_t <classname>::fgNCoefficients; // Number of terms
1231  // Double_t <classname>::fgDMean; // Mean from training sample
1232  // Double_t <classname>::fgXMean[]; // Mean from training sample
1233  // Double_t <classname>::fgXMin[]; // Min from training sample
1234  // Double_t <classname>::fgXMax[]; // Max from training sample
1235  // Double_t <classname>::fgCoefficient[]; // Coefficients
1236  // Int_t <classname>::fgPower[]; // Function powers
1237  //
1238  // Double_t Eval(Double_t *x);
1239  // };
1240  //
1241  // Whether the method <classname>::Eval should be static or not, is
1242  // up to the user.
1243 
1244  MakeRealCode(Form("%sMDF.cxx", classname), classname, option);
1245 }
1246 
1247 //____________________________________________________________________
1249  // PRIVATE METHOD:
1250  // Normalize data to the interval [-1;1]. This is needed for the
1251  // classes method to work.
1252 
1253  Int_t i = 0;
1254  Int_t j = 0;
1255  Int_t k = 0;
1256 
1257  for (i = 0; i < fSampleSize; i++) {
1258  if (TESTBIT(fHistogramMask, HIST_DORIG))
1259  ((TH1D *)fHistograms->FindObject("d_orig"))->Fill(fQuantity(i));
1260 
1263 
1264  if (TESTBIT(fHistogramMask, HIST_DSHIF))
1265  ((TH1D *)fHistograms->FindObject("d_shifted"))->Fill(fQuantity(i));
1266 
1267  for (j = 0; j < fNVariables; j++) {
1268  Double_t range = 1. / (fMaxVariables(j) - fMinVariables(j));
1269  k = i * fNVariables + j;
1270 
1271  // Fill histograms of original independent variables
1272  if (TESTBIT(fHistogramMask, HIST_XORIG))
1273  ((TH1D *)fHistograms->FindObject(Form("x_%d_orig", j)))->Fill(fVariables(k));
1274 
1275  // Normalise independent variables
1276  fVariables(k) = 1 + 2 * range * (fVariables(k) - fMaxVariables(j));
1277 
1278  // Fill histograms of normalised independent variables
1279  if (TESTBIT(fHistogramMask, HIST_XNORM))
1280  ((TH1D *)fHistograms->FindObject(Form("x_%d_norm", j)))->Fill(fVariables(k));
1281  }
1282  }
1283  // Shift min and max of dependent variable
1286 
1287  // Shift mean of independent variables
1288  for (i = 0; i < fNVariables; i++) {
1289  Double_t range = 1. / (fMaxVariables(i) - fMinVariables(i));
1290  fMeanVariables(i) = 1 + 2 * range * (fMeanVariables(i) - fMaxVariables(i));
1291  }
1292 }
1293 
1294 //____________________________________________________________________
1296  // PRIVATE METHOD:
1297  // Find the parameterization over the training sample. A full account
1298  // of the algorithm is given in the
1299  // Begin_Html<a href="#TMultiDimFet:description">class description</a>End_Html
1300 
1301  Int_t i = -1;
1302  Int_t j = 0;
1303  Int_t k = 0;
1304  Int_t maxPass = 3;
1305  Int_t studied = 0;
1306  Double_t squareResidual = fSumSqAvgQuantity;
1307  fNCoefficients = 0;
1309  fFunctions.ResizeTo(fMaxTerms, fSampleSize);
1311  fOrthFunctionNorms.ResizeTo(fMaxTerms);
1312  fOrthCoefficients.ResizeTo(fMaxTerms);
1314  fFunctions = 1;
1315 
1316  fFunctionCodes.resize(fMaxFunctions);
1317  fPowerIndex.resize(fMaxTerms);
1318  Int_t l;
1319  for (l = 0; l < fMaxFunctions; l++)
1320  fFunctionCodes[l] = 0;
1321  for (l = 0; l < fMaxTerms; l++)
1322  fPowerIndex[l] = 0;
1323 
1324  if (fMaxAngle != 0)
1325  maxPass = 100;
1326  if (fIsUserFunction)
1327  maxPass = 1;
1328 
1329  // Loop over the number of functions we want to study.
1330  // increment inspection counter
1331  while (kTRUE) {
1332  // Reach user defined limit of studies
1333  if (studied++ >= fMaxStudy) {
1335  break;
1336  }
1337 
1338  // Considered all functions several times
1339  if (k >= maxPass) {
1341  break;
1342  }
1343 
1344  // increment function counter
1345  i++;
1346 
1347  // If we've reached the end of the functions, restart pass
1348  if (i == fMaxFunctions) {
1349  if (fMaxAngle != 0)
1350  fMaxAngle += (90 - fMaxAngle) / 2;
1351  i = 0;
1352  studied--;
1353  k++;
1354  continue;
1355  }
1356  if (studied == 1)
1357  fFunctionCodes[i] = 0;
1358  else if (fFunctionCodes[i] >= 2)
1359  continue;
1360 
1361  // Print a happy message
1362  if (fIsVerbose && studied == 1)
1363  edm::LogInfo("TMultiDimFet") << "Coeff SumSqRes Contrib Angle QM Func"
1364  << " Value W^2 Powers"
1365  << "\n";
1366 
1367  // Make the Gram-Schmidt
1368  Double_t dResidur = MakeGramSchmidt(i);
1369 
1370  if (dResidur == 0) {
1371  // This function is no good!
1372  // First test is in MakeGramSchmidt
1373  fFunctionCodes[i] = 1;
1374  continue;
1375  }
1376 
1377  // If user specified function, assume she/he knows what he's doing
1378  if (!fIsUserFunction) {
1379  // Flag this function as considered
1380  fFunctionCodes[i] = 2;
1381 
1382  // Test if this function contributes to the fit
1383  if (!TestFunction(squareResidual, dResidur)) {
1384  fFunctionCodes[i] = 1;
1385  continue;
1386  }
1387  }
1388 
1389  // If we get to here, the function currently considered is
1390  // fNCoefficients, so we increment the counter
1391  // Flag this function as OK, and store and the number in the
1392  // index.
1393  fFunctionCodes[i] = 3;
1395  fNCoefficients++;
1396 
1397  // We add the current contribution to the sum of square of
1398  // residuals;
1399  squareResidual -= dResidur;
1400 
1401  // Calculate control parameter from this function
1402  for (j = 0; j < fNVariables; j++) {
1403  if (fNCoefficients == 1 || fMaxPowersFinal[j] <= fPowers[i * fNVariables + j] - 1)
1404  fMaxPowersFinal[j] = fPowers[i * fNVariables + j] - 1;
1405  }
1406  Double_t s = EvalControl(&fPowers[i * fNVariables]);
1407 
1408  // Print the statistics about this function
1409  if (fIsVerbose) {
1410  edm::LogVerbatim("TMultiDimFet") << std::setw(5) << fNCoefficients << " " << std::setw(10) << std::setprecision(4)
1411  << squareResidual << " " << std::setw(10) << std::setprecision(4) << dResidur
1412  << " " << std::setw(7) << std::setprecision(3) << fMaxAngle << " "
1413  << std::setw(7) << std::setprecision(3) << s << " " << std::setw(5) << i << " "
1414  << std::setw(10) << std::setprecision(4) << fOrthCoefficients(fNCoefficients - 1)
1415  << " " << std::setw(10) << std::setprecision(4)
1416  << fOrthFunctionNorms(fNCoefficients - 1) << " " << std::flush;
1417  for (j = 0; j < fNVariables; j++)
1418  edm::LogInfo("TMultiDimFet") << " " << fPowers[i * fNVariables + j] - 1 << std::flush;
1419  edm::LogInfo("TMultiDimFet") << "\n";
1420  }
1421 
1422  if (fNCoefficients >= fMaxTerms /* && fIsVerbose */) {
1424  break;
1425  }
1426 
1427  Double_t err = TMath::Sqrt(TMath::Max(1e-20, squareResidual) / fSumSqAvgQuantity);
1428  if (err < fMinRelativeError) {
1430  break;
1431  }
1432  }
1433 
1434  fError = TMath::Max(1e-20, squareResidual);
1436  fRMS = TMath::Sqrt(fError / fSampleSize);
1437 }
1438 
1439 //____________________________________________________________________
1440 void TMultiDimFet::MakeRealCode(const char *filename, const char *classname, Option_t *) {
1441  // PRIVATE METHOD:
1442  // This is the method that actually generates the code for the
1443  // evaluation the parameterization on some point.
1444  // It's called by TMultiDimFet::MakeCode and TMultiDimFet::MakeMethod.
1445  //
1446  // The options are: NONE so far
1447  Int_t i, j;
1448 
1449  Bool_t isMethod = (classname[0] == '\0' ? kFALSE : kTRUE);
1450  const char *prefix = (isMethod ? Form("%s::", classname) : "");
1451  const char *cv_qual = (isMethod ? "" : "static ");
1452 
1453  std::ofstream outFile(filename, std::ios::out | std::ios::trunc);
1454  if (!outFile) {
1455  Error("MakeRealCode", "couldn't open output file '%s'", filename);
1456  return;
1457  }
1458 
1459  if (fIsVerbose)
1460  edm::LogInfo("TMultiDimFet") << "Writing on file \"" << filename << "\" ... " << std::flush;
1461  //
1462  // Write header of file
1463  //
1464  // Emacs mode line ;-)
1465  outFile << "// -*- mode: c++ -*-"
1466  << "\n";
1467  // Info about creator
1468  outFile << "// "
1469  << "\n"
1470  << "// File " << filename << " generated by TMultiDimFet::MakeRealCode"
1471  << "\n";
1472  // Time stamp
1473  TDatime date;
1474  outFile << "// on " << date.AsString() << "\n";
1475  // ROOT version info
1476  outFile << "// ROOT version " << gROOT->GetVersion() << "\n"
1477  << "//"
1478  << "\n";
1479  // General information on the code
1480  outFile << "// This file contains the function "
1481  << "\n"
1482  << "//"
1483  << "\n"
1484  << "// double " << prefix << "MDF(double *x); "
1485  << "\n"
1486  << "//"
1487  << "\n"
1488  << "// For evaluating the parameterization obtained"
1489  << "\n"
1490  << "// from TMultiDimFet and the point x"
1491  << "\n"
1492  << "// "
1493  << "\n"
1494  << "// See TMultiDimFet class documentation for more "
1495  << "information "
1496  << "\n"
1497  << "// "
1498  << "\n";
1499  // Header files
1500  if (isMethod)
1501  // If these are methods, we need the class header
1502  outFile << "#include \"" << classname << ".h\""
1503  << "\n";
1504 
1505  //
1506  // Now for the data
1507  //
1508  outFile << "//"
1509  << "\n"
1510  << "// Static data variables"
1511  << "\n"
1512  << "//"
1513  << "\n";
1514  outFile << cv_qual << "int " << prefix << "gNVariables = " << fNVariables << ";"
1515  << "\n";
1516  outFile << cv_qual << "int " << prefix << "gNCoefficients = " << fNCoefficients << ";"
1517  << "\n";
1518  outFile << cv_qual << "double " << prefix << "gDMean = " << fMeanQuantity << ";"
1519  << "\n";
1520 
1521  // Assignment to mean vector.
1522  outFile << "// Assignment to mean vector."
1523  << "\n";
1524  outFile << cv_qual << "double " << prefix << "gXMean[] = {"
1525  << "\n";
1526  for (i = 0; i < fNVariables; i++)
1527  outFile << (i != 0 ? ", " : " ") << fMeanVariables(i) << std::flush;
1528  outFile << " };"
1529  << "\n"
1530  << "\n";
1531 
1532  // Assignment to minimum vector.
1533  outFile << "// Assignment to minimum vector."
1534  << "\n";
1535  outFile << cv_qual << "double " << prefix << "gXMin[] = {"
1536  << "\n";
1537  for (i = 0; i < fNVariables; i++)
1538  outFile << (i != 0 ? ", " : " ") << fMinVariables(i) << std::flush;
1539  outFile << " };"
1540  << "\n"
1541  << "\n";
1542 
1543  // Assignment to maximum vector.
1544  outFile << "// Assignment to maximum vector."
1545  << "\n";
1546  outFile << cv_qual << "double " << prefix << "gXMax[] = {"
1547  << "\n";
1548  for (i = 0; i < fNVariables; i++)
1549  outFile << (i != 0 ? ", " : " ") << fMaxVariables(i) << std::flush;
1550  outFile << " };"
1551  << "\n"
1552  << "\n";
1553 
1554  // Assignment to coefficients vector.
1555  outFile << "// Assignment to coefficients vector."
1556  << "\n";
1557  outFile << cv_qual << "double " << prefix << "gCoefficient[] = {" << std::flush;
1558  for (i = 0; i < fNCoefficients; i++)
1559  outFile << (i != 0 ? "," : "") << "\n"
1560  << " " << fCoefficients(i) << std::flush;
1561  outFile << "\n"
1562  << " };"
1563  << "\n"
1564  << "\n";
1565 
1566  // Assignment to powers vector.
1567  outFile << "// Assignment to powers vector."
1568  << "\n"
1569  << "// The powers are stored row-wise, that is"
1570  << "\n"
1571  << "// p_ij = " << prefix << "gPower[i * NVariables + j];"
1572  << "\n";
1573  outFile << cv_qual << "int " << prefix << "gPower[] = {" << std::flush;
1574  for (i = 0; i < fNCoefficients; i++) {
1575  for (j = 0; j < fNVariables; j++) {
1576  if (j != 0)
1577  outFile << std::flush << " ";
1578  else
1579  outFile << "\n"
1580  << " ";
1582  << (i == fNCoefficients - 1 && j == fNVariables - 1 ? "" : ",") << std::flush;
1583  }
1584  }
1585  outFile << "\n"
1586  << "};"
1587  << "\n"
1588  << "\n";
1589 
1590  //
1591  // Finally we reach the function itself
1592  //
1593  outFile << "// "
1594  << "\n"
1595  << "// The " << (isMethod ? "method " : "function ") << " double " << prefix << "MDF(double *x)"
1596  << "\n"
1597  << "// "
1598  << "\n";
1599  outFile << "double " << prefix << "MDF(double *x) {"
1600  << "\n"
1601  << " double returnValue = " << prefix << "gDMean;"
1602  << "\n"
1603  << " int i = 0, j = 0, k = 0;"
1604  << "\n"
1605  << " for (i = 0; i < " << prefix << "gNCoefficients ; i++) {"
1606  << "\n"
1607  << " // Evaluate the ith term in the expansion"
1608  << "\n"
1609  << " double term = " << prefix << "gCoefficient[i];"
1610  << "\n"
1611  << " for (j = 0; j < " << prefix << "gNVariables; j++) {"
1612  << "\n"
1613  << " // Evaluate the polynomial in the jth variable."
1614  << "\n"
1615  << " int power = " << prefix << "gPower[" << prefix << "gNVariables * i + j]; "
1616  << "\n"
1617  << " double p1 = 1, p2 = 0, p3 = 0, r = 0;"
1618  << "\n"
1619  << " double v = 1 + 2. / (" << prefix << "gXMax[j] - " << prefix << "gXMin[j]) * (x[j] - " << prefix
1620  << "gXMax[j]);"
1621  << "\n"
1622  << " // what is the power to use!"
1623  << "\n"
1624  << " switch(power) {"
1625  << "\n"
1626  << " case 1: r = 1; break; "
1627  << "\n"
1628  << " case 2: r = v; break; "
1629  << "\n"
1630  << " default: "
1631  << "\n"
1632  << " p2 = v; "
1633  << "\n"
1634  << " for (k = 3; k <= power; k++) { "
1635  << "\n"
1636  << " p3 = p2 * v;"
1637  << "\n";
1638  if (fPolyType == kLegendre)
1639  outFile << " p3 = ((2 * i - 3) * p2 * v - (i - 2) * p1)"
1640  << " / (i - 1);"
1641  << "\n";
1642  if (fPolyType == kChebyshev)
1643  outFile << " p3 = 2 * v * p2 - p1; "
1644  << "\n";
1645  outFile << " p1 = p2; p2 = p3; "
1646  << "\n"
1647  << " }"
1648  << "\n"
1649  << " r = p3;"
1650  << "\n"
1651  << " }"
1652  << "\n"
1653  << " // multiply this term by the poly in the jth var"
1654  << "\n"
1655  << " term *= r; "
1656  << "\n"
1657  << " }"
1658  << "\n"
1659  << " // Add this term to the final result"
1660  << "\n"
1661  << " returnValue += term;"
1662  << "\n"
1663  << " }"
1664  << "\n"
1665  << " return returnValue;"
1666  << "\n"
1667  << "}"
1668  << "\n"
1669  << "\n";
1670 
1671  // EOF
1672  outFile << "// EOF for " << filename << "\n";
1673 
1674  // Close the file
1675  outFile.close();
1676 
1677  if (fIsVerbose)
1678  edm::LogInfo("TMultiDimFet") << "done"
1679  << "\n";
1680 }
1681 
1682 //____________________________________________________________________
1683 void TMultiDimFet::Print(Option_t *option) const {
1684  // Print statistics etc.
1685  // Options are
1686  // P Parameters
1687  // S Statistics
1688  // C Coefficients
1689  // R Result of parameterisation
1690  // F Result of fit
1691  // K Correlation Matrix
1692  // M Pretty print formula
1693  //
1694  Int_t i = 0;
1695  Int_t j = 0;
1696 
1697  TString opt(option);
1698  opt.ToLower();
1699 
1700  if (opt.Contains("p")) {
1701  // Print basic parameters for this object
1702  edm::LogInfo("TMultiDimFet") << "User parameters:"
1703  << "\n"
1704  << "----------------"
1705  << "\n"
1706  << " Variables: " << fNVariables << "\n"
1707  << " Data points: " << fSampleSize << "\n"
1708  << " Max Terms: " << fMaxTerms << "\n"
1709  << " Power Limit Parameter: " << fPowerLimit << "\n"
1710  << " Max functions: " << fMaxFunctions << "\n"
1711  << " Max functions to study: " << fMaxStudy << "\n"
1712  << " Max angle (optional): " << fMaxAngle << "\n"
1713  << " Min angle: " << fMinAngle << "\n"
1714  << " Relative Error accepted: " << fMinRelativeError << "\n"
1715  << " Maximum Powers: " << std::flush;
1716  for (i = 0; i < fNVariables; i++)
1717  edm::LogInfo("TMultiDimFet") << " " << fMaxPowers[i] - 1 << std::flush;
1718  edm::LogInfo("TMultiDimFet") << "\n"
1719  << "\n"
1720  << " Parameterisation will be done using " << std::flush;
1721  if (fPolyType == kChebyshev)
1722  edm::LogInfo("TMultiDimFet") << "Chebyshev polynomials"
1723  << "\n";
1724  else if (fPolyType == kLegendre)
1725  edm::LogInfo("TMultiDimFet") << "Legendre polynomials"
1726  << "\n";
1727  else
1728  edm::LogInfo("TMultiDimFet") << "Monomials"
1729  << "\n";
1730  edm::LogInfo("TMultiDimFet") << "\n";
1731  }
1732 
1733  if (opt.Contains("s")) {
1734  // Print statistics for read data
1735  edm::LogInfo("TMultiDimFet") << "Sample statistics:"
1736  << "\n"
1737  << "------------------"
1738  << "\n"
1739  << " D" << std::flush;
1740  for (i = 0; i < fNVariables; i++)
1741  edm::LogInfo("TMultiDimFet") << " " << std::setw(10) << i + 1 << std::flush;
1742  edm::LogInfo("TMultiDimFet") << "\n"
1743  << " Max: " << std::setw(10) << std::setprecision(7) << fMaxQuantity << std::flush;
1744  for (i = 0; i < fNVariables; i++)
1745  edm::LogInfo("TMultiDimFet") << " " << std::setw(10) << std::setprecision(4) << fMaxVariables(i) << std::flush;
1746  edm::LogInfo("TMultiDimFet") << "\n"
1747  << " Min: " << std::setw(10) << std::setprecision(7) << fMinQuantity << std::flush;
1748  for (i = 0; i < fNVariables; i++)
1749  edm::LogInfo("TMultiDimFet") << " " << std::setw(10) << std::setprecision(4) << fMinVariables(i) << std::flush;
1750  edm::LogInfo("TMultiDimFet") << "\n"
1751  << " Mean: " << std::setw(10) << std::setprecision(7) << fMeanQuantity << std::flush;
1752  for (i = 0; i < fNVariables; i++)
1753  edm::LogInfo("TMultiDimFet") << " " << std::setw(10) << std::setprecision(4) << fMeanVariables(i) << std::flush;
1754  edm::LogInfo("TMultiDimFet") << "\n"
1755  << " Function Sum Squares: " << fSumSqQuantity << "\n"
1756  << "\n";
1757  }
1758 
1759  if (opt.Contains("r")) {
1760  edm::LogInfo("TMultiDimFet") << "Results of Parameterisation:"
1761  << "\n"
1762  << "----------------------------"
1763  << "\n"
1764  << " Total reduction of square residuals " << fSumSqResidual << "\n"
1765  << " Relative precision obtained: " << fPrecision << "\n"
1766  << " Error obtained: " << fError << "\n"
1767  << " Multiple correlation coefficient: " << fCorrelationCoeff << "\n"
1768  << " Reduced Chi square over sample: " << fChi2 / (fSampleSize - fNCoefficients)
1769  << "\n"
1770  << " Maximum residual value: " << fMaxResidual << "\n"
1771  << " Minimum residual value: " << fMinResidual << "\n"
1772  << " Estimated root mean square: " << fRMS << "\n"
1773  << " Maximum powers used: " << std::flush;
1774  for (j = 0; j < fNVariables; j++)
1775  edm::LogInfo("TMultiDimFet") << fMaxPowersFinal[j] << " " << std::flush;
1776  edm::LogInfo("TMultiDimFet") << "\n"
1777  << " Function codes of candidate functions."
1778  << "\n"
1779  << " 1: considered,"
1780  << " 2: too little contribution,"
1781  << " 3: accepted." << std::flush;
1782  for (i = 0; i < fMaxFunctions; i++) {
1783  if (i % 60 == 0)
1784  edm::LogInfo("TMultiDimFet") << "\n"
1785  << " " << std::flush;
1786  else if (i % 10 == 0)
1787  edm::LogInfo("TMultiDimFet") << " " << std::flush;
1788  edm::LogInfo("TMultiDimFet") << fFunctionCodes[i];
1789  }
1790  edm::LogInfo("TMultiDimFet") << "\n"
1791  << " Loop over candidates stopped because " << std::flush;
1792  switch (fParameterisationCode) {
1793  case PARAM_MAXSTUDY:
1794  edm::LogInfo("TMultiDimFet") << "max allowed studies reached"
1795  << "\n";
1796  break;
1797  case PARAM_SEVERAL:
1798  edm::LogInfo("TMultiDimFet") << "all candidates considered several times"
1799  << "\n";
1800  break;
1801  case PARAM_RELERR:
1802  edm::LogInfo("TMultiDimFet") << "wanted relative error obtained"
1803  << "\n";
1804  break;
1805  case PARAM_MAXTERMS:
1806  edm::LogInfo("TMultiDimFet") << "max number of terms reached"
1807  << "\n";
1808  break;
1809  default:
1810  edm::LogInfo("TMultiDimFet") << "some unknown reason"
1811  << "\n";
1812  break;
1813  }
1814  edm::LogInfo("TMultiDimFet") << "\n";
1815  }
1816 
1817  if (opt.Contains("f")) {
1818  edm::LogInfo("TMultiDimFet") << "Results of Fit:"
1819  << "\n"
1820  << "---------------"
1821  << "\n"
1822  << " Test sample size: " << fTestSampleSize << "\n"
1823  << " Multiple correlation coefficient: " << fTestCorrelationCoeff << "\n"
1824  << " Relative precision obtained: " << fTestPrecision << "\n"
1825  << " Error obtained: " << fTestError << "\n"
1826  << " Reduced Chi square over sample: " << fChi2 / (fSampleSize - fNCoefficients)
1827  << "\n"
1828  << "\n";
1829  /*
1830  if (fFitter) {
1831  fFitter->PrintResults(1,1);
1832  edm::LogInfo("TMultiDimFet") << "\n";
1833  }
1834 */
1835  }
1836 
1837  if (opt.Contains("c")) {
1838  edm::LogInfo("TMultiDimFet") << "Coefficients:"
1839  << "\n"
1840  << "-------------"
1841  << "\n"
1842  << " # Value Error Powers"
1843  << "\n"
1844  << " ---------------------------------------"
1845  << "\n";
1846  for (i = 0; i < fNCoefficients; i++) {
1847  edm::LogInfo("TMultiDimFet") << " " << std::setw(3) << i << " " << std::setw(12) << fCoefficients(i) << " "
1848  << std::setw(12) << fCoefficientsRMS(i) << " " << std::flush;
1849  for (j = 0; j < fNVariables; j++)
1850  edm::LogInfo("TMultiDimFet") << " " << std::setw(3) << fPowers[fPowerIndex[i] * fNVariables + j] - 1
1851  << std::flush;
1852  edm::LogInfo("TMultiDimFet") << "\n";
1853  }
1854  edm::LogInfo("TMultiDimFet") << "\n";
1855  }
1856  if (opt.Contains("k") && fCorrelationMatrix.IsValid()) {
1857  edm::LogInfo("TMultiDimFet") << "Correlation Matrix:"
1858  << "\n"
1859  << "-------------------";
1860  fCorrelationMatrix.Print();
1861  }
1862 
1863  if (opt.Contains("m")) {
1864  edm::LogInfo("TMultiDimFet") << std::setprecision(25);
1865  edm::LogInfo("TMultiDimFet") << "Parameterization:"
1866  << "\n"
1867  << "-----------------"
1868  << "\n"
1869  << " Normalised variables: "
1870  << "\n";
1871  for (i = 0; i < fNVariables; i++)
1872  edm::LogInfo("TMultiDimFet") << "\ty" << i << "\t:= 1 + 2 * (x" << i << " - " << fMaxVariables(i) << ") / ("
1873  << fMaxVariables(i) << " - " << fMinVariables(i) << ")"
1874  << "\n";
1875  edm::LogInfo("TMultiDimFet") << "\n"
1876  << " f[";
1877  for (i = 0; i < fNVariables; i++) {
1878  edm::LogInfo("TMultiDimFet") << "y" << i;
1879  if (i != fNVariables - 1)
1880  edm::LogInfo("TMultiDimFet") << ", ";
1881  }
1882  edm::LogInfo("TMultiDimFet") << "] := ";
1883  for (Int_t i = 0; i < fNCoefficients; i++) {
1884  if (i != 0)
1885  edm::LogInfo("TMultiDimFet") << " " << (fCoefficients(i) < 0 ? "- " : "+ ") << TMath::Abs(fCoefficients(i));
1886  else
1887  edm::LogInfo("TMultiDimFet") << fCoefficients(i);
1888  for (Int_t j = 0; j < fNVariables; j++) {
1889  Int_t p = fPowers[fPowerIndex[i] * fNVariables + j];
1890  switch (p) {
1891  case 1:
1892  break;
1893  case 2:
1894  edm::LogInfo("TMultiDimFet") << " * y" << j;
1895  break;
1896  default:
1897  switch (fPolyType) {
1898  case kLegendre:
1899  edm::LogInfo("TMultiDimFet") << " * L" << p - 1 << "(y" << j << ")";
1900  break;
1901  case kChebyshev:
1902  edm::LogInfo("TMultiDimFet") << " * C" << p - 1 << "(y" << j << ")";
1903  break;
1904  default:
1905  edm::LogInfo("TMultiDimFet") << " * y" << j << "^" << p - 1;
1906  break;
1907  }
1908  }
1909  }
1910  }
1911  edm::LogInfo("TMultiDimFet") << "\n";
1912  }
1913 }
1914 
1915 //____________________________________________________________________
1917  // M Pretty print formula
1918  //
1919  Int_t i = 0;
1920  // Int_t j = 0;
1921 
1922  TString opt(option);
1923  opt.ToLower();
1924 
1925  if (opt.Contains("m")) {
1926  edm::LogInfo("TMultiDimFet") << std::setprecision(25);
1927  edm::LogInfo("TMultiDimFet") << "Parameterization:"
1928  << "\n"
1929  << "-----------------"
1930  << "\n"
1931  << " Normalised variables: "
1932  << "\n";
1933  for (i = 0; i < fNVariables; i++)
1934  edm::LogInfo("TMultiDimFet") << "\tdouble y" << i << "\t=1+2*(x" << i << "-" << fMaxVariables(i) << ")/("
1935  << fMaxVariables(i) << "-" << fMinVariables(i) << ");"
1936  << "\n";
1937  edm::LogInfo("TMultiDimFet") << "\n"
1938  << " f[";
1939  for (i = 0; i < fNVariables; i++) {
1940  edm::LogInfo("TMultiDimFet") << "y" << i;
1941  if (i != fNVariables - 1)
1942  edm::LogInfo("TMultiDimFet") << ", ";
1943  }
1944  edm::LogInfo("TMultiDimFet") << "] := " << fMeanQuantity << " + ";
1945  for (Int_t i = 0; i < fNCoefficients; i++) {
1946  if (i != 0)
1947  edm::LogInfo("TMultiDimFet") << " " << (fCoefficients(i) < 0 ? "-" : "+") << TMath::Abs(fCoefficients(i));
1948  else
1949  edm::LogInfo("TMultiDimFet") << fCoefficients(i);
1950  for (Int_t j = 0; j < fNVariables; j++) {
1951  Int_t p = fPowers[fPowerIndex[i] * fNVariables + j];
1952  switch (p) {
1953  case 1:
1954  break;
1955  case 2:
1956  edm::LogInfo("TMultiDimFet") << "*y" << j;
1957  break;
1958  default:
1959  switch (fPolyType) {
1960  case kLegendre:
1961  edm::LogInfo("TMultiDimFet") << "*Leg(" << p - 1 << ",y" << j << ")";
1962  break;
1963  case kChebyshev:
1964  edm::LogInfo("TMultiDimFet") << "*C" << p - 1 << "(y" << j << ")";
1965  break;
1966  default:
1967  edm::LogInfo("TMultiDimFet") << "*y" << j << "**" << p - 1;
1968  break;
1969  }
1970  }
1971  }
1972  edm::LogInfo("TMultiDimFet") << "\n";
1973  }
1974  edm::LogInfo("TMultiDimFet") << "\n";
1975  }
1976 }
1977 
1978 //____________________________________________________________________
1979 Bool_t TMultiDimFet::Select(const Int_t *) {
1980  // Selection method. User can override this method for specialized
1981  // selection of acceptable functions in fit. Default is to select
1982  // all. This message is sent during the build-up of the function
1983  // candidates table once for each set of powers in
1984  // variables. Notice, that the argument array contains the powers
1985  // PLUS ONE. For example, to De select the function
1986  // f = x1^2 * x2^4 * x3^5,
1987  // this method should return kFALSE if given the argument
1988  // { 3, 4, 6 }
1989  return kTRUE;
1990 }
1991 
1992 //____________________________________________________________________
1993 void TMultiDimFet::SetMaxAngle(Double_t ang) {
1994  // Set the max angle (in degrees) between the initial data vector to
1995  // be fitted, and the new candidate function to be included in the
1996  // fit. By default it is 0, which automatically chooses another
1997  // selection criteria. See also
1998  // Begin_Html<a href="#TMultiDimFet:description">class description</a>End_Html
1999  if (ang >= 90 || ang < 0) {
2000  Warning("SetMaxAngle", "angle must be in [0,90)");
2001  return;
2002  }
2003 
2004  fMaxAngle = ang;
2005 }
2006 
2007 //____________________________________________________________________
2008 void TMultiDimFet::SetMinAngle(Double_t ang) {
2009  // Set the min angle (in degrees) between a new candidate function
2010  // and the subspace spanned by the previously accepted
2011  // functions. See also
2012  // Begin_Html<a href="#TMultiDimFet:description">class description</a>End_Html
2013  if (ang > 90 || ang <= 0) {
2014  Warning("SetMinAngle", "angle must be in [0,90)");
2015  return;
2016  }
2017 
2018  fMinAngle = ang;
2019 }
2020 
2021 //____________________________________________________________________
2022 void TMultiDimFet::SetPowers(const Int_t *powers, Int_t terms) {
2023  // Define a user function. The input array must be of the form
2024  // (p11, ..., p1N, ... ,pL1, ..., pLN)
2025  // Where N is the dimension of the data sample, L is the number of
2026  // terms (given in terms) and the first number, labels the term, the
2027  // second the variable. More information is given in the
2028  // Begin_Html<a href="#TMultiDimFet:description">class description</a>End_Html
2029  fIsUserFunction = kTRUE;
2030  fMaxFunctions = terms;
2031  fMaxTerms = terms;
2032  fMaxStudy = terms;
2034  fPowers.resize(fMaxFunctions * fNVariables);
2035  Int_t i, j;
2036  for (i = 0; i < fMaxFunctions; i++)
2037  for (j = 0; j < fNVariables; j++)
2038  fPowers[i * fNVariables + j] = powers[i * fNVariables + j] + 1;
2039 }
2040 
2041 //____________________________________________________________________
2043  // Set the user parameter for the function selection. The bigger the
2044  // limit, the more functions are used. The meaning of this variable
2045  // is defined in the
2046  // Begin_Html<a href="#TMultiDimFet:description">class description</a>End_Html
2047  fPowerLimit = limit;
2048 }
2049 
2050 //____________________________________________________________________
2051 void TMultiDimFet::SetMaxPowers(const Int_t *powers) {
2052  // Set the maximum power to be considered in the fit for each
2053  // variable. See also
2054  // Begin_Html<a href="#TMultiDimFet:description">class description</a>End_Html
2055  if (!powers)
2056  return;
2057 
2058  for (Int_t i = 0; i < fNVariables; i++)
2059  fMaxPowers[i] = powers[i] + 1;
2060 }
2061 
2062 //____________________________________________________________________
2064  // Set the acceptable relative error for when sum of square
2065  // residuals is considered minimized. For a full account, refer to
2066  // the
2067  // Begin_Html<a href="#TMultiDimFet:description">class description</a>End_Html
2069 }
2070 
2071 //____________________________________________________________________
2072 Bool_t TMultiDimFet::TestFunction(Double_t squareResidual, Double_t dResidur) {
2073  // PRIVATE METHOD:
2074  // Test whether the currently considered function contributes to the
2075  // fit. See also
2076  // Begin_Html<a href="#TMultiDimFet:description">class description</a>End_Html
2077 
2078  if (fNCoefficients != 0) {
2079  // Now for the second test:
2080  if (fMaxAngle == 0) {
2081  // If the user hasn't supplied a max angle do the test as,
2082  if (dResidur < squareResidual / (fMaxTerms - fNCoefficients + 1 + 1E-10)) {
2083  return kFALSE;
2084  }
2085  } else {
2086  // If the user has provided a max angle, test if the calculated
2087  // angle is less then the max angle.
2088  if (TMath::Sqrt(dResidur / fSumSqAvgQuantity) < TMath::Cos(fMaxAngle * DEGRAD)) {
2089  return kFALSE;
2090  }
2091  }
2092  }
2093  // If we get here, the function is OK
2094  return kTRUE;
2095 }
2096 
2097 //____________________________________________________________________
2098 //void mdfHelper(int& /*npar*/, double* /*divs*/, double& chi2,
2099 // double* coeffs, int /*flag*/)
2100 /*{
2101  // Helper function for doing the minimisation of Chi2 using Minuit
2102 
2103  // Get pointer to current TMultiDimFet object.
2104  // TMultiDimFet* mdf = TMultiDimFet::Instance();
2105  //chi2 = mdf->MakeChi2(coeffs);
2106 }
2107 */
size
Write out results.
Log< level::Info, true > LogVerbatim
edm::ErrorSummaryEntry Error
Double_t fMaxQuantity
Definition: TMultiDimFet.h:44
TMatrixD fCorrelationMatrix
Multi Correlation coefficient.
Definition: TMultiDimFet.h:104
Double_t fSumSqQuantity
Min value of dependent quantity.
Definition: TMultiDimFet.h:46
Double_t fMinAngle
Size of test sample.
Definition: TMultiDimFet.h:63
TVectorD fTestVariables
Test sample, Error in quantity.
Definition: TMultiDimFet.h:59
const TMultiDimFet & operator=(const TMultiDimFet &in)
Definition: TMultiDimFet.cc:83
TVectorD fMinVariables
Definition: TMultiDimFet.h:53
Int_t fTestSampleSize
Test sample, independent variables.
Definition: TMultiDimFet.h:61
Double_t fSumSqAvgQuantity
SumSquare of dependent quantity.
Definition: TMultiDimFet.h:47
Double_t fMinQuantity
Max value of dependent quantity.
Definition: TMultiDimFet.h:45
virtual void MakeCoefficientErrors()
void ZeroDoubiousCoefficients(double error)
void SetPowerLimit(Double_t limit=1e-3)
int32_t *__restrict__ iv
Int_t fParameterisationCode
Chi square of fit.
Definition: TMultiDimFet.h:97
Double_t fMinResidual
Max redsidual value.
Definition: TMultiDimFet.h:85
EMDFPolyType fPolyType
Bit pattern of hisograms used.
Definition: TMultiDimFet.h:112
TMatrixD fFunctions
Control parameter.
Definition: TMultiDimFet.h:70
#define HIST_RD
Definition: TMultiDimFet.cc:32
Double_t fTestCorrelationCoeff
Correlation matrix.
Definition: TMultiDimFet.h:105
void SetMaxPowers(const Int_t *powers)
virtual Double_t EvalControl(const Int_t *powers)
TMatrixD fOrthFunctions
max functions to study
Definition: TMultiDimFet.h:75
Byte_t fHistogramMask
List of histograms.
Definition: TMultiDimFet.h:108
~TMultiDimFet() override
Double_t fMaxAngle
Min angle for acepting new function.
Definition: TMultiDimFet.h:64
std::vector< Int_t > fPowers
Definition: TMultiDimFet.h:80
Double_t fPowerLimit
maximum powers, ex-array
Definition: TMultiDimFet.h:68
Double_t fPrecision
Error from test.
Definition: TMultiDimFet.h:101
#define HIST_DSHIF
Definition: TMultiDimFet.cc:30
virtual void MakeHistograms(Option_t *option="A")
TVectorD fCoefficientsRMS
Definition: TMultiDimFet.h:94
virtual void MakeParameterization()
virtual Double_t MakeGramSchmidt(Int_t function)
#define HIST_RX
Definition: TMultiDimFet.cc:31
Int_t fMaxResidualRow
Min redsidual value.
Definition: TMultiDimFet.h:86
void Print(Option_t *option="ps") const override
Double_t fTestError
Error from parameterization.
Definition: TMultiDimFet.h:100
virtual void AddTestRow(const Double_t *x, Double_t D, Double_t E=0)
void SetMinRelativeError(Double_t error)
virtual void MakeNormalized()
#define DEGRAD
Definition: TMultiDimFet.cc:26
virtual Double_t Eval(const Double_t *x, const Double_t *coeff=nullptr) const
virtual Bool_t TestFunction(Double_t squareResidual, Double_t dResidur)
virtual void SetPowers(const Int_t *powers, Int_t terms)
Int_t fNVariables
Training sample, independent variables.
Definition: TMultiDimFet.h:50
#define PARAM_SEVERAL
Definition: TMultiDimFet.cc:36
virtual void MakeCandidates()
Double_t fChi2
Root mean square of fit.
Definition: TMultiDimFet.h:96
Bool_t fIsVerbose
Definition: TMultiDimFet.h:115
Bool_t fShowCorrelation
Definition: TMultiDimFet.h:113
Int_t fMinResidualRow
Row giving max residual.
Definition: TMultiDimFet.h:87
virtual void PrintPolynomialsSpecial(Option_t *option="m") const
TVectorD fTestSqError
Test sample, dependent quantity.
Definition: TMultiDimFet.h:58
TVectorD fQuantity
Definition: TMultiDimFet.h:41
Double_t fMinRelativeError
Definition: TMultiDimFet.h:66
virtual void MakeCorrelation()
TVectorD fOrthCoefficients
Definition: TMultiDimFet.h:91
Double_t fRMS
Vector of RMS of coefficients.
Definition: TMultiDimFet.h:95
void Fill(HcalDetId &id, double val, std::vector< TH2F > &depth)
std::vector< Int_t > fPowerIndex
Definition: TMultiDimFet.h:81
Double_t fMeanQuantity
Training sample, error in quantity.
Definition: TMultiDimFet.h:43
TVectorD fOrthFunctionNorms
As above, but orthogonalised.
Definition: TMultiDimFet.h:76
#define HIST_RTRAI
Definition: TMultiDimFet.cc:33
virtual void MakeCode(const char *functionName="MDF", Option_t *option="")
double f[11][100]
#define PARAM_MAXTERMS
Definition: TMultiDimFet.cc:38
Double_t fSumSqResidual
Row giving min residual.
Definition: TMultiDimFet.h:88
ClassImp(TMultiDimFet)
#define PARAM_RELERR
Definition: TMultiDimFet.cc:37
virtual void AddRow(const Double_t *x, Double_t D, Double_t E=0)
virtual Double_t MakeChi2(const Double_t *coeff=nullptr)
Double_t fMaxResidual
Vector of the final residuals.
Definition: TMultiDimFet.h:84
virtual void MakeRealCode(const char *filename, const char *classname, Option_t *option="")
virtual Bool_t Select(const Int_t *iv)
#define HIST_XNORM
Definition: TMultiDimFet.cc:29
TVectorD fMaxVariables
mean value of independent variables
Definition: TMultiDimFet.h:52
virtual void FindParameterization(double precision)
Double_t fTestPrecision
Relative precision of param.
Definition: TMultiDimFet.h:102
#define HIST_DORIG
Definition: TMultiDimFet.cc:28
TList * fHistograms
Multi Correlation coefficient.
Definition: TMultiDimFet.h:107
Log< level::Info, false > LogInfo
Int_t fMaxTerms
Max angle for acepting new function.
Definition: TMultiDimFet.h:65
TVectorD fTestQuantity
Size of training sample.
Definition: TMultiDimFet.h:57
DecomposeProduct< arg, typename Div::arg > D
Definition: Factorize.h:141
TVectorD fVariables
Sum of squares away from mean.
Definition: TMultiDimFet.h:49
Int_t fMaxFunctions
Functions evaluated over sample.
Definition: TMultiDimFet.h:71
Int_t fSampleSize
Definition: TMultiDimFet.h:55
double b
Definition: hdecay.h:118
Bool_t fIsUserFunction
Definition: TMultiDimFet.h:114
Double_t fError
Exit code of parameterisation.
Definition: TMultiDimFet.h:99
Int_t fNCoefficients
Sum of Square residuals.
Definition: TMultiDimFet.h:90
#define HIST_XORIG
Definition: TMultiDimFet.cc:27
Int_t fMaxFunctionsTimesNVariables
maximum powers from fit, ex-array
Definition: TMultiDimFet.h:79
std::vector< Int_t > fFunctionCodes
Definition: TMultiDimFet.h:72
TVectorD fSqError
Training sample, dependent quantity.
Definition: TMultiDimFet.h:42
col
Definition: cuy.py:1009
void SetMinAngle(Double_t angle=1)
#define PARAM_MAXSTUDY
Definition: TMultiDimFet.cc:35
Double_t fCorrelationCoeff
Relative precision of test.
Definition: TMultiDimFet.h:103
float x
TMatrixD fOrthCurvatureMatrix
The model coefficients.
Definition: TMultiDimFet.h:92
virtual void MakeCoefficients()
TVectorD fResiduals
Definition: TMultiDimFet.h:83
std::vector< Int_t > fMaxPowers
Min relative error accepted.
Definition: TMultiDimFet.h:67
TVectorD fMeanVariables
Definition: TMultiDimFet.h:51
void Clear(Option_t *option="") override
virtual void MakeMethod(const Char_t *className="MDF", Option_t *option="")
void ReducePolynomial(double error)
std::vector< Int_t > fMaxPowersFinal
Norm of the evaluated functions.
Definition: TMultiDimFet.h:78
uint32_t dimension(pat::CandKinResolution::Parametrization parametrization)
Returns the number of free parameters in a parametrization (3 or 4)
void SetMaxAngle(Double_t angle=0)
TVectorD fCoefficients
Model matrix.
Definition: TMultiDimFet.h:93
Int_t fMaxStudy
acceptance code, ex-array
Definition: TMultiDimFet.h:73
#define HIST_RTEST
Definition: TMultiDimFet.cc:34
virtual Double_t EvalFactor(Int_t p, Double_t x) const