Dear Foivos, thank you very much for your example. This looks great. :)
I built a minimal example and included my wrapper of holding the interpolated data which is supposed to pass the data spline and accelerator to gsl_params. The code does compile so far but I get a segmentation fault, when I run it.
I think I did something wrong with passing unique_ptr via std::move but I do not find the error.
Has someone an idea?
Kind regards,
Klaus Huthmacher.
#include <iostream>
#include <memory>
#include <vector>
#include "gsl/gsl_integration.h"
#include "gsl/gsl_math.h"
#include "gsl/gsl_spline.h"
class data_set
{
public:
data_set(std::vector<double>, std::vector<double>);
std::vector<double> _x, _y;
std::unique_ptr<gsl_interp_accel,void(*)(gsl_interp_accel*)> _acc;
std::unique_ptr<gsl_spline,void(*)(gsl_spline*)> _spline;
};
data_set::data_set(std::vector<double> x, std::vector<double> y):
_x(x), _y(y),
_acc(gsl_interp_accel_alloc(),gsl_interp_accel_free),
_spline(gsl_spline_alloc(gsl_interp_cspline, _x.size()),gsl_spline_free)
{
gsl_spline_init(_spline.get(), _x.data(), _y.data(), _x.size());
}
class gsl_params
{
public:
gsl_params(std::unique_ptr<gsl_interp_accel,void(*)(gsl_interp_accel*)>,
std::unique_ptr<gsl_spline,void(*)(gsl_spline*)>);
std::unique_ptr<gsl_interp_accel,void(*)(gsl_interp_accel*)> _acc;
std::unique_ptr<gsl_spline,void(*)(gsl_spline*)> _spline;
};
gsl_params::gsl_params(
std::unique_ptr<gsl_interp_accel,void(*)(gsl_interp_accel*)> acc,
std::unique_ptr<gsl_spline,void(*)(gsl_spline*)> spline
):
_acc(std::move(acc)), _spline(std::move(spline))
{}
auto gsl_kernel(double x, void* p) -> double
{
std::unique_ptr<gsl_params> params(static_cast<gsl_params*>(p));
return gsl_spline_eval(params->_spline.get(), x, params->_acc.get());
}
auto gsl_integral(gsl_params* my_params, double lower, double upper) -> double
{
unsigned int size = 1000;
double result(0.0), error(0.0);
std::unique_ptr<gsl_integration_workspace,void(*)(gsl_integration_workspace*)>
w(gsl_integration_workspace_alloc(size),gsl_integration_workspace_free);
gsl_function f{ gsl_kernel, my_params };
gsl_integration_qags(&f, lower, upper, 0.0, 1.0e-7, size, w.get(), &result, &error);
return result;
}
int main()
{
std::vector<double> x, y;
for(unsigned int i = 0; i <= 100; ++i)
{
double x_value = static_cast<double>(i * 0.1);
x.push_back(x_value);
y.push_back(x_value * x_value);
}
data_set data(std::move(x), std::move(y));
gsl_params params(std::move(data._acc), std::move(data._spline));
std::cout << gsl_integral(¶ms, 0.0, 3.0) << std::endl;
return 0;
}
<<attachment: huthmacher.vcf>>
