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 typedefed 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;
}
Demo
Related
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
I wish to write a function, which uses the return value of a double function but/and I want to choose this double function during the function call. My idea is:
#include <iostream>
double linea(double a, double b, double x);
double parabola(double a, double b, double c, double x);
void konjgrad(double (*function)(void** params), void** params);
double linea(double a, double b, double x){
return a*x+b;
}
double parabola(double a, double b, double c, double x){
return a*x*x+b*x+c;
}
void konjgrad(double (*function)(void** params), void** params){
double d;
d=function(params);
std::cout<<d<<std::endl;
}
int main(){
konjgrad(linea(1.6,5.1,2.6));
konjgrad(parabola(2.4,3.1,4,2.6));
return 0;
}
But I stuck in the maze of the pointers. Has anyone an idea, how to solve the problem?
You can use variadic templates and perfect-forwarding to introduce the flexibility you require without any additional run-time overhead:
template <typename TF, typename... TArgs>
void konjgrad(TF&& f, TArgs&&... args)
{
double d;
d = std::forward<TF>(f)(std::forward<TArgs>(args)...);
std::cout<<d<<std::endl;
}
konjgrad can then be called as follows:
konjgrad(linea, 1.6, 5.1, 2.6);
konjgrad(parabola, 2.4, 3.1, 4, 2.6);
wandbox example
Alternatively, you could use lambda expressions and put the burden of binding the arguments on the caller:
template <typename TF>
void konjgrad(TF&& f)
{
double d;
d = std::forward<TF>(f)();
std::cout<<d<<std::endl;
}
konjgrad can then be called as follows:
konjgrad([]{ return linea(1.6, 5.1, 2.6); });
konjgrad([]{ return parabola(2.4, 3.1, 4, 2.6); });
wandbox example
Edited
Based upon Vittorio Romeo review, updated to pass vectors as const reference and added necessary assertion inside the linea and parabola APIs.
Here is little naive approach if you want to avoid variadic functions. As your function interface is clearly defined you can pass in vector or array of double type parameters in your linea and parabola functions.
#include <vector>
using namespace std;
double linea(const std::vector<double>& params)
{
assert(params.size() == 3 /*Linear 3 parameters required*/);
return params[0] * params[1] + params[2];
}
double parabola(const std::vector<double>& params)
{
assert(params.size() == 4 /*Parabola 4 parameters required*/);
return params[0] * params[3] * params[3] +
params[1] * params[3] +
params[2];
}
Little bit modified version of your konjgrad function, it is now returning the double value from the underlying call through function pointer. Please notice that first parameter clearly defines the function interface. Second parameter is the vector of doubles.
double konjgrad(double(*function)(const std::vector<double>&), const std::vector<double>& params)
{
return function(params);//returning value from here
}
Finally here's how you should invoke above defined APIs.
int main(int argc, wchar_t* argv[])
{
std::vector<double> vals;
vals.push_back(1.6);
vals.push_back(5.1);
vals.push_back(2.6);
double v1 = konjgrad(linea, vals);
std::vector<double> parab;
parab.push_back(2.4);
parab.push_back(3.1);
parab.push_back(4.0);
parab.push_back(2.6);
double v2 = konjgrad(parabola, parab);
return 0;
}
Hope this would help.
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.
In the code below, I cannot figure out a way of passing a member function to a generic root-finder.
#include <stdio.h>
double OneDimBisector(double (*fun)(float), float a, float b, float tol){
double val;
val = (*fun)(0.5*(b-a)); // actually: do proper bisection
return val;
}
class EOS {
public:
double S_array[10][10]; // actually: filled by constructor
double S(double T, double P);
double T_PS(double P, double S);
double functForT_PS(double T);
double (EOS::*pfunctForT_PS)(double);
double Sseek, Pseek;
};
double EOS::S(double T, double P){
double val = T+P; // actually: interpolate in S_array
return val;
}
double EOS::functForT_PS(double T){
return S(T,Pseek)-Sseek;
}
// Find T from P and S (T is invertible), assuming the intervals are ok
double EOS::T_PS(double P, double S0){
double Tmin = 2., Tmax = 7., T1, tol=1e-8;
pfunctForT_PS = &EOS::functForT_PS;
Sseek = S0;
Pseek = P;
printf("\n %f\n", (*this.*pfunctForT_PS)(4.)); // no problem
T1 = OneDimBisector(pfunctForT_PS, Tmin, Tmax, tol); // wrong type for pfunctForT_PS
return T1;
}
int main() {
double P=3., S=8;
EOS myEOS;
printf("\n %f %f %f\n",P,S,myEOS.T_PS(P,S));
}
I do not want to make the root-finder a member because it is not specific to this class, and the solution of making everything static seems very inelegant. Would someone have an idea? This must be a common situation yet I did not find a relevant post that was also understandable to me.
Thanks!
Edit: Actually, I also meant to ask: Is there a proper, thread-safe way of setting the Pseek variable other than what I did? Just to make it clear: I am doing one-dimensional root finding on a two-dimensional function but fixing one of the two arguments.
One way would be to change the signature of the root finder (add #include <functional>):
double OneDimBisector(std::function<double(float)> f, float a, float b, float tol);
Then invoke it with bind:
T1 = OneDimBisector(std::bind(pfunctForT_PS, this, std::placeholders::_1),
Tmin, Tmax, tol);
This carries a certain overhead. If you don't mind having lots of duplicate code, you can make the function a template:
template <typename Func>
double OneDimBisector(Func f, float a, float b, float tol);
You invoke it the same way, but every time you have a new function type, a new instance of the template is created in your compilate.
The "traditional" solution would be to have a free (or static) function that accepts an additional instance argument.
Update: The "traditional solution":
double OneDimBisector(double(*f)(float, void *), void * data, ...);
double EOSBisect(float f, void * data)
{
EOS * e = static_cast<EOS *>(data); // very "traditional"
return e->functorForT_PS(f);
}
Usage: T1 = OneDimBisector(EOSBisect, this, Tmin, Tmax, tol);
You cannot pass a member function pointer as a function pointer, because the latter lacks the context pointer (the this) to properly invoke the member function pointer.
The general way to solve this (as in the standard C++ library) is to use a template:
template <typename F>
double OneDimBisector(F fun, float a, float b, float tol){
double val;
val = fun(0.5*(b-a));
return val;
}
and pass a function object to it
struct Evaluator
{
EOS* this_;
Evaluator(EOS* this_) : this_(this_) {} // constructor
double operator()(double value) const // call the function
{
return this_->functForT_PS(value);
}
};
T1 = OneDimBisector(Evaluator(this), Tmin, Tmax, tol);
You could also use std::bind1st(std::mem_fun(&EOS::functForT_PS), this), but what it does is just the same as the structure above. (BTW, both std::bind1st and std::mem_fun have been deprecated.)
If you don't like templates, you could accept a polymorphic function instead (e.g. using Boost.Function or std::function in C++11), but it will be slower:
double OneDimBisector(const boost::function<double(double)>& fun,
float a, float b, float tol)
{
return fun(0.5 * (b-a));
}
and finally, if you can use C++11, you could use a lambda function on calling OneDimBisector:
T1 = OneDimBisector([=](double value){ return functForT_PS(value); },
Tmin, Tmax, tol);
The problem you face is that a function pointer is something different to a member funcgtion pointer.
A common (Java World) Approach to circumvent the problem is using the Strategy pattern (fun of the Bisector would be some Implementation of a Strategy).
A common C++-Approach would be using functors/binding, e.g. with boost:
typedef boost::function<double (double)> MyFun;
double OneDimBisector(const MyFun & fun, float a, float b, float tol){
double val;
val = fun(0.5*(b-a)); // actually: do proper bisection
return val;
}
// Calling
T1 = OneDimBisector (boost::bind (&EOS::functForT_PS, *this), Tmin, Tmax, tol));
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=¶msAPlusX;
//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.