How to implement custom gradient calculation procedure in TVirtualFitter?

Hello,
I cannot find any tutorials with custom (provided by user) gradient calculation procedure for Minuit or Minuit2. When I try to make very simple test procedure like

void FCN(Int_t&npar, Double_t*gin, Double_t&f, Double_t*par, Int_t flag)
{// select case using flag
	switch(flag)
	{
		case 1: 
			// Initialization
			cout<<"case1\n";
		break;
		case 2:
			cout<<"case2\n";
			gin[0]=2*par[0]-8;
			// Compute derivatives   
			// store them in gin
		break;
		case 3:    
			cout<<"case3\n";
		break;
		default:
		cout<<"flag:"<<flag<<"\n";
		f=pow(par[0],2)-8*par[0]+4;
		cout<<f<<"\n";
		break;
	}
}
void test()
{
        TVirtualFitter::SetDefaultFitter("Minuit");
	TVirtualFitter * minuit = TVirtualFitter::Fitter(0,1);
	minuit->SetParameter(0,"x",0,0.01,0,0);
	minuit->SetFCN(FCN);
	
	double arglist[100];
	arglist[0] = 0;
	// set print level
	minuit->ExecuteCommand("SET PRINT",arglist,2);

	// minimize
	arglist[0] = 5000; // number of function calls
	arglist[1] = 0.01; // tolerance
	minuit->ExecuteCommand("MIGRAD",arglist,2);
}

Minuit always sets flag=4, so custom derivative procedure never used.

_ROOT Version:_6.20/04
Platform: x86-x64
_Compiler:_g++


@moneta Do you have a suggestion?

I think I has found a solution for Minuit, an additional command is needed:

double GrPar[]={1};
minuit->ExecuteCommand("SET GRA",GrPar,1);

where value in the GrPar is defined according to conditions:
If GrPar[0]==0, Minuit will check the user-defined gradient by numerical calculation before use it;
if GrPar[0]==1, Minuit will use the user-defined derivatives without any checks.

Anyway, it would be interesting how to do similar trick with other minimizers.

Hi,
For minimizers that supports it, you can provide custom gradient calculation when fitting. This is the case for example when Automatic differentiation is used when fitting an histogram with a function expressed by a formula.
The ROOT::Math::Minimizer interface supports it, by simply providing the right function interface to the minimizer. You need to call the right SetFunction method, see
ROOT: ROOT::Math::Minimizer Class Reference.

Lorenzo

Thank you!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.