398 #define RADDEG (180. / TMath::Pi())
399 #define DEGRAD (TMath::Pi() / 180.)
408 #define PARAM_MAXSTUDY 1
409 #define PARAM_SEVERAL 2
410 #define PARAM_RELERR 3
411 #define PARAM_MAXTERMS 4
416 static void mdfHelper(
int&,
double*,
double&,
double*,
int);
420 ClassImp(TMultiDimFit);
424 TMultiDimFit* TMultiDimFit::fgInstance = 0;
430 TMultiDimFit::TMultiDimFit()
436 fSumSqAvgQuantity = 0;
445 fMinRelativeError = 0;
467 fParameterisationCode = 0;
473 fCorrelationCoeff = 0;
474 fTestCorrelationCoeff = 0;
482 fPolyType = kMonomials;
483 fShowCorrelation = kFALSE;
484 fIsUserFunction = kFALSE;
505 TMultiDimFit::TMultiDimFit(Int_t dimension,
508 : TNamed(
"multidimfit",
"Multi-dimensional fit object"),
509 fQuantity(dimension),
511 fVariables(dimension*100),
512 fMeanVariables(dimension),
513 fMaxVariables(dimension),
514 fMinVariables(dimension)
522 fSumSqAvgQuantity = 0;
524 fNVariables = dimension;
531 fMinRelativeError = 0.01;
532 fMaxPowers =
new Int_t[dimension];
540 fMaxPowersFinal =
new Int_t[dimension];
553 fParameterisationCode = 0;
559 fCorrelationCoeff = 0;
560 fTestCorrelationCoeff = 0;
569 fShowCorrelation = kFALSE;
570 fIsUserFunction = kFALSE;
572 TString opt = option;
575 if (opt.Contains(
"k")) fShowCorrelation = kTRUE;
576 if (opt.Contains(
"v")) fIsVerbose = kTRUE;
583 TMultiDimFit::~TMultiDimFit()
586 delete [] fMaxPowers;
587 delete [] fMaxPowersFinal;
588 delete [] fPowerIndex;
589 delete [] fFunctionCodes;
590 if (fHistograms) fHistograms->Clear(
"nodelete");
608 void TMultiDimFit::AddRow(
const Double_t *x, Double_t D, Double_t E)
613 if (++fSampleSize == 1) {
617 fSumSqQuantity = D * D;
620 fMeanQuantity *= 1 - 1./Double_t(fSampleSize);
621 fMeanQuantity += D / Double_t(fSampleSize);
622 fSumSqQuantity += D * D;
624 if (D >= fMaxQuantity) fMaxQuantity = D;
625 if (D <= fMinQuantity) fMinQuantity = D;
631 Int_t size = fQuantity.GetNrows();
632 if (fSampleSize > size) {
633 fQuantity.ResizeTo(size + size/2);
634 fSqError.ResizeTo(size + size/2);
638 fQuantity(fSampleSize-1) = D;
639 fSqError(fSampleSize-1) = (E == 0 ? D : E);
644 size = fVariables.GetNrows();
645 if (fSampleSize * fNVariables > size)
646 fVariables.ResizeTo(size + size/2);
651 for (i = 0; i < fNVariables; i++) {
652 if (fSampleSize == 1) {
653 fMeanVariables(i) = x[i];
654 fMaxVariables(i) = x[i];
655 fMinVariables(i) = x[i];
658 fMeanVariables(i) *= 1 - 1./Double_t(fSampleSize);
659 fMeanVariables(i) += x[i] / Double_t(fSampleSize);
662 if (x[i] >= fMaxVariables(i)) fMaxVariables(i) = x[i];
665 if (x[i] <= fMinVariables(i)) fMinVariables(i) = x[i];
670 j = (fSampleSize-1) * fNVariables + i;
671 fVariables(j) = x[i];
687 void TMultiDimFit::AddTestRow(
const Double_t *x, Double_t D, Double_t E)
689 if (fTestSampleSize++ == 0) {
690 fTestQuantity.ResizeTo(fNVariables);
691 fTestSqError.ResizeTo(fNVariables);
692 fTestVariables.ResizeTo(fNVariables * 100);
697 Int_t size = fTestQuantity.GetNrows();
698 if (fTestSampleSize > size) {
699 fTestQuantity.ResizeTo(size + size/2);
700 fTestSqError.ResizeTo(size + size/2);
704 fTestQuantity(fTestSampleSize-1) = D;
705 fTestSqError(fTestSampleSize-1) = (E == 0 ? D : E);
710 size = fTestVariables.GetNrows();
711 if (fTestSampleSize * fNVariables > size)
712 fTestVariables.ResizeTo(size + size/2);
717 for (i = 0; i < fNVariables; i++) {
718 j = fNVariables * (fTestSampleSize - 1) + i;
719 fTestVariables(j) = x[i];
721 if (x[i] > fMaxVariables(i))
722 Warning(
"AddTestRow",
"variable %d (row: %d) too large: %f > %f",
723 i, fTestSampleSize, x[i], fMaxVariables(i));
724 if (x[i] < fMinVariables(i))
725 Warning(
"AddTestRow",
"variable %d (row: %d) too small: %f < %f",
726 i, fTestSampleSize, x[i], fMinVariables(i));
734 void TMultiDimFit::Browse(TBrowser* b)
737 TIter next(fHistograms);
739 while ((h = (TH1*)next()))
740 b->Add(h,h->GetName());
742 if (fVariables.IsValid())
743 b->Add(&fVariables,
"Variables (Training)");
744 if (fQuantity.IsValid())
745 b->Add(&fQuantity,
"Quantity (Training)");
746 if (fSqError.IsValid())
747 b->Add(&fSqError,
"Error (Training)");
748 if (fMeanVariables.IsValid())
749 b->Add(&fMeanVariables,
"Mean of Variables (Training)");
750 if (fMaxVariables.IsValid())
751 b->Add(&fMaxVariables,
"Mean of Variables (Training)");
752 if (fMinVariables.IsValid())
753 b->Add(&fMinVariables,
"Min of Variables (Training)");
754 if (fTestVariables.IsValid())
755 b->Add(&fTestVariables,
"Variables (Test)");
756 if (fTestQuantity.IsValid())
757 b->Add(&fTestQuantity,
"Quantity (Test)");
758 if (fTestSqError.IsValid())
759 b->Add(&fTestSqError,
"Error (Test)");
760 if (fFunctions.IsValid())
761 b->Add(&fFunctions,
"Functions");
762 if(fCoefficients.IsValid())
763 b->Add(&fCoefficients,
"Coefficients");
764 if(fCoefficientsRMS.IsValid())
765 b->Add(&fCoefficientsRMS,
"Coefficients Errors");
766 if (fOrthFunctions.IsValid())
767 b->Add(&fOrthFunctions,
"Orthogonal Functions");
768 if (fOrthFunctionNorms.IsValid())
769 b->Add(&fOrthFunctionNorms,
"Orthogonal Functions Norms");
770 if (fResiduals.IsValid())
771 b->Add(&fResiduals,
"Residuals");
772 if(fOrthCoefficients.IsValid())
773 b->Add(&fOrthCoefficients,
"Orthogonal Coefficients");
774 if (fOrthCurvatureMatrix.IsValid())
775 b->Add(&fOrthCurvatureMatrix,
"Orthogonal curvature matrix");
776 if(fCorrelationMatrix.IsValid())
777 b->Add(&fCorrelationMatrix,
"Correlation Matrix");
779 b->Add(fFitter, fFitter->GetName());
786 void TMultiDimFit::Clear(Option_t *option)
788 Int_t i, j, n = fNVariables, m = fMaxFunctions;
797 fSumSqAvgQuantity = 0;
803 fMeanVariables.Zero();
804 fMaxVariables.Zero();
805 fMinVariables.Zero();
808 fTestQuantity.Zero();
810 fTestVariables.Zero();
819 fOrthFunctions.Zero();
820 fOrthFunctionNorms.Zero();
823 fMinRelativeError = 0;
829 for (i = 0; i < n; i++) {
831 fMaxPowersFinal[i] = 0;
832 for (j = 0; j < m; j++)
833 fPowers[i * n + j] = 0;
846 fOrthCoefficients = 0;
847 fOrthCurvatureMatrix = 0;
849 fCorrelationMatrix.Zero();
856 fCoefficients.Zero();
857 fCoefficientsRMS.Zero();
859 fHistograms->Clear(option);
862 fPolyType = kMonomials;
863 fShowCorrelation = kFALSE;
864 fIsUserFunction = kFALSE;
873 Double_t TMultiDimFit::Eval(
const Double_t *x,
const Double_t* coeff)
const
875 Double_t returnValue = fMeanQuantity;
879 for (i = 0; i < fNCoefficients; i++) {
881 term = (coeff ? coeff[i] : fCoefficients(i));
882 for (j = 0; j < fNVariables; j++) {
884 Int_t p = fPowers[fPowerIndex[i] * fNVariables + j];
885 Double_t y = 1 + 2. / (fMaxVariables(j) - fMinVariables(j))
886 * (x[j] - fMaxVariables(j));
887 term *= EvalFactor(p,y);
901 Double_t TMultiDimFit::EvalError(
const Double_t *x,
const Double_t* coeff)
const
903 Double_t returnValue = 0;
907 for (i = 0; i < fNCoefficients; i++) {
910 for (i = 0; i < fNCoefficients; i++) {
912 term = (coeff ? coeff[i] : fCoefficientsRMS(i));
913 for (j = 0; j < fNVariables; j++) {
915 Int_t p = fPowers[fPowerIndex[i] * fNVariables + j];
916 Double_t y = 1 + 2. / (fMaxVariables(j) - fMinVariables(j))
917 * (x[j] - fMaxVariables(j));
918 term *= EvalFactor(p,y);
922 returnValue += term*term;
925 returnValue = sqrt(returnValue);
934 Double_t TMultiDimFit::EvalControl(
const Int_t *iv)
const
937 Double_t epsilon = 1e-6;
938 for (Int_t i = 0; i < fNVariables; i++) {
939 if (fMaxPowers[i] != 1)
940 s += (epsilon + iv[i] - 1) / (epsilon + fMaxPowers[i] - 1);
949 Double_t TMultiDimFit::EvalFactor(Int_t p, Double_t x)
const
966 for (i = 3; i <= p; i++) {
968 if (fPolyType == kLegendre)
969 p3 = ((2 * i - 3) * p2 * x - (i - 2) * p1) / (i - 1);
970 else if (fPolyType == kChebyshev)
971 p3 = 2 * x * p2 - p1;
991 void TMultiDimFit::FindParameterization(Option_t *)
995 MakeParameterization();
997 MakeCoefficientErrors();
1010 void TMultiDimFit::Fit(Option_t *option)
1013 Double_t* x =
new Double_t[fNVariables];
1014 Double_t sumSqD = 0;
1016 Double_t sumSqR = 0;
1020 for (i = 0; i < fTestSampleSize; i++) {
1021 for (j = 0; j < fNVariables; j++)
1022 x[j] = fTestVariables(i * fNVariables + j);
1023 Double_t res = fTestQuantity(i) - Eval(x);
1024 sumD += fTestQuantity(i);
1025 sumSqD += fTestQuantity(i) * fTestQuantity(i);
1027 sumSqR += res * res;
1028 if (TESTBIT(fHistogramMask,HIST_RTEST))
1029 ((TH1D*)fHistograms->FindObject(
"res_test"))->Fill(res);
1031 Double_t dAvg = sumSqD - (sumD * sumD) / fTestSampleSize;
1032 Double_t rAvg = sumSqR - (sumR * sumR) / fTestSampleSize;
1033 fTestCorrelationCoeff = (dAvg - rAvg) / dAvg;
1034 fTestError = sumSqR;
1035 fTestPrecision = sumSqR / sumSqD;
1037 TString opt(option);
1040 if (!opt.Contains(
"m"))
1043 if (fNCoefficients * 50 > fTestSampleSize)
1044 Warning(
"Fit",
"test sample is very small");
1046 if (!opt.Contains(
"m")) {
1047 Error(
"Fit",
"invalid option");
1052 fFitter = TVirtualFitter::Fitter(0,fNCoefficients);
1054 Error(
"Fit",
"Cannot create Fitter");
1058 fFitter->SetFCN(mdfHelper);
1060 const Int_t maxArgs = 16;
1062 Double_t* arglist =
new Double_t[maxArgs];
1064 fFitter->ExecuteCommand(
"SET PRINT",arglist,args);
1066 for (i = 0; i < fNCoefficients; i++) {
1067 Double_t startVal = fCoefficients(i);
1068 Double_t startErr = fCoefficientsRMS(i);
1069 fFitter->SetParameter(i, Form(
"coeff%02d",i),
1070 startVal, startErr, 0, 0);
1076 fFitter->ExecuteCommand(
"MIGRAD",arglist,args);
1078 for (i = 0; i < fNCoefficients; i++) {
1079 Double_t val = 0, err = 0, low = 0, high = 0;
1080 fFitter->GetParameter(i, Form(
"coeff%02d",i),
1081 val, err, low, high);
1082 fCoefficients(i) = val;
1083 fCoefficientsRMS(i) = err;
1091 TMultiDimFit* TMultiDimFit::Instance()
1102 void TMultiDimFit::MakeCandidates()
1110 fMaxFuncNV = fNVariables * fMaxFunctions;
1111 Int_t *powers =
new Int_t[fMaxFuncNV];
1114 Double_t* control =
new Double_t[fMaxFunctions];
1117 Int_t *iv =
new Int_t[fNVariables];
1118 for (i = 0; i < fNVariables; i++)
1121 if (!fIsUserFunction) {
1124 Int_t numberFunctions = 0;
1127 Int_t maxNumberFunctions = 1;
1128 for (i = 0; i < fNVariables; i++)
1129 maxNumberFunctions *= fMaxPowers[i];
1133 Double_t s = EvalControl(iv);
1135 if (s <= fPowerLimit) {
1144 if (numberFunctions > fMaxFunctions)
1149 control[numberFunctions-1] = Int_t(1.0e+6*s);
1152 for (i = 0; i < fNVariables; i++) {
1153 j = (numberFunctions - 1) * fNVariables + i;
1159 for (i = 0; i < fNVariables; i++)
1160 if (iv[i] < fMaxPowers[i])
1165 if (i == fNVariables) {
1166 fMaxFunctions = numberFunctions;
1171 if (i < fNVariables) iv[i]++;
1173 for (j = 0; j < i; j++)
1179 for (i = 0; i < fMaxFunctions; i++) {
1181 for (j = 0; j < fNVariables; j++) {
1182 powers[i * fNVariables + j] = fPowers[i * fNVariables + j];
1183 iv[j] = fPowers[i * fNVariables + j];
1186 control[i] = Int_t(1.0e+6*EvalControl(iv));
1192 Int_t *order =
new Int_t[fMaxFunctions];
1193 for (i = 0; i < fMaxFunctions; i++)
1195 fMaxFuncNV = fMaxFunctions * fNVariables;
1196 fPowers =
new Int_t[fMaxFuncNV];
1198 for (i = 0; i < fMaxFunctions; i++) {
1199 Double_t x = control[i];
1203 for (j = i; j < fMaxFunctions; j++) {
1204 if (control[j] <= x) {
1212 control[k] = control[i];
1214 order[k] = order[i];
1219 for (i = 0; i < fMaxFunctions; i++)
1220 for (j = 0; j < fNVariables; j++)
1221 fPowers[i * fNVariables + j] = powers[order[i] * fNVariables + j];
1237 Double_t TMultiDimFit::MakeChi2(
const Double_t* coeff)
1241 Double_t* x =
new Double_t[fNVariables];
1242 for (i = 0; i < fTestSampleSize; i++) {
1244 for (j = 0; j < fNVariables; j++)
1245 x[j] = fTestVariables(i * fNVariables + j);
1248 Double_t f = Eval(x,coeff);
1251 fChi2 += 1. / TMath::Max(fTestSqError(i),1e-20)
1252 * (fTestQuantity(i) - f) * (fTestQuantity(i) - f);
1287 void TMultiDimFit::MakeCode(
const char* filename, Option_t *option)
1290 TString outName(filename);
1291 if (!outName.EndsWith(
".C") && !outName.EndsWith(
".cxx"))
1294 MakeRealCode(outName.Data(),
"",option);
1304 void TMultiDimFit::MakeCoefficientErrors()
1309 TVectorD iF(fSampleSize);
1310 TVectorD jF(fSampleSize);
1311 fCoefficientsRMS.ResizeTo(fNCoefficients);
1313 TMatrixDSym curvatureMatrix(fNCoefficients);
1316 for (i = 0; i < fNCoefficients; i++) {
1317 iF = TMatrixDRow(fFunctions,i);
1318 for (j = 0; j <= i; j++) {
1319 jF = TMatrixDRow(fFunctions,j);
1320 for (k = 0; k < fSampleSize; k++)
1321 curvatureMatrix(i,j) +=
1322 1 / TMath::Max(fSqError(k), 1e-20) * iF(k) * jF(k);
1323 curvatureMatrix(j,i) = curvatureMatrix(i,j);
1329 for (i = 0; i < fSampleSize; i++) {
1331 for (j = 0; j < fNCoefficients; j++)
1332 f += fCoefficients(j) * fFunctions(j,i);
1333 fChi2 += 1. / TMath::Max(fSqError(i),1e-20) * (fQuantity(i) - f)
1334 * (fQuantity(i) - f);
1338 const TVectorD diag = TMatrixDDiag_const(curvatureMatrix);
1339 curvatureMatrix.NormByDiag(diag);
1341 TDecompChol chol(curvatureMatrix);
1342 if (!chol.Decompose())
1343 Error(
"MakeCoefficientErrors",
"curvature matrix is singular");
1344 chol.Invert(curvatureMatrix);
1346 curvatureMatrix.NormByDiag(diag);
1348 for (i = 0; i < fNCoefficients; i++)
1349 fCoefficientsRMS(i) = TMath::Sqrt(curvatureMatrix(i,i));
1362 void TMultiDimFit::MakeCoefficients()
1365 Int_t col = 0, row = 0;
1368 for (col = 1; col < fNCoefficients; col++) {
1369 for (row = col - 1; row > -1; row--) {
1370 fOrthCurvatureMatrix(row,col) = 0;
1371 for (i = row; i <= col ; i++)
1372 fOrthCurvatureMatrix(row,col) -=
1373 fOrthCurvatureMatrix(i,row)
1374 * fOrthCurvatureMatrix(i,col);
1379 fCoefficients.ResizeTo(fNCoefficients);
1381 for (i = 0; i < fNCoefficients; i++) {
1383 for (j = i; j < fNCoefficients; j++)
1384 sum += fOrthCurvatureMatrix(i,j) * fOrthCoefficients(j);
1385 fCoefficients(i) = sum;
1389 fResiduals.ResizeTo(fSampleSize);
1390 for (i = 0; i < fSampleSize; i++)
1391 fResiduals(i) = fQuantity(i);
1393 for (i = 0; i < fNCoefficients; i++)
1394 for (j = 0; j < fSampleSize; j++)
1395 fResiduals(j) -= fCoefficients(i) * fFunctions(i,j);
1399 fMinResidual = 10e10;
1400 fMaxResidual = -10e10;
1402 for (i = 0; i < fSampleSize; i++){
1403 sqRes += fResiduals(i) * fResiduals(i);
1404 if (fResiduals(i) <= fMinResidual) {
1405 fMinResidual = fResiduals(i);
1406 fMinResidualRow = i;
1408 if (fResiduals(i) >= fMaxResidual) {
1409 fMaxResidual = fResiduals(i);
1410 fMaxResidualRow = i;
1414 fCorrelationCoeff = fSumSqResidual / fSumSqAvgQuantity;
1415 fPrecision = TMath::Sqrt(sqRes / fSumSqQuantity);
1418 if (TESTBIT(fHistogramMask,HIST_RD) ||
1419 TESTBIT(fHistogramMask,HIST_RTRAI) ||
1420 TESTBIT(fHistogramMask,HIST_RX)) {
1421 for (i = 0; i < fSampleSize; i++) {
1422 if (TESTBIT(fHistogramMask,HIST_RD))
1423 ((TH2D*)fHistograms->FindObject(
"res_d"))->Fill(fQuantity(i),
1425 if (TESTBIT(fHistogramMask,HIST_RTRAI))
1426 ((TH1D*)fHistograms->FindObject(
"res_train"))->Fill(fResiduals(i));
1428 if (TESTBIT(fHistogramMask,HIST_RX))
1429 for (j = 0; j < fNVariables; j++)
1430 ((TH2D*)fHistograms->FindObject(Form(
"res_x_%d",j)))
1431 ->Fill(fVariables(i * fNVariables + j),fResiduals(i));
1442 void TMultiDimFit::MakeCorrelation()
1444 if (!fShowCorrelation)
1447 fCorrelationMatrix.ResizeTo(fNVariables,fNVariables+1);
1450 Double_t ddotXi = 0;
1451 Double_t xiNorm = 0;
1452 Double_t xidotXj = 0;
1453 Double_t xjNorm = 0;
1455 Int_t i, j, k, l, m;
1456 for (i = 0; i < fSampleSize; i++)
1457 d2 += fQuantity(i) * fQuantity(i);
1459 for (i = 0; i < fNVariables; i++) {
1462 for (j = 0; j< fSampleSize; j++) {
1464 k = j * fNVariables + i;
1465 ddotXi += fQuantity(j) * (fVariables(k) - fMeanVariables(i));
1466 xiNorm += (fVariables(k) - fMeanVariables(i))
1467 * (fVariables(k) - fMeanVariables(i));
1469 fCorrelationMatrix(i,0) = ddotXi / TMath::Sqrt(d2 * xiNorm);
1471 for (j = 0; j < i; j++) {
1474 for (k = 0; k < fSampleSize; k++) {
1477 l = k * fNVariables + j;
1478 m = k * fNVariables + i;
1481 xidotXj += (fVariables(m) - fMeanVariables(i))
1482 * (fVariables(l) - fMeanVariables(j));
1483 xjNorm += (fVariables(l) - fMeanVariables(j))
1484 * (fVariables(l) - fMeanVariables(j));
1487 fCorrelationMatrix(i,j+1) = xidotXj / TMath::Sqrt(xiNorm * xjNorm);
1501 Double_t TMultiDimFit::MakeGramSchmidt(Int_t
function)
1507 fOrthCoefficients(fNCoefficients) = 0;
1508 fOrthFunctionNorms(fNCoefficients) = 0;
1512 for (j = 0; j < fSampleSize; j++) {
1513 fFunctions(fNCoefficients, j) = 1;
1514 fOrthFunctions(fNCoefficients, j) = 0;
1516 for (k = 0; k < fNVariables; k++) {
1517 Int_t p = fPowers[
function * fNVariables + k];
1518 Double_t x = fVariables(j * fNVariables + k);
1519 fFunctions(fNCoefficients, j) *= EvalFactor(p,x);
1523 f2 += fFunctions(fNCoefficients,j) * fFunctions(fNCoefficients,j);
1525 fOrthFunctions(fNCoefficients, j) = fFunctions(fNCoefficients, j);
1529 for (j = 0; j < fNCoefficients; j++) {
1532 for (k = 0; k < fSampleSize; k++) {
1533 fdw += fFunctions(fNCoefficients, k) * fOrthFunctions(j,k)
1534 / fOrthFunctionNorms(j);
1537 fOrthCurvatureMatrix(fNCoefficients,j) = fdw;
1539 for (k = 0; k < fSampleSize; k++)
1540 fOrthFunctions(fNCoefficients,k) -= fdw * fOrthFunctions(j,k);
1543 for (j = 0; j < fSampleSize; j++) {
1545 fOrthFunctionNorms(fNCoefficients) +=
1546 fOrthFunctions(fNCoefficients,j)
1547 * fOrthFunctions(fNCoefficients,j);
1550 fOrthCoefficients(fNCoefficients) += fQuantity(j)
1551 * fOrthFunctions(fNCoefficients, j);
1555 if (!fIsUserFunction)
1556 if (TMath::Sqrt(fOrthFunctionNorms(fNCoefficients) / (f2 + 1e-10))
1557 < TMath::Sin(fMinAngle*DEGRAD))
1564 fOrthCurvatureMatrix(fNCoefficients,fNCoefficients) = 1;
1565 Double_t b = fOrthCoefficients(fNCoefficients);
1566 fOrthCoefficients(fNCoefficients) /= fOrthFunctionNorms(fNCoefficients);
1569 Double_t dResidur = fOrthCoefficients(fNCoefficients) * b;
1594 void TMultiDimFit::MakeHistograms(Option_t *option)
1596 TString opt(option);
1599 if (opt.Length() < 1)
1603 fHistograms =
new TList;
1609 if (opt.Contains(
"x") || opt.Contains(
"a")) {
1610 SETBIT(fHistogramMask,HIST_XORIG);
1611 for (i = 0; i < fNVariables; i++)
1612 if (!fHistograms->FindObject(Form(
"x_%d_orig",i)))
1613 fHistograms->Add(
new TH1D(Form(
"x_%d_orig",i),
1614 Form(
"Original variable # %d",i),
1615 fBinVarX, fMinVariables(i),
1620 if (opt.Contains(
"d") || opt.Contains(
"a")) {
1621 SETBIT(fHistogramMask,HIST_DORIG);
1622 if (!fHistograms->FindObject(
"d_orig"))
1623 fHistograms->Add(
new TH1D(
"d_orig",
"Original Quantity",
1624 fBinVarX, fMinQuantity, fMaxQuantity));
1628 if (opt.Contains(
"n") || opt.Contains(
"a")) {
1629 SETBIT(fHistogramMask,HIST_XNORM);
1630 for (i = 0; i < fNVariables; i++)
1631 if (!fHistograms->FindObject(Form(
"x_%d_norm",i)))
1632 fHistograms->Add(
new TH1D(Form(
"x_%d_norm",i),
1633 Form(
"Normalized variable # %d",i),
1638 if (opt.Contains(
"s") || opt.Contains(
"a")) {
1639 SETBIT(fHistogramMask,HIST_DSHIF);
1640 if (!fHistograms->FindObject(
"d_shifted"))
1641 fHistograms->Add(
new TH1D(
"d_shifted",
"Shifted Quantity",
1642 fBinVarX, fMinQuantity - fMeanQuantity,
1643 fMaxQuantity - fMeanQuantity));
1647 if (opt.Contains(
"r1") || opt.Contains(
"a")) {
1648 SETBIT(fHistogramMask,HIST_RX);
1649 for (i = 0; i < fNVariables; i++)
1650 if (!fHistograms->FindObject(Form(
"res_x_%d",i)))
1651 fHistograms->Add(
new TH2D(Form(
"res_x_%d",i),
1652 Form(
"Computed residual versus x_%d", i),
1655 fMinQuantity - fMeanQuantity,
1656 fMaxQuantity - fMeanQuantity));
1660 if (opt.Contains(
"r2") || opt.Contains(
"a")) {
1661 SETBIT(fHistogramMask,HIST_RD);
1662 if (!fHistograms->FindObject(
"res_d"))
1663 fHistograms->Add(
new TH2D(
"res_d",
1664 "Computed residuals vs Quantity",
1666 fMinQuantity - fMeanQuantity,
1667 fMaxQuantity - fMeanQuantity,
1669 fMinQuantity - fMeanQuantity,
1670 fMaxQuantity - fMeanQuantity));
1674 if (opt.Contains(
"r3") || opt.Contains(
"a")) {
1675 SETBIT(fHistogramMask,HIST_RTRAI);
1676 if (!fHistograms->FindObject(
"res_train"))
1677 fHistograms->Add(
new TH1D(
"res_train",
1678 "Computed residuals over training sample",
1679 fBinVarX, fMinQuantity - fMeanQuantity,
1680 fMaxQuantity - fMeanQuantity));
1683 if (opt.Contains(
"r4") || opt.Contains(
"a")) {
1684 SETBIT(fHistogramMask,HIST_RTEST);
1685 if (!fHistograms->FindObject(
"res_test"))
1686 fHistograms->Add(
new TH1D(
"res_test",
1687 "Distribution of residuals from test",
1688 fBinVarX,fMinQuantity - fMeanQuantity,
1689 fMaxQuantity - fMeanQuantity));
1739 void TMultiDimFit::MakeMethod(
const Char_t* classname, Option_t* option)
1741 MakeRealCode(Form(
"%sMDF.cxx", classname), classname, option);
1751 void TMultiDimFit::MakeNormalized()
1757 for (i = 0; i < fSampleSize; i++) {
1758 if (TESTBIT(fHistogramMask,HIST_DORIG))
1759 ((TH1D*)fHistograms->FindObject(
"d_orig"))->Fill(fQuantity(i));
1761 fQuantity(i) -= fMeanQuantity;
1762 fSumSqAvgQuantity += fQuantity(i) * fQuantity(i);
1764 if (TESTBIT(fHistogramMask,HIST_DSHIF))
1765 ((TH1D*)fHistograms->FindObject(
"d_shifted"))->Fill(fQuantity(i));
1767 for (j = 0; j < fNVariables; j++) {
1768 Double_t range = 1. / (fMaxVariables(j) - fMinVariables(j));
1769 k = i * fNVariables + j;
1772 if (TESTBIT(fHistogramMask,HIST_XORIG))
1773 ((TH1D*)fHistograms->FindObject(Form(
"x_%d_orig",j)))
1774 ->Fill(fVariables(k));
1777 fVariables(k) = 1 + 2 * range * (fVariables(k) - fMaxVariables(j));
1780 if (TESTBIT(fHistogramMask,HIST_XNORM))
1781 ((TH1D*)fHistograms->FindObject(Form(
"x_%d_norm",j)))
1782 ->Fill(fVariables(k));
1787 fMaxQuantity -= fMeanQuantity;
1788 fMinQuantity -= fMeanQuantity;
1791 for (i = 0; i < fNVariables; i++) {
1792 Double_t range = 1. / (fMaxVariables(i) - fMinVariables(i));
1793 fMeanVariables(i) = 1 + 2 * range * (fMeanVariables(i)
1794 - fMaxVariables(i));
1805 void TMultiDimFit::MakeParameterization()
1812 Double_t squareResidual = fSumSqAvgQuantity;
1814 fSumSqResidual = fSumSqAvgQuantity;
1815 fFunctions.ResizeTo(fMaxTerms,fSampleSize);
1816 fOrthFunctions.ResizeTo(fMaxTerms,fSampleSize);
1817 fOrthFunctionNorms.ResizeTo(fMaxTerms);
1818 fOrthCoefficients.ResizeTo(fMaxTerms);
1819 fOrthCurvatureMatrix.ResizeTo(fMaxTerms,fMaxTerms);
1822 fFunctionCodes =
new Int_t[fMaxFunctions];
1823 fPowerIndex =
new Int_t[fMaxTerms];
1825 for (l=0;l<fMaxFunctions;l++) fFunctionCodes[l] = 0;
1826 for (l=0;l<fMaxTerms;l++) fPowerIndex[l] = 0;
1828 if (fMaxAngle != 0) maxPass = 100;
1829 if (fIsUserFunction) maxPass = 1;
1836 if (studied++ >= fMaxStudy) {
1837 fParameterisationCode = PARAM_MAXSTUDY;
1843 fParameterisationCode = PARAM_SEVERAL;
1851 if (i == fMaxFunctions) {
1853 fMaxAngle += (90 - fMaxAngle) / 2;
1860 fFunctionCodes[i] = 0;
1861 else if (fFunctionCodes[i] >= 2)
1865 if (fIsVerbose && studied == 1)
1866 std::cout <<
"Coeff SumSqRes Contrib Angle QM Func"
1867 <<
" Value W^2 Powers" << std::endl;
1870 Double_t dResidur = MakeGramSchmidt(i);
1872 if (dResidur == 0) {
1875 fFunctionCodes[i] = 1;
1880 if (!fIsUserFunction) {
1882 fFunctionCodes[i] = 2;
1885 if (!TestFunction(squareResidual, dResidur)) {
1886 fFunctionCodes[i] = 1;
1895 fFunctionCodes[i] = 3;
1896 fPowerIndex[fNCoefficients] = i;
1901 squareResidual -= dResidur;
1905 for (j = 0; j < fNVariables; j++) {
1906 if (fNCoefficients == 1
1907 || fMaxPowersFinal[j] <= fPowers[i * fNVariables + j] - 1)
1908 fMaxPowersFinal[j] = fPowers[i * fNVariables + j] - 1;
1910 Double_t s = EvalControl(&fPowers[i * fNVariables]);
1914 std::cout << std::setw(5) << fNCoefficients <<
" "
1915 << std::setw(10) << std::setprecision(4) << squareResidual <<
" "
1916 << std::setw(10) << std::setprecision(4) << dResidur <<
" "
1917 << std::setw(7) << std::setprecision(3) << fMaxAngle <<
" "
1918 << std::setw(7) << std::setprecision(3) << s <<
" "
1919 << std::setw(5) << i <<
" "
1920 << std::setw(10) << std::setprecision(4)
1921 << fOrthCoefficients(fNCoefficients-1) <<
" "
1922 << std::setw(10) << std::setprecision(4)
1923 << fOrthFunctionNorms(fNCoefficients-1) <<
" "
1925 for (j = 0; j < fNVariables; j++)
1926 std::cout <<
" " << fPowers[i * fNVariables + j] - 1 << std::flush;
1927 std::cout << std::endl;
1930 if (fNCoefficients >= fMaxTerms ) {
1931 fParameterisationCode = PARAM_MAXTERMS;
1935 Double_t err = TMath::Sqrt(TMath::Max(1e-20,squareResidual) /
1937 if (err < fMinRelativeError) {
1938 fParameterisationCode = PARAM_RELERR;
1944 fError = TMath::Max(1e-20,squareResidual);
1945 fSumSqResidual -= fError;
1946 fRMS = TMath::Sqrt(fError / fSampleSize);
1958 void TMultiDimFit::MakeRealCode(
const char *filename,
1959 const char *classname,
1964 Bool_t isMethod = (classname[0] ==
'\0' ? kFALSE : kTRUE);
1965 const char *prefix = (isMethod ? Form(
"%s::", classname) :
"");
1966 const char *cv_qual = (isMethod ?
"" :
"static ");
1968 std::ofstream outFile(filename,std::ios::out|std::ios::trunc);
1970 Error(
"MakeRealCode",
"couldn't open output file '%s'",filename);
1975 std::cout <<
"Writing on file \"" << filename <<
"\" ... " << std::flush;
1980 outFile <<
"// -*- mode: c++ -*-" << std::endl;
1982 outFile <<
"// " << std::endl
1983 <<
"// File " << filename
1984 <<
" generated by TMultiDimFit::MakeRealCode" << std::endl;
1987 outFile <<
"// on " << date.AsString() << std::endl;
1989 outFile <<
"// ROOT version " << gROOT->GetVersion()
1990 << std::endl <<
"//" << std::endl;
1992 outFile <<
"// This file contains the function " << std::endl
1993 <<
"//" << std::endl
1994 <<
"// double " << prefix <<
"MDF(double *x); " << std::endl
1995 <<
"//" << std::endl
1996 <<
"// For evaluating the parameterization obtained" << std::endl
1997 <<
"// from TMultiDimFit and the point x" << std::endl
1998 <<
"// " << std::endl
1999 <<
"// See TMultiDimFit class documentation for more "
2000 <<
"information " << std::endl <<
"// " << std::endl;
2004 outFile <<
"#include \"" << classname <<
".h\"" << std::endl;
2009 outFile <<
"//" << std::endl
2010 <<
"// Static data variables" << std::endl
2011 <<
"//" << std::endl;
2012 outFile << cv_qual <<
"int " << prefix <<
"gNVariables = "
2013 << fNVariables <<
";" << std::endl;
2014 outFile << cv_qual <<
"int " << prefix <<
"gNCoefficients = "
2015 << fNCoefficients <<
";" << std::endl;
2016 outFile << cv_qual <<
"double " << prefix <<
"gDMean = "
2017 << fMeanQuantity <<
";" << std::endl;
2020 outFile <<
"// Assignment to mean vector." << std::endl;
2021 outFile << cv_qual <<
"double " << prefix
2022 <<
"gXMean[] = {" << std::endl;
2023 for (i = 0; i < fNVariables; i++)
2024 outFile << (i != 0 ?
", " :
" ") << fMeanVariables(i) << std::flush;
2025 outFile <<
" };" << std::endl << std::endl;
2028 outFile <<
"// Assignment to minimum vector." << std::endl;
2029 outFile << cv_qual <<
"double " << prefix
2030 <<
"gXMin[] = {" << std::endl;
2031 for (i = 0; i < fNVariables; i++)
2032 outFile << (i != 0 ?
", " :
" ") << fMinVariables(i) << std::flush;
2033 outFile <<
" };" << std::endl << std::endl;
2036 outFile <<
"// Assignment to maximum vector." << std::endl;
2037 outFile << cv_qual <<
"double " << prefix
2038 <<
"gXMax[] = {" << std::endl;
2039 for (i = 0; i < fNVariables; i++)
2040 outFile << (i != 0 ?
", " :
" ") << fMaxVariables(i) << std::flush;
2041 outFile <<
" };" << std::endl << std::endl;
2044 outFile <<
"// Assignment to coefficients vector." << std::endl;
2045 outFile << cv_qual <<
"double " << prefix
2046 <<
"gCoefficient[] = {" << std::flush;
2047 for (i = 0; i < fNCoefficients; i++)
2048 outFile << (i != 0 ?
"," :
"") << std::endl
2049 <<
" " << fCoefficients(i) << std::flush;
2050 outFile << std::endl <<
" };" << std::endl << std::endl;
2053 outFile <<
"// Assignment to error coefficients vector." << std::endl;
2054 outFile << cv_qual <<
"double " << prefix
2055 <<
"gCoefficientRMS[] = {" << std::flush;
2056 for (i = 0; i < fNCoefficients; i++)
2057 outFile << (i != 0 ?
"," :
"") << std::endl
2058 <<
" " << fCoefficientsRMS(i) << std::flush;
2059 outFile << std::endl <<
" };" << std::endl << std::endl;
2062 outFile <<
"// Assignment to powers vector." << std::endl
2063 <<
"// The powers are stored row-wise, that is" << std::endl
2064 <<
"// p_ij = " << prefix
2065 <<
"gPower[i * NVariables + j];" << std::endl;
2066 outFile << cv_qual <<
"int " << prefix
2067 <<
"gPower[] = {" << std::flush;
2068 for (i = 0; i < fNCoefficients; i++) {
2069 for (j = 0; j < fNVariables; j++) {
2070 if (j != 0) outFile << std::flush <<
" ";
2071 else outFile << std::endl <<
" ";
2072 outFile << fPowers[fPowerIndex[i] * fNVariables + j]
2073 << (i == fNCoefficients - 1 && j == fNVariables - 1 ?
"" :
",")
2077 outFile << std::endl <<
"};" << std::endl << std::endl;
2083 outFile <<
"// " << std::endl
2085 << (isMethod ?
"method " :
"function ")
2086 <<
" double " << prefix
2088 << std::endl <<
"// " << std::endl;
2089 outFile <<
"double " << prefix
2090 <<
"MDF(double *x) {" << std::endl
2091 <<
" double returnValue = " << prefix <<
"gDMean;" << std::endl
2092 <<
" int i = 0, j = 0, k = 0;" << std::endl
2093 <<
" for (i = 0; i < " << prefix <<
"gNCoefficients ; i++) {"
2095 <<
" // Evaluate the ith term in the expansion" << std::endl
2096 <<
" double term = " << prefix <<
"gCoefficient[i];"
2098 <<
" for (j = 0; j < " << prefix <<
"gNVariables; j++) {"
2100 <<
" // Evaluate the polynomial in the jth variable." << std::endl
2101 <<
" int power = "<< prefix <<
"gPower["
2102 << prefix <<
"gNVariables * i + j]; " << std::endl
2103 <<
" double p1 = 1, p2 = 0, p3 = 0, r = 0;" << std::endl
2104 <<
" double v = 1 + 2. / ("
2105 << prefix <<
"gXMax[j] - " << prefix
2106 <<
"gXMin[j]) * (x[j] - " << prefix <<
"gXMax[j]);" << std::endl
2107 <<
" // what is the power to use!" << std::endl
2108 <<
" switch(power) {" << std::endl
2109 <<
" case 1: r = 1; break; " << std::endl
2110 <<
" case 2: r = v; break; " << std::endl
2111 <<
" default: " << std::endl
2112 <<
" p2 = v; " << std::endl
2113 <<
" for (k = 3; k <= power; k++) { " << std::endl
2114 <<
" p3 = p2 * v;" << std::endl;
2115 if (fPolyType == kLegendre)
2116 outFile <<
" p3 = ((2 * i - 3) * p2 * v - (i - 2) * p1)"
2117 <<
" / (i - 1);" << std::endl;
2118 if (fPolyType == kChebyshev)
2119 outFile <<
" p3 = 2 * v * p2 - p1; " << std::endl;
2120 outFile <<
" p1 = p2; p2 = p3; " << std::endl <<
" }" << std::endl
2121 <<
" r = p3;" << std::endl <<
" }" << std::endl
2122 <<
" // multiply this term by the poly in the jth var" << std::endl
2123 <<
" term *= r; " << std::endl <<
" }" << std::endl
2124 <<
" // Add this term to the final result" << std::endl
2125 <<
" returnValue += term;" << std::endl <<
" }" << std::endl
2126 <<
" return returnValue;" << std::endl <<
"}" << std::endl << std::endl;
2129 outFile <<
"// EOF for " << filename << std::endl;
2135 std::cout <<
"done" << std::endl;
2151 void TMultiDimFit::Print(Option_t *option)
const
2156 TString opt(option);
2159 if (opt.Contains(
"p")) {
2161 std::cout <<
"User parameters:" << std::endl
2162 <<
"----------------" << std::endl
2163 <<
" Variables: " << fNVariables << std::endl
2164 <<
" Data points: " << fSampleSize << std::endl
2165 <<
" Max Terms: " << fMaxTerms << std::endl
2166 <<
" Power Limit Parameter: " << fPowerLimit << std::endl
2167 <<
" Max functions: " << fMaxFunctions << std::endl
2168 <<
" Max functions to study: " << fMaxStudy << std::endl
2169 <<
" Max angle (optional): " << fMaxAngle << std::endl
2170 <<
" Min angle: " << fMinAngle << std::endl
2171 <<
" Relative Error accepted: " << fMinRelativeError << std::endl
2172 <<
" Maximum Powers: " << std::flush;
2173 for (i = 0; i < fNVariables; i++)
2174 std::cout <<
" " << fMaxPowers[i] - 1 << std::flush;
2175 std::cout << std::endl << std::endl
2176 <<
" Parameterisation will be done using " << std::flush;
2177 if (fPolyType == kChebyshev)
2178 std::cout <<
"Chebyshev polynomials" << std::endl;
2179 else if (fPolyType == kLegendre)
2180 std::cout <<
"Legendre polynomials" << std::endl;
2182 std::cout <<
"Monomials" << std::endl;
2183 std::cout << std::endl;
2186 if (opt.Contains(
"s")) {
2188 std::cout <<
"Sample statistics:" << std::endl
2189 <<
"------------------" << std::endl
2190 <<
" D" << std::flush;
2191 for (i = 0; i < fNVariables; i++)
2192 std::cout <<
" " << std::setw(10) << i+1 << std::flush;
2193 std::cout << std::endl <<
" Max: " << std::setw(10) << std::setprecision(7)
2194 << fMaxQuantity << std::flush;
2195 for (i = 0; i < fNVariables; i++)
2196 std::cout <<
" " << std::setw(10) << std::setprecision(4)
2197 << fMaxVariables(i) << std::flush;
2198 std::cout << std::endl <<
" Min: " << std::setw(10) << std::setprecision(7)
2199 << fMinQuantity << std::flush;
2200 for (i = 0; i < fNVariables; i++)
2201 std::cout <<
" " << std::setw(10) << std::setprecision(4)
2202 << fMinVariables(i) << std::flush;
2203 std::cout << std::endl <<
" Mean: " << std::setw(10) << std::setprecision(7)
2204 << fMeanQuantity << std::flush;
2205 for (i = 0; i < fNVariables; i++)
2206 std::cout <<
" " << std::setw(10) << std::setprecision(4)
2207 << fMeanVariables(i) << std::flush;
2208 std::cout << std::endl <<
" Function Sum Squares: " << fSumSqQuantity
2209 << std::endl << std::endl;
2212 if (opt.Contains(
"r")) {
2213 std::cout <<
"Results of Parameterisation:" << std::endl
2214 <<
"----------------------------" << std::endl
2215 <<
" Total reduction of square residuals "
2216 << fSumSqResidual << std::endl
2217 <<
" Relative precision obtained: "
2218 << fPrecision << std::endl
2219 <<
" Error obtained: "
2220 << fError << std::endl
2221 <<
" Multiple correlation coefficient: "
2222 << fCorrelationCoeff << std::endl
2223 <<
" Reduced Chi square over sample: "
2224 << fChi2 / (fSampleSize - fNCoefficients) << std::endl
2225 <<
" Maximum residual value: "
2226 << fMaxResidual << std::endl
2227 <<
" Minimum residual value: "
2228 << fMinResidual << std::endl
2229 <<
" Estimated root mean square: "
2230 << fRMS << std::endl
2231 <<
" Maximum powers used: " << std::flush;
2232 for (j = 0; j < fNVariables; j++)
2233 std::cout << fMaxPowersFinal[j] <<
" " << std::flush;
2234 std::cout << std::endl
2235 <<
" Function codes of candidate functions." << std::endl
2236 <<
" 1: considered,"
2237 <<
" 2: too little contribution,"
2238 <<
" 3: accepted." << std::flush;
2239 for (i = 0; i < fMaxFunctions; i++) {
2241 std::cout << std::endl <<
" " << std::flush;
2242 else if (i % 10 == 0)
2243 std::cout <<
" " << std::flush;
2244 std::cout << fFunctionCodes[i];
2246 std::cout << std::endl <<
" Loop over candidates stopped because " << std::flush;
2247 switch(fParameterisationCode){
2248 case PARAM_MAXSTUDY:
2249 std::cout <<
"max allowed studies reached" << std::endl;
break;
2251 std::cout <<
"all candidates considered several times" << std::endl;
break;
2253 std::cout <<
"wanted relative error obtained" << std::endl;
break;
2254 case PARAM_MAXTERMS:
2255 std::cout <<
"max number of terms reached" << std::endl;
break;
2257 std::cout <<
"some unknown reason" << std::endl;
2260 std::cout << std::endl;
2263 if (opt.Contains(
"f")) {
2264 std::cout <<
"Results of Fit:" << std::endl
2265 <<
"---------------" << std::endl
2266 <<
" Test sample size: "
2267 << fTestSampleSize << std::endl
2268 <<
" Multiple correlation coefficient: "
2269 << fTestCorrelationCoeff << std::endl
2270 <<
" Relative precision obtained: "
2271 << fTestPrecision << std::endl
2272 <<
" Error obtained: "
2273 << fTestError << std::endl
2274 <<
" Reduced Chi square over sample: "
2275 << fChi2 / (fSampleSize - fNCoefficients) << std::endl
2278 fFitter->PrintResults(1,1);
2279 std::cout << std::endl;
2283 if (opt.Contains(
"c")){
2284 std::cout <<
"Coefficients:" << std::endl
2285 <<
"-------------" << std::endl
2286 <<
" # Value Error Powers" << std::endl
2287 <<
" ---------------------------------------" << std::endl;
2288 for (i = 0; i < fNCoefficients; i++) {
2289 std::cout <<
" " << std::setw(3) << i <<
" "
2290 << std::setw(12) << fCoefficients(i) <<
" "
2291 << std::setw(12) << fCoefficientsRMS(i) <<
" " << std::flush;
2292 for (j = 0; j < fNVariables; j++)
2293 std::cout <<
" " << std::setw(3)
2294 << fPowers[fPowerIndex[i] * fNVariables + j] - 1 << std::flush;
2295 std::cout << std::endl;
2297 std::cout << std::endl;
2299 if (opt.Contains(
"k") && fCorrelationMatrix.IsValid()) {
2300 std::cout <<
"Correlation Matrix:" << std::endl
2301 <<
"-------------------";
2302 fCorrelationMatrix.Print();
2305 if (opt.Contains(
"m")) {
2306 std::cout <<
"Parameterization:" << std::endl
2307 <<
"-----------------" << std::endl
2308 <<
" Normalised variables: " << std::endl;
2309 for (i = 0; i < fNVariables; i++)
2310 std::cout <<
"\ty_" << i <<
"\t= 1 + 2 * (x_" << i <<
" - "
2311 << fMaxVariables(i) <<
") / ("
2312 << fMaxVariables(i) <<
" - " << fMinVariables(i) <<
")"
2314 std::cout << std::endl
2316 for (i = 0; i < fNVariables; i++) {
2317 std::cout <<
"y_" << i;
2318 if (i != fNVariables-1) std::cout <<
", ";
2320 std::cout <<
") = ";
2321 for (i = 0; i < fNCoefficients; i++) {
2323 std::cout << std::endl <<
"\t" << (fCoefficients(i) < 0 ?
"- " :
"+ ")
2324 << TMath::Abs(fCoefficients(i));
2326 std::cout << fCoefficients(i);
2327 for (j = 0; j < fNVariables; j++) {
2328 Int_t p = fPowers[fPowerIndex[i] * fNVariables + j];
2331 case 2: std::cout <<
" * y_" << j;
break;
2334 case kLegendre: std::cout <<
" * L_" << p-1 <<
"(y_" << j <<
")";
break;
2335 case kChebyshev: std::cout <<
" * C_" << p-1 <<
"(y_" << j <<
")";
break;
2336 default: std::cout <<
" * y_" << j <<
"^" << p-1;
break;
2342 std::cout << std::endl;
2358 Bool_t TMultiDimFit::Select(
const Int_t *)
2370 void TMultiDimFit::SetMaxAngle(Double_t ang)
2372 if (ang >= 90 || ang < 0) {
2373 Warning(
"SetMaxAngle",
"angle must be in [0,90)");
2386 void TMultiDimFit::SetMinAngle(Double_t ang)
2388 if (ang > 90 || ang <= 0) {
2389 Warning(
"SetMinAngle",
"angle must be in [0,90)");
2406 void TMultiDimFit::SetPowers(
const Int_t* powers, Int_t terms)
2408 fIsUserFunction = kTRUE;
2409 fMaxFunctions = terms;
2412 fMaxFuncNV = fMaxFunctions * fNVariables;
2413 fPowers =
new Int_t[fMaxFuncNV];
2415 for (i = 0; i < fMaxFunctions; i++)
2416 for(j = 0; j < fNVariables; j++)
2417 fPowers[i * fNVariables + j] = powers[i * fNVariables + j] + 1;
2426 void TMultiDimFit::SetPowerLimit(Double_t limit)
2428 fPowerLimit = limit;
2436 void TMultiDimFit::SetMaxPowers(
const Int_t* powers)
2441 for (Int_t i = 0; i < fNVariables; i++)
2442 fMaxPowers[i] = powers[i]+1;
2451 void TMultiDimFit::SetMinRelativeError(Double_t error)
2453 fMinRelativeError = error;
2463 Bool_t TMultiDimFit::TestFunction(Double_t squareResidual,
2466 if (fNCoefficients != 0) {
2468 if (fMaxAngle == 0) {
2471 squareResidual / (fMaxTerms - fNCoefficients + 1 + 1E-10)) {
2478 if (TMath::Sqrt(dResidur/fSumSqAvgQuantity) <
2479 TMath::Cos(fMaxAngle*DEGRAD)) {
2492 void mdfHelper(
int& ,
double* ,
double& chi2,
2493 double* coeffs,
int )
2496 TMultiDimFit* mdf = TMultiDimFit::Instance();
2497 chi2 = mdf->MakeChi2(coeffs);