Using GSL functions defined in a structure - c++

I want to write a structure containing all the functions (including GSL functions) and parameters for solving an ODE system. From the main function, I only want to call an update function defined in the struct to advance the system by one time-step. When I try this however, I get the error:
Line 27, ERROR: cannot convert ‘ODE::funcS’ from type ‘int (ODE::)(double, const double*, double*, void*)’ to type ‘int (*)(double, const double*, double*, void*)’ Below is a minimal code. \
Here is a minimal version of my code:
#include <iostream>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_odeiv.h>
struct ODE
{
void update(double dt)
{
// code to advance ODE solution by one time-step dt
}
int
funcS (double t, const double y[], double f[],
void *params)
{
return GSL_SUCCESS;
}
double mu = 10;
gsl_odeiv_system sysS;
void
initializeSys()
{
sysS.function = funcS; //Line 27
}
};
int
func (double t, const double y[], double f[],
void *params)
{
return GSL_SUCCESS;
}
int main()
{
// GIVES ERROR
ODE mySys;
mySys.update(0.01);
// WORKS
double mu = 10;
gsl_odeiv_system sys;
sys.function = func;
return 0;
}

You don't need to use static function directly. Instead you can write a very general wrapper.
I believe this is a duplicate question. My answer to the question I just linked is based on the wrapper presented here. However, I generalized it using templates to avoid the performance penalty of std::function due to heap allocation of the functor that std::function holds (the original answer only warns the reader about the penalty that is caused by the multiple indirection involved in std::function implementation, and this is negligible in comparison to the problem caused by heap allocation).
EDIT 1: This issue is also discussed here
EDIT 2 (to answer a question you raised in your first comment to my answer). The first caveat is that you have to make sure that whatever std::function holds is not deleted before GSL finish the calculation. Also, #Managu pointed out that the wrapper itself must not be out of scope while GSL works. This is not hard to enforce if you code carefully. Example of bad code:
// BAD PROGRAM - EXAMPLE OF WHAT YOU MUST NOT DO. DO NOT COPY THIS CODE
// HERE THE WRAPPER GETS PREMATURELY OUT OF SCOPE => CRASH
gsl_function *F
auto ptr = [](double x)->double{return 2*x;};
std::function<double(double)> FF1(std::cref(ptr))
{
gsl_function_pp Fp(FF1);
F = static_cast<gsl_function*>(&Fp);
}
(...)
// CALL GSL

Related

Is there a way to create an array of functions inside a loop in C++

I'm using ROOT Cern to solve a multi-variable non-linear system of equations. For some problems I have 4 functions and 4 variables. However, for others I need 20 functions with 20 variables. I'm using a class called "WrappedParamFunction" to wrap the functions and then I add the wrapped functions to the "GSLMultiRootFinder" to solve them. The function is wrapped this way:
ROOT::Math::WrappedParamFunction<> g0(&f0, "number of variables", "number of parameters");
Therefore, I need to declare the f0...fi functions before my void main(){} part of the code. I'm declaring the functions in this way:
double f0(const double *x, const double *par){return -par[0]+y[0]*par[1];}
double f1(const double *x, const double *par){return -par[1]+y[1]*par[2];}
.
.
Is there a way to create those functions inside a loop and stack them in an array? Something like this:
double (*f[20])(const double *x, const double *par);
for(int i=0;i<20;i++){
f[i]= -par[i]+x[i]*par[i+1];
}
So that later I can wrap the functions in this way:
ROOT::Math::WrappedParamFunction<> g0(f[0], "number of variables", "number of parameters");
f[i]= -par[i]+x[i]*par[i+1];
You can't generate code at runtime, so you can't do exactly what you're asking for.
You can however save the value of i for use at runtime, so you have a single callable object with a hidden parameter i not passed explicitly by the caller. The simplest example is
auto f = [i](const double *x, const double *par)
{
return -par[i]+x[i]*par[i+1];
};
but this gives a unique type to the lambda f, so you can't easily have an array of them.
You can however write
using Callable = std::function<double, const double *, const double *>;
std::array<Callable, 20> f;
and store the lambdas in that.
I think you'll need to use ROOT::Math::WrappedParamFunction<Callable> for this to work, though, since the FuncPtr parameter type is not erased.
If you really can't change the WrappedParamFunction type parameter for whatever reason, you can generate a free function instead of a stateful lambda using templates - but it's pretty ugly.
Edit - I was considering writing that version out too, but fabian beat me to it. Do note that you have to either write out all that machinery for each distinct function that needs this treatment, wrap it in a macro, or generalize everything to take a function template parameter as well.
There are almost certainly better ways of accomplishing this, but this probably gets you closest to the desired result described in the question:
Create a function template with the offset as template parameter and then create an std::array of function pointers with function pointers pointing to specializations of a template function. Note that the size of the array must be a compile time constant for this to work:
template<size_t Offset>
double f(const double* y, const double* par)
{
return -par[Offset] + y[Offset] * par[Offset+1];
}
template<size_t ... Offsets>
std::array<double(*)(double const*, double const*), sizeof...(Offsets)> CreateFsHelper(std::index_sequence<Offsets...>)
{
return { &f<Offsets>... };
}
template<size_t N>
std::array<double(*)(double const*, double const*), N> CreateFs()
{
return CreateFsHelper(std::make_index_sequence<N>{});
}
int main()
{
auto functions = CreateFs<20>();
}
Making your i a template parameter and generating the functions recursively at compile time can also do the trick:
using FunctionPrototype = double(*)(const double *, const double *);
template<int i>
double func(const double * x, const double * par) {
return -par[i]+x[i]*par[i+1];
}
template<int i>
void generate_rec(FunctionPrototype f[]) {
f[i-1] = &func<i-1>;
generate_rec<i-1>(f);
}
template<>
void generate_rec<0>(FunctionPrototype f[]) { }
template<int i>
FunctionPrototype* generate_functions()
{
FunctionPrototype * f = new FunctionPrototype[i]();
generate_rec<i>(f);
return f;
}
FunctionPrototype * myFuncs = generate_functions<3>(); // myFuncs is now an array of 3 functions
"Is there a way to create an array of functions inside a loop in C or C++"
sure, you can create a std::array or std::vector of std::function.
You can also create a container of function pointers if you so desire.

How can you pass a function pointer and compare it in a function in C++?

For testing reasons I have a certain number of methods whose signature in C++ would look like:
dvec3 (*)(dvec3, dvec3, double)
I put them in a vector as follows:
vector<dvec3 (*)(dvec3, dvec3, double)> methods = {lerp, plerp, splerp, ilerp};
The idea is to make a function that takes the function pointer and returns a string to identify the function that is currently being used (i.e I want to print out which function, among the 4 above, is being used)
For this I attempted to write the method as follows (I ommitted most cases on purpose):
string inline erpToString(dvec3 (*f)(dvec3, dvec3, double))
{
if (f==lerp)
{
return "Lerp";
}
}
The above however does not compile, the error message states that it's a casting error. What did I do wrong?
EDIT:
Compiler message:
/home/kronos/Desktop/OpenGL-Template/source/Rendering/rendering.cpp: In function ‘std::__cxx11::string erpToString(glm::dvec3* (*)(glm::dvec3, glm::dvec3, double))’:
/home/kronos/Desktop/OpenGL-Template/source/Rendering/rendering.cpp:1362:7: error: invalid operands of types ‘glm::dvec3* (*)(glm::dvec3, glm::dvec3, double) {aka glm::tvec3<double, (glm::precision)0>* (*)(glm::tvec3<double, (glm::precision)0>, glm::tvec3<double, (glm::precision)0>, double)}’ and ‘<unresolved overloaded function type>’ to binary ‘operator==’
if (f==lerp)
~^~~~~~
make[2]: *** [CMakeFiles/voxel-world.dir/build.make:111: CMakeFiles/voxel-world.dir/source/Rendering/rendering.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:68: CMakeFiles/voxel-world.dir/all] Error 2
EDIT:
I have made the minimum possible file that would have the same logic, however it does not reproduce the error:
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <string>
using namespace std;
using namespace glm;
dvec3 lerp(dvec3 p1, dvec3 p2, double t)
{
return (1-t)*p1+t*p2;
}
string inline erpToString(dvec3 (*f)(dvec3, dvec3, double))
{
if (f==lerp)
{
return "Lerp";
}
}
int main()
{
}
Playing around with the code shows the other methods (ilerp and company) do work. So it seems I have a namespace conflict (yay for using namespaces). SInce GLM defines a lerp function, but the one I need to use is the one I defined. Anyone got a suggestion?
You could use using or typedef to simplify all thing. Code works for me
int a(float x, float y, double z)
{
return int(x + y + z);
}
int b(float x, float y, double z)
{
return int(x - y - z);
}
using fdef = int(*)(float, float, double); // or typedef int (*fdef)(float, float, double);
std::vector<fdef> v{a, b};
if (v[0] == a)
std::cout << "qqq\n";
The key is ‘<unresolved overloaded function type>’
In particular, you have two lerp functions. That's generally allowed. In most contexts, C++ will figure out which one you want. For instance, when you call lerp(arg1,arg2, arg3), C++ will do overload resolution with those three arguments. But in f==lerp, there are no three arguments for overload resolution. That is why C++ says "unresolved overload".
The solution is to cast lerp to the type of f: if (f==static_cast<decltype(f)>(&lerp)). The three arguments to use for overload resolution are those of f.
The problem was caused because GLM defines a lerp Function as well, thus the compiler couldn't choose which function I was referring too.
The solution was, as suggested in the comments, renaming my function from lerp to mlerp
I guess this is a very good example as to why using namespaces is not a great idea.
This is not an answer to how to fix the bug, but an answer to your attemp of giving a name of the method your are using.
I suggest you to use std::unordered_map to discriminate different functions.
std::unordered_map<void*, const char*> funcmap{4};
union cast_fptr {
dvec3 (*)(dvec3, dvec3, double) fptr;
void *void_ptr;
};
#define MAP_VAL(FUNC_NAME) std::pair<void*, const char*>{cast_fptr{.fptr = &FUNC_NAME}.void_ptr, #FUNC_NAME}
funcmap.insert({MAP_VAL(lerp), MAP_VAL(plerp), MAP_VAL(splerp), MAP_VAL(ilerp)});
#undef MAP_VAL
inline const char* erpToString(dvec3 (*f)(dvec3, dvec3, double)) noexcept {
return funcmap[f];
}

Undefined behavior when passing C++ objects to C routine

Update
I found that if I pass by reference in the constructor, then it fix the problem in A.cpp!
i.e. InfoPass(vector<double> &arg0, vector<double> &arg1...), but what's the reason?
Update
Basically I want to call some c code from c++.
as explained in the c mannual, to avoid using gloabal variables, a "void *fdata" is provided to get addtional information, if not any, it's pointed to NULL.
int f(unsigned ndim, unsigned npts, const double *x, void *fdata,
unsigned fdim, double *fval);
Now I need to pack some c++ objects and pass to "f" through this *fdata argument, the way I could think of is to define a class "InfoPass", and pass it to the c routine.
my c++ snippet (example A.cpp and B.cpp, A doesn't work properly while B is OK):
// Example A.cpp
#include "cubature.h" // the c library called cubature
#include "extern_cpp_class.hpp" //
class InfoPass
{
public:
extern_cpp_class obj1;
extern_cpp_class obj2;
extern_cpp_class obj3;
double arr[3];
InfoPass(vector<double>arg0, vector<double>arg1, vector<double>arg2, vector<double>arg3)
: obj1{arg0, arg1}, obj2{arg0, arg2}, obj3{arg0, arg3} {}
};
// the declaration of int f() and cubature() below are in the c code
int f(unsigned ndim, const double *x, void *fdata, unsigned fdim, double *fval);
int main() {
/*** do something ***/
InfoPass cubpass{arg0, arg1, arg2, arg3}; // initialize
cubature(2, f, &cubpass, 2, xmin, xmax, 1e5, 0, 1e-5, ERROR_PAIRED, OUTPUT, &err);
/*** process with output ***/
}
int f(unsigned ndim, const double *x, void *fdata, unsigned fdim, double *fval)
{
InfoPass *fcubpass=static_cast<InfoPass*>(fdata);
/*** do things with fcubpass.obj1, .obj2 ... ***/
}
Now, I can compile(gcc) and run example A, strangely, there are undefinded behaviors, sometimes it gives NaN, sometimes gives very crazy numbers...
However, if instead I do in the following way (Example B, use pointers to class) then use "new" in f, it works fine! wondering why? since I prefer the Example A to B in which I need to alway "new" somthing...
// Example B.cpp
class InfoPass
{
public:
extern_cpp_class *obj1=NULL;
extern_cpp_class *obj2=NULL;
extern_cpp_class *obj3=NULL;
double arr[3];
~InfoPass(){
delete obj1;
delete obj2;
delete obj3;
}
}
int main() {
/*** do something ***/
InfoPass cubpass; // declare
cubpass.obj1 = new extern_cpp_class(arg0,arg1);
cubpass.obj2 = new extern_cpp_class(arg0,arg2);
cubpass.obj3 = new extern_cpp_class(arg0,arg3);
cubature(2, f, &cubpass, 2, xmin, xmax, 1e5, 0, 1e-5, ERROR_PAIRED, OUTPUT, &err);
/*** process with output ***/
}
int f(unsigned ndim, const double *x, void *fdata, unsigned fdim, double *fval)
{
InfoPass *fcubpass=static_cast<InfoPass*>(fdata);
/*** do things with fcubpass->obj1, .obj2 ... ***/
}
Just a shot in the dark here.
What do extern_cpp_class objects do with their initialization parameters? If they take and store their vector arguments as references, you'd run into trouble with the original A.cpp since the arguments are temporary copies that are destroyed — invalidating the references — after cubpass's constructor is finished executing. Switching to passing references would fix this by ensuring that the extern_cpp_class objects receive references to vectors created in main that (presumably) remain valid until the program exits (or at least until you're done working with cubpass). In B.cpp, the constructors already get references to such vectors, hence no problems.
Since f should be the Callback function that is called by C-code it should use c's calling convention.
But since you declare and define it in cpp it uses another calling convention.
So maybe the parameter passing somehow goes wrong.
Try adding extern "C" in front of the declaration of f.
But this obviously does not satisfactorily explain, why one of your examples does work.
Could you change the initialization list in your InfoClass constructor to use parenthesis instead of curly braces?
obj1(arg0, arg1), obj2(arg0, arg2), obj3(arg0, arg3)
P.S. I would have posted this as a comment, but I dont have the reputations yet.

Does C++11 does optimise away tail recursive calls in lambdas?

My tentative answer is no, as observed by the following test code:
#include <functional>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void TestFunc (void);
int TestFuncHelper (vector<int>&, int, int);
int main (int argc, char* argv[]) {
TestFunc ();
return 0;
} // End main ()
void TestFunc (void) {
// Recursive lambda
function<int (vector<int>&, int, int)> r = [&] (vector<int>& v_, int d_, int a_) {
if (d_ == v_.size ()) return a_;
else return r (v_, d_ + 1, a_ + v_.at (d_));
};
int UpperLimit = 100000; // Change this value to possibly observe different behaviour
vector<int> v;
for (auto i = 1; i <= UpperLimit; i++) v.push_back (i);
// cout << TestFuncHelper (v, 0, 0) << endl; // Uncomment this, and the programme works
// cout << r (v, 0, 0) << endl; // Uncomment this, and we have this web site
} // End Test ()
int TestFuncHelper (vector<int>& v_, int d_, int a_) {
if (d_ == v_.size ()) return a_;
else return TestFuncHelper (v_, d_ + 1, a_ + v_.at (d_));
} // End TestHelper ()
Is there a way to force the compiler to optimise recursive tail calls in lambdas?
Thanks in advance for your help.
EDIT
I just wanted to clarify that I meant to ask if C++11 optimizes recursive tail calls in lambdas. I am using Visual Studio 2012, but I could switch environments if it is absolutely known that GCC does the desired optimization.
You are not actually doing a tail-call in the "lambda" code, atleast not directly. std::function is a polymorphic function wrapper, meaning it can store any kind of callable entity. A lambda in C++ has a unique, unnamed class type and is not a std::function object, they can just be stored in them.
Since std::function uses type-erasure, it has to jump through several hoops to call the thing that was originally passed to it. These hoops are commenly done with either virtual functions or function-pointers to function template specializations and void*.
The sole nature of indirection makes it very hard for optimizers to see through them. In the same vein, it's very hard for a compiler to see through std::function and decide whether you have a tail-recursive call.
Another problem is that r may be changed from within r or concurrently, since it's a simple variable, and suddenly you don't have a recursive call anymore! With function identifiers, that's just not possible, they can't change meanings mid-way.
I just wanted to clarify that I meant to ask if C++11 optimizes recursive tail calls in lambdas.
The C++11 standard describes how a working program on an abstract machine behaves, not how the compiler optimizes stuff. In fact, the compiler is only allowed to optimize things if it doesn't change the observable behaviour of the program (with copy-elision/(N)RVO being the exception).

Passing a function pointer by reference

Hi I am trying to learn some function pointers in C/C++ and I was trying to write the following C++ code with gcc on Ubuntu.
This code should execute the multiply or or the add function depending on the
preprocessor flag -DADD or -DMULTIPLY provided during compilation
#include <iostream>
#include <iomanip>
//Adds two numbers
int add(int a, int b)
{
return a+b;
}
//Multiplies two numbers
int multiply(int a, int b)
{
return a*b;
}
//Function to set the correct function to be executed.
//All functions here should have the same signature.
void functionsetter( void (*ptr2fun)(int,int) )
{
#ifdef ADD
ptr2fun = add;
#endif
#ifdef MULTIPLY
ptr2fun = multiply
#endif
}
int main(int argc, char *argv[])
{
int a = 5;
int b = 6;
void (*foo)(int,int);
functionsetter(foo);
return 0;
}
I cannot figure out how to pass the function pointer foo to the function-setter function by reference. Can someone help me out on this.I am sure the declaration of
functionsetter is wrong in the code, Please let me know how to fix it.
I am trying to compile this with g++ -O2 -g -Wall -DADD main.cpp -o main
Note: I want to use such preprocessor flags and function pointers in some other-code elsewhere.
Please let me know if such a thing is a good idea / practice.
Without using a typedef, the syntax for a reference to a function pointer is:
void functionsetter(void (*&ptr2fun)(int, int)) { ... }
But it is generally simpler to create a typedef for the pointer type:
typedef void (*FunctionPointer)(int, int);
void functionsetter(FunctionPointer& ptr2fun) { ... }
Or for the function type:
typedef void Function(int, int);
void functionsetter(Function*& ptr2fun) { ... }
Use a typedef:
typedef void (*MyFunctionPointer)(int,int);
void functionsetter(MyFunctionPointer& fp);
I want to use such preprocessor flags and function pointers in some other-code elsewhere. Please let me know if such a thing is a good idea / practice.
No, not really. It isn't clear from your example what you are trying to accomplish, but your implementation is rather unusual. Consider using virtual member functions or std::function to switch function implementations at runtime, or (possibly) templates to switch them at compile-time. There's nothing wrong with using conditional compilation for static selection like this, but mixing that with function pointers is a bit odd.
Without a good understanding of the problem you are trying to solve, it's difficult to give good advice as to how best to solve it.
You'd change your signature to:
void functionsetter( void (*&ptr2fun)(int,int) )
Note that the ptr2fun function pointer has the wrong signature, your add and multiply functions return an int, and so should ptr2fun
This becomes a lot easier if you use a typedef:
typedef int (*ptr2fun)(int,int);
void functionsetter(ptr2fun& func) { ...
Though, personally I'd just return the function pointer.
ptr2fun functionsetter()
{
#ifdef ADD
return add;
#endif
#ifdef MULTIPLY
return multiply
#endif
}
First, you're not passing a function pointer reference to the method, you're just passing a function pointer. You need to change the method signature to
void functionsetter( void (*&ptr2fun)(int,int) )
Also, your method signature is void(*)(int,int) in some places and int(*)(int,int) in some, they should probably be the latter everywhere since your add and multiply methods return int.
That said, since you're using C++, manipulating pointers in this manner isn't something I'd recommend, C++ has inheritance/virtual methods that can usually replace most function pointer use and makes the code much more readable and extensible.