Reputation: 2134
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?
Upvotes: 1
Views: 138
Reputation: 7647
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()
.
Upvotes: 2
Reputation: 12573
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
}
Upvotes: 0