Fumili Objective Function

Hello,

I am using ROOT Version 5.19/03
On a CentOS 5 machine.

I am having trouble changing the Objective Function for Fumili minimization.
I have checked the examples in the tutorials such as minuit2FitBench.C, but I can’t find an example of changing the objective function.

Essentially, I am trying to do what the comment says on line 133 of FumiliChi2FCN.h
"Calculates the sum of Elements squared, ie the chi-square. The user must
implement in a class which inherits from FumiliChi2FCN the member function
Elements() which will supply the Elements for the sum."

I am compiling using -lMinuit2 -lFumili and it compiles with no errors.

I have copied FumiliStandardChi2FCN.c and FumiliStandardChi2FCN.h to my working directory and renamed them to
MyFumiliStandardChi2FCN.c
MyFumiliStandardChi2FCN.h

I have copied GaussianModelFunction.h to my working directory and changed it to
MyModelFunction.h

//—CASE 1: The Following works--------------------------------
TGraphErrors* mygraph =new TGraphErrors(1000,x,y,ex,ey);
TF1 fit = new TF1(“fit”,fpeaksnumerical,fitrangelower,fitrangeupper,3+2npeaks);
//TVirtualFitter::SetDefaultFitter(“Fumili2”);
TVirtualFitter::SetDefaultFitter(“Fumili”);
TVirtualFitter::Fitter(mygraph,10+2*npeaks);
fit-> Set and Fix parameters …

int fitResult = mygraph->Fit(“fit”,“NBR”);
//------------------------------------------------------

//—CASE 2: The following does NOT work------------------------
#include “MyFumiliStandardChi2FCN.h”
#include “MyModelFunction.h”

TGraphErrors* mygraph =new TGraphErrors(1000,x,y,ex,ey);
TF1 fit = new TF1(“fit”,fpeaksnumerical,fitrangelower,fitrangeupper,3+2npeaks);
//TVirtualFitter::SetDefaultFitter(“Fumili2”);
TVirtualFitter::SetDefaultFitter(“Fumili”);
TVirtualFitter::Fitter(mygraph,10+2*npeaks);

std::vector params(9);
ROOT::Minuit2::MyModelFunction *modelfunc = new ROOT::Minuit2::MyModelFunction(params);
std::vector meas(1000);
std::vector pos(1000);
std::vector mvar(1000);
for (int i=0;i<1000;i++){
pos[i] = x[i];
meas[i] = y[i];
mvar[i] = ey[i];
}
ROOT::Minuit2::MyFumiliStandardChi2FCN *myObjective = new ROOT::Minuit2::MyFumiliStandardChi2FCN(*modelfunc,meas,pos,mvar);
TVirtualFitter::Fitter(mygraph)->SetFCN(myObjective);

TVirtualFitter::Fitter(mygraph)->SetUserFunc((TObject*)modelfunc);
//TVirtualFitter::Fitter(ourTGTwaveform)->SetUserFunc(fit);

int fitResult = mygraph->Fit(“fit”,“NBRU”);
//------------------------------------------------------

//===CASE 3: This does NOT work===============================
I found in older versions of ROOT, a function called GraphFitChisquareFumili.
I copied and pasted this into my program:

extern void GraphFitChisquareFumiliModified(Int_t &npar, Double_t * gin, Double_t &f,
Double_t *u, Int_t flag);
//______________________________________________________________________________
void GraphFitChisquareFumiliModified(Int_t &npar, Double_t * gin, Double_t &f,
Double_t *u, Int_t flag)
{
same as original
}

same as CASE 1, but with:
TVirtualFitter::Fitter(mygraph)->SetFCN(GraphFitChisquareFumiliModified);
and
int fitResult = mygraph->Fit(“fit”,“NBRU”);

This one compiles, but fails with Segmentation Violation at runtime:

//============================================================

Question 1:

When using SetDefaultFitter(“Fumili2”) in CASE 2 I get the following error:
Error in : FumiliMinimizer: Error : wrong FCN type. Try to use default minimizer

How can this be, since myObjective is of a class which is a copy and paste of FumiliStandardChi2FCN.

Question 2:

To test if the new objective function is called, I uncommented line 48 in MyFumiliStandardChi2FCN.c
and changed this->getModelFunction() to this->ModelFunction()

std::cout << "element " << i << " " << (*(this->ModelFunction()))(par, currentPosition) << " " << fMeasurements[i] << " " << result[i] << std::endl;

But nothing is printed to the terminal.

I used:
->SetFCN(myObjective)
and
->Fit(“fit”,“U”);
and I’ve tried the calls to
->SetUserFunc(…)
shown above.

How do I get my fitter (Fumili) to use my user specified objective function?

Thanks,
Anthony

Hi,

can you move to use the latest version of ROOT 5.22 ?
Few things have been changed concerning fitting and it will easier helping you.

What do you want to do ? A standard chi2 fit to a set of data points or do you need to write a customize chi2 function ?

Regards

Lorenzo

Yes, I would like to write a customized chi2 function, and use FUMILI, not MINUIT.

Can you point me to an example in some documentation online?
Or provide a short example if one doesn’t exist?

Hi,

for using Fumili, ( via TFumili or the new Fumili2) with a custumized objective function, you should make your chi2 function deriving from the
ROOT::Math::FitMethodFunction interface:

root.cern.ch/root/htmldoc/ROOT__ … iDim_.html

you need basically to implement the following abstract methods

double DoEval(const double *x)  const 

impelmenting the evaluation of the function

double	DataElement(const double* x, unsigned int i, double* g = 0) const

calculating the single chi2 contribution and its derivative.
Im addition you should also implement the Clone method and Type() method by returning kLeastSquare.

After that you can use directly the ROOT::Math::Minimizer interface for minimizing your chi2 function.
See root.cern.ch/root/htmldoc/ROOT__ … mizer.html
You should set your own chi2 function in the SetFunction method.

An example of using this Minimizer interface is in this program (but it uses Minuit).
root.cern.ch/viewvc/trunk/math/m … tMinim.cxx

I can make an example with Fumili when I’ll back in the office after the vacation.

Best Regards

Lorenzo

Attached is an example of performing a chi2 fit using FUmili witha user provided chi2 function.

Best Regards

Lorenzo
exampleFumili.C (4.32 KB)

Thank you very much, this is exactly what I needed.

I have another question:

How can I now switch back to the default Fumili CHI Squared objective function, kLeastSquare.

In your example (lines 120 and 128) you have:

// create the chi2 function
MyChi2Function chi2(ndata, f1, x, y, ey);

// set minimizer function (chi2)
// for minuit it needs to be set before setting the variables
min->SetFunction(chi2);

What can I do to get the original back again for comparison?

I tried something like:

// create the chi2 function
FumiliFunction myFumiliFunc(…);

// set minimizer function (chi2)
// for minuit it needs to be set before setting the variables
min->SetFunction(myFumiliFunc);

Was “FumiliFunc” removed from version 5.22 ?

Hi,

if I have understood you well, you want to try using the default chi2 function used for example in fitting the histogram.

This is possible, by using the class ROOT::Fit::Chi2Function , I add this example in the buttom of the previous one, see the attached file

Best Regards

Lorenzo
exampleFumili2.C (5.22 KB)