I would like to get some function/functor acts as a composite function/functor:
Specifically, I have functions f(x, y), and g(u, v), and I want to create a function pointer or functor h(t) = f(g(t,C1), C2), so that I can pass functor h into a for_each() loop, where C1, C2 are some constants.
Or, let's do it in my real example:
I have a function double g(T1 u, T2 v) which calculate something. I want to loop through all u from a vector vector<T1> vecInput, with fixed 2nd argument t2VConst. After calculating all these numbers, I want to save them into a vector vector<double> results.
I would like to do it with something similar to this:
foreach(vecInput.begin(), vecInput.end(), std::bind2nd(&results::push_back, std::bind2nd(g, t2VConst)))
Note that in this case, the f(x,y) function is really a member function vector::push_back. (It seems that push_back only have one argument. However, as a member function, it has an extra argument, which is the object itself.)
To make the case worse, I really have to do it in C++03, not C++11. Is there any solution? Moreover, I wish the solution can be cleaner (if it can be done in one line like above).
UPDATE
Related issue for bind2nd():
I got compile error, and now I reduce it to a simpler code to look at it:
#include <functional>
#include <algorithm>
#define CASE2 // choose define of CASE1 to CASE3
#ifdef CASE1
double g(double x, double y) // 1. OK
#endif
#ifdef CASE2
double g(double &x, double y) // 2. overload error
#endif
#ifdef CASE3
double g(double *x, double y) // 3. OK
#endif
{
#ifdef CASE2
x = 5.0;
#endif
#ifdef CASE3
*x = 5.0;
#endif
// Note: no case1, since in case 1, x is a local variable,
// no meaning to assign value to it.
return 3.0;
}
int main(int argc, char *argv[])
{
double t = 2.0;
double u;
#if defined(CASE1) || defined(CASE2)
u = std::bind2nd(std::ptr_fun(&g), 3.0)(t);
#endif
#ifdef CASE3
u = std::bind2nd(std::ptr_fun(&g), 3.0)(&t);
#endif
}
I don't know why CASE 2 fails...
I have functions f(x, y), and g(u, v), and I want to create a function pointer or functor h(t) = f(g(t,C1), C2). I have to do it in C++03.
It's not possible to compose functions using only the adapters available in the standard library of C++03. Obviously, nothing stops you from implementing this functionality on your own. However, if you want to utilize any of the existing libraries, and get a true one-liner, there are few alternatives:
Option #1: SGI extensions
libstdc++ is shipped with the standard library extensions from SGI. It provides several additional adapters and functors, namely: compose1, compose2 and constant1. They can be combined in the following way:
#include <functional>
#include <ext/functional>
int f(int x, int y);
int g(int u, int v);
const int arg = 1;
const int C1 = 2;
const int C2 = 3;
__gnu_cxx::compose2(std::ptr_fun(&f)
, std::bind2nd(std::ptr_fun(&g), C1)
, __gnu_cxx::constant1<int>(C2)
)(arg);
Option #2: TR1 extensions
The initial implementation of C++11's std::bind can be also found in tr1 extension libraries:
#include <tr1/functional>
int f(int x, int y);
int g(int u, int v);
const int arg = 1;
const int C1 = 2;
const int C2 = 3;
std::tr1::bind(&f
, std::tr1::bind(&g
, std::tr1::placeholders::_1
, C1)
, C2
)(arg);
Option #3: Boost library
Boost.Bind library is probably the most portable solution:
#include <boost/bind.hpp>
int f(int x, int y);
int g(int u, int v);
const int arg = 1;
const int C1 = 2;
const int C2 = 3;
boost::bind(&f, boost::bind(&g, _1, C1), C2)(arg);
The f(x,y) function is really a member function vector::push_back
When it comes to binding a member function in C++03 you would normally use std::mem_fun together with std::bind1st to bind the object parameter:
Class object;
std::bind1st(std::mem_fun(&Class::func), &object)(arg);
However, this will fail for member functions taking its parameter by reference. Once again, you could use Boost/TR1 instead:
boost::bind(&std::vector<double>::push_back
, &results
, boost::bind(&g, _1, C1)
)(arg);
Note that when switching to C++11 you'd need to manually resolve overloaded std::vector<double>::push_back.
But fortunately, your use-case qualifies to be replaced by std::transform algorithm with std::back_inserter, that will take care of calling push_back member function of your vector for transformed arguments.
#include <algorithm>
#include <functional>
#include <iterator>
int g(int u, int v);
const int C1 = 2;
std::vector<int> input, output;
std::transform(input.begin(), input.end()
, std::back_inserter(output)
, std::bind2nd(std::ptr_fun(&g), C1));
DEMO
It's important to remember that these library functions aren't magic, they just deduce rather involved types.
In your case, you don't need all this flexibility, if only because you know you'll need vector::push_back. Instead of deducing a rather involved type, just create a type explicitly to capture the function. There's even a library type which does this, std::back_insert_iterator, but in general you can do it yourself.
So, you'll end up with a template class that takes typenames T1 and T2, stores &g, T2 C2, and std::vector<double>&. It simply implements void operator()(T1 t1) { v.pus_back(g(t1, C2)); }.
Related
I have a function which calculates the first derivative dy/dx for discrete values y(x) stroed as std::vector:
vector<double> CalcDerivative(vector<double>&y, vector<double>&x) {...}
Often the spacing dx is constant so it would be more efficient to pass a double to this function instead of vector<double> as argument x.
I tried to accomplish this with std::variant. The drawback with std::variant is however, that it cannot handle references so the vector x has to be copied while being passed as a variant to the function.
For now I solved the problem by defining two functions with overloaded arguments. But I wonder whether there is a more elegant solution which won't duplicate the code for the two cases (x as double or as vector<double>).
One possible solution might be to define the "worker" function such that it is independent of the "number of passed doubles". For this purpose, std::span is suitable. The exemplary solution might look like:
std::vector<double> CalcDWorker(
std::span<const double> y, std::span<const double> x)
{
... // x.size() == 1 indicates uniform spacing
}
std::vector<double> CalcDerivative(
const std::vector<double>& y, const std::vector<double>& x)
{
return CaclDWorker({y.begin(), y.end()}, {x.begin(), x.end()});
}
std::vector<double> CalcDerivative(
const std::vector<double>& y, double x)
{
return CaclDWorker({y.begin(), y.end()}, {&x, 1});
}
It requires C++20, but there are third-party span implementations available also for earlier C++ versions (such as the one provided by Boost).
Live demo: https://godbolt.org/z/n6adEKWes
I was wondering if it is possible to apply boost's automatic differentiation library:
#include <boost/math/differentiation/autodiff.hpp>
to functions which return std::complex<double> values?
For instance, consider the multivariate complex valued function:
#include <complex>
std::complex<double> complex_function(double a, double c){
// Assuming a < 0
return exp(sqrt(std::complex(a, 0.0))) + sin(c);
}
How can I take the derivative wrt to a or c using Boost's autodiff? Is that even possible?
is [it] possible to apply boost's automatic differentiation library to functions which return std::complex<double> values?
Not at the present time.
A version that did might look something like this:
// THIS DOES NOT COMPILE - FOR DISCUSSION ONLY
#include <boost/math/differentiation/autodiff.hpp>
#include <iostream>
#include <complex>
namespace ad = boost::math::differentiation;
template <typename T0, typename T1>
auto complex_function(T0 a, T1 c){
// Assuming a < 0
return exp(sqrt(complex(a, 0.0))) + sin(c); // DOES NOT COMPILE
}
int main() {
auto const a = ad::make_fvar<double, 2>(-3);
auto const c = 0.0;
auto const answer = complex_function(a, c);
return 0;
}
This requires complex to be defined specific to autodiff::fvar template types, similar to how other mathematical functions (exp, sqrt, etc.) have overloads in the autodiff library, and are called via ADL.
As #user14717 pointed out in the comments, it is a special case of vector-valued autodiff since the return value isn't a single truncated Taylor polynomial, but rather a tuple of them.
I would like to compute the function composition -- f ( g (param) ). Here is what I tried:
auto fComposition(auto&& f, auto&& g, auto&&... params)
{
/* some stuff */
auto result = std::forward<decltype(f)>(f)(
std::forward<decltype(g)>(g)(
std::forward<decltype(params)>(param)
)
);
/* other stuff */
return result;
};
Compiling with
g++ -std=c++17 src.cpp
basic test
#include <random>
#include <math.h>
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<double> distr(-1.0, 1.0);
auto xx = fComposition(round, distr, gen);
return 0;
}
I've got the message that it doesn't recognize the type of first function .
BTW, is this really your code? You're not expanding params so it should not compile.
I. The way you define composition, it is indistinguishable from a simple invocation: your fComposition(f, g, arg) is the same as f(g(arg)) except for extra characters typing. The real composition is usually a combinator that accepts two functions and returns a closure that, when invoked on actual arguments, applies them in succession. Something like:
template<class F, class G> auto comp(F f, G g) {
return [f, g](auto &&... args) {
return f(g(std::forward<decltype(args)>(args)...));
};
}
(Note by-values bindings. In C++17, they are more advanced than twenty years ago. :) You can add std::moves and std::forwards by taste.)
This way you compose two functions:
auto fg = comp(f, g);
and later invoke the result on arguments:
auto x = fg(arg1, arg2);
II. But really, why limit ourselves with two operands? In Haskell, (.) is a single binary function. In C++, we can have a whole tree of overloads:
template<class Root, class... Branches> auto comp(Root &&root, Branches &&... branches) {
return [root, branches...](auto &&...args) {
return root(branches(std::forward<decltype(args)>(args)...)...);
};
}
Now you can encapsulate any AST in a single callable:
int f(int x, int y) { return x + y; }
int g(int x) { return x * 19; }
int h(int x) { return x + 2; }
#include <iostream>
int main() {
auto fgh = comp(f, g, h);
std::cout << fgh(2) << '\n';
}
A similar technique was the only way known to me to have anonymous closures in C++ prior to 11 standard.
III. But wait, is there a library solution? In fact, yes. From std::bind's description
If the stored argument arg is of type T for which std::is_bind_expression<T>::value == true (for example, another bind expression was passed directly into the initial call to bind), then bind performs function composition: instead of passing the function object that the bind subexpression would return, the subexpression is invoked eagerly, and its return value is passed to the outer invokable object. If the bind subexpression has any placeholder arguments, they are shared with the outer bind (picked out of u1, u2, ...). Specifically, the argument vn in the std::invoke call above is arg(std::forward<Uj>(uj)...) and the type Vn in the same call is std::result_of_t<T cv &(Uj&&...)>&& (cv qualification is the same as that of g).
Sorry, no examples here at this moment. >_<
P.S. And yes, std::round is an overloaded function so you should typecast it to specify which exactly overload you need to be composed.
The include of random includes cmath, which in libstdc++ also defines several of the math operators (including round) in the default namespace as well as in the std namespace. (See this answer for the rationale.) And C++'s round has multiple overloads. As a result, you have several versions of round available, and your function doesn't know which round you want to use, thus the error message about ambiguity. The correct solution is to disambiguate which round you mean. You can do this with a static cast:
static_cast<double(*)(double)>(round)
Since you have to go through the trouble anyway, you may as well also use the cmath header instead of math.h and use std::round instead. At least then you know that it's going to be overloaded up front.
I have a long algorithm that should process some instruction described from more than one #define in order to reduce drastically my source-code. For example:
#define LongFunction(x, y, alg) return alg(x, y)
#define Alg1(x, y) ((x)+(y))
#define Alg2(x, y) ((x)^((x)-(y)))
And all I need to do is
LongFunction(x, y, Alg1);
LongFunction(x, y, Alg2);
I'd like to not pass a function as parameter because LongFunction is full of loops and I want that the code will be as fast as possible. How can I accomplish this task smartly?
There are many ways to parameterize on function.
Using macros might seem simple, but macros don't respect scopes, and there are problems with parameter substitution and side-effects, so they're Evil™.
In C++11 and later the most natural alternative is to use std::function and lambdas, like this:
#include <functional> // std::function
#include <math.h> // pow
using std::function;
auto long_function(
double const x,
double const y,
function<auto(double, double) -> double> alg
)
-> double
{
// Whatever.
return alg( x, y ); // Combined with earlier results.
}
auto alg1(double const x, double const y)
-> double
{ return x + y; }
auto alg2(double const x, double const y)
-> double
{ return pow( x, x - y ); }
#include <iostream>
using namespace std;
auto main() -> int
{
cout << long_function( 3, 5, alg1 ) << endl;
}
Regarding “fast as possible”, with a modern compiler the macro code is not likely to be faster. But since this is important, do measure. Only measurements, for release build and in the typical execution environment, can tell you what's fastest and whether the speed is relevant to the end user.
Of old, and formally, you could use the inline specifier to hint to the compiler that it should machine code inline calls to a function. Modern compilers are likely to just ignore inline for this (it has another more guaranteed meaning wrt. ODR). But it probably won't hurt to apply it. Again, it's important to measure. And note that results can vary with compilers.
One alternative to the above is to pass a simple function pointer. That might be faster than std::function, but is less general. However, in the other direction, you can templatize on a type, with a member function, and that gives the compiler more information, more opportunity to inline, at the cost of not being able to e.g. select operations from array at runtime. I believe that when you measure, if this is important enough, you'll find that templatization yields fastest code. Or at least as fast as the above.
Example of templatizing on a type that provides the operation:
#include <math.h> // pow
template< class Op >
auto long_function( double const x, double const y )
-> double
{
// Whatever.
return Op()( x, y ); // Combined with earlier results.
}
struct Alg1
{
auto operator()(double const x, double const y)
-> double
{ return x + y; }
};
struct Alg2
{
auto operator()(double const x, double const y)
-> double
{ return pow( x, x - y ); }
};
#include <iostream>
using namespace std;
auto main() -> int
{
cout << long_function<Alg1>( 3, 5 ) << endl;
}
By the way, note that ^ is not an exponentiation operator in C++ (it is in e.g. Visual Basic). In C and C++ it's a bitlevel XOR operator. In the code above I've assumed that you really meant exponentiation, and used the pow function from <math.h>.
If, instead, you really meant bitlevel XOR, then the arguments would need to be integers (preferably unsigned integers), which then would indicate that you want argument types for long_function depending on the argument types for the specified operation. That's more thorny issue, but involves either overloading or templating, or both. If that's what you really want then please do elaborate on that.
I have a base function
int base(const int i, const double &x)
In this function, I consider i to be a "parameter" (which can take predefined values from 0 to N-1), while x I consider to be the actual "argument" (which can take any arbitrary value).
What I need is to create an array of function pointers int (*pointers[N])(const double &x). Each member of the array corresponds to a different value for the parameter i and thus each call pointers[n](x) should be equivalent to a call base(n, x).
Is there a way to achieve this functionality?
I have been trying to educate myself about functors (is this a way to go?) and recently also looked into std::bind but my understanding is that it only works with C++11 (which I currently cannot use).
Any advice or code snippet would be really helpful. Thanks!
You can use non-capturing lambdas for that:
typedef int (*fp)(double);
fp p1 = [](double x) -> int { return base(1, x); };
fp p2 = [](double x) -> int { return base(2, x); };
fp p3 = [](double x) -> int { return base(3, x); };
This doesn't work for capturing lambdas, and so you can't generate those programatically. There's essentially no difference between this and spelling out one function for each value in C:
int f1(double x) { return base(1, x); }
fp p = f1;