33 :
Tool(msg), dimension(dim), target(_target_), targetcov(_cov_), cov(dim, dim), histtool(msg)
35 auto titleguard =
MSGUser()->StartTitleWithGuard(
"Chi2Fitter::Chi2Fitter");
38 MSGUser()->MSG_ERROR(
"Target histogram is not valid");
116 auto titleguard =
MSGUser()->StartTitleWithGuard(
"Chi2Fitter::SetModel");
119 MSGUser()->MSG_ERROR(
"Model histogram is not valid");
124 MSGUser()->MSG_ERROR(
"Target histogram is not valid");
130 MSGUser()->MSG_ERROR(
"Model histogram has less bins than fit range");
134 if (covmodel && (hmodel->GetNbinsX() != covmodel->GetNbinsX() || hmodel->GetNbinsX() != covmodel->GetNbinsY()))
136 MSGUser()->MSG_ERROR(
"Model histogram and covariance matrix do not match");
142 MSGUser()->MSG_ERROR(
"Size of list of model parameters does not match");
152 if (
target->GetBinError(i) != 0 || hmodel->GetBinError(i) != 0)
153 chi2 += pow(
target->GetBinContent(i) - hmodel->GetBinContent(i), 2) / (
target->GetBinError(i) *
target->GetBinError(i) + hmodel->GetBinError(i) * hmodel->GetBinError(i));
158 TMatrixD matcovtarget(
target->GetNbinsX(),
target->GetNbinsX());
159 TMatrixD matcovmodel(hmodel->GetNbinsX(), hmodel->GetNbinsX());
166 for (
int i = 1; i <=
target->GetNbinsX(); i++)
167 matcovtarget(i - 1, i - 1) =
target->GetBinError(i) *
target->GetBinError(i);
172 for (
int i = 1; i <= hmodel->GetNbinsX(); i++)
173 matcovmodel(i - 1, i - 1) = hmodel->GetBinError(i) * hmodel->GetBinError(i);
176 TMatrixD partialmatcov(psize, psize);
178 for (
int i = 0; i < psize; i++)
179 for (
int j = 0; j < psize; j++)
182 auto invertcov = partialmatcov.InvertFast();
183 for (
int i = 0; i < psize; i++)
184 for (
int j = 0; j < psize; j++)
193 if (
vchi2.size() == 1)
320 auto titleguard =
MSGUser()->StartTitleWithGuard(
"Chi2Fitter::Fit");
323 std::vector<double> vnf1, vnf2;
324 std::vector<std::vector<double>> vvaluescaled;
329 if (fabs(vnf1.back()) < 1e-8)
338 std::vector<double> vpara;
342 Eigen::VectorXf Y = Eigen::VectorXf(
vchi2.size());
343 for (
size_t n = 0; n <
vchi2.size(); n++)
347 for (
size_t j = 0; j <= i; j++)
349 X(n, count) = ((
vvalue[n][i] - vnf2[i]) / vnf1[i]) * (
vvalue[n][j] - vnf2[j]) / vnf1[j];
355 X(n, count) = ((
vvalue[n][i] - vnf2[i]) / vnf1[i]);
372 Eigen::VectorXf B = X.bdcSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(Y);
378 for (
int i = 0; i < B.size(); i++)
379 vpara.emplace_back(B(i));
384 std::vector<std::vector<double>> scaledvvalue;
385 for (
size_t i = 0; i <
vchi2.size(); i++)
389 sv[j] = (sv[j] - vnf2[j]) / vnf1[j];
391 scaledvvalue.emplace_back(sv);
395 ROOT::Minuit2::MnUserParameters upar;
397 for (
size_t j = 0; j <= i; j++)
398 upar.Add(TString::Format(
"invertcov_%lu_%lu", i, j).Data(), 0, 1);
401 upar.Add(TString::Format(
"linearpar_%lu", i).Data(), 2, 2);
403 upar.Add(
"offset", 0, 1);
406 ROOT::Minuit2::MnSimplex simplex(fcn, upar, 2);
407 auto minsimplex = simplex(1e5);
409 ROOT::Minuit2::MnMigrad migrad(fcn, minsimplex.UserState(), ROOT::Minuit2::MnStrategy(2));
410 auto minmigrad = migrad(1e5);
412 chi2 = minmigrad.Fval();
413 vpara = minmigrad.UserState().Params();
419 cov(i, j) /= vnf1[i] * vnf1[j];
421 auto invertcov =
cov;
424 std::vector<double> linearterm;
432 value[i] -=
cov(i, j) * linearterm[j] / (2 * vnf1[j]);
441 std::vector<double> tempvalue(
dimension, 0);
444 tempvalue[i] -= tempcov(i, j) * linearterm[j] / 2;
448 offset -= tempvalue[i] * tempinvertcov(i, j) * tempvalue[j];
452 if (
cov(i, i) <= 0 || !isfinite(
cov(i, i)))
453 MSGUser()->MSG_WARNING(
"Variance of value ", i,
" is negative or is not finite, the fit results are not trustworthy");
473 std::vector<double> gradient(vpara.size(), 0);
478 for (
size_t i = 0; i < dim; i++)
479 for (
size_t j = 0; j <= i; j++)
482 gradient[count] = vx[i] * vx[i];
484 gradient[count] = 2 * vx[i] * vx[j];
489 for (
size_t i = 0; i < dim; i++)
490 gradient[count + i] = vx[i];
506 std::vector<double> gradient(vpara.size(), 0);
507 for (
size_t i = 0; i < vc->size(); i++)
509 auto chi2gradient = GradientQuadraticChi2(vv->at(i), vpara);
510 double dchi2 = QuadraticChi2(vv->at(i), vpara) - vc->at(i);
511 for (
size_t j = 0; j < gradient.size(); j++)
512 gradient[j] += 2 * dchi2 * chi2gradient[j];