35#ifdef USE_FUMILI_FUNCTION
46template<
class MethodFunc>
57 fObjFunc =
dynamic_cast<const MethodFunc *
>(func);
58 assert(fObjFunc != 0);
62 fFumili->SetUserFunc(fModFunc);
67 FumiliFunction *
Clone()
const {
return new FumiliFunction(fFumili, fObjFunc); }
71 double DataElement(
const double * ,
unsigned int i,
double *
g,
double *)
const {
76 unsigned int npar = fObjFunc->NDim();
79 const double *
x = fObjFunc->Data().GetPoint(
i,
y,invError);
80 double fval = fFumili->EvalTFN(
g,
const_cast<double *
>(
x));
81 fFumili->Derivatives(
g,
const_cast<double *
>(
x));
85 for (
unsigned int k = 0; k < npar; ++k) {
86 g[k] *= (
y/fval - 1.) ;
92 double resVal = (
y-fval)*invError;
93 for (
unsigned int k = 0; k < npar; ++k) {
105 double DoEval(
const double *
x )
const {
106 return (*fObjFunc)(
x);
110 const MethodFunc * fObjFunc;
147#ifdef USE_STATIC_TMINUIT
175 if (
this == &rhs)
return *
this;
201 Error(
"SetFunction",
"Wrong Fit method function type used for Fumili");
215 Error(
"SetFunction",
"Wrong Fit method function type used for Fumili");
223#ifdef USE_FUMILI_FUNCTION
226 fgFunc =
new FumiliFunction<ROOT::Fit::PoissonLikelihoodFCN<ROOT::Math::FitMethodFunction::BaseFunction> >(
fFumili,fcnfunc);
228 fgFunc =
new FumiliFunction<ROOT::Fit::Chi2FCN<ROOT::Math::FitMethodFunction::BaseFunction> >(
fFumili,fcnfunc);
268 unsigned int ndata = 0;
269 unsigned int npar = 0;
271 ndata =
fgFunc->NPoints();
282 std::vector<double> gf(npar);
283 std::vector<double> hess(npar*(npar+1)/2);
284 std::vector<double>
h(npar*(npar+1)/2);
287 for (
unsigned int ipar = 0; ipar < npar; ++ipar)
294 std::cout <<
"=============================================";
295 std::cout <<
"par = ";
296 for (
unsigned int ipar = 0; ipar < npar; ++ipar)
297 std::cout <<
x[ipar] <<
"\t";
298 std::cout << std::endl;
299 if (
fgFunc) std::cout <<
"type " <<
fgFunc->Type() << std::endl;
309 for (
unsigned int i = 0;
i < ndata; ++
i) {
313 fval =
fgFunc->DataElement(
x,
i, &gf[0]);
317 fval =
fgFunc->DataElement(
x,
i, gf.data(),
h.data() );
323 sum += 0.5 * fval * fval;
325 for (
unsigned int j = 0; j < npar; ++j) {
326 grad[j] += fval * gf[j];
327 for (
unsigned int k = j; k < npar; ++ k) {
328 int idx = j + k*(k+1)/2;
330 hess[idx] += 0.5 *
h[idx];
343 for (
unsigned int i = 0;
i < ndata; ++
i) {
346 fval =
fgFunc->DataElement(
x,
i, &gf[0]);
351 fval =
fgFunc->DataElement(
x,
i, &gf[0],
h.data());
358 for (
unsigned int j = 0; j < npar; ++j) {
360 for (
unsigned int k = j; k < npar; ++ k) {
361 int idx = j + k*(k+1)/2;
371 for (
unsigned int i = 0;
i < ndata; ++
i) {
374 fval =
fgFunc->DataElement(
x,
i, &gf[0]);
378 fval =
fgFunc->DataElement(
x,
i, &gf[0]);
384 for (
unsigned int j = 0; j < npar; ++j) {
387 for (
unsigned int k = j; k < npar; ++k) {
388 int idx = j + k * (k + 1) / 2;
389 hess[idx] += gfj * gf[k];
394 Error(
"EvaluateFCN",
" type of fit method is not supported, it must be chi2 or log-likelihood");
399 double * zmatrix =
fgFumili->GetZ();
401 assert(zmatrix !=
nullptr);
402 assert(pl0 !=
nullptr);
405 for (
unsigned int i = 0;
i < npar; ++
i) {
406 for (
unsigned int j = 0; j <=
i; ++j) {
407 if (pl0[
i] > 0 && pl0[j] > 0) {
408 zmatrix[
l++] = hess[k];
415 std::cout <<
"FCN value " <<
sum <<
" grad ";
416 for (
unsigned int ipar = 0; ipar < npar; ++ipar)
417 std::cout << grad[ipar] <<
"\t";
418 std::cout << std::endl << std::endl;
431 Error(
"SetVariableValue",
"invalid TFumili pointer. Set function first ");
435 std::cout <<
"set variable " << ivar <<
" " <<
name <<
" value " << val <<
" step " << step << std::endl;
438 int ierr =
fFumili->SetParameter(ivar ,
name.c_str(), val, step, 0., 0. );
440 Error(
"SetVariable",
"Error for parameter %d ",ivar);
449 Error(
"SetVariableValue",
"invalid TFumili pointer. Set function first ");
453 std::cout <<
"set limited variable " << ivar <<
" " <<
name <<
" value " << val <<
" step " << step << std::endl;
455 int ierr =
fFumili->SetParameter(ivar,
name.c_str(), val, step, lower, upper );
457 Error(
"SetLimitedVariable",
"Error for parameter %d ",ivar);
463bool Fumili2Minimizer::SetLowerLimitedVariable(
unsigned int ivar ,
const std::string &
name ,
double val ,
double step ,
double lower ) {
465 double s = val-lower;
466 double upper = s*1.0E15;
467 if (s != 0) upper = 1.0E15;
468 return SetLimitedVariable(ivar,
name, val, step, lower,upper);
476 Error(
"SetVariableValue",
"invalid TFumili pointer. Set function first ");
481 int ierr =
fFumili->SetParameter(ivar,
name.c_str(), val, 0., val, val );
485 std::cout <<
"Fix variable " << ivar <<
" " <<
name <<
" value " << std::endl;
489 Error(
"SetFixedVariable",
"Error for parameter %d ",ivar);
498 Error(
"SetVariableValue",
"invalid TFumili pointer. Set function first ");
502 double oldval, verr, vlow, vhigh = 0;
503 int ierr =
fFumili->GetParameter( ivar, &
name[0], oldval, verr, vlow, vhigh);
505 Error(
"SetVariableValue",
"Error for parameter %d ",ivar);
509 std::cout <<
"set variable " << ivar <<
" " <<
name <<
" value "
510 << val <<
" step " << verr << std::endl;
513 ierr =
fFumili->SetParameter(ivar ,
name , val, verr, vlow, vhigh );
515 Error(
"SetVariableValue",
"Error for parameter %d ",ivar);
528 Error(
"SetVariableValue",
"invalid TFumili pointer. Set function first ");
548 if (printlevel == 0)
fFumili->ExecuteCommand(
"SET NOW",arglist,0);
549 else fFumili->ExecuteCommand(
"SET WAR",arglist,0);
558 std::cout <<
"Minimize using TFumili with tolerance = " <<
Tolerance()
561 int iret =
fFumili->ExecuteCommand(
"MIGRAD",arglist,2);
585 assert (
static_cast<unsigned int>(ntot) ==
fDim);
586 assert( nfree ==
fFumili->GetNumberFreeParameters() );
595 const double * cv =
fFumili->GetCovarianceMatrix();
597 for (
unsigned int i = 0;
i <
fDim; ++
i) {
602 for (
unsigned int j = 0; j <=
i ; ++j) {
612 return (iret==0) ?
true :
false;
true
Register systematic variations for multiple existing columns using auto-generated tags.
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
virtual Type_t Type() const
virtual double DataElement(const double *x, unsigned int i, double *g=nullptr, double *h=nullptr, bool fullHessian=false) const=0
ROOT::Math::IMultiGenFunction::BaseFunc BaseFunction
virtual IBaseFunctionMultiDimTempl< double > * Clone() const=0
virtual bool HasGradient() const
virtual unsigned int NDim() const =0
Retrieve the dimension of the function.
virtual double DoEval(const double *x) const=0
double Tolerance() const
absolute tolerance
unsigned int MaxFunctionCalls() const
max number of function calls
int fStatus
status of minimizer
Minimizer()
Default constructor.
int PrintLevel() const
minimizer configuration parameters
TFumiliMinimizer class: minimizer implementation based on TFumili.
static ROOT::Math::FitMethodFunction * fgFunc
bool SetFixedVariable(unsigned int, const std::string &, double) override
set fixed variable (override if minimizer supports them )
TFumiliMinimizer(int dummy=0)
Default constructor (an argument is needed by plug-in manager)
std::vector< double > fParams
bool SetLimitedVariable(unsigned int ivar, const std::string &name, double val, double step, double, double) override
set upper/lower limited variable (override if minimizer supports them )
static double EvaluateFCN(const double *x, double *g)
implementation of FCN for Fumili when user provided gradient is used
~TFumiliMinimizer() override
Destructor (no operations)
bool Minimize() override
method to perform the minimization
static ROOT::Math::FitMethodGradFunction * fgGradFunc
TFumiliMinimizer & operator=(const TFumiliMinimizer &rhs)
Assignment operator.
static TFumili * fgFumili
bool SetVariableValue(unsigned int ivar, double val) override
set the value of an existing variable
std::vector< double > fErrors
std::vector< double > fCovar
void SetFunction(const ROOT::Math::IMultiGenFunction &func) override
set the function to minimize
bool SetVariable(unsigned int ivar, const std::string &name, double val, double step) override
set free variable
static void Fcn(int &, double *, double &f, double *, int)
implementation of FCN for Fumili
T EvalLog(T x)
safe evaluation of log(x) with a protections against negative or zero argument to the log smooth line...
IMultiGenFunctionTempl< double > IMultiGenFunction
BasicFitMethodFunction< ROOT::Math::IMultiGenFunction > FitMethodFunction
ParamFunctorTempl< double > ParamFunctor
BasicFitMethodFunction< ROOT::Math::IMultiGradFunction > FitMethodGradFunction
static uint64_t sum(uint64_t i)