What is wrong with a simple loop?
for (size_t i = 0; i < n; ++i)
y[i] += f(x[i]);
In general even in Fortran it would be:
forall(i=0:n) y(i) += f(x(i))
Though with restrictions on f
, x
, y
it could be written as:
y += f(x)
transform()
variant is more generic and verbose:
std::transform(boost::begin(y), boost::end(y), boost::begin(x),
boost::begin(y), _1 += bind(f, _2));
It might be possible to write zip()
using boost::zip_iterator
:
foreach (auto v, zip(y, z))
v.get<0>() += f(v.get<1>());
where foreach
is BOOST_FOREACH
.
Here's variant similar to @Matthieu M.'s indices:
foreach (size_t i, range(n)) // useless compared to simple loop
y[i] += f(x[i]);
Possible range()
Implementation
template<class T, class T2>
std::pair<boost::counting_iterator<T>,
boost::counting_iterator<T> >
range(T first, T2 last) {
return std::make_pair(boost::counting_iterator<T>(first),
boost::counting_iterator<T>(last));
}
template<class T>
std::pair<boost::counting_iterator<T>,
boost::counting_iterator<T> >
range(T last) {
return range<T>(0, last);
}
Draft (broken) zip()
Implementation
template<class Range1, class Range2>
struct zip_return_type {
typedef boost::tuple<
typename boost::range_iterator<Range1>::type,
typename boost::range_iterator<Range2>::type> tuple_t;
typedef std::pair<
boost::zip_iterator<tuple_t>,
boost::zip_iterator<tuple_t> > type;
};
template<class Range1, class Range2>
typename zip_return_type<Range1, Range2>::type
zip(Range1 r1, Range2 r2) {
return std::make_pair(
boost::make_zip_iterator(
boost::make_tuple(boost::begin(r1), boost::begin(r2))),
boost::make_zip_iterator(
boost::make_tuple(boost::end(r1), boost::end(r2))));
}