Как переписать вложенный цикл с использованием алгоритмов С++ STL?
Цикл достаточно прост, но я просто не могу оборачивать голову, используя алгоритмы STL, чтобы дать тот же самый вложенный цикл ниже.
const int a_size = 5; // input
const int c_size = 2; // output
const int b_size = a_size * c_size; // multipliers
std::vector<float> a(a_size);
std::vector<float> b(b_size);
std::vector<float> c(c_size);
// fill a and b with data
// this nested loop
for(int i = 0; i<c_size; i++) {
c[i] = 0.0;
for(int k = 0; k<a_size; k++) {
c[i] += (a[k] * b[i*a_size+k]);
}
c[i] = sigmoid(c[i]);
}
Причина, по которой я хотел бы сделать это, - это библиотека Boost.Compute, которая будет выполнять вычисления на графическом процессоре с использованием STL-подобных алгоритмов (std:: transform, std:: for_each и т.д.).
Ответы
Ответ 1
Я подошел с:
auto i = 0;
generate(begin(c), end(c), [&i, &a, &b]
{
return sigmoid(inner_product
(
begin(a), end(a),
begin(b) + distance(begin(a), end(a)) * i++, 0.f
));
});
Но это выглядит не очень хорошо - возможно, в таком случае я бы предпочел написать свой собственный алгоритм.
Или используйте матричную форму. В библиотеке Eigen
это будет:
MatrixXd b;
VectorXd a, c;
// ...
c = (b*a).unaryExpr(sigmoid);
Ответ 2
фактически вложенный цикл является алгоритмом std:: inner_product.
auto first = std::begin( b );
auto increment = std::distance( std::begin( a ), std::end( a ) );
//,,
c[i] = std::inner_product( std::begin( a ), std::end( a ), first, 0 );
std::advance( first, increment );
Вместо внешнего цикла вы можете использовать алгоритм std:: generate.