I want to use gsl package for numerical integration, which may look easy. However, my function is multi-parameters. I use a struct data type for the parameters of the function. Here is my code to integrate the function f=a*x+b as an example which contains the parameters a and b.
#include <stdio.h>
#include <math.h>
#include <gsl/gsl_integration.h>
struct parameters { double a; double b;};
double func (double x, void * params) {
struct parameters alpha = *(struct parameters *) params;
double func = alpha->a*x+alpha->b;
return func;
}
int main (void)
{
gsl_integration_cquad_workspace * w
= gsl_integration_cquad_workspace_alloc (100);
double result, error;
size_t neval;
struct parameters alpha = {10.0, 3.0};
gsl_function F;
F.function = &func;
F.params = α
gsl_integration_cquad(&F, 0, 1., 0., 1e-7, w, &result, &error, &neval);
printf ("result = % .18f\n", result);
printf ("estimated error = % .18f\n", error);
gsl_integration_cquad_workspace_free (w);
return 0;
}
This however doesn't work. I don't know how to integrate multi-parameter functions. The function which is named here (func) has the argument (void * params), which I always get an error on changing it to a variable of any type other than a void pointer, and I can't assign the struct alpha that containing the parameters a and b to this void pointer.
You've done the casting wrong. This:
struct parameters alpha = *(struct parameters *) params;
...should be written as below if you want to copy params
to alpha
:
struct parameters alpha = *((struct parameters *) params);
...but you later use alpha
as a pointer, so it should really be this:
struct parameters* alpha = (struct parameters *) params;
You can however leave struct
out when programming C++ since the struct is typedef
ed automatically. You should also use C++ casts:
double func(double x, void* params) {
auto alpha = static_cast<parameters*>(params);
return alpha->a * x + alpha->b;
}
You could also make alpha
a reference:
double func(double x, void* params) {
auto& alpha = *static_cast<parameters*>(params);
return alpha.a * x + alpha.b;
}