13 #ifndef ROOT_Fit_FitUtil 14 #define ROOT_Fit_FitUtil 20 #include "ROOT/TThreadExecutor.hxx" 36 #define USE_PARAMCACHE 43 vecCore::Mask<T> Int2Mask(
unsigned i)
46 for (
unsigned j = 0; j < vecCore::VectorSize<T>(); j++)
47 vecCore::Set<T>(x, j, j);
48 return vecCore::Mask<T>(x <
T(i));
78 LikelihoodAux(
T logv = {},
T w = {},
T w2 = {}) : logvalue(logv), weight(w), weight2(w2) {}
101 LikelihoodAux(
double logv = 0.0,
double w = 0.0,
double w2 = 0.0) : logvalue(logv), weight(w), weight2(w2){};
128 template <
class ParamFunc = ROOT::Math::IParamMultiFunctionTempl<
double>>
133 : fDim(0), fParams(0), fFunc(0), fIg1Dim(0), fIgNDim(0), fFunc1Dim(0), fFuncNDim(0)
136 SetFunction(func, p);
155 *
this, &IntegralEvaluator::F1);
158 fIg1Dim->SetFunction(static_cast<const ROOT::Math::IGenFunction &>(*fFunc1Dim));
159 }
else if (fDim > 1) {
162 const>(*
this, &IntegralEvaluator::FN, fDim);
164 fIgNDim->SetFunction(*fFuncNDim);
192 return ExecFunc(fFunc, &xx, fParams);
195 double FN(
const double *
x)
const {
return ExecFunc(fFunc, x, fParams); }
197 double Integral(
const double *x1,
const double *x2)
200 return (fIg1Dim) ? fIg1Dim->Integral(*x1, *x2) : fIgNDim->Integral(x1, x2);
207 double dV = *x2 - *x1;
208 return fIg1Dim->Integral(*x1, *x2) / dV;
209 }
else if (fIgNDim) {
211 for (
unsigned int i = 0; i < fDim; ++i)
212 dV *= (x2[i] - x1[i]);
213 return fIgNDim->Integral(x1, x2) / dV;
223 inline double ExecFunc(
T *f,
const double *
x,
const double *p)
const 228 #ifdef R__HAS_VECCORE 233 vecCore::Load<ROOT::Double_v>(xx,
x);
234 const double *p0 = p;
235 auto res = (*f)(&xx, (
const double *)p0);
236 return vecCore::Get<ROOT::Double_v>(res, 0);
238 std::vector<ROOT::Double_v> xx(fDim);
239 for (
unsigned int i = 0; i < fDim; ++i) {
240 vecCore::Load<ROOT::Double_v>(xx[i], x + i);
242 auto res = (*f)(xx.data(), p);
243 return vecCore::Get<ROOT::Double_v>(res, 0);
250 IntegralEvaluator &operator=(
const IntegralEvaluator &rhs);
269 double EvaluateChi2(
const IModelFunction &func,
const BinData &data,
const double *
x,
unsigned int &nPoints,
284 unsigned int &nPoints,
286 unsigned nChunks = 0);
292 double EvaluateLogL(
const IModelFunction &func,
const UnBinData &data,
const double *p,
int iWeight,
bool extended,
300 unsigned int &nPoints,
302 unsigned nChunks = 0);
317 unsigned nChunks = 0);
324 unsigned int &nPoints,
326 unsigned nChunks = 0);
346 EvaluatePdf(
const IModelFunction &func,
const UnBinData &data,
const double *
x,
unsigned int ipoint,
double *g = 0);
348 #ifdef R__HAS_VECCORE 349 template <class NotCompileIfScalarBackend = std::enable_if<!(std::is_same<double, ROOT::Double_v>::value)>>
355 auto fval = func(&
x, p);
357 return vecCore::Get<ROOT::Double_v>(logPdf, 0);
373 #ifdef R__HAS_VECCORE 384 unsigned int n = data.
Size();
388 #ifdef USE_PARAMCACHE 398 Error(
"FitUtil::EvaluateChi2",
"The vectorized implementation doesn't support Integrals, BinVolume or ExpErrors\n. Aborting operation.");
402 double maxResValue = std::numeric_limits<double>::max() / n;
403 std::vector<double> ones{1, 1, 1, 1};
404 auto vecSize = vecCore::VectorSize<T>();
406 auto mapFunction = [&](
unsigned int i) {
408 T x1,
y, invErrorVec;
410 vecCore::Load<T>(
y, data.
ValuePtr(i * vecSize));
411 const auto invError = data.
ErrorPtr(i * vecSize);
412 auto invErrorptr = (invError !=
nullptr) ? invError : &ones.front();
413 vecCore::Load<T>(invErrorVec, invErrorptr);
417 if(data.
NDim() > 1) {
418 xc.resize(data.
NDim());
420 for (
unsigned int j = 1; j < data.
NDim(); ++j)
429 #ifdef USE_PARAMCACHE 436 T tmp = (y - fval) * invErrorVec;
441 auto m = vecCore::Mask_v<T>(chi2 > maxResValue);
443 vecCore::MaskedAssign<T>(chi2,
m, maxResValue);
449 auto redFunction = [](
const std::vector<T> &objs) {
450 return std::accumulate(objs.begin(), objs.end(),
T{});
457 Warning(
"FitUtil::EvaluateChi2",
"Multithread execution policy requires IMT, which is disabled. Changing " 458 "to ROOT::Fit::ExecutionPolicy::kSerial.");
465 for (
unsigned int i = 0; i < (data.
Size() / vecSize); i++) {
466 res += mapFunction(i);
472 ROOT::TThreadExecutor pool;
473 res = pool.MapReduce(mapFunction, ROOT::TSeq<unsigned>(0, data.
Size() / vecSize), redFunction, chunks);
479 Error(
"FitUtil::EvaluateChi2",
"Execution policy unknown. Avalaible choices:\n ROOT::Fit::ExecutionPolicy::kSerial (default)\n ROOT::Fit::ExecutionPolicy::kMultithread (requires IMT)\n");
484 vecCore::MaskedAssign(res, vecCore::Int2Mask<T>(data.
Size() % vecSize),
485 res + mapFunction(data.
Size() / vecSize));
487 return vecCore::ReduceAdd(res);
491 int iWeight,
bool extended,
unsigned int &nPoints,
495 unsigned int n = data.
Size();
498 bool normalizeFunc =
false;
501 #ifdef USE_PARAMCACHE 508 if (!normalizeFunc) {
509 if (data.
NDim() == 1) {
515 std::vector<T>
x(data.
NDim());
516 for (
unsigned int j = 0; j < data.
NDim(); ++j)
527 std::vector<double> xmin(data.
NDim());
528 std::vector<double> xmax(data.
NDim());
533 for (
unsigned int ir = 0; ir < data.
Range().
Size(); ++ir) {
535 norm += igEval.Integral(xmin.data(), xmax.data());
542 vecCore::Load<T>(xmin_v, xmin.data());
543 vecCore::Load<T>(xmax_v, xmax.data());
544 if (vecCore::ReduceAdd(func(&xmin_v, p)) != 0 || vecCore::ReduceAdd(func(&xmax_v, p)) != 0) {
545 MATH_ERROR_MSG(
"FitUtil::EvaluateLogLikelihood",
"A range has not been set and the function is not zero at +/- inf");
548 norm = igEval.Integral(&xmin[0], &xmax[0]);
554 auto vecSize = vecCore::VectorSize<T>();
555 unsigned int numVectors = n / vecSize;
557 auto mapFunction = [ &, p](
const unsigned i) {
566 const T *
x =
nullptr;
567 unsigned int ndim = data.
NDim();
572 for (
unsigned int j = 1; j < ndim; ++j)
579 #ifdef USE_PARAMCACHE 586 if (i < 5 || (i > numVectors-5) ) {
587 if (ndim == 1) std::cout << i <<
" x " << x[0] <<
" fval = " << fval;
588 else std::cout << i <<
" x " << x[0] <<
" y " << x[1] <<
" fval = " << fval;
592 if (normalizeFunc) fval = fval * (1 / norm);
601 vecCore::Load<T>(weight, data.
WeightsPtr(i*vecSize));
608 W2 = weight * weight;
613 if (i < 5 || (i > numVectors-5) ) {
614 std::cout <<
" " << fval <<
" logfval " << logval << std::endl;
623 auto redFunction = [](
const std::vector<LikelihoodAux<T>> &objs) {
634 Warning(
"FitUtil::EvaluateLogL",
"Multithread execution policy requires IMT, which is disabled. Changing " 635 "to ROOT::Fit::ExecutionPolicy::kSerial.");
644 for (
unsigned int i = 0; i < numVectors; ++i) {
645 auto resArray = mapFunction(i);
646 logl_v += resArray.logvalue;
647 sumW_v += resArray.weight;
648 sumW2_v += resArray.weight2;
653 ROOT::TThreadExecutor pool;
654 auto resArray = pool.MapReduce(mapFunction, ROOT::TSeq<unsigned>(0, data.
Size() / vecSize), redFunction, chunks);
655 logl_v = resArray.logvalue;
656 sumW_v = resArray.weight;
657 sumW2_v = resArray.weight2;
663 Error(
"FitUtil::EvaluateLogL",
"Execution policy unknown. Avalaible choices:\n ROOT::Fit::ExecutionPolicy::kSerial (default)\n ROOT::Fit::ExecutionPolicy::kMultithread (requires IMT)\n");
667 unsigned int remainingPoints = n % vecSize;
668 if (remainingPoints > 0) {
669 auto remainingPointsContribution = mapFunction(numVectors);
671 auto remainingMask = vecCore::Int2Mask<T>(remainingPoints);
672 vecCore::MaskedAssign(logl_v, remainingMask, logl_v + remainingPointsContribution.logvalue);
673 vecCore::MaskedAssign(sumW_v, remainingMask, sumW_v + remainingPointsContribution.weight);
674 vecCore::MaskedAssign(sumW2_v, remainingMask, sumW2_v + remainingPointsContribution.weight2);
683 for (
unsigned vIt = 0; vIt < vecSize; vIt++) {
686 sumW2 += sumW2_v[vIt];
691 double extendedTerm = 0;
695 if (!normalizeFunc) {
697 std::vector<double> xmin(data.
NDim());
698 std::vector<double> xmax(data.
NDim());
703 for (
unsigned int ir = 0; ir < data.
Range().
Size(); ++ir) {
705 nuTot += igEval.
Integral(xmin.data(), xmax.data());
712 vecCore::Load<T>(xmin_v, xmin.data());
713 vecCore::Load<T>(xmax_v, xmax.data());
714 if (vecCore::ReduceAdd(func(&xmin_v, p)) != 0 || vecCore::ReduceAdd(func(&xmax_v, p)) != 0) {
715 MATH_ERROR_MSG(
"FitUtil::EvaluateLogLikelihood",
"A range has not been set and the function is not zero at +/- inf");
718 nuTot = igEval.
Integral(&xmin[0], &xmax[0]);
724 extendedTerm = - nuTot;
728 extendedTerm = - (sumW2 / sumW) * nuTot;
737 logl += extendedTerm;
741 std::cout <<
"Evaluated log L for parameters (";
742 for (
unsigned int ip = 0; ip < func.
NPar(); ++ip)
743 std::cout <<
" " << p[ip];
744 std::cout <<
") nll = " << -logl << std::endl;
756 int iWeight,
bool extended,
unsigned int,
774 #ifdef USE_PARAMCACHE 777 auto vecSize = vecCore::VectorSize<T>();
780 if (fitOpt.fExpErrors || fitOpt.fIntegral)
781 Error(
"FitUtil::EvaluateChi2",
782 "The vectorized implementation doesn't support Integrals or BinVolume\n. Aborting operation.");
783 bool useW2 = (iWeight == 2);
785 auto mapFunction = [&](
unsigned int i) {
787 vecCore::Load<T>(
y, data.
ValuePtr(i * vecSize));
790 if (data.
NDim() > 1) {
791 std::vector<T>
x(data.
NDim());
792 for (
unsigned int j = 0; j < data.
NDim(); ++j)
794 #ifdef USE_PARAMCACHE 795 fval = func(
x.data());
797 fval = func(
x.data(), p);
803 #ifdef USE_PARAMCACHE 812 vecCore::MaskedAssign<T>(fval, fval < 0.0, 0.0);
822 assert (data.
GetErrorType() != ROOT::Fit::BinData::ErrorType::kNoError);
824 vecCore::Load<T>(error, data.
ErrorPtr(i * vecSize));
826 auto m = vecCore::Mask_v<T>(y != 0.0);
829 nloglike = weight * ( fval -
y);
838 if (extended) nloglike = fval -
y;
840 vecCore::MaskedAssign<T>(
848 auto redFunction = [](
const std::vector<T> &objs) {
return std::accumulate(objs.begin(), objs.end(),
T{}); };
854 Warning(
"FitUtil::Evaluate<T>::EvalPoissonLogL",
855 "Multithread execution policy requires IMT, which is disabled. Changing " 856 "to ROOT::Fit::ExecutionPolicy::kSerial.");
863 for (
unsigned int i = 0; i < (data.
Size() / vecSize); i++) {
864 res += mapFunction(i);
869 ROOT::TThreadExecutor pool;
870 res = pool.MapReduce(mapFunction, ROOT::TSeq<unsigned>(0, data.
Size() / vecSize), redFunction, chunks);
877 "FitUtil::Evaluate<T>::EvalPoissonLogL",
878 "Execution policy unknown. Avalaible choices:\n ROOT::Fit::ExecutionPolicy::kSerial (default)\n ROOT::Fit::ExecutionPolicy::kMultithread (requires IMT)\n");
882 vecCore::MaskedAssign(res, vecCore::Int2Mask<T>(data.
Size() % vecSize),
883 res + mapFunction(data.
Size() / vecSize));
885 return vecCore::ReduceAdd(res);
890 Error(
"FitUtil::Evaluate<T>::EvalChi2Effective",
"The vectorized evaluation of the Chi2 with coordinate errors is still not supported");
897 static vecCore::Mask<T> CheckInfNaNValues(
T &rval)
899 auto mask = rval > -vecCore::NumericLimits<T>::Max() && rval < vecCore::NumericLimits<T>::Max();
902 vecCore::MaskedAssign(rval, !mask, +vecCore::NumericLimits<T>::Max());
905 vecCore::MaskedAssign(rval, !mask && rval < 0, -vecCore::NumericLimits<T>::Max());
911 unsigned int &nPoints,
913 unsigned nChunks = 0)
923 "Error on the coordinates are not used in calculating Chi2 gradient");
928 assert(fg !=
nullptr);
934 Error(
"FitUtil::EvaluateChi2Gradient",
"The vectorized implementation doesn't support Integrals," 935 "BinVolume or ExpErrors\n. Aborting operation.");
937 unsigned int npar = func.
NPar();
938 auto vecSize = vecCore::VectorSize<T>();
939 unsigned initialNPoints = data.
Size();
940 unsigned numVectors = initialNPoints / vecSize;
943 std::vector<vecCore::Mask<T>> validPointsMasks(numVectors + 1);
945 auto mapFunction = [&](
const unsigned int i) {
947 std::vector<T> gradFunc(npar);
948 std::vector<T> pointContributionVec(npar);
953 vecCore::Load<T>(
y, data.
ValuePtr(i * vecSize));
954 const auto invErrorPtr = data.
ErrorPtr(i * vecSize);
956 if (invErrorPtr ==
nullptr)
959 vecCore::Load<T>(invError, invErrorPtr);
965 const T *
x =
nullptr;
967 unsigned int ndim = data.
NDim();
974 for (
unsigned int j = 1; j < ndim; ++j)
991 validPointsMasks[i] = CheckInfNaNValues(fval);
992 if (vecCore::MaskEmpty(validPointsMasks[i])) {
994 return pointContributionVec;
998 for (
unsigned int ipar = 0; ipar < npar; ++ipar) {
1001 validPointsMasks[i] = CheckInfNaNValues(gradFunc[ipar]);
1003 if (vecCore::MaskEmpty(validPointsMasks[i])) {
1008 vecCore::MaskedAssign(pointContributionVec[ipar], validPointsMasks[i],
1009 -2.0 * (y - fval) * invError * invError * gradFunc[ipar]);
1012 return pointContributionVec;
1016 auto redFunction = [&](
const std::vector<std::vector<T>> &partialResults) {
1017 std::vector<T> result(npar);
1019 for (
auto const &pointContributionVec : partialResults) {
1020 for (
unsigned int parameterIndex = 0; parameterIndex < npar; parameterIndex++)
1021 result[parameterIndex] += pointContributionVec[parameterIndex];
1027 std::vector<T> gVec(npar);
1028 std::vector<double> g(npar);
1036 Warning(
"FitUtil::EvaluateChi2Gradient",
1037 "Multithread execution policy requires IMT, which is disabled. Changing " 1038 "to ROOT::Fit::ExecutionPolicy::kSerial.");
1044 std::vector<std::vector<T>> allGradients(numVectors);
1045 for (
unsigned int i = 0; i < numVectors; ++i) {
1046 allGradients[i] = mapFunction(i);
1049 gVec = redFunction(allGradients);
1054 ROOT::TThreadExecutor pool;
1055 gVec = pool.MapReduce(mapFunction, ROOT::TSeq<unsigned>(0, numVectors), redFunction, chunks);
1064 "FitUtil::EvaluateChi2Gradient",
1065 "Execution policy unknown. Avalaible choices:\n 0: Serial (default)\n 1: MultiThread (requires IMT)\n");
1069 unsigned int remainingPoints = initialNPoints % vecSize;
1070 if (remainingPoints > 0) {
1071 auto remainingPointsContribution = mapFunction(numVectors);
1073 auto remainingMask = vecCore::Int2Mask<T>(remainingPoints);
1074 for (
unsigned int param = 0; param < npar; param++) {
1075 vecCore::MaskedAssign(gVec[param], remainingMask, gVec[param] + remainingPointsContribution[param]);
1079 for (
unsigned int param = 0; param < npar; param++) {
1080 grad[param] = vecCore::ReduceAdd(gVec[param]);
1084 nPoints = initialNPoints;
1086 if (std::any_of(validPointsMasks.begin(), validPointsMasks.end(),
1087 [](vecCore::Mask<T> validPoints) {
return !vecCore::MaskFull(validPoints); })) {
1088 unsigned nRejected = 0;
1090 for (
const auto &mask : validPointsMasks) {
1091 for (
unsigned int i = 0; i < vecSize; i++) {
1092 nRejected += !vecCore::Get(mask, i);
1096 assert(nRejected <= initialNPoints);
1097 nPoints = initialNPoints - nRejected;
1099 if (nPoints < npar) {
1101 "Too many points rejected for overflow in gradient calculation");
1108 Error(
"FitUtil::Evaluate<T>::EvalChi2Residual",
"The vectorized evaluation of the Chi2 with the ith residual is still not supported");
1115 Error(
"FitUtil::Evaluate<T>::EvaluatePoissonBinPdf",
"The vectorized evaluation of the BinnedLikelihood fit evaluated point by point is still not supported");
1123 unsigned nChunks = 0)
1128 assert(fg !=
nullptr);
1137 Error(
"FitUtil::EvaluatePoissonLogLGradient",
"The vectorized implementation doesn't support Integrals," 1138 "BinVolume or ExpErrors\n. Aborting operation.");
1140 unsigned int npar = func.
NPar();
1141 auto vecSize = vecCore::VectorSize<T>();
1142 unsigned initialNPoints = data.
Size();
1143 unsigned numVectors = initialNPoints / vecSize;
1145 auto mapFunction = [&](
const unsigned int i) {
1147 std::vector<T> gradFunc(npar);
1148 std::vector<T> pointContributionVec(npar);
1153 vecCore::Load<T>(
y, data.
ValuePtr(i * vecSize));
1157 const T *
x =
nullptr;
1159 unsigned ndim = data.
NDim();
1164 for (
unsigned int j = 1; j < ndim; ++j)
1175 for (
unsigned int ipar = 0; ipar < npar; ++ipar) {
1176 vecCore::Mask<T> positiveValuesMask = fval > 0;
1179 vecCore::MaskedAssign(pointContributionVec[ipar], positiveValuesMask, gradFunc[ipar] * (1. - y / fval));
1181 vecCore::Mask<T> validNegativeValuesMask = !positiveValuesMask && gradFunc[ipar] != 0;
1183 if (!vecCore::MaskEmpty(validNegativeValuesMask)) {
1185 const T kdmax2 = vecCore::NumericLimits<T>::Max() / (4 * initialNPoints);
1186 T gg = kdmax1 * gradFunc[ipar];
1187 pointContributionVec[ipar] = -vecCore::Blend(gg > 0, vecCore::math::Min(gg, kdmax2), vecCore::math::Max(gg, -kdmax2));
1191 #ifdef DEBUG_FITUTIL 1193 R__LOCKGUARD(gROOTMutex);
1194 if (i < 5 || (i > data.
Size()-5) ) {
1195 if (data.
NDim() > 1) std::cout << i <<
" x " << x[0] <<
" y " << x[1];
1196 else std::cout << i <<
" x " << x[0];
1197 std::cout <<
" func " << fval <<
" gradient ";
1198 for (
unsigned int ii = 0; ii < npar; ++ii) std::cout <<
" " << pointContributionVec[ii];
1204 return pointContributionVec;
1208 auto redFunction = [&](
const std::vector<std::vector<T>> &partialResults) {
1209 std::vector<T> result(npar);
1211 for (
auto const &pointContributionVec : partialResults) {
1212 for (
unsigned int parameterIndex = 0; parameterIndex < npar; parameterIndex++)
1213 result[parameterIndex] += pointContributionVec[parameterIndex];
1219 std::vector<T> gVec(npar);
1227 Warning(
"FitUtil::EvaluatePoissonLogLGradient",
1228 "Multithread execution policy requires IMT, which is disabled. Changing " 1229 "to ROOT::Fit::ExecutionPolicy::kSerial.");
1235 std::vector<std::vector<T>> allGradients(numVectors);
1236 for (
unsigned int i = 0; i < numVectors; ++i) {
1237 allGradients[i] = mapFunction(i);
1240 gVec = redFunction(allGradients);
1245 ROOT::TThreadExecutor pool;
1246 gVec = pool.MapReduce(mapFunction, ROOT::TSeq<unsigned>(0, numVectors), redFunction, chunks);
1254 Error(
"FitUtil::EvaluatePoissonLogLGradient",
"Execution policy unknown. Avalaible choices:\n " 1255 "ROOT::Fit::ExecutionPolicy::kSerial (default)\n " 1256 "ROOT::Fit::ExecutionPolicy::kMultithread (requires IMT)\n");
1261 unsigned int remainingPoints = initialNPoints % vecSize;
1262 if (remainingPoints > 0) {
1263 auto remainingPointsContribution = mapFunction(numVectors);
1265 auto remainingMask = vecCore::Int2Mask<T>(remainingPoints);
1266 for (
unsigned int param = 0; param < npar; param++) {
1267 vecCore::MaskedAssign(gVec[param], remainingMask, gVec[param] + remainingPointsContribution[param]);
1271 for (
unsigned int param = 0; param < npar; param++) {
1272 grad[param] = vecCore::ReduceAdd(gVec[param]);
1275 #ifdef DEBUG_FITUTIL 1276 std::cout <<
"***** Final gradient : ";
1277 for (
unsigned int ii = 0; ii< npar; ++ii) std::cout << grad[ii] <<
" ";
1284 double *grad,
unsigned int &,
1286 unsigned nChunks = 0)
1291 assert(fg !=
nullptr);
1296 unsigned int npar = func.
NPar();
1297 auto vecSize = vecCore::VectorSize<T>();
1298 unsigned initialNPoints = data.
Size();
1299 unsigned numVectors = initialNPoints / vecSize;
1301 #ifdef DEBUG_FITUTIL 1302 std::cout <<
"\n===> Evaluate Gradient for parameters ";
1303 for (
unsigned int ip = 0; ip < npar; ++ip)
1304 std::cout <<
" " << p[ip];
1311 const T kdmax2 = vecCore::NumericLimits<T>::Max() / (4 * initialNPoints);
1313 auto mapFunction = [&](
const unsigned int i) {
1314 std::vector<T> gradFunc(npar);
1315 std::vector<T> pointContributionVec(npar);
1320 const T *
x =
nullptr;
1322 unsigned int ndim = data.
NDim();
1323 std::vector<T> xc(ndim);
1327 for (
unsigned int j = 1; j < ndim; ++j)
1335 T fval = func(x, p);
1338 #ifdef DEBUG_FITUTIL 1339 if (i < 5 || (i > numVectors-5) ) {
1340 if (ndim > 1) std::cout << i <<
" x " << x[0] <<
" y " << x[1] <<
" gradient " << gradFunc[0] <<
" " << gradFunc[1] <<
" " << gradFunc[3] << std::endl;
1341 else std::cout << i <<
" x " << x[0] <<
" gradient " << gradFunc[0] <<
" " << gradFunc[1] <<
" " << gradFunc[3] << std::endl;
1345 vecCore::Mask<T> positiveValues = fval > 0;
1347 for (
unsigned int kpar = 0; kpar < npar; ++kpar) {
1348 if (!vecCore::MaskEmpty(positiveValues))
1349 vecCore::MaskedAssign<T>(pointContributionVec[kpar], positiveValues, -1. / fval * gradFunc[kpar]);
1351 vecCore::Mask<T> nonZeroGradientValues = !positiveValues && gradFunc[kpar] != 0;
1352 if (!vecCore::MaskEmpty(nonZeroGradientValues)) {
1353 T gg = kdmax1 * gradFunc[kpar];
1354 pointContributionVec[kpar] =
1355 vecCore::Blend(nonZeroGradientValues && gg > 0, -vecCore::math::Min(gg, kdmax2),
1356 -vecCore::math::Max(gg, -kdmax2));
1361 return pointContributionVec;
1365 auto redFunction = [&](
const std::vector<std::vector<T>> &pointContributions) {
1366 std::vector<T> result(npar);
1368 for (
auto const &pointContributionVec : pointContributions) {
1369 for (
unsigned int parameterIndex = 0; parameterIndex < npar; parameterIndex++)
1370 result[parameterIndex] += pointContributionVec[parameterIndex];
1376 std::vector<T> gVec(npar);
1377 std::vector<double> g(npar);
1385 Warning(
"FitUtil::EvaluateLogLGradient",
1386 "Multithread execution policy requires IMT, which is disabled. Changing " 1387 "to ROOT::Fit::ExecutionPolicy::kSerial.");
1393 std::vector<std::vector<T>> allGradients(numVectors);
1394 for (
unsigned int i = 0; i < numVectors; ++i) {
1395 allGradients[i] = mapFunction(i);
1397 gVec = redFunction(allGradients);
1402 ROOT::TThreadExecutor pool;
1403 gVec = pool.MapReduce(mapFunction, ROOT::TSeq<unsigned>(0, numVectors), redFunction, chunks);
1411 Error(
"FitUtil::EvaluateLogLGradient",
"Execution policy unknown. Avalaible choices:\n " 1412 "ROOT::Fit::ExecutionPolicy::kSerial (default)\n " 1413 "ROOT::Fit::ExecutionPolicy::kMultithread (requires IMT)\n");
1417 unsigned int remainingPoints = initialNPoints % vecSize;
1418 if (remainingPoints > 0) {
1419 auto remainingPointsContribution = mapFunction(numVectors);
1421 auto remainingMask = vecCore::Int2Mask<T>(initialNPoints % vecSize);
1422 for (
unsigned int param = 0; param < npar; param++) {
1423 vecCore::MaskedAssign(gVec[param], remainingMask, gVec[param] + remainingPointsContribution[param]);
1427 for (
unsigned int param = 0; param < npar; param++) {
1428 grad[param] = vecCore::ReduceAdd(gVec[param]);
1431 #ifdef DEBUG_FITUTIL 1432 std::cout <<
"Final gradient ";
1433 for (
unsigned int param = 0; param < npar; param++) {
1434 std::cout <<
" " << grad[param];
1445 static double EvalChi2(
const IModelFunction &func,
const BinData &data,
const double *p,
unsigned int &nPoints,
1460 int iWeight,
bool extended,
unsigned int &nPoints,
1467 int iWeight,
bool extended,
unsigned int &nPoints,
1478 double *g,
unsigned int &nPoints,
1480 unsigned nChunks = 0)
1497 unsigned int &nPoints,
1499 unsigned nChunks = 0)
1505 double *g,
unsigned int &nPoints,
1507 unsigned nChunks = 0)
1519 #if defined (R__HAS_VECCORE) && defined(R__HAS_VC) LikelihoodAux & operator+=(const LikelihoodAux &l)
void SetFunction(const ParamFunc &func, const double *p=0)
static double EvalChi2Residual(const IModelFunctionTempl< double > &func, const BinData &data, const double *p, unsigned int i, double *g=0)
ROOT::Math::IntegratorOneDim * fIg1Dim
LikelihoodAux operator+(const LikelihoodAux &l) const
Interface (abstract class) for generic functions objects of one-dimension Provides a method to evalua...
void SetParameters(const double *p)
unsigned int NDim() const
return coordinate data dimension
double ExecFunc(T *f, const double *x, const double *p) const
Namespace for new ROOT classes and functions.
double EvaluateChi2(const IModelFunction &func, const BinData &data, const double *x, unsigned int &nPoints, ROOT::Fit::ExecutionPolicy executionPolicy, unsigned nChunks=0)
Chi2 Functions.
void EvaluateLogLGradient(const IModelFunction &func, const UnBinData &data, const double *x, double *grad, unsigned int &nPoints, ROOT::Fit::ExecutionPolicy executionPolicy=ROOT::Fit::ExecutionPolicy::kSerial, unsigned nChunks=0)
evaluate the LogL gradient given a model function and the data at the point x.
double EvaluatePoissonBinPdf(const IModelFunction &func, const BinData &data, const double *x, unsigned int ipoint, double *g=0)
evaluate the pdf contribution to the Poisson LogL given a model function and the BinPoint data...
ROOT::Math::IMultiGenFunction * fFuncNDim
ErrorType GetErrorType() const
retrieve the errortype
static double EvalLogL(const IModelFunctionTempl< double > &func, const UnBinData &data, const double *p, int iWeight, bool extended, unsigned int &nPoints, ROOT::Fit::ExecutionPolicy executionPolicy, unsigned nChunks=0)
const double * ValuePtr(unsigned int ipoint) const
return a pointer to the value for the given fit point
static void EvalChi2Gradient(const IModelFunctionTempl< double > &func, const BinData &data, const double *p, double *g, unsigned int &nPoints, ROOT::Fit::ExecutionPolicy executionPolicy=ROOT::Fit::ExecutionPolicy::kSerial, unsigned nChunks=0)
unsigned setAutomaticChunking(unsigned nEvents)
Class describing the unbinned data sets (just x coordinates values) of any dimensions.
Interface (abstract class) for parametric gradient multi-dimensional functions providing in addition ...
ROOT::Math::IParamMultiGradFunction IGradModelFunction
ROOT::Math::IntegratorMultiDim * fIgNDim
static double EvalPoissonBinPdf(const IModelFunctionTempl< double > &func, const BinData &data, const double *p, unsigned int i, double *g)
evaluate the pdf (Poisson) contribution to the logl (return actually log of pdf) and its gradient ...
static double EvalPoissonLogL(const IModelFunctionTempl< double > &func, const BinData &data, const double *p, int iWeight, bool extended, unsigned int &nPoints, ROOT::Fit::ExecutionPolicy executionPolicy, unsigned nChunks=0)
you should not use this method at all Int_t y
double SumOfError2() const
compute the total sum of the error square (sum of weight square in case of a weighted data set) ...
LikelihoodAux(double logv=0.0, double w=0.0, double w2=0.0)
void GetRange(unsigned int irange, unsigned int icoord, double &xmin, double &xmax) const
get the i-th range for given coordinate.
const double * GetCoordComponent(unsigned int ipoint, unsigned int icoord) const
returns a single coordinate component of a point.
void EvaluatePoissonLogLGradient(const IModelFunction &func, const BinData &data, const double *x, double *grad, unsigned int &nPoints, ROOT::Fit::ExecutionPolicy executionPolicy=ROOT::Fit::ExecutionPolicy::kSerial, unsigned nChunks=0)
evaluate the Poisson LogL given a model function and the data at the point x.
static double EvalChi2(const IModelFunction &func, const BinData &data, const double *p, unsigned int &nPoints, ROOT::Fit::ExecutionPolicy executionPolicy, unsigned nChunks=0)
double EvaluatePoissonLogL(const IModelFunction &func, const BinData &data, const double *x, int iWeight, bool extended, unsigned int &nPoints, ROOT::Fit::ExecutionPolicy executionPolicy, unsigned nChunks=0)
evaluate the Poisson LogL given a model function and the data at the point x.
double FN(const double *x) const
unsigned int Size() const
return number of fit points
#define MATH_ERROR_MSG(loc, str)
T EvalLog(T x)
safe evaluation of log(x) with a protections against negative or zero argument to the log smooth line...
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t Int_t m
Documentation for the abstract class IBaseFunctionMultiDim.
void EvaluateChi2Gradient(const IModelFunction &func, const BinData &data, const double *x, double *grad, unsigned int &nPoints, ROOT::Fit::ExecutionPolicy executionPolicy=ROOT::Fit::ExecutionPolicy::kSerial, unsigned nChunks=0)
evaluate the Chi2 gradient given a model function and the data at the point x.
virtual unsigned int NPar() const =0
Return the number of Parameters.
DataOptions : simple structure holding the options on how the data are filled.
double EvaluateChi2Effective(const IModelFunction &func, const BinData &data, const double *x, unsigned int &nPoints)
evaluate the effective Chi2 given a model function and the data at the point x.
LikelihoodAux & operator+=(const LikelihoodAux &l)
unsigned int Size(unsigned int icoord=0) const
return range size for coordinate icoord (starts from zero) Size == 0 indicates no range is present [-...
double EvaluateChi2Residual(const IModelFunction &func, const BinData &data, const double *x, unsigned int ipoint, double *g=0)
evaluate the residual contribution to the Chi2 given a model function and the BinPoint data and if th...
IntegralEvaluator(const ParamFunc &func, const double *p, bool useIntegral=true)
User Class for performing numerical integration of a function in one dimension.
LikelihoodAux operator+(const LikelihoodAux &l) const
const DataOptions & Opt() const
access to options
virtual void ParameterGradient(const T *x, const double *p, T *grad) const
Evaluate the all the derivatives (gradient vector) of the function with respect to the parameters at ...
Class describing the binned data sets : vectors of x coordinates, y values and optionally error on y ...
bool HaveCoordErrors() const
flag to control if data provides error on the coordinates
* x
Deprecated and error prone model selection interface.
ROOT::Math::IParamMultiFunction IModelFunction
ROOT::Math::IGenFunction * fFunc1Dim
static void EvalPoissonLogLGradient(const IModelFunctionTempl< double > &func, const BinData &data, const double *p, double *g, unsigned int &nPoints, ROOT::Fit::ExecutionPolicy executionPolicy=ROOT::Fit::ExecutionPolicy::kSerial, unsigned nChunks=0)
IParamFunction interface (abstract class) describing multi-dimensional parameteric functions It is a ...
virtual void SetParameters(const double *p)=0
Set the parameter values.
const double * ErrorPtr(unsigned int ipoint) const
return error on the value for the given fit point Safe (but slower) method returning correctly the er...
static void EvalLogLGradient(const IModelFunctionTempl< double > &func, const UnBinData &data, const double *p, double *g, unsigned int &nPoints, ROOT::Fit::ExecutionPolicy executionPolicy=ROOT::Fit::ExecutionPolicy::kSerial, unsigned nChunks=0)
double F1(double x) const
double EvaluatePdf(const IModelFunction &func, const UnBinData &data, const double *x, unsigned int ipoint, double *g=0)
evaluate the pdf contribution to the LogL given a model function and the BinPoint data...
static double EvalChi2Effective(const IModelFunctionTempl< double > &func, const BinData &data, const double *p, unsigned int &nPoints)
double EvaluateLogL(const IModelFunction &func, const UnBinData &data, const double *p, int iWeight, bool extended, unsigned int &nPoints, ROOT::Fit::ExecutionPolicy executionPolicy, unsigned nChunks=0)
evaluate the LogL given a model function and the data at the point x.
double SumOfContent() const
compute the total sum of the data content (sum of weights in case of weighted data set) ...
LikelihoodAux(T logv={}, T w={}, T w2={})
User class for performing multidimensional integration.
unsigned int NDim() const
return coordinate data dimension
const DataRange & Range() const
access to range
double Integral(const double *x1, const double *x2)
Double_t Sqrt(Double_t x)
Template class to wrap any member function of a class taking a double and returning a double in a 1D ...
double operator()(const double *x1, const double *x2)
const double * WeightsPtr(unsigned int ipoint) const