function pointer in C++ in bisection method - c++

I have a function my_func(), which takes 2 parameters a and b.
I want to define a function inside the solve_for_b_by_bisection() function, called f, such that I can just call f(b), which is my_func(a, b) for some fixed input a. How do I do that? Do I use a function pointer?
The reason I am doing this instead of calling f(a,b) directly is that in the actual thing I am working on, it has 10+ variables which are constants - it is not possible to repeat the variable list every time.
double my_func(const double a, const double b)
{
/* some arbitary function */
}
double solve_for_b_for_contant_a_by_bisection (const double a,
const double upperbound,
const double lowerbound)
{
double (*my_func_pointer)(const double b)
{
&my_func(a, b)
}
lowerboundvalue = *my_func(lowerbound)
upperboundvalue = *my_func(upperbound)
midpointvalue = *my_func(0.5 * (lowerbound+upperbound))
/* The rest of the implementation */
}

You might use lambda:
auto func = [a](double b) { return my_func(a, b); };

Just use lambda:
double solve_for_b_for_contant_a_by_bisection (const double a,
const double upperbound,
const double lowerbound)
{
auto f = [a]( double b ) { return my_func( a, b ); };
auto lowerboundvalue = f(lowerbound)
auto upperboundvalue = f(upperbound)
auto midpointvalue = f(0.5 * (lowerbound+upperbound));
/* The rest of the implementation */
}

You could either use a lambda function, as others have suggested, or std::bind. See how that will look and whether you like it better:
#include <functional>
double my_func(const double a, const double b)
{
/* some arbitary function */
}
double solve_for_b_for_contant_a_by_bisection (const double a,
const double upperbound,
const double lowerbound)
{
const auto f = std::bind(my_func, a, std::placeholders::_1);
const auto lowerboundvalue = f(lowerbound);
const auto upperboundvalue = f(upperbound);
const auto midpointvalue = f(0.5 * (lowerbound+upperbound));
/* The rest of the implementation */
}

Related

Convert a function pointer to another having more arguments

Suppose I am trying to use a function which accepts a binary function and calls it with some arguments:
typedef double (*BinaryFunction)(double a, double b);
typedef double (*UnaryFunction)(double a);
// Can't change this
double ExternalFunction(BinaryFunction binaryFunction)
{
return binaryFunction(1, 2);
}
Now suppose a user of my code is going to provide me with a unary function. My goal is to convert it into a binary function so that I can call ExternalFunction with it:
double MyFunction(UnaryFunction unaryFunction)
{
BinaryFunction binaryFunction = /* want a function (a, b) -> unaryFunction(a + b) */;
return ExternalFunction(binaryFunction);
}
How do I do this? Just to be clear, I understand that this would be easy if the unary function were known at compile time, but it's not - it will be an argument to my function. Thanks in advance.
Here's a summary of my attempts. I believe I understand why these don't work, but I'm providing them so you can see what I've been thinking so far.
I can't use a lambda, because I'd have to capture UnaryFunction, and capturing lambdas can't be converted to function pointers:
double MyFunction(UnaryFunction unaryFunction)
{
BinaryFunction binaryFunction = [unaryFunction](double a, double b){ return unaryFunction(a + b); };
return ExternalFunction(binaryFunction);
}
Use std::function ? Can't get that to work either:
void MyFunction(UnaryFunction unaryFunction)
{
std::function<double(double, double)> binaryFunctionTemp = [unaryFunction](double a, double b)
{
return unaryFunction(a + b);
};
BinaryFunction binaryFunction = binaryFunctionTemp.target<double(double, double)>();
ExternalFunction(binaryFunction);
}
What about a function object? Won't work because we'd need a pointer to a member function:
class BinaryFromUnary
{
public:
BinaryFromUnary(UnaryFunction unaryFunction) : unary_(unaryFunction) {};
double operator()(double a, double b)
{
return unary_(a + b);
}
private:
UnaryFunction unary_;
};
void MyFunction(UnaryFunction unaryFunction)
{
BinaryFromUnary functionObject(unaryFunction);
std::function<double(double, double)> binaryFunction = functionObject;
ExternalFunction(binaryFunction.target<double(double, double)>());
}
Even had a go with std::bind (and probably messed it up):
struct Converter {
Converter(UnaryFunction unary) : unary_(unary) {}
double binary(double a, double b) const { return unary_(a + b); }
UnaryFunction unary_;
};
void MyFunction(UnaryFunction unaryFunction)
{
Converter converter(unaryFunction);
std::function<double(double, double)> binaryFunction = std::bind( &Converter::binary, converter, _1, _2);
ExternalFunction(binaryFunction.target<double(double, double)>());
}
Tried a couple of other things along the same lines. Any ideas would be much appreciated.
Use an external variable to hold the unary function.
Include standard disclaimers about how inelegant and non-thread safe this is, etc. but at least this is a hack consistent with the stated requirements:
#include <iostream>
typedef double (*BinaryFunction)(double a, double b);
typedef double (*UnaryFunction)(double a);
// Can't change this
double ExternalFunction(BinaryFunction binaryFunction) {
return binaryFunction(1, 2);
}
namespace foo {
thread_local UnaryFunction unaryFunction;
}
double MyBinaryFunction(double a, double b) {
return foo::unaryFunction(a + b);
}
double MyUnaryFunction(double a) {
return 2 * a;
}
double MyFunction(UnaryFunction unaryFunction) {
foo::unaryFunction = unaryFunction;
BinaryFunction binaryFunction = MyBinaryFunction;
return ExternalFunction(binaryFunction);
}
int main() {
std::cout << MyFunction(MyUnaryFunction) << std::endl; // 6
return 0;
}
I don't know your exact use-case, but there's a chance this might help you:
typedef double (*BinaryFunction)(double a, double b);
typedef double (*UnaryFunction)(double a);
// Can't change this
double ExternalFunction(BinaryFunction binaryFunction)
{
return binaryFunction(1, 2);
}
// If you always know the unary function at compile time:
// Create a wrapper function with the BinaryFunction signature that takes
// a unary function as a NTTP:
template <UnaryFunction unaryFunction>
double wrapper(double a, double b)
{
return unaryFunction(a + b);
}
// Simply use this wrapper to implement MyFunction as follows:
template <UnaryFunction unaryFunction>
double MyFunction()
{
return ExternalFunction(wrapper<unaryFunction>);
}
// Using it:
double unary1(double x) { return x * 2; }
double unary2(double x) { return x * 3; }
int main()
{
std::cout << MyFunction<unary1>() << '\n';
std::cout << MyFunction<unary2>() << '\n';
}
Have a godbolt link to play around with it as well.
Unlike the other answer, this doesn't require a global, but this also only works if you always know your function at compile-time, which there's a good chance you don't, so sorry in advance. Hope it was still interesting.

boost::polycollection, std::variant, or CRTP?

Suppose the "standard" C++ inheritance paradigm:
struct GeneralFunc
{
/*..members..*/
virtual double value(double a, double b) { return 0; }
};
struct Func_classA : GeneralFunc
{
/*..members..*/
double value(double a, double b) { return a * b; }
};
struct Func_classB : GeneralFunc
{
/*..members..*/
double value(double a, double b) { return a + b; }
};
void main(){
double a = 1.0, b = 1.0;
std::vector<GeneralFunc*> my_functions;
//fill my_functions from input
for (auto& f : my_functions)
{
double v = f->value(a, b);
}
}
I would like an implementation that is most efficient for the iteration, i.e. minimizes indirect references, maximizes inline optimizations, ect. To constrain the problem, I know beforehand each specific "type" I want to implement (I can define only the "func" types I require, without having to allow other possibilities).
several options appear available:
boost::polycollection
#include <boost/poly_collection/base_collection.hpp>
//...rest the same
boost::base_collection<GeneralFunc> my_functions
//...rest the same
std::variant
#include <variant>
//...rts
using funcs = std::variant<Func_classA, Func_classB /*..possibly more../*>
std::vector<funcs> my_functions
or CRTP (Curiously Recurring Template Pattern)
Let me know the correct nomenclature for this, but here I "upcast" the base class based on the "type" -- a kind of manual dispatch.
template<typename T>
struct GeneralFunc
{
/*..members..*/
int my_type;
double value(double a, double b) {
switch (my_type){
case TYPE_A:
return static_cast<Func_classA*>(this)->value(a,b);
/*..you get the idea..*/
I'm okay sacrificing marginal efficiency for ease of development, but is there a consensus on the "best practice" in this case?
EDITS* fixed some typos; my current development is "in-development" of CRTP the last option.
SOLUTION:
After testing, both boost::polycollection and std::variant are valid approaches. However, this turned out to be far most efficient (from memory, may be slightly off).
enum ftype { A = 0, B, C };
struct GeneralFunc
{
ftype my_type;
GeneralFunc(ftype t) : my_type(t) {}
inline double value(double a, double b) const; // delay definition until derived classes are defined
}
struct Func_classA : GeneralFunc
{
Func_classA() : GeneralFunc(ftype::A) {}
inline double value(double a, double b) const { return a * b; }
}
/* define B, C (& whatever) */
inline double GeneralFunc::value(double a, double b)
{
switch(my_type){
case (ftype::A):
return static_cast<Func_classA*>(this)->value(a,b);
/* same pattern for B, C, ect */
}
}
void main(){
std::vector<std::unique_ptr<GeneralFunc>> funcs;
funcs.push_back(std::make_unique<Func_classA>());
funcs.push_back(std::make_unique<Func_classB>());
funcs[0]->value(1.0,1.0); // calls Func_classA.value
funcs[1]->value(1.0,1.0); // calls Func_classB.value
}
I'd be tempted to just use std::function as the container, rather than re-writing it.
using GeneralFunc = std::function<double(double, double);
struct Func_classA
{
/*..members..*/
double value(double a, double b) { return a * b; }
/*explicit*/ operator GeneralFunc () const { return [this](double a, double b){ value(a, b) }; }
};
struct Func_classB
{
/*..members..*/
double value(double a, double b) { return a + b; }
/*explicit*/ operator GeneralFunc () const { return [this](double a, double b){ value(a, b) }; }
};
void main(){
double a = 1.0, b = 1.0;
std::vector<GeneralFunc> my_functions;
//fill my_functions from input
for (auto& f : my_functions)
{
double v = f(a, b);
}
}
I think there's an option you didn't include (which is the one I'd use for performance critical code), that is to create a tuple of function objects and "iterate" over such tuple. Unfortunately there is no nice API to iterate over a tuple, so one has to implement his own. See the snippet below
#include <tuple>
#include <functional>
template<int ... Id, typename Functions>
auto apply(std::integer_sequence<int, Id ...>, Functions& my_functions, double& v, double a, double b){
([](auto a, auto b){a=b;}(v, std::get<Id>(my_functions)( a, b )), ...);
}
int main(){
auto fA = [](double a, double b){return a*b;};
auto fB = [](double a, double b){return a+b;};
//create the tuple
auto my_functions=std::make_tuple(fA, fB);
double v=0;
double a = 1.;
double b = 1.;
//iterate over the tuple
apply(std::make_integer_sequence<int, 2>(), my_functions, v, a, b);
}
This way you create a type safe zero overhead abstraction, since the compiler knows everything about the types you use (you don't need any type erasure mechanism). Also there's no need of virtual functions (same as in CRTP), so the compiler will probably inline the function calls. The snippet above uses C++17 generic lambdas, could be also implemented in C++14 or C++11 compliant way, but it would be more verbose. I would prefer this over CRTP because to me it looks more readable: no static cast to the derived class, and no artificial hierarchy of inheritance.
EDIT: from your answer looks like you don't really need the CRTP here, what you write using the CRTP solution is equivalent to this
enum ftype { A = 0, B, C };
auto fA = [](double a, double b){return a*b;};
auto fB = [](double a, double b){return a+b;};
int main(){
std::vector<ftype> types(2);
types[0]=A;
types[1]=B;
auto value = [&types](double a, double b, ftype i){
switch(i){
case (ftype::A):
return fA(a,b);
break;
case (ftype::B):
return fB(a,b);
break;
}
};
double v=value(1., 1., A);
v=value(1., 1., B);
}
Might be a matter of taste, but I think the version above is more readable (you don't really need a common base class, or static cast to the derived class).

Replace function pointers by templates in C++11

I have a script (python symbolic toolbox) which auto-generates C++11 code to fill the entries of a matrix, like:
double J00(double a, double b) {return a+b;}
double J01(double a, double b) {return a-b;}
double J10(double a, double b) {return -a+b;}
double J11(double a, double b) {return -a-b;}
Now I could use an array of function pointers to store all the functions and fill the matrix, i.e.:
typedef double (*FillFunction) (double a, double b);
double J00(double a, double b) {return a+b;}
double J01(double a, double b) {return a-b;}
double J10(double a, double b) {return -a+b;}
double J11(double a, double b) {return -a-b;}
void main()
{
FillFunction J[2][2] = {{J00, J01}, {J10, J11}};
param0 = 0;
param1 = 1;
double Jresult[2][2];
for(int i = 0; i < 2; i++)
{
for(int j = 0; j < 2; j++)
{
Jresult[i][j] = J[i][j](param0, param1);
}
}
}
However, this is a performance critical part of my code and I would thus rather not use function pointers, especially since the size of the matrix and all functions are know at compile time. Is there a neat way to do this with templates or anything similar?
Note: I did not compile this code so I don't know if it would actually work, but I hope you get the idea.
If you are using external code generator anyway, just generate this:
double Jresult[2][2] = {
{J00(param0, param1), J01(param0, param1)},
{J10(param0, param1), J11(param0, param1)},
};

C++ using only one default argument in function

How can i use only 3rd argument (first and second arguments must be default)?
Like this:
double func(const double a = 5, const double b = 6, const double c = 7);
int main()
{
cout << "A = " << func(10) << endl << endl; //if i do like this, i'm using first argument, but not 3rd.
}
C++ doesn't support what you want to do currently. However, there are ways around it. You can use the Named Parameter Idiom or boost's Paremeter library.
I recommend the former. It's clearer, easier to debug, etc...
The only way to do this would be to swap the argument order:
double func(const double c = 7, const double a = 5, const double b = 6);
You could (possibly) use a few wrapper types and overloading, then use the types to name the parameter when calling:
struct A { double a; constexpr static double def = 5.0; };
struct B { double b; constexpr static double def = 6.0; };
struct C { double c; constexpr static double def = 7.0; };
double func(double a=A::def, double b=B::def, double c=C::def) { /* whatever */ }
double func(A a) { return func(a.a, B::def, C::def); }
double func(B b) { return func(A::def, b.b, C::def); }
double func(C c) { return func(A::def, B::def, c.c); }
int main()
{
func(A{3.0});
func(B{9.0});
func(C{12.0});
}

Passing member function pointer to class-less function

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));