I know I can do this y[i] += f(x[i]) using transform with two input iterators.
however it seems somewhat counterintuitive and more complicated than for loop.
Is there a more natural way to do so using existing algorithm in boost or Stl. I could not find clean equivalent.
here is transform (y = y + a*x):
using boost::lambda;
transform(y.begin(), y.end(), x.begin(), y.begin(), (_1 + scale*_2);
// I thought something may exist:
transform2(x.begin(), x.end(), y.begin(), (_2 + scale*_1);
// it does not, so no biggie. I will write wrapper
Thanks
There are several ways to do this.
As you noted you can use transform with a number of predicates, some more or less automatically generated:
std::vector<X> x = /**/;
std::vector<Y> y = /**/;
assert(x.size() == y.size());
//
// STL-way
//
struct Predicate: std::binary_function<X,Y,Y>
{
Y operator()(X lhs, Y rhs) const { return rhs + f(lhs); }
};
std::transform(x.begin(), x.end(), y.begin(), y.begin(), Predicate());
//
// C++0x way
//
std::transform(x.begin(), x.end(), y.begin(), y.begin(),
[](X lhs, Y rhs) { return rhs += f(lhs); });
Now, if we had a vector with the range of indices, we could do it in a more "pythony" way:
std::vector<size_t> indices = /**/;
//
// STL-way
//
class Predicate: public std::unary_function<size_t, void>
{
public:
Predicate(const std::vector<X>& x, std::vector<Y>& y): mX(x), mY(y) {}
void operator()(size_t i) const { y.at(i) += f(x.at(i)); }
private:
const std::vector<X>& mX;
std::vector<Y>& mY;
};
std::foreach(indices.begin(), indices.end(), Predicate(x,y));
//
// C++0x way
//
std::foreach(indices.begin(), indices.end(), [&](size_t i) { y.at(i) += f(x.at(i)); });
//
// Boost way
//
BOOST_FOREACH(size_t i, indices) y.at(i) += f(x.at(i));
I don't know if there could be something to do with views, they normally allow some pretty syntax. Of course it's a bit difficult here I think because of the self-modifying y.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With