Numerical integration of lambda function with gsl - c++

I am working with gsl to integrate a function. That function is built in a lambda function that has as input a double and a void *, and as output a double.
Now, everything works fine if I use the lambda without any variable capture. But if I do variable capturing, it doesn't work any more.
Could anyone explain me why so?
Here are two snippets of code that I made up to explain my problem:
This one works fine:
int main(int argc, char **argv)
{
double beg = 0;
double end = 10;
auto f = [] (double x, void * p) {return 2.0;};
gsl_integration_workspace * w = gsl_integration_workspace_alloc (GSL_INTEGRATION_WORKSPACE_SIZE);
double result;
double error;
gsl_function F;
F.function = f;
F.params = NULL;
gsl_integration_qags (&F, beg, end, 0, GSL_INTEGRATION_RELATIVE_PRECISION, GSL_INTEGRATION_WORKSPACE_SIZE, w, &result, &error);
cout<<result<<endl;
}
While this one
int main(int argc, char **argv)
{
double beg = 0;
double end = 10;
double p = 2.0;
auto f = [&] (double x, void * p) {return p;};
gsl_integration_workspace * w = gsl_integration_workspace_alloc (GSL_INTEGRATION_WORKSPACE_SIZE);
double result;
double error;
gsl_function F;
F.function = f;
F.params = NULL;
gsl_integration_qags (&F, beg, end, 0, GSL_INTEGRATION_RELATIVE_PRECISION, GSL_INTEGRATION_WORKSPACE_SIZE, w, &result, &error);
cout<<result<<endl;
}
Yields on the line
F.function = f;
the following error:
Assigning to 'double (*)(double, void *)' from incompatible type '<lambda at /[omissis]/main.cpp>'

The answer given by #user657267 is correct. That is why a small wrapper is needed to convert lambas with capture to gsl_function.
Here is the wrapper for the f gsl_function and Here is the wrapper for the fdf gsl_function
You can convert lambda functions to gsl_function after using the wrapper proposed in these two answers in the following way (I haven't invented the version with std::function, it was a well known answer. The template version I haven't seen before my answer).
// std::function version
double a = 1;
gsl_function_pp Fp([=](double x)->double{return a*x;});
gsl_function *F = static_cast<gsl_function*>(&Fp);
//template version
double a = 1;
auto ptr = [=](double x)->double{return a*x;};
gsl_function_pp<decltype(ptr)> Fp(ptr);
gsl_function *F = static_cast<gsl_function*>(&Fp);

Only lambdas without captures can be converted to function pointers.
[expr.prim.lambda]
6 The closure type for a non-generic lambda-expression with no
lambda-capture has a public non-virtual non explicit const conversion
function to pointer to function with C++ language linkage (7.5) having
the same parameter and return types as the closure type’s function
call operator.
Essentially what this means is that
[] (double, void*) {return 2.0;};
acts as though it were defined as
class Lambda
{
public:
double operator()(double, void*);
operator double(*)(double, void*)() const;
};
if the lambda has a capture however the conversion function is not defined, and the lambda cannot be converted to a regular function pointer.

Related

How to pass an Auto variable as input to another function

I really want to pass a variable that is auto (function) as input in another function.
Here is a structure that receives parameters for my xroot f:
struct my_f_params {
double flag;
auto inter_auto(double x, double y);
};
Here is the function I essentially want to have (it's based on a GSL library, so the form can't be changed). I want to be able to pass a "function" as a variable, and the only way I guessed it would happen is with auto.
After passing it, I try storing it to a new auto, But I get an error (see below):
double xrootf (double x, void * p)
{
my_f_params * params = (my_f_params *)p;
double flag = (params->flag);
auto inter_auto = (params->inter_auto);
return flag*inter_auto(x);
}
Here is an auto function that returns an auto function. This works perfectly (if xrootf is commented, I can print for example new_f(2)(2), etc):
auto new_f(double x){
auto in_result = [](double x, double y){
return x*y;
};
using namespace std::placeholders;
auto result_f = std::bind(in_result,x,_1);
return result_f;
}
The test code that proves that the auto function new_f is working good:
int main(int argc, char const *argv[])
{
auto nest_f = new_f(-0.5);
printf("%f\n", nest_f(+2));
return 0;
}
Recasting the auto function to double is not working, either (for the struct part of the code).
The error I'm getting is:
auto_pass.cpp: In function 'double xrootf(double, void*)':
auto_pass.cpp:28:42: error: unable to deduce 'auto' from 'params->my_f_params::inter_auto'
28 | auto inter_auto = (params->inter_auto);
| ^
auto_pass.cpp:28:42: note: couldn't deduce template parameter 'auto'
The aim of the code is this:
Have a function that is able to return a function (DONE W/ new_f)
Have a function that is able to take a function as a variable (the one with new_f) (Not Done)
EDIT: Here's a quick Python script that's very easy to achieve what I'm saying:
def new_f(y):
#make any number of computatioanly costly Algebra with y
def g(x):
return x*y
return g
def xroot(f,flag):
return flag-f(flag)
auto is just a placeholder for a compiler-deduced type, depending on the context in which auto is used.
In your example, you can't use auto as the return value of my_f_params::inter_auto(), because the compiler has no way to know what type inter_auto() actually returns, so it can't deduce the type of the auto. You would need to do this instead:
struct my_f_params {
double flag;
auto inter_auto(double x, double y) { return ...; }
};
Then the compiler can deduce the type of the auto from the return statement.
Without that inline code, you would have to be explicit about the return type, eg:
struct my_f_params {
double flag;
double inter_auto(double x, double y);
};
double my_f_params::inter_auto(double x, double y) {
return ...;
}
But in any case, this is not what you really want. Your xrootf() function is trying to call inter_auto() with only one parameter, but my_f_params::inter_auto() is declared to take 2 parameters instead. Based on the Python script you showed, what you really want is for inter_auto to be a reference to some other external function instead. In which case, you can use std::function for that purpose (and there is no need to use std::bind() with a lambda at all).
Try this:
#include <iostream>
#include <functional>
struct my_f_params {
double flag;
std::function<double(double)> inter_auto;
};
double xrootf(double x, void * p)
{
my_f_params * params = static_cast<my_f_params*>(p);
return params->flag * params->inter_auto(x);
}
auto new_f(double x){
return [x](double y) {
return x * y;
};
}
int main(int argc, char const *argv[])
{
my_f_params p;
p.flag = 123.45;
p.inter_auto = new_f(-0.5);
std::cout << xrootf(+2, &p) << std::endl;
return 0;
}
Demo
When calling xrootf(), the resulting equation will be:
flag * (x * y)
which in this example is:
123.45 * (-0.5 * +2) = -123.45

Conversion between 'std::function<double(double)>’ to ‘double (*)(double)’

I am trying to pass a custom lambda to a function that expects a function pointer (more precisely the zero function in Brent library).
The idea is that I would create the lambda once with the parameters and then it would be evaluated at several values x inside this function.
I have tried the steps in this thread with no success and I am getting an error of no known conversion for argument 4 from ‘Function {aka std::function<double(double)>}’ to ‘double (*)(double)’. As far as I understand the compiler does not know how to cast from those 2 types.
Is there a workaround around this error? It would be better if no modifications had to be made to the library and it could be solved within my program. Here is a snippet of code to show the problem.
# include <functional>
# include "brent.hpp"
using namespace brent;
typedef std::function<double(double)> Function;
Function function_builder (double a, double b)
{
return [a,b](double x) {
return ( a * x + b );
};
}
int main ( )
{
Function func = function_builder ( 2.0, -1.0 );
double z = zero (0, 1, 0.001, func ); //func should be a function pointer of type double (*)(double)
return 0;
}
In your case, your lambda function has state - the captured a, b variables. There is no way to convert a stateful lambda to a pointer to function, but...
The Brent library does not expect a pointer to function. The zero function is declared as:
double zero ( double a, double b, double t, func_base& f )
and has an overload defined as:
// This is the overload you asked about, but....
double zero ( double a, double b, double t, double f ( double x ) ){
func_wrapper foo(f);
return zero(a, b, t, foo);
}
But you should use the first variant for your needs, which expects:
class func_base{
public:
virtual double operator() (double) = 0;
};
which is good news, since you simply have to derive from func_base, and put a lambda in there:
template <class Lambda>
class FunctionWithState : public func_base, public Lambda {
public:
FunctionWithState(const Lambda & lambda): Lambda(lambda) {}
double operator()(double x) override
{ return Lambda::operator()(x); }
};
template<class Lambda>
auto function_builder_base (Lambda lambda)
{
return FunctionWithState<decltype(lambda)>(lambda);
}
auto function_builder(double a, double b)
{
return function_builder_base([a,b](double x) {
return ( a * x + b );
});
}
The implementation details are a bit ugly, but the usage is reasonable:
main ( )
{
// func must be "auto" because the type depends on lambda, whose type is unknown.
auto func = function_builder ( 2.0, -1.0 );
double z = zero (0, 1, 0.001, func );
return 0;
}
Of course, it is possible to get rid of the lambda function altogether, and to manage state inside a non-templated object. But on the other hand, inheriting from lambda makes it easy to define many other function builders such as:
auto function_builder3(double a, double b, double c)
{
return function_builder_base([a,b,c](double x) {
return ( a*x*x + b*x + c );
});
}
In fact, you can use function_builder_base directly everywhere, eliminating the need for a function_builder middleman.
You won't have much luck without ugly hack (like using a global object of sorts) of passing a std::function<double(double)> to a double(*)(double). The key difference is that function pointer genuinely only abstract stateless functions while std::function<double(double)> or lambda functions with non-empty capture contain state.
Specifically for the Brent library mentioned there is, however, a way! The library doesn't really take function pointer but travels in terms of func_base objects. You can get one of these with a simple adapter:
struct brent_fun: func_base {
std::function<double(double)> fun;
template <typename Fun>
explicit brent_fun(Fun&& fun): fun(std::move(fun)) {}
double operator()(double value) override { return this->fun(value); }
};

Pointer to member function of an object [duplicate]

This question already has answers here:
Function pointer to member function
(8 answers)
Closed 5 years ago.
I would like to integrate a function with gsl. Therefor I have to define a function f (the integrant, which has to be of the form double (*)(double, void*)). For the call of the gsl integration method I need to define a struct, which contains a pointer to a function (this struct is called gsl_function).
gsl_function F;
F.function = &MyClass::my_f;
The function f must be implemented in a class (in the same class from which the integration procedure should be called). How can I assign the pointer above correctly, since the 2nd line is not compiling and leads to the error:
cannot convert ‘double (MyClass::*)(double, void*)’ to ‘double (*)(double, void*)’ in assignment.
Here the definition of my_f
struct my_f_params { double a; double b;};
double my_f (double x, void * p) {
struct my_f_params * params = (struct my_f_params *)p;
double a = (params->a);
double b = (params->b);
return 1.0/(sqrt(a * (1.0 + x)*(1.0 + x)*(1.0 + x) + (1-a) * std::pow((1.0 + x), (3.0 * (1.0 + b)))));
}
which has to be of the form double (*)(double, void*)
Non static member function declarations involve the implicit call scope qualifier as stated in the error message
double (MyClass::*)(double, void*)
// ^^^^^^^^^
This is different from the callback function pointer definition.
What you probably can do with such interface, is to pass the this pointer through the void* argument of the callback function:
class MyClass {
static double func(double d,void* thisPtr) {
MyClass* myClass = (MyClass*)thisPtr;
// do something
}
};
As mentioned in the documentation you can set the params like that in a wrapper class:
class gsl_function_wrapper {
public:
gsl_function_wrapper() {
F.function = &func;
F.params = this;
}
private:
gsl_function F;
double a;
double b;
static double func(double d,void* thisPtr) {
gsl_function_wrapper* myWrapper = (gsl_function_wrapper*)thisPtr;
// do something with a and b
foo(d,myWrapper->a,myWrapper->b);
}
};

definition pointer variable

i can't understand following defining pointer variable. can you help me?
double(*)(double *) foo;
note : sory, i edit name of variable func to foo.
This is not valid C. Perhaps you mean this:
double(*func)(double *);
which declares func as a pointer to a function that takes a pointer-to-double, and returns a double.
You can use http://cdecl.org for this sort of thing.
Try this (tested):
// functions that take double * and return double
double dfunc(double *d) { return (*d) * 2.0; }
double tfunc(double *d) { return (*d) * 3.0; }
int main()
{
double val = 3.0;
double // 3. the function returns double
(*pFunc) // 1. it's a pointer to a function
(double *); // 2. the function takes double *
pFunc = dfunc;
printf("%f\n", pFunc(&val)); // calls dfunc()
pFunc = tfunc;
printf("%f\n", pFunc(&val)); // calls tfunc()
}
Output:
6.000000
9.000000
it's a pointer to a function returning double having a parameter of type pointer to double, if you correct the variable declaration since as it stands its just incorrect correct syntax would be double (*foo) (double*)
uses are polymorphism by being able to replace a function:
struct memory_manager{
void*(*getmem)(size_t);
void(*freemem)(void*);
}mem_man;
void* always_fail(size_t){return 0;}
void* myalloc(size_t s){
void* p=mem_man.get_mem(s);
if(p) return p;
mem_man.getmem=always_fail;
return 0;
}
void myfree(void* p){
if(p) freemem(p);
}
it's not really the c++-way i geuss, since for most purposes inheritance and virtual functions offer a better solution, but if you're restricted to c, then you can use this technique to simulate virtual functions.

Function pointers working as closures in C++

Is there a way in C++ to effectively create a closure which will be a function pointer? I am using the Gnu Scientific Library and I have to create a gsl_function. This function needs to effectively "close" a couple of parameters available when I create it. Is there a nice trick to create a closure so that I don't have to pass all of them as params in the gsl_function structure? If not, should I just pass in a pointer to an array containing these parameters?
EDIT
I have tried to use boost::bind like this:
#include <gsl/gsl_integration.h>
#include <boost/bind.hpp>
#include "bondpricecalculator.h"
#include "functions.h"
double integrand (double xi, double t, double x, void * p) {
Functions *functions = (Functions *) p;
double vx = functions->v(x);
return functions->rho0(x)*exp(vx * xi - 0.5 * vx * vx * t);
}
double BondPriceCalculator::value(double t, double T, double xi)
{
gsl_integration_workspace * w
= gsl_integration_workspace_alloc (10000);
gsl_function F;
F.function = &boost::bind(integrand, xi, t, _1, _2);
F.params = &functions;
double integral_t;
double integral_T;
double error;
int res = gsl_integration_qags(&F, T, 1e+14, 0, 1e-7, 10000, w, &integral_T, &error);
if(res)
{
throw "Error intgrating";
}
int res = gsl_integration_qags(&F, T, 1e+14, 0, 1e-7, 10000, w, &integral_t, &error);
if(res)
{
throw "Error intgrating";
}
return integral_T/integral_t;
}
but I got the following error message:
/home/ga/svn/PhD/inflation/cpp/ioi/bondpricecalculator.cpp:20: error: cannot convert ‘boost::_bi::bind_t<double, double (*)(double, double, double, void*), boost::_bi::list4<boost::_bi::value<double>, boost::_bi::value<double>, boost::arg<1>, boost::arg<2> > >*’ to ‘double (*)(double, void*)’ in assignment
I found below code at.
http://bytes.com/topic/c/answers/657124-interface-problem
// Use in combination with boost::bind.
template<class F>
static double gslFunctionAdapter( double x, void* p)
{
// Here I do recover the "right" pointer, safer to use static_cast
// than reinterpret_cast.
F* function = static_cast<F*>( p );
return (*function)( x );
}
template<class F>
gsl_function convertToGslFunction( const F& f )
{
gsl_function gslFunction;
const void* p = &f;
assert (p != 0);
gslFunction.function = &gslFunctionAdapter<F>;
// Just to eliminate the const.
gslFunction.params = const_cast<void*>( p );
return gslFunction;
}
and use this like
gslFunction gslF = convertToGslFunction( boost::bind( &Sde::drift, &sde, _1 ) );
Take a look at this simple example of combining boost::bind and boost::function.
I'm guessing from all those "gsl_" prefixes that the library is not C++, but plain C. Which means it doesn't grok C++ closures (functors). You can't pass a C++ functor to a C function. You'll have to pass void pointers around, cross your fingers and reinterpret_cast them into C oblivion.
Though bradgonesurfing has given a nice answer that will work for converting closures into gsl_functions without any further thought, I would like to share with you the idiom for doing a direct translation from C++ into C.
Supposing you have the closure:
double a;
[&a](double x){return a+x;}
You would convert translate this into an equivalent function pointer idiom as follows:
struct paramsAPlusX{
double* a;
paramsAPlusX(double & a_):a(&a_){}
}
double funcAPlusX(double x, void* params){
paramsAPlusX* p= (paramsAPlusX*)params;
return *(p->a) + x;
}
//calling code:
double a;
paramsAPlusX params(a);
gsl_function f;
f.function=funcAPlusX;
f.params=&paramsAPlusX;
//use f here.
Many C libraries use this sort of idiom, and they don't all use a struct for it (they frequently pass it as two separate parameters to the function) so automatic conversion isn't always possible.