Re: TMinuit.SetFCN() casting in a class

Patrick Decowski (decowski@mit.edu)
Sun, 13 Dec 1998 11:37:54 -0500 (EST)


hi stephen,

you are stumbling into the problem that C++ treats functions to
members (a pointer-to-member) differently than functions to real (C)
functions. there is a way around it, in your code you need to wrap the
code in a "real" function pointer.

you could do the following as an example:

------------TMyClass.cxx----
// a global; will point to the object that wants to do the fitting
TMyClass* gThisIsWrappedThis = NULL;

extern "C" CWrapFit(Double*x, Double_t *par); // the "real" funtion

Double_t CWrapFit(Double_t *x, Double_t *par)
{
Double_t FitResult;
// use the global variable to access the object.
FitResult = gThisIsWrappedThis->Fit(x, par);
// free global, so that other objects
//can use it.
gThisIsWrappedThis = NULL;

return FitResult;
}

Double_t TPhMyClass::Fit(....) { .... }

void TPhMyClass:SetupFit()
{
// assign pointer to this object to the global variable
// first make sure that no other instant of the same class is trying
// to fit - that is the price you pay for using globals.
if(gThisIsWrappedThis == NULL)
gThisIsWrappedThis = this;
else
printf("Can't assign 'this' - other object trying to fit\n");

}

you will have to call SetupFit() before fitting and you will have
to call CWrapFit as the fit function instead of TPhMyClass::Fit. note
that you will need to add this line to your LinkDef.h:

#pragma link C function CWrapFit;

so that if you can assign CWrapFit to SetFCN in a macro (if that is
where you assign it).

hope this helps somewhat,

patrick.

On Sat, 12 Dec 1998, Stephen Bailey wrote:

>
> Hi.
>
> I'm trying to use TMinuit and am having problems with the
> casting of my minimization function for SetFCN(). A snippet
> of my code is:
>
> void (*pf)(Int_t&, Double_t*, Double_t&, Double_t*, Int_t);
> pf = MinusLogLikelihood;
> gMinuit->SetFCN(pf);
>
> MinusLogLikelihood is a member function of the class DataSet
> which contains the fitting routine from which this code comes.
> My compiler (KAI KCC 3.3e) complains
>
> KCC -g +K0 -O0 --no_exceptions -fPIC
> -I/usr/products/root/v2_00_13b/include -c DataSet.cc -o DataSet.o
> "DataSet.cc", line 67: error: a value of type "void (DataSet::*)(Int_t &,
> Double_t *, Double_t &, Double_t *, Int_t)" cannot be assigned
> to an
> entity of type
> "void (*)(Int_t &, Double_t *, Double_t &, Double_t *, Int_t)"
> pf = MinusLogLikelihood;
> ^
>
> If I make MinusLogLikelihood a regular function not belonging to
> any class, these statements compile fine, but then MinusLogLikelihood
> no longer has any access to the data in my DataSet object. Even if
> I provided public access functions, it still wouldn't know which DataSet
> object to use. The example in the tutorial relies upon the data to be
> fit being global. Can this be avoided? Does anyone have experience using
> TMinuit from within the context of a class structure with data belonging
> to objects? I also tried using SetFCN(void *) and the compiler was
> similarly unhappy about my casting.
>
> Thanks.
>
> Stephen
>
>
>
>
>

-------------------------------------------o-------------------------------
Patrick Decowski |
24-504 | Home: (617)625-9352
Massachusetts Institute of Technology | Office: (617)253-9735
77 Massachusetts Ave | Fax: (617)253-1755
Cambridge, MA 02139-4307 |
-------------------------------------------o-------------------------------
http://web.mit.edu/decowski/www/home.html | e-mail: decowski@mit.edu
-------------------------------------------o-------------------------------