I'm using the Gnu Scientific Library to implement a module in my program that computes integrals numerically. The functions are based on the example that can be found on the GSL website in Numerical integration examples:
and here's my code (most of it is the same as in the example):
typedef map<float, float> SignalData;
double f (double x, void * params) {
SignalData * alpha = static_cast<SignalData *>(params);
double f = InterpolatorGSL::interpolatedValueForTime(alpha, x);
return f;
}
float IntegrationComparator::integral(SignalData * signalData){
gsl_integration_workspace * w = gsl_integration_workspace_alloc (100000);
double result, error;
double expected = -4.0;
SignalData * alpha = signalData;
gsl_function F;
F.function = &f;
F.params = α
gsl_integration_qags (&F, -3.36e-08, -2.36e-08 , 0, 1e-7, 100000,
w, &result, &error);
printf ("result = % .18f\n", result);
printf ("exact result = % .18f\n", expected);
printf ("estimated error = % .18f\n", error);
printf ("actual error = % .18f\n", result - expected);
printf ("intervals = %d\n", w->size);
gsl_integration_workspace_free (w);
}
The problem can be tracked to the following line:
SignalData * alpha = static_cast<SignalData *>(params);
The cast apparently does not work correctly: if I try to do anything with the SignalData object (that is to use any method that takes it as a parameter, ie. a method for printing it out) it produces Segmentation Violation error (it actually prints out 4 random numbers before the error). In the code that I pasted above, it's the interpolation method that uses this object and that's where the Segmentation Violations occurs:
InterpolatorGSL::interpolatedValueForTime(alpha, x);
But this is due to the faulty casting as well.
I don't have much experience with C++ and I've never used void pointers before, so excuse me if this is a stupid question, but what is the right way to pass my map<float, float> *
as a void *
parameter?
Let's look at Numerical integration example
double f (double x, void * params) {
double alpha = *(double *) params;
double f = log(alpha*x) / sqrt(x);
return f;
}
...
double alpha = 1.0;
gsl_function F;
F.function = &f;
F.params = α
passed variable has type double *
and casted to double *
in f
function
in your code
double f (double x, void * params) {
SignalData * alpha = static_cast<SignalData *>(params);
double f = InterpolatorGSL::interpolatedValueForTime(alpha, x);
return f;
}
...
SignalData * alpha = signalData;
gsl_function F;
F.function = &f;
F.params = α
you assign SignalData **
but casting it to SignalData *
Thus I would suggest remove one &
symbol from your code as following
F.params = alpha;