is it possible to have a std::function return an std::function and use various functions recursive with other std::functions, say a function of a function? In other words I want to collapse an array of functions into a single function.
for example going off basic tutorials
double genFunc(double x, std::function<double (double x)>f)
{
double res = f(x);
return res;
}
double square(double x){
return x * x;
}
double dbl_sq(double x){
return square(x * x);
}
How can i modify this to allow for nested std::function<std::function> calls?
I'm not entirely sure what you are asking, but I'll take a stab at it.
So, you want a std::function that's nested, but calls all of the elements in one call? That would mean you could do several things, but the simplest would be, something like this:
std::function<double(double)> nest(const std::function<double(double)> functions[], const int count) {
if (count == 1) {
return functions[0];
}
return [=](double input) {
return nest(functions + 1, count - 1)(functions[0](input));
};
}
int main()
{
static const auto sq = [](double input) {
return input * input;
};
static const auto dbl_sq = [](double input) {
return sq(input * input);
};
static const auto dbl = [](double input) {
return input * 2;
};
static const std::function<double(double)> sqrt = ::sqrt;
// now lets construct a 'nested lambda'
static const std::function<double(double)> funcs[] = {
sq, dbl, sqrt
};
static const std::function<double(double)> func = nest(funcs, 3);
std::cout << func(4) << std::endl; // 5.65685
std::cout << ::sqrt((4 * 4) * 2) << std::endl; // 5.65685
}
Which simply 'collapses' an array of functions into a single function.
If this isn't what you are requesting, then please edit your original question to make it more clear what you wish to accomplish.
Related
Following up to a previous question I asked in Fixing parameters of a fitting function in Nonlinear Least-Square GSL (successfully answered by #zkoza), I would like to implement an algorithm that can fit data to a non-linear function, by fixing some of its parameters while leaving other parameters to change for finding the best fit to the data. The difference to my previous question is that I want to have two independent variables instead of one independent variable.
Non-linear function used to fit the data
double gaussian(double x, double b, double a, double c)
{
const double z = (x - b) / c;
return a * std::exp(-0.5 * z * z);
}
In my previous question I was considering that x was the only independent variable. Now I would like to consider two independent variables, x and b.
The original algorithm used to fit a non-linear function using only one independent variable (while fixing variable a) is a C++ wrapper of the GSL nonlinear least-squares algorithm (borrowed from https://github.com/Eleobert/gsl-curve-fit/blob/master/example.cpp):
template <typename F, size_t... Is>
auto gen_tuple_impl(F func, std::index_sequence<Is...> )
{
return std::make_tuple(func(Is)...);
}
template <size_t N, typename F>
auto gen_tuple(F func)
{
return gen_tuple_impl(func, std::make_index_sequence<N>{} );
}
template <class R, class... ARGS>
struct function_ripper {
static constexpr size_t n_args = sizeof...(ARGS);
};
template <class R, class... ARGS>
auto constexpr n_params(R (ARGS...) )
{
return function_ripper<R, ARGS...>();
}
auto internal_solve_system(gsl_vector* initial_params, gsl_multifit_nlinear_fdf *fdf,
gsl_multifit_nlinear_parameters *params) -> std::vector<double>
{
// This specifies a trust region method
const gsl_multifit_nlinear_type *T = gsl_multifit_nlinear_trust;
const size_t max_iter = 200;
const double xtol = 1.0e-8;
const double gtol = 1.0e-8;
const double ftol = 1.0e-8;
auto *work = gsl_multifit_nlinear_alloc(T, params, fdf->n, fdf->p);
int info;
// initialize solver
gsl_multifit_nlinear_init(initial_params, fdf, work);
//iterate until convergence
gsl_multifit_nlinear_driver(max_iter, xtol, gtol, ftol, nullptr, nullptr, &info, work);
// result will be stored here
gsl_vector * y = gsl_multifit_nlinear_position(work);
auto result = std::vector<double>(initial_params->size);
for(int i = 0; i < result.size(); i++)
{
result[i] = gsl_vector_get(y, i);
}
auto niter = gsl_multifit_nlinear_niter(work);
auto nfev = fdf->nevalf;
auto njev = fdf->nevaldf;
auto naev = fdf->nevalfvv;
// nfev - number of function evaluations
// njev - number of Jacobian evaluations
// naev - number of f_vv evaluations
//logger::debug("curve fitted after ", niter, " iterations {nfev = ", nfev, "} {njev = ", njev, "} {naev = ", naev, "}");
gsl_multifit_nlinear_free(work);
gsl_vector_free(initial_params);
return result;
}
template<auto n>
auto internal_make_gsl_vector_ptr(const std::array<double, n>& vec) -> gsl_vector*
{
auto* result = gsl_vector_alloc(vec.size());
int i = 0;
for(const auto e: vec)
{
gsl_vector_set(result, i, e);
i++;
}
return result;
}
template<typename C1>
struct fit_data
{
const std::vector<double>& t;
const std::vector<double>& y;
// the actual function to be fitted
C1 f;
};
template<typename FitData, int n_params>
int internal_f(const gsl_vector* x, void* params, gsl_vector *f)
{
auto* d = static_cast<FitData*>(params);
// Convert the parameter values from gsl_vector (in x) into std::tuple
auto init_args = [x](int index)
{
return gsl_vector_get(x, index);
};
auto parameters = gen_tuple<n_params>(init_args);
// Calculate the error for each...
for (size_t i = 0; i < d->t.size(); ++i)
{
double ti = d->t[i];
double yi = d->y[i];
auto func = [ti, &d](auto ...xs)
{
// call the actual function to be fitted
return d->f(ti, xs...);
};
auto y = std::apply(func, parameters);
gsl_vector_set(f, i, yi - y);
}
return GSL_SUCCESS;
}
using func_f_type = int (*) (const gsl_vector*, void*, gsl_vector*);
using func_df_type = int (*) (const gsl_vector*, void*, gsl_matrix*);
using func_fvv_type = int (*) (const gsl_vector*, const gsl_vector *, void *, gsl_vector *);
template<auto n>
auto internal_make_gsl_vector_ptr(const std::array<double, n>& vec) -> gsl_vector*;
auto internal_solve_system(gsl_vector* initial_params, gsl_multifit_nlinear_fdf *fdf,
gsl_multifit_nlinear_parameters *params) -> std::vector<double>;
template<typename C1>
auto curve_fit_impl(func_f_type f, func_df_type df, func_fvv_type fvv, gsl_vector* initial_params, fit_data<C1>& fd) -> std::vector<double>
{
assert(fd.t.size() == fd.y.size());
auto fdf = gsl_multifit_nlinear_fdf();
auto fdf_params = gsl_multifit_nlinear_default_parameters();
fdf.f = f;
fdf.df = df;
fdf.fvv = fvv;
fdf.n = fd.t.size();
fdf.p = initial_params->size;
fdf.params = &fd;
// "This selects the Levenberg-Marquardt algorithm with geodesic acceleration."
fdf_params.trs = gsl_multifit_nlinear_trs_lmaccel;
return internal_solve_system(initial_params, &fdf, &fdf_params);
}
template <typename Callable, auto n>
auto curve_fit(Callable f, const std::array<double, n>& initial_params, const std::vector<double>& x, const std::vector<double>& y) -> std::vector<double>
{
// We can't pass lambdas without convert to std::function.
//constexpr auto n = 3;//decltype(n_params(f))::n_args - 5;
//constexpr auto n = 2;
assert(initial_params.size() == n);
auto params = internal_make_gsl_vector_ptr(initial_params);
auto fd = fit_data<Callable>{x, y, f};
return curve_fit_impl(internal_f<decltype(fd), n>, nullptr, nullptr, params, fd);
}
In order to fix one of the parameters of the gaussian function, #zkoza proposed to use functors:
struct gaussian_fixed_a
{
double a;
gaussian_fixed_a(double a) : a{a} {}
double operator()(double x, double b, double c) const { return gaussian(x, b, a, c); }
};
And these last lines show how I would create a fake dataset of observed data (with some noise which is normally distributed) and test the fitting curve function with two independent variables, given by the vectors xs and bs.
int main()
{
auto device = std::random_device();
auto gen = std::mt19937(device());
auto xs = linspace<std::vector<double>>(0.0, 1.0, 300);
auto bs = linspace<std::vector<double>>(0.4, 1.4, 300);
auto ys = std::vector<double>(xs.size());
double a = 5.0, c = 0.15;
for(size_t i = 0; i < xs.size(); i++)
{
auto y = gaussian(xs[i], a, bs[i], c);
auto dist = std::normal_distribution(0.0, 0.1 * y);
ys[i] = y + dist(gen);
}
gaussian_fixed_a g(a);
auto r = curve_fit(g, std::array{0.11}, xs, bs, ys);
std::cout << "result: " << r[0] << ' ' << '\n';
std::cout << "error : " << r[0] - c << '\n';
}
Do you have any idea on how I could implement the two-independent variables non-linear fitting?
The solution, as suggested in the comments by #BenVoigt, is to replace the x and b independent variables in the gaussian function with 'one independent variable' given as a vector, whose first element is x and the second element is b.
Also the backbone of the nonlinear fitting needs to be slightly edited. The edits consist:
Replace the fit_data functor with:
struct fit_data
{
const std::vector< vector<double> > &t;
const std::vector<double>& y;
// the actual function to be fitted
C1 f;
};
Such that, the independent variable is no longer a vector but rather a vector of a vector (aka a matrix).
Replace within the function internal_f.
a) double ti = d->t[i] with std::vector<double> ti = d->t[i]
b) auto func = [ti, &d](auto ...xs) with auto func = [ti, &d](auto ...xs_matrix)
c) return d->f(ti, xs...) with return d->f(ti, xs_matrix...)
Replace within curve_fit function:
a) const std::vector<double>& x with const std::vector< vector<double> > &xs_matrix
b) auto fd = fit_data<Callable>{x, y, f} with auto fd = fit_data<Callable>{xs_matrix, y, f}
Whereas the gaussian function, gaussian_fixed_a functor and the fitting function looks like:
double gaussian(std::vector<double> x_vector, double a, double c)
{
const double z = (x_vector[0] - x_vector[1]) / c;
return a * std::exp(-0.5 * z * z);
}
struct gaussian_fixed_a
{
double a;
gaussian_fixed_a(double a) : a{a} {}
double operator()(std::vector<double> x_vector, double c) const { return gaussian(x_vector, a, c); }
};
double fittingTest(const std::vector< vector<double> > &xs_matrix, const std::vector<double> ys, const double a){
gaussian_fixed_a g(a);
auto r = curve_fit(g, std::array{3.0}, xs_matrix, ys);
return r[0]);
}
My code
bool func(int i){
if(i==x)return 1;
else return 0;
}
int findFrequency(vector<int> v, int x){
int ans=count_if(v.begin(),v.end(),func);
return ans;
}
How do I pass 'x' in the count_if function?
Here, 'x' is the number present in the vector which is to be counted.
To count a specific value in the vector, you can use std::count():
std::vector<int> v;
int x = 1;
auto c = std::count(v.begin(), v.end(), x);
If you want to use std::count_if(), you can use a function object with state:
struct if_counter {
int x;
bool operator()(int y) { return x == y; }
};
auto x = 1;
auto c = std::count_if(v.begin(), v.end(), if_counter{x});
Basically, this is the same as you get from using a lambda expression:
int x = 1;
c = std::count_if(v.begin(), v.end(), [x](int y){ return x == y; });
Complete Example
Using a lambda function inside your findFrequency function is a nice clean approach. The above answer #idclev notes this, here's a version that's more similar to your existing code:
int findFrequency(std::vector<int>& v, int x) {
auto func = [&] (int i) { // [&] means 'capture by reference'
if (i == x) return 1;
else return 0;
};
int res = std::count_if(v.begin(), v.end(), func);
return res;
}
(1) How do you create an std::vector of functions so that you could do something like this:
int main ()
{
std::vector<????> vector_of_functions;
// Add an adding function into the vector
vector_of_functions.push_back(
double function (double a, double b) {
return a + b
}
);
// Add a multiplying function into the vector
vector_of_functions.push_back(
double function (double a, double b) {
return a * b;
}
);
// Use the functions
std::cout << "5 + 7 = " << vector_of_functions[0](5, 7); // >>> 5 + 7 = 12
std::cout << "5 * 7 = " << vector_of_functions[1](5, 7); // >>> 5 * 7 = 35
return 0;
}
While I would like if the function return and parameters could be any type, it doesn't have to be. I'm fine if they're a set type.
(2) How do you pass that kind of std::vector as a parameter of a function.
void func (std::vector<???> vof) {
std::cout << vof[0](5, 7);
};
int main ()
{
std::vector<????> vector_of_functions;
// Add an adding function into the vector
vector_of_functions.push_back(
double function (double a, double b) {
return a + b
}
);
// Add a multiplying function into the vector
vector_of_functions.push_back(
double function (double a, double b) {
return a * b;
}
);
// Call the function
func( vector_of_functions ); // >>> 12
return 0;
}
(3) How do I do the same thing except where the function is a method of a class defined in a header file.
The .cpp code will be the same as before, except the function will be void ClassName::func(...);
The .h code will be something like this:
class ClassName {
public:
ClassName();
void func(????);
}
If you can use C++11+, than you can use std::function and std::bind, or lambda.
So, something like:
using func = std::function<double(double, double)>;
using vfuncs = std::vector<func>;
vfuncs vf;
vf.push_back([](double first, double second) { return first + second; });
vf.push_back([](double first, double second) { return first * second; });
/* obj is some function, which member function you want to call */
vf.push_back([&obj](double first, double second) { return obj.op(first, second); });
Use std::function<double(double,double)> as the template parameter for your vector and then use either std::function<double(double,double)> objects or something that can convert to std::function<double(double,double)>, such as a lamda: for example [](double a, double b) -> double { return a + b; }.
This function calculates the value of the Derivation of the Function Foo at X
double Deriv( double(* Foo)(double x), double X )
{
const double mtDx = 1.0e-6;
double x1 = Foo(X+mtDx);
double x0 = Foo(X);
return ( x1 - x0 ) / mtDx;
}
I would like to write a Funktion, which returned not the value of the derivation at X, but a new function which IS the derivation of the function Foo.
xxxx Deriv( double(* Foo)(double x) )
{
return Derivation of Foo;
}
Then it would be possible to write
SecondDeriv = Deriv( Deriv( Foo ))
Is it possible in C++ according to new standard to write such a function ?
I think with old standard it was impossible.
Once you can compute the value of a function at one point, you can use that to implement your general function. Lambda expressions allow you to generate those derived functions easily:
auto MakeDerivative(double (&f)(double)) {
return [=](double x) { return Deriv(f, x); };
}
If you want to be able to use stateful functions, you may need to update your Deriv to be a function template whose first parameter type is a template parameter. This is true in particular if you want to apply MakeDerivative repeatedly (since its return types are stateful closures):
template <typename F>
double Deriv(F f, double x) {
// your code here
}
template <typename F>
auto MakeDerivative(F f) {
return [=](double x) { return Deriv(f, x); };
}
However, you may be interested in techniques like "automatic differentiation" which allow you to express the derivative directly in terms of the definition of the original function, at the cost of working on an enlarged domain (an infinitesimal neighbourhood, essentially).
Here's one way to do it.
#include <iostream>
#include <functional>
std::function<double(double)> Deriv( double(*Foo)(double x) )
{
auto f = [Foo](double x) -> double
{
const double mtDx = 1.0e-6;
double x1 = Foo(x+mtDx);
double x0 = Foo(x);
return ( x1 - x0 ) / mtDx;
};
return f;
}
double Foo(double x)
{
return x*x;
}
double Bar(double x)
{
return x*x*x;
}
int main()
{
std::cout << Deriv(Foo)(10) << std::endl;
std::cout << Deriv(Bar)(10) << std::endl;
}
Output:
20
300
Using generic lambda, implementing a toy derivative is simple. In the following code, derivative is a derivative operator in the math sense. It accepts a function double -> double, produces its derivative double -> double.
#include <iostream>
double delta = 0.001;
auto derivative = [] ( auto foo ) {
return [foo] (double x) {
// the simplest formula for numeric derivative
return (foo(x + delta) - foo(x)) / delta;
};
};
// test
int main() {
auto quar = [] ( double x ) { return x * x; };
auto dev_quar = derivative(quar);
auto dev_dev_quar = derivative(dev_quar);
for ( double s = 0.0; s < 10.0; ++s ) {
std::cout << "(" << quar(s) << "," << dev_quar(s) << "," << dev_dev_quar(s) << ")\n";
}
}
Creating a functor requires an unnecessary boiler plate. The state has to be written 4 times!
struct f{
double s; // 1st
f(double state): s(state) {} // 2nd, 3rd and 4th
double operator() (double x) {
return x*s;
}
};
is there a library with a macro that would be just double functor(state)(x){ return x*state; } or something similar.
BOOST_FOREACH is a macro adapter that works well. I'm looking for something similar.
any suggestions on how to write one is appreciated too.
ps. using struct for functor is faster then bind Class's operator() or bind a function as a functor?
Update(1)
in regards to lambdas:
the functor has to be modular, meaning, it should be reusable in other function. lambdas have to be within a function -- lambda has to be in main to be called from main and other functions outside of main, can't call the lambda defined in main.
How about relying on aggregate initialization? Simply do not declare the constructor:
struct f {
double s;
double operator()(double x) {
return x * s;
}
};
use it like this
int main()
{
auto ff = f{42};
std::cout << ff(2);
return 0;
}
Define the functionality you want, e.g., you multiplication, as a function and then use std::bind() to create a suitable function object:
#include <functional>
double some_operation(double state, double x) {
return state * x;
}
int main() {
auto function = std::bind(&some_operation, 17, std::placeholders::_1);
return function(18);
}
Since a call through a function pointer generally can't be inlined, you might want to write your function as a function object instead:
#include <functional>
struct some_operation {
double operator()(double state, double x) const {
return state * x;
}
};
int main() {
auto function = std::bind(some_operation(), 17, std::placeholders::_1);
return function(18);
}
Below is a test program which seems to indicate that the speed of a hand-crafted function object and a bound function object are about the same, i.e., the results I get are
in 90 ms, functor as a struct; result = 1.5708e+16
in 262 ms, function pointer through bind; result = 1.5708e+16
in 261 ms, function through bind; result = 1.5708e+16
in 87 ms, function object through bind; result = 1.5708e+16
in 88 ms, non-called bind with function; result = 1.5708e+16
in 88 ms, non-called bind with function pointer; result = 1.5708e+16
using a recent version of clang (more precisely: clang version 3.4 (trunk 182411)) on a MacOS system optimizing with -O2 option. Using and gcc (more precisely: gcc version 4.9.0 20130811 (experimental) (GCC)) gives similar results.
It seems it makes a difference whether the function object is build in the local context or passed via template argument to a separate function. This difference is interesting as I would expect that most of the uses of bind() a function will result in passing off the resulting function object somewhere.
The code is based on https://stackoverflow.com/a/18175033/1120273:
#include <iostream>
#include <functional>
#include <chrono>
using namespace std;
using namespace std::placeholders;
using namespace std::chrono;
struct fs {
double s;
fs(double state) : s(state) {}
double operator()(double x) {
return x*s;
}
};
struct ff {
double operator()(double x, double state) const {
return x * state;
}
};
double fb(double x, double state) {
return x*state;
}
template <typename Function>
void measure(char const* what, Function function)
{
const auto stp1 = high_resolution_clock::now();
double sresult(0.0);
for(double x=0.0; x< 1.0e8; ++x) {
sresult += function(x);
}
const auto stp2 = high_resolution_clock::now();
const auto sd = duration_cast<milliseconds>(stp2 - stp1);
cout << "in " << sd.count() << " ms, ";
cout << what << "; result = " << sresult << endl;
}
int main() {
double state=3.1415926;
measure("functor as a struct", fs(state));
measure("function through bind", std::bind(&fb, _1, state));
measure("function object through bind", std::bind(ff(), _1, state));
{
const auto stp1 = high_resolution_clock::now();
double sresult(0.0);
auto function = std::bind(fb, _1, state);
for(double x=0.0; x< 1.0e8; ++x) {
sresult += function(x);
}
const auto stp2 = high_resolution_clock::now();
const auto sd = duration_cast<milliseconds>(stp2 - stp1);
cout << "in " << sd.count() << " ms, ";
cout << "embedded bind with function; result = " << sresult << endl;
}
{
const auto stp1 = high_resolution_clock::now();
double sresult(0.0);
auto function = std::bind(&fb, _1, state);
for(double x=0.0; x< 1.0e8; ++x) {
sresult += function(x);
}
const auto stp2 = high_resolution_clock::now();
const auto sd = duration_cast<milliseconds>(stp2 - stp1);
cout << "in " << sd.count() << " ms, ";
cout << "embedded bind with function pointer; result = " << sresult << endl;
}
return 0;
}
We've got lambdas for this:
double s = 42;
auto f = [s](double x) {
return s * x;
};
Down to single mention of state on line 2 (as you dont seem to count one in the actual expression). Whether initialization on line 1 counts as mention is debatable, your desired form does not contain any initialization, which is required, so I assume this to be acceptable.
In c++14 we'll get extension of lambda capture syntax allowing even more terse form:
auto f = [s{42}](double x) {
return s * x;
};
Have a look at BOOST_LOCAL_FUNCTION which seems to be exactly what youre looking for, as you even mention a macro :)
double s = 42;
double BOOST_LOCAL_FUNCTION(bind& s, double x) {
return x*s;
} BOOST_LOCAL_FUNCTION_NAME(f)
Personal note: If you have a modern compiler, go with C++11 lambdas.