passing pointer function to lfit within class


davidmontgom
01-05-2007, 03:49 PM
Hello,

I have the following class

class ARIMA{

private:

void ARIMA::arma_funcs(const DP x, Vec_O_DP &afunc);
void ARIMA::RunArima();
}

ARIMA::RunArima()
{

lfit(xxxxxx,ARIMA::arma_funcs);

}
ARIMA::arma_funcs(const DP x, Vec_O_DP &afunc)
{
//Do Something
}

How do I pass the the arma_funcs to the lfit function? Doing like I did it obviously does not work.

Please help.

Thanks

Bill Press
01-06-2007, 02:17 PM
If I understand correctly, you want to pass a pointer to a member function to lfit. This is actually not easy. See
here (http://www.parashift.com/c++-faq-lite/pointers-to-members.html) for example.

A workaround is to define a little global function that makes an instance of your class and then uses your member function internally. Pass the global function name to lfit.

HTH

davidmontgom
01-06-2007, 04:57 PM
I have tried many many many ways to try and implement functors etc....to no avail.

I have to pass other arrays to my function routine and I cant make everything that depends on it global. I have no choice but to use some means of passing a pointer to a member function from within a class.

Doing this stuff is very advanced C++ programming. I highly recomend that some NR guru write a wrapper to be able to handle these types of situations and post it on the NR site.

Thanks

Kevin Dolan
03-09-2007, 05:28 AM
This might work.

Add a static variable to your ARIMA class. This variable will be a pointer to an instance of ARIMA. Note that you will need to do a forward declaration of ARIMA for this to work.

Next, make your "arma_funcs" function a static member function of ARIMA. Static member functions can be passed as pointers just like normal functions.

Finally, within that static function you access any data members of the ARIMA class you need through the pointer.

Then all you have to do is set the pointer before you make the function call. In effect, the pointer refers to the "active" instance of the ARIMA class.

You can even make the static member function use the pointer to call the normal member function you already wrote.

The code would look something like this:

class ARIMA; // Forward Declaration

class ARIMA{

public:
ARIMA *ptr;
static void arma_funcs_wrapper(const DP x, Vec_O_DP &afunc);
private:

void arma_funcs(const DP x, Vec_O_DP &afunc);
void RunArima();
};

ARIMA::RunArima()
{
lfit(xxxxxx,ARIMA::arma_funcs_wrapper);
}
ARIMA::arma_funcs_wrapper(const DP x, Vec_O_DP &afunc)
{
ARIMA::ptr->arma_funcs(x, afunc);
}
ARIMA::arma_funcs(const DP x, Vec_O_DP &afunc)
{
//Do Something
}


Then after you create your ARIMA object, but before you call the RunArima() member function on it, set ARIMA::ptr to be the address of that object. In fact, you could alter the RunArima function to do this itself.

ARIMA::RunArima()
{
ARIMA::ptr = this;
lfit(xxxxxx,ARIMA::arma_funcs_wrapper);
}

Now everything is completely transparent.


Kevin

jakob
07-14-2007, 11:59 AM
I haven't tried your particle code-example, but have you tried chaning the RunArima() implementatino to the following:
ARIMA::RunArima()
{
lfit(xxxxxx, &ARIMA::arma_funcs);
}

(ie: explicitly add the &-operator?) This should work. You could call it a bug in C++, or an inconsistency or whatever, but the trick to remember is that in C++ you always MUST explicitly use the address-of-operator when you want to address a memberfunction.