Getting parameter values between iterations (Minuit2)


HI All,

I am fitting a function to data using minuit2, I define my parameters using ROOT::Minuit2::MnUserParameters mnPars; then for the fitting process I use ROOT::Minuit2::MnMigrad, The fitter works perfectly fine, but I’ve had a really bad time getting my parameters printed between iterations(I want to see how my parameters are changing until the fitter finds the best fit values!). For this I have set the level of verbosity like this ROOT::Minuit2::MnPrint::SetLevel(3); and the only output I got is the following:

MnSeedGenerator: for initial parameters FCN = 0.0003300328819113 MnSeedGenerator: Initial state:   - FCN = 0.0003300328819113 Edm = 0.000344345  NCalls = 11
VariableMetric: start iterating until Edm is < 0.0002
VariableMetric: Initial state   - FCN = 0.0003300328819113 Edm = 0.000344345  NCalls = 11
VariableMetric: Iteration # 0   - FCN = 0.0003300328819113 Edm = 0.000344345  NCalls = 11
VariableMetric: Iteration # 1   - FCN = 2.463992588027e-05 Edm = 2.2635e-05   NCalls = 17
VariableMetric: After Hessian   - FCN = 2.463992588027e-05 Edm = 2.46442e-05  NCalls = 27
VariableMetric: Iteration # 2   - FCN = 2.463992588027e-05 Edm = 2.46442e-05  NCalls = 27
Minuit did successfully converge.

Is there a way to do this?

Best,

David.


Hi,

The parameter values are not printed, because there can be a lot of them and also because inside Minuit is updating the internal value and this could be confusing when parameters have bounds

The way to get this information is via using the class MnTraceObject of Minuit2.
You need to create a derived class of MnTraceObject.h (see https://root.cern.ch/doc/master/classROOT_1_1Minuit2_1_1MnTraceObject.html) and call
`MnMigrad.Minimizer().Builder().SetTraceObject(your_trace_object) to enabled that functionality.

In your derived class of MnTraceObject you need to re-implement the operator() function, for example as this :

void MyTraceObject::operator() ( int iter, const MinimumState & state) { 
   std::cout << "iteration " << inter << " parameters vector " << state.Vec() << std::endl;
}

and this function is called at each iteration of the minimizer. If you need to access the external parameter values, you would need to set in the TraceObject the corresponding MnUserParameterState object, by calling the MnTraceObject::Init function.
You can see a more detailed example how this works in the implementation of the class TMinuit2TraceObject:

https://root.cern.ch/doc/master/TMinuit2TraceObject_8cxx_source.html

If you have questions, please let me know

Cheers

Lorenzo

@moneta Thank you so much for your prompt response and your useful suggestions!, I have been looking into this, and have a problem with the implementation of MnMigrad.Minimizer().Builder().SetTraceObject(your_trace_object). please see here is the part where I’m implementing this:

ROOT::Minuit2::MnTraceObject traceObj();  
ROOT::Minuit2::MnMigrad  mn(*((ROOT::Minuit2::FCNBase *) this), mnPars, int(fPrec));
mn.Minimizer().Builder().SetTraceObject(traceObj);

(I have been doing this directly with MnTraceObject before implement a derived class, this to make sure and check this works). This is the error I got doing the above :

error: passing ‘const ROOT::Minuit2::MinimumBuilder’ as ‘this’ argument discards qualifiers [-fpermissive]
mn.Minimizer().Builder().SetTraceObject(traceObj);
note:   initializing argument 1 of ‘virtual void ROOT::Minuit2::MinimumBuilder::SetTraceObject(ROOT::Minuit2::MnTraceObject&)’
virtual void SetTraceObject(MnTraceObject & obj) {

I also tried defining the trace object like this ROOT::Minuit2::MnTraceObject &traceObj(); and obtained the same error.
Is there anything I’m missing here, does something needs to be set as constant?.

Thanks,

David

Hi,
Strage yu are getting this error, since there exists non const version of the Minimizer() and Builder() funcitons.
Try this:

ROOT::Minuit2::MnTraceObject traceObj(); 
ROOT::Minuit2::MnMigrad  mn(*((ROOT::Minuit2::FCNBase *) this), mnPars, int(fPrec));
ROOT::Minuit2::ModularFunctionMinimizer& minimizer minim = mn.Minimizer(); 
ROOT::Minuit2::MinimumBuilder & builder  = minim.Builder(); 
builder.SetTraceObject(traceObj);

Lorenzo