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;
146#ifdef USE_STATIC_TMINUIT
187 Error(
"SetFunction",
"Wrong Fit method function type used for Fumili");
201 Error(
"SetFunction",
"Wrong Fit method function type used for Fumili");
209#ifdef USE_FUMILI_FUNCTION
212 fgFunc =
new FumiliFunction<ROOT::Fit::PoissonLikelihoodFCN<ROOT::Math::FitMethodFunction::BaseFunction> >(
fFumili,fcnfunc);
214 fgFunc =
new FumiliFunction<ROOT::Fit::Chi2FCN<ROOT::Math::FitMethodFunction::BaseFunction> >(
fFumili,fcnfunc);
254 unsigned int ndata = 0;
255 unsigned int npar = 0;
257 ndata =
fgFunc->NPoints();
268 std::vector<double> gf(npar);
269 std::vector<double> hess(npar*(npar+1)/2);
270 std::vector<double>
h(npar*(npar+1)/2);
273 for (
unsigned int ipar = 0; ipar < npar; ++ipar)
280 std::cout <<
"=============================================";
281 std::cout <<
"par = ";
282 for (
unsigned int ipar = 0; ipar < npar; ++ipar)
283 std::cout <<
x[ipar] <<
"\t";
284 std::cout << std::endl;
285 if (
fgFunc) std::cout <<
"type " <<
fgFunc->Type() << std::endl;
295 for (
unsigned int i = 0; i < ndata; ++i) {
299 fval =
fgFunc->DataElement(
x, i, &gf[0]);
303 fval =
fgFunc->DataElement(
x, i, gf.data(),
h.data() );
305 fval =
fgGradFunc->DataElement(
x, i, gf.data(),
h.data());
309 sum += 0.5 * fval * fval;
311 for (
unsigned int j = 0; j < npar; ++j) {
312 grad[j] += fval * gf[j];
313 for (
unsigned int k = j; k < npar; ++ k) {
314 int idx = j + k*(k+1)/2;
316 hess[idx] += 0.5 *
h[idx];
329 for (
unsigned int i = 0; i < ndata; ++i) {
332 fval =
fgFunc->DataElement(
x, i, &gf[0]);
337 fval =
fgFunc->DataElement(
x, i, &gf[0],
h.data());
344 for (
unsigned int j = 0; j < npar; ++j) {
346 for (
unsigned int k = j; k < npar; ++ k) {
347 int idx = j + k*(k+1)/2;
357 for (
unsigned int i = 0; i < ndata; ++i) {
360 fval =
fgFunc->DataElement(
x, i, &gf[0]);
364 fval =
fgFunc->DataElement(
x, i, &gf[0]);
370 for (
unsigned int j = 0; j < npar; ++j) {
373 for (
unsigned int k = j; k < npar; ++k) {
374 int idx = j + k * (k + 1) / 2;
375 hess[idx] += gfj * gf[k];
380 Error(
"EvaluateFCN",
" type of fit method is not supported, it must be chi2 or log-likelihood");
385 double * zmatrix =
fgFumili->GetZ();
387 assert(zmatrix !=
nullptr);
388 assert(pl0 !=
nullptr);
391 for (
unsigned int i = 0; i < npar; ++i) {
392 for (
unsigned int j = 0; j <= i; ++j) {
393 if (pl0[i] > 0 && pl0[j] > 0) {
394 zmatrix[
l++] = hess[k];
401 std::cout <<
"FCN value " <<
sum <<
" grad ";
402 for (
unsigned int ipar = 0; ipar < npar; ++ipar)
403 std::cout << grad[ipar] <<
"\t";
404 std::cout << std::endl << std::endl;
419 Error(
"SetVariableValue",
"invalid TFumili pointer. Set function first ");
423 std::cout <<
"set variable " << ivar <<
" " <<
name <<
" value " << val <<
" step " << step << std::endl;
426 int ierr =
fFumili->SetParameter(ivar ,
name.c_str(), val, step, 0., 0. );
428 Error(
"SetVariable",
"Error for parameter %d ",ivar);
437 Error(
"SetVariableValue",
"invalid TFumili pointer. Set function first ");
441 std::cout <<
"set limited variable " << ivar <<
" " <<
name <<
" value " << val <<
" step " << step << std::endl;
443 int ierr =
fFumili->SetParameter(ivar,
name.c_str(), val, step, lower, upper );
445 Error(
"SetLimitedVariable",
"Error for parameter %d ",ivar);
451bool Fumili2Minimizer::SetLowerLimitedVariable(
unsigned int ivar ,
const std::string &
name ,
double val ,
double step ,
double lower ) {
453 double s = val-lower;
454 double upper = s*1.0E15;
455 if (s != 0) upper = 1.0E15;
456 return SetLimitedVariable(ivar,
name, val, step, lower,upper);
464 Error(
"SetVariableValue",
"invalid TFumili pointer. Set function first ");
469 int ierr =
fFumili->SetParameter(ivar,
name.c_str(), val, 0., val, val );
473 std::cout <<
"Fix variable " << ivar <<
" " <<
name <<
" value " << std::endl;
477 Error(
"SetFixedVariable",
"Error for parameter %d ",ivar);
486 Error(
"SetVariableValue",
"invalid TFumili pointer. Set function first ");
490 double oldval, verr, vlow, vhigh = 0;
491 int ierr =
fFumili->GetParameter( ivar, &
name[0], oldval, verr, vlow, vhigh);
493 Error(
"SetVariableValue",
"Error for parameter %d ",ivar);
497 std::cout <<
"set variable " << ivar <<
" " <<
name <<
" value "
498 << val <<
" step " << verr << std::endl;
501 ierr =
fFumili->SetParameter(ivar ,
name , val, verr, vlow, vhigh );
503 Error(
"SetVariableValue",
"Error for parameter %d ",ivar);
516 Error(
"SetVariableValue",
"invalid TFumili pointer. Set function first ");
537 fFumili->ExecuteCommand(
"SET NOW",arglist,0);
539 fFumili->ExecuteCommand(
"SET WAR",arglist,0);
542 fFumili->ExecuteCommand(
"SET NOD",arglist,0);
544 fFumili->ExecuteCommand(
"SET DEB",arglist,0);
552 std::cout <<
"Minimize using TFumili with tolerance = " <<
Tolerance()
555 int iret =
fFumili->ExecuteCommand(
"MIGRAD",arglist,2);
582 assert (
static_cast<unsigned int>(ntot) ==
fDim);
583 assert( nfree ==
fFumili->GetNumberFreeParameters() );
592 const double * cv =
fFumili->GetCovarianceMatrix();
594 for (
unsigned int i = 0; i <
fDim; ++i) {
599 for (
unsigned int j = 0; j <=i ; ++j) {
609 return (iret==0) ? true :
false;
Error("WriteTObject","The current directory (%s) is not associated with a file. The object (%s) has not been written.", GetName(), objname)
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
int PrintLevel() const
Set print level.
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
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)