Thomas5631
Thomas5631

Reputation: 244

Efficiently completing multiple transformations in C++

I have to perform the following mathematical operation on every element in an array:

X = Y*(X - 1) + 1

I currently achieve this as follows:

#include <vector> 
#include <algorithm>

for (unsigned i = 0; i < dataSet.size(); i++) {
    std::transform(dataSet[i].begin(), dataSet[i].end(), dataSet[i].begin(),
        std::bind2nd(std::minus<double>(), 1.00));
    std::transform(dataSet[i].begin(), dataSet[i].end(), dataSet[i].begin(),
        std::bind1st(std::multiplies<double>(), scaleFact));
    std::transform(dataSet[i].begin(), dataSet[i].end(), dataSet[i].begin(), 
        std::bind2nd(std::plus<double>(), 1.00));
}

Can I complete all three of the operations inside the for loop in a single transform?

Can I complete the operation for every element in the vector of vectors without a for loop?

Upvotes: 0

Views: 183

Answers (2)

Benjamin Lindley
Benjamin Lindley

Reputation: 103703

I'm just gonna put this out there, I know it doesn't technically answer your question. Sometimes I think people overdo it with the algorithms. Is a for loop really so bad?

for (auto& data : dataSet) {
    for (auto& e : data) {
        e = scaleFact * (e - 1) + 1;
    }
}

Upvotes: 2

Rakete1111
Rakete1111

Reputation: 48948

Can I complete all three of the operations inside the for loop in a single transform?

Yes, you can:

std::transform(dataSet[i].begin(), dataSet[i].end(), dataSet[i].begin(),
    [scaleFact](double value) { return scaleFact * (value - 1) + 1; });

Can I complete the operation for every element in the vector of vectors without a for loop?

That's a bit tricky, because you can't get around a loop. What you could use is a wrapper around a loop, like std::for_each:

std::for_each(std::begin(dataSet), std::end(dataSet), [scaleFact](auto& data) {
    std::transform(data.begin(), data.end(), data.begin(),
        [scaleFact](double value) { return scaleFact * (value - 1) + 1; });
});

Or even better, a ranged loop:

for (auto& data : dataSet)
{
    std::transform(data.begin(), data.end(), data.begin(),
        [scaleFact](double value) { return scaleFact * (value - 1) + 1; });
}

Upvotes: 2

Related Questions