Pass function as parameter to integrate object using lambda - c++

For educational purposes
I have a function integrate which takes in a std::function as a parameter.
double calculus::integralSimple(std::function<double(double)> fn, double begin, double end)
{
double integral = 0;
for (long double i = begin; i < end; i += _step)
{
integral += fn(i) * _step; // _step defined in class
}
return integral;
}
Currently I am calling this function from main.cpp using
calculus cl;
std::cout << cl.integralSimple(calculus::identity,0,1);
std::cout << cl.integralSimple([](double x) { return x*x; }, 0, 1);
where identity is a static function defined in calculus.h and the other uses a lambda function.
I was wondering whether I could make the syntax easier for the user and closer to a mathematics way.
So what I would prefer is that the user just have to type:
std::cout << cl.integralSimple( x*x ,0,1); // Always take a function of this form
std::cout << cl.integralSimple( x*sin(x) - x*x ,0,1);
Is there any way to achieve this in C++?

That is exactly what Boost.Lambda was designed for. The syntax would look like this:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
const double PI =3.141592653589793238463;
double func(double v) { return std::sin(v); } // to avoid having to
// cast std::sin
int main()
{
using namespace boost::lambda;
std::vector<double> v = {0, PI / 4, PI / 2, PI};
std::for_each(v.begin(), v.end(),
std::cout << _1 * bind(func, _1) - _1 * _1 << '\n'
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑
// to delay invocation of func
);
}
Whether that's better than the C++11 lambda syntax or not is entirely up to you.
Note that thanks to C++14 and some abuse of features, we can actually write exactly the expression you want too:
auto x = _1;
auto sin(decltype(_1) ) {
return bind(static_cast<double(*)(double)>(std::sin), _1);
}
With that, we can do:
std::for_each(v.begin(), v.end(),
std::cout << x * sin(x) - x * x << '\n');
Which will print exactly the same thing the original example did. Just... more cryptically.

Related

How to multiply a vector and scalar in C++?

I would like to multiply a vector with a scalar. This vector was created using the accepted answer to this question of mine namely:
std::vector<int> n(N + 1);
std::iota(begin(n), end(n), 0);
and I would like to multiply this vector, n, with a scalar (specifically of type double, if it is relevant here) called npi.
I have seen this answer to a previous question here, but it wasn't all that helpful. The way I attempted to implement it was by adding:
std::transform(n.begin(), n.end(), n.begin(),
std::bind1st(std::multiplies<T>(),pin));
to my C++ program. This returned the compile error:
error: ‘T’ was not declared in this scope
std::bind1st(std::multiplies<T>(),pin));
I would like to call the vector created by multiplying this vector with a scalar npi, so please do not give me code that will call this new vector n (i.e., overwriting my existing n vector).
EDIT:
If it will placate whomever voted to close this question, here is my full program:
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <cmath>
#include <utility>
#include <unistd.h>
#include <algorithm>
#include <numeric>
/*#include <armadillo>*/
using namespace std;
/*using namespace arma;*/
double N = 1000.0;
double x0 = 0;
double x1 = 100;
double pin = M_PI / double(N);
int main() {
std::vector<int> n(N + 1);
std::iota(begin(n), end(n), 0);
std::transform(n.begin(), n.end(), n.begin(),
std::bind1st(std::multiplies<T>(),pin));
for(double i: n)
{
std::cout << i << '\n' << std::scientific;
}
}
For vector<int> output, one way is:
auto npi = n;
for( auto& i: npi )
i *= pin;
If npi should be vector<double> (not clear from the question) then replace the first line with:
std::vector<double> npi( n.begin(), n.end() );
You need to replace T by the type contained in the vector, in this case int. However you can probably simplify your code by using a lambda function here instead:
#include <algorithm> // for std::transform
#include <cmath> // for M_PI
#include <iostream> // for std::cout etc
#include <numeric> // for std::iota
#include <vector> // for awesome
int main() {
std::vector<int> vec1(10);
std::iota(vec1.begin(), vec1.end(), 0);
int N = 42;
std::vector<double> vec2(vec1.size()); // vec2 needs to be as big or bigger than vec1
std::transform(vec1.begin(), vec1.end(), vec2.begin(),
[N](int i) { return i * M_PI / N; });
for (auto a : vec1)
std::cout << a << " ";
std::cout << std::endl;
for (auto a : vec2)
std::cout << a << " ";
std::cout << std::endl;
}
Here's an online example: http://melpon.org/wandbox/permlink/XrNxDND0steJmym8
If I have understood you correctly you need the following
std::vector<double> v;
v.reserve(n.size());
std::transform(n.begin(), n.end(), std::back_inserter( v ),
std::bind1st(std::multiplies<double>(), pin));
You can pass the scalar in the capture clause of the Lambda function and do the multiplication inside the lambda function itself
#include <algorithm>
#include <vector>
std::vector<int> foo;
std::vector<int> bar;
auto npi=4.0;
std::transform (foo.begin(), foo.end(), bar.begin(), foo.begin(), [&npi](auto& c){return c * npi;}

Correct way to compare two pointees to use in std algorithms

I am playing with boost::range and boost::lambda with following example to compare two numbers and get the element out which has same number.
#include <iostream>
#include <boost/optional.hpp>
#include <boost/range/algorithm/find_if.hpp>
#include <boost/typeof/typeof.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/utility/compare_pointees.hpp>
template <class Range, class Predicate>
boost::optional<typename boost::range_value<Range>::type>
search_for(const Range& r, Predicate pred)
{
BOOST_AUTO (it, boost::find_if(r, pred));
if (it == boost::end(r))
return boost::none;
return *it;
}
int main()
{
int a = 1;
int b = 2;
int c = 3;
int d = 3;
std::vector<int*> m = {&a, &b, &c};
if (boost::optional<int*> number =
search_for(m, boost::equal_pointees(???, &d))) {
std::cout << "found:" << (*number.get()) << std::endl;
}
else {
std::cout << "not found" << std::endl;
}
}
What should I use for ??? above in search_for function?
I believe it could be very simple but don't know how to do it. I can use the boost::bind or std::bind2d, etc to compare but was thinking if there is any elegant way to do it. Also, this code sample could be restructured to much simpler one but I am just learning.
With boost::lambda, it looks like this:
namespace ll = boost::lambda;
search_for(m, *ll::_1 == d)
Which is far less complicated than taking a pointer to d just so you can use equal_pointees.

Calling a function on every element of a C++ vector

In C++, is there a way to call a function on each element of a vector, without using a loop running over all vector elements? Something similar to a 'map' in Python.
You've already gotten several answers mentioning std::for_each.
While these respond to the question you've asked, I'd add that at least in my experience, std::for_each is about the least useful of the standard algorithms.
I use (for one example) std::transform, which is basically a[i] = f(b[i]); or result[i] = f(a[i], b[i]); much more frequently than std::for_each. Many people frequently use std::for_each to print elements of a collection; for that purpose, std::copy with an std::ostream_iterator as the destination works much better.
Yes: std::for_each.
#include <algorithm> //std::for_each
void foo(int a) {
std::cout << a << "\n";
}
std::vector<int> v;
...
std::for_each(v.begin(), v.end(), &foo);
On C++ 11: You could use a lambda. For example:
std::vector<int> nums{3, 4, 2, 9, 15, 267};
std::for_each(nums.begin(), nums.end(), [](int &n){ n++; });
ref: http://en.cppreference.com/w/cpp/algorithm/for_each
If you have C++11, there's an even shorter method: ranged-based for. Its purpose is exactly this.
std::vector<int> v {1,2,3,4,5};
for (int element : v)
std::cout << element; //prints 12345
You can also apply references and const to it as well, when appropriate, or use auto when the type is long.
std::vector<std::vector<int>> v {{1,2,3},{4,5,6}};
for (const auto &vec : v)
{
for (int element : vec)
cout << element;
cout << '\n';
}
Output:
123
456
The OP mentions the map function in Python.
This Python function actually applies a function to every element of a list (or iterable) and returns a list (or iterable) that collects all results.
In other words, it does something like this:
def f( x ) :
""" a function that computes something with x"""
# code here
return y
input = [ x1, x2, x3, ... ]
output = map( func, input )
# output is now [ f(x1), f(x2), f(x3), ...]
Hence, the closest C++ standard-library equivalent to Python's map is actually std::transform (from the <algorithm> header).
Example usage is as follows:
#include <vector>
#include <algorithm>
using namespace std;
double f( int x ) {
// a function that computes the square of x divided by 2.0
return x * x / 2.0 ;
}
int main( ) {
vector<int> input{ 1, 5, 10 , 20};
vector<double> output;
output.resize( input.size() ); // unfortunately this is necessary
std::transform( input.begin(), input.end(), output.begin(), f );
// output now contains { f(1), f(5), f(10), f(20) }
// = { 0.5, 12.5, 50.0, 200.0 }
return 0;
}
Use for_each:
// for_each example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
void myfunction (int i) {
cout << " " << i;
}
struct myclass {
void operator() (int i) {cout << " " << i;}
} myobject;
int main () {
vector<int> myvector;
myvector.push_back(10);
myvector.push_back(20);
myvector.push_back(30);
cout << "myvector contains:";
for_each (myvector.begin(), myvector.end(), myfunction);
// or:
cout << "\nmyvector contains:";
for_each (myvector.begin(), myvector.end(), myobject);
cout << endl;
return 0;
}
You can use std::for_each which takes a pair of iterators and a function or functor.
Thought I would share std::ranges equivalents for for_each and transform, should anyone prefer them:
std::vector<int> v;
std::ranges::for_each(v,[](const auto& n) {});
const auto squared = v | std::views::transform([](const auto& n) { return n*2; });
Running on godbolt: https://godbolt.org/z/zYME6b

How to get an average in C++?

I have an assignment to read a file and output the average test scores.
It is pretty simple but I don't like how the average is done.
average = (test1 + test2 + test3 + test4 + test5) / 5.0;
Is there a way to just have it divide by the number of test scores? I couldn't find anything like this in the book or from google. Something like
average = (test + test + test + test) / ntests;
If you have the values in a vector or an array, just use std::accumulate from <numeric>:
std::vector<double> vec;
// ... fill vec with values (do not use 0; use 0.0)
double average = std::accumulate(vec.begin(), vec.end(), 0.0) / vec.size();
Step 1. Via iteration (if you want to be done) or recursion (if you want to be brave) place all test scores into an array (if you want simplicity and speed) or a linked list (if you want flexibility but slow)
Step 2. Iterate through the array/list until you reach the end; adding the contents of each cell/node as you go. Keep a count of what cell/node you are currently at as you go as well.
Step 3. Take the sum from the first variable and divide it by the second variable that kept track of where you were. This will yield the mean.
Wondering, why no one mentioned boost::accumulators. It is not the shortest of the already posted solutions, but can be more easily extended for more general statistical values. Like standard deviation or higher moments.
#include <iostream>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <algorithm>
#include <vector>
double mean(const std::vector<double>& values) {
namespace bo = boost::accumulators;
if (values.empty()) return 0.;
bo::accumulator_set<double, bo::stats<bo::tag::mean>> acc;
acc=std::for_each(values.begin(), values.end(), acc);
return bo::mean(acc);
}
int main()
{
std::vector<double> test = { 2.,6.,4.,7. };
std::cout << "Mean: " << mean(test) << std::endl;
std::cout << "Mean: " << mean({}) << std::endl;
return 0;
}
Here is my generalization of getting the average of the elements of a container by specifying a lambda function to obtain each value and then add up:
template <typename ForwardIterator, typename F>
double inline averageOf (ForwardIterator first, ForwardIterator last, F function) {
std::vector<typename std::result_of<F(typename ForwardIterator::value_type)>::type> values;
while (first != last) {
values.emplace_back (function(*first));
++first;
}
return static_cast<double>(std::accumulate (values.begin(), values.end(), 0)) / values.size();
}
The client code I tested it with goes like
const std::list<CharmedObserver*> devotees =
charmer->getState<CharmerStateBase>(CHARMER)->getDevotees();
const int averageHitPointsOfDevotees = averageOf (devotees.begin(), devotees.end(),
[](const CharmedObserver* x)->int {return x->getCharmedBeing()->getHitPoints();});
C++11 gives nice solution:
constexpr auto countArguments() -> size_t
{
return 0;
}
template<class T1, class ... Ti>
constexpr auto countArguments(T1, Ti ...xi) -> size_t
{
return 1 + countArguments(xi...);
}
template<class T>
constexpr auto sumAruguments(T x) -> double
{
return x;
}
template<class T1, class ... Ti>
constexpr auto sumAruguments(T1 x1, Ti ...xi) -> double // decltype(x1 + sumAruguments(xi...))
{
return x1 + sumAruguments(xi...);
}
template<class...T>
constexpr auto avarage(T...xi) -> double
{
return sumAruguments(xi...) / countArguments(xi...);
}
I was unable to write it so it auto-deduce return type.
When I tried I get weird result for average(-2).
https://wandbox.org/permlink/brssPjggn64lBGVq
You can also calculate average using variable number of arguments. The principle of this a function that an unknown number of arguments is stored in a stack and we can take them.
double average(int n, ...) // where n - count of argument (number)
{
int *p = &n; // get pointer on list of number in stack
p++; // get first number
double *pp = (double *)p; // transformation of the pointer type
double sum = 0;
for ( int i = 0; i < n; pp++, i++ ) //looking all stack
sum+=(*pp); // summarize
return sum/n; //return average
}
And you can using this function like:
double av1 = average( 5, 3.0, 1.5, 5.0, 1.0, 2.0 );
double av2 = average( 2, 3.0, 1.5 );
But the number of arguments must match with the n.

boost function and lambda to wrap a function

I want to convert this simple code:
void setZComp(Imath::V3f& pt)
{
pt.z = 0.0;
}
int myfunc()
{
...
std::vector<Imath::V3f> vec(5,Imath::V3f(1.0,1.0,1.0));
std::for_each(vec.begin(),vec.end(),boost::bind(&setZComp,_1));
...
}
to something like that, in order to not have setZComp declared outside but some sort of inline declaration
int myfunc()
{
...
boost::function<double(Imath::V3f&)> f = (boost::lambda::_1 ->* &Imath::V3f::z = 0.0) ;
std::for_each(vec.begin(),vec.end(),boost::bind(&f,_1));
...
}
I'm quite new to Boost Bind and Lambda and I don't know if this can be done in some way. Obviously the code above does not work.
Are you using a sledgehammer to break a nut? Sometimes, I think it is simpler to just use a normal for loop and set the variable explicitly yourself. This makes the code much easier to read and maintain.
typedef std::vector<Imath::V3f> V3fVector;
V3fVector vec(5,Imath::V3f(1.0,1.0,1.0));
for (V3fVector::iterator i = vec.begin(), iEnd = vec.end(); iEnd != i; ++i)
i->z = 0.0;
As much as boost bind is useful, its also a syntactical mess that make simple code unreadable.
If you cannot use a C++11 lambda, then you can use boost::lambda::bind.
So in your case something like the following:
boost::lambda::bind(&Imath::V3f::z, boost::lambda::_1) = 0.0
A full example since I don't know your internals:
struct S
{
S():i(0){};
int i;
};
int main()
{
std::vector<S> vec;
vec.push_back(S());
std::for_each(vec.begin(), vec.end(), boost::lambda::bind(&S::i, boost::lambda::_1) = 5);
std::cout << vec.front().i << std::endl; // outputs 5
return 0
}
You might also consider taking a look at boost::phoenix. I think it's a more fully fleshed out implementation of functional programming for c++ than the lambda library.
As explained in the section Member variables as targets:
A pointer to a member variable is not really a function, but the first argument to the [boost::lambda::bind] function can nevertheless be a pointer to a member variable. Invoking such a bind expression returns a reference to the data member.
So to construct a lambda expression that accesses the z member, you can use:
boost::lambda::bind(&Imath::V3f::z, boost::lambda::_1)
The returned object can itself be used in other expressions. For example,
boost::lambda::bind(&Imath::V3f::z, boost::lambda::_1) = 0.0
means "obtain the double ref to the z member of the first argument (type Imath::V3f&) and assign the value 0.0".
You can then use this lambda with Boost.Function and std::for_each:
boost::function<void(Imath::V3f&)> f = boost::lambda::bind(&Imath::V3f::z, boost::lambda::_1) = 0.0;
std::for_each(vec.begin(), vec.end(), f);
For reference, here is a complete, compilable example:
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <boost/function.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>
namespace Imath
{
class V3f
{
public:
double x, y, z;
V3f(double x_, double y_, double z_)
: x(x_), y(y_), z(z_)
{
}
friend std::ostream& operator<<(std::ostream& os, const V3f& pt) {
return (os << '(' << pt.x << ", " << pt.y << ", " << pt.z << ')');
}
};
}
int main()
{
std::vector<Imath::V3f> vec(5, Imath::V3f(1.0, 1.0, 1.0));
boost::function<void(Imath::V3f&)> f = boost::lambda::bind(&Imath::V3f::z, boost::lambda::_1) = 0.0;
std::for_each(vec.begin(), vec.end(), f);
std::vector<Imath::V3f>::iterator it, end = vec.end();
for (it = vec.begin(); it != end; ++it) {
std::cout << *it << std::endl;
}
return EXIT_SUCCESS;
}
Outputs:
(1, 1, 0)
(1, 1, 0)
(1, 1, 0)
(1, 1, 0)
(1, 1, 0)
If you have access to a recent version of g++ with C++11 support, or MSVC 2010, you could do the following:
int myfunc()
{
...
std::for_each(vec.begin(),vec.end(),[](Imath::V3f& pt){ pt.z = 0.0; });
...
}
If you want to use boost::lambda, I sometimes find it cleaner to declare a "pointer-to-member" variable immediately before the line that contains the lambda, which then allows you to use the ->* operator instead of using boost::lambda::bind.
However, as Alan pointed out, a simple loop here might be the simplest solution. Use BOOST_FOREACH to make it even simpler.
Here's a modified version of mkaes's sample implementation that uses operator ->* instead of bind, and it also shows how to use BOOST_FOREACH as an alternative.
#include <iostream>
#include <vector>
#include <boost/lambda/lambda.hpp>
#include <boost/foreach.hpp>
// I like to provide alternate names for the boost::lambda placeholders
boost::lambda::placeholder1_type& arg1 = boost::lambda::_1 ;
boost::lambda::placeholder2_type& arg2 = boost::lambda::_2 ;
boost::lambda::placeholder3_type& arg3 = boost::lambda::_3 ;
struct S
{
S():i(0){};
int i;
};
int main()
{
std::vector<S> vec;
vec.push_back(S());
// Define this pointer-to-member so we can
// use it in the lambda via the ->* operator
int S::* i = &S::i ;
std::for_each(vec.begin(), vec.end(), &arg1->*i = 5);
std::cout << vec.front().i << std::endl; // outputs 5
// Alternatively, just use a simple foreach loop
BOOST_FOREACH( S & s, vec )
{
s.i = 6 ;
}
std::cout << vec.front().i << std::endl; // outputs 6
return 0 ;
}