2013-10-30 18 views
10

该循环足够简单,但我似乎无法绕过我的头使用STL算法给下面相同的嵌套循环。如何使用C++ 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类算法做对GPU计算(标准::变换的std :: for_each的,等)。

+4

似乎可以重写你的算法使用矩阵运算。 –

+1

我认为让用户在'Boost.Compute'中编写任意内核更好 - 它会更有用。例如通过['TaskGraph'](http://ideone.com/qQ4Pvo)方法,我描述[这里](http://boost.2283326.n4.nabble.com/compute-GPGPU-Library-Request-For反馈系统开发与-tp4643691p4643927.html)。 –

回答

6

我想出了with

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); 
+0

我需要一段时间来消化它。从未听说过Eigen,它是否支持GPU上的计算? – user1973386

+1

@ user1973386 AFAIK - 目前它不支持GPU。虽然它通过内在函数(SSE2等)进行矢量化。我刚刚发现了以下事情:['gpumatrix'](https://github.com/rudaoshi/gpumatrix) - “* GPU上的矩阵和阵列库,界面与Eigen *兼容” - 我认为它也值得一看。 –

+0

太糟糕了,它现在还不支持OpenCL,但它已经计划好了。我会跟踪该图书馆:)。 – user1973386

7

事实上,嵌套循环是算法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。