1

I have a quadrature class for which I would like to be able to pass any integrand into, regardless of whether the function defining the integrand is a free function or a member function of another class. For the latter case, the best progress I've made is like the following.

Class ChiSquared contains a pointer to the GaussQuadrature class and passes a member function to the GaussQuadrature named Quad like so:

double ChiSquared::LowerIncompleteGammaIntegrand(double x) {
  return pow(x, (5/2.0)-1)*exp(-x);
}    

double ChiSquared::LowerIncompleteGamma(double x) {                               
  Quad->Quadrature(&ChiSquared::LowerIncompleteGammaIntegrand, other args...);
  return Quad->getQuad();
}

In the GaussQuadrature template class, the Quadrature function that accepts this call is

template<typename T>
void GaussQuadrature<T>::
Quadrature(double (ChiSquared::*Integrand)(double), other args...)
{
   T val = Integrand(argument);
   ...
   // other math stuff
}

Firstly, This generates the error

error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘Integrand (...)’, e.g. ‘(... ->* Integrand) (...)’

which makes it seem like I need an instance of ChiSquared in the GaussQuadrature class, not the other way around, and I want to avoid this because:

Secondly, I want to decouple the GaussQuadature class from any other classes, as mentioned before. Ideally, ANY function would be able to be passed in as an "integrand" and so I don't want to have to declare a separate Quadrature function for each possible type of class the "integrand" could come from. Could I use some sort of function template here?

3
  • If you make ChiSquared::LowerIncompleteGammaIntegrand static it will be free (not have a this). Commented Feb 27, 2014 at 22:46
  • alternativly look up lambdas, then you can wrap it in an anonymous function, that can bind this. Commented Feb 27, 2014 at 22:49
  • Or make one of your other args... the pointer to the ChiSquared object on which to do the firing. To do your second requirement would need an overload using a non member function pointer. Commented Feb 27, 2014 at 22:54

2 Answers 2

2

You can try

double ChiSquared::LowerIncompleteGamma(double x) {
    std::function<double(double)> f =
        std::bind( &ChiSquared::LowerIncompleteGammaIntegrand, *this, _1 );
    Quad->Quadrature(f, other args...);
    return Quad->getQuad();
}

where GaussQuadrature is modified to take a function<...> argument, or made into a template:

template<typename T>
template<typename F>
void GaussQuadrature<T>::
Quadrature(const F& Integrand, other args...)
{
   T val = Integrand(argument);
   ...
   // other math stuff
}

Here, std::bind binds the ChiSquared object *this with its method LowerIncompleteGammaIntegrand(), giving a function that takes a double argument and returns a double; then, std::function represents this only with its signature double(double), hiding the underlying type ChiSquared.

By the way, some things are apparently missing, e.g. I can't see where parameter x is used in ChiSquared::LowerIncompleteGamma(), or where argument comes from in GaussQuadrature<T>::Quadrature().

Sign up to request clarification or add additional context in comments.

1 Comment

+1 this is a straight-forward solution to both issues raised, while still allowing ChiSquared the ability to fire-my-member.
0

May be you should omit the other class from the function signature?

template<typename T> void GaussQuadrature<T>::
Quadrature(double (*Integrand)(double), other args...)
{
   T val = Integrand(argument);
   ...
   // other math stuff
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.