Re: Re: Using Minuit(2) with objects and member methods

From: Christian Holm Christensen <cholm_at_nbi.dk>
Date: Thu, 11 Feb 2010 15:40:04 +0100


hi,

On Thu, 2010-02-11 at 13:48 +0100, Robert Riemann wrote:
> Is there really nobody, who have worked with TMinuit2 already?
>
> 2010/2/4 Robert Riemann <robert.riemann_at_desy.de>:
> > Hi Rooters,
> >
> > I would like to integrate minuit with my object.
> >
> > When creating a TMinuit I get an error: no matching function for call
> > to `TMinuit::SetFCN(<unresolved overloaded function type>)'.
> >
> > I read that there is a Minuit2 which allows the usage in objects, but
> > I cannot find an example. Can someone send me a short piece of code
> > with Minuit2?

You really shouldn't use the TMinuit nor the TMinuit2 interface directly. Instead, use the virtual interface defined by TVirtualFitter.

OK, so to fit some function to some data in a class, you need to make a trampoline function. Suppose you have a (base) class called VirtualDataSet.

        class VirtualDataSet : public TObject 
        {
        public:
           void Fit() 
           {
        TVirtualFitter* fitter = TVirtualFitter::GetFitter();
             fitter->SetObjectFit(this);
             fitter->ExecuteCommand("...");
           }
           virtual void     StartFit(Int_t npar, Double_t* par);
           virtual Double_t EvalMinimizedFunction(int npar, Double_t* par) = 0;
           virtual void     EvalMinimizedGradient(int npar, Double_t* par, Double_t* ret) = 0;
           virtual void     FinishFit(Int_t npar, Double_t* par);
        protected:
           Int_t Eval(Int_t     npar, 
        	      Double_t* grad,
                      Double_t& fval,
                      Double_t* par,
        	      Int_t     flag)
           {
               if (flag == 1) StartFit(npar, par);
               if (flag == 2) EvalMinimizedGradient(npar, par, grad);
               fval = EvalMinimizedFunction(npar, par);
               if (flag == 3) FinishFit(npar, par);
               return 0;
           }
           friend Int_t TrambolineFunc(Int_t     npar, 
        	                       Double_t* grad,
                                       Double_t& fval,
                                       Double_t* par,
        	                       Int_t     flag);
        };

Next, we need to define the tramboline

        Int_t TrambolineFunc(Int_t     npar, 
                	     Double_t* grad,
                             Double_t& fval,
                             Double_t* par,
                	     Int_t     flag)
        {
           TVirtualFitter* fitter = TVirtualFitter::GetFitter();
           TObject*        object = fitter->GetObjectFit();
           VirtualDataSet* data   = static_cast<VirtualDataSet*>(object);
           return data->Eval(npar, grad, fval, par, flat);
        }
        

Note, as is evident from the above, the fitter is a singleton - that is, there's only one such object. This effectively means that you can never perform more than 1 fit at a time.

Suppose you now have a class deriving from VirtualDataSet

        class DataSet : public VirtualDataSet
        {
        public:
          DataSet(std::istream& input) { ... }
          virtual void     StartFit(Int_t, Double_t*) { }
          virtual Double_t EvalMinimizedFunction(int npar, Double_t* par) 
          {
              Double_t f = 0;
              Int_t    nData = GetSampleSize();
              for (Int_t i = 0; i < nData; i++) {
                 Double_t fx = fFunc->EvalPar(GetDataPointX(i), par);
                 Double_t ei = GetDataPointYError(i);
                 Double_t yi = GetDataPointY(i); 
                 f +=          (fx - yi) / ei;
              }
              return f;
          }
          virtual void     EvalMinimizedGradient(int npar, Double_t* par, Double_t* ret) { }
          virtual void     FinishFit(Int_t npar, Double_t* par) {}
        protected:
          TF1* fFunc;
        };
        ...
        
        
        SomeFunc() {
           DataPoint d(std::cin);
           d.Fit();
        }
        

Note, that the above works no-matter which fitter you're using.

Yours,

-- 
 ___  |  Christian Holm Christensen 
  |_| |  -------------------------------------------------------------
    | |  Address: Sankt Hansgade 23, 4    Phone:     (+45) 35 35 96 91
     _|           DK-2200 Copenhagen N    Cell:      (+45) 24 61 85 91
    _|            Denmark                 Office:    (+45) 353  25 447
 ____|   Email:   cholm@nbi.dk            Web:    http://cern.ch/cholm
 | |
Received on Thu Feb 11 2010 - 15:40:16 CET

This archive was generated by hypermail 2.2.0 : Thu Feb 11 2010 - 17:50:01 CET