使用CSR或COO存储格式查找矩阵的行和

时间:2014-06-10 17:26:04

标签: c++ matlab cuda openmp thrust

我有以下矩阵B,它以COO和CSR格式存储(从非对称示例here中检索)。您能否建议使用sum(B,2)coo(或两者)存储格式来应用matlab csr函数的高效c ++方法?因为可以使用大型数组,我们可以使用并行编程(omp或CUDA(例如推力))吗?

非常感谢任何基于算法的建议。 谢谢!

PS:构建稀疏矩阵并获取CSR坐标的代码可以在this帖子的答案中找到。

enter image description here

首席运营官格式: CSR格式:

       row_index col_index value                 columns  row_index  value
          1         1         1                     0         0       1
          1         2        -1                     1         3      -1
          1         3        -3                     3         5      -3   
          2         1        -2                     0         8      -2
          2         2         5                     1         11      5
          3         3         4                     2         13      4
          3         4         6                     3                 6
          3         5         4                     4                 4
          4         1        -4                     0                -4
          4         3         2                     2                 2
          4         4         7                     3                 7     
          5         2         8                     1                 8
          5         5        -5                     4                -5

1 个答案:

答案 0 :(得分:1)

对于首席运营官来说非常简单:

struct MatrixEntry {
    size_t row;
    size_t col;
    int value;
};

std::vector<MatrixEntry> matrix = {
    { 1, 1, 1 },
    { 1, 2, -1 },
    { 1, 3, -3 },
    { 2, 1, -2 },
    { 2, 2, 5 },
    { 3, 3, 4 },
    { 3, 4, 6 },
    { 3, 5, 4 },
    { 4, 1, -4 },
    { 4, 3, 2 },
    { 4, 4, 7 },
    { 5, 2, 8 },
    { 5, 5, -5 },
};

std::vector<int> sum(5);

for (const auto& e : matrix) {
    sum[e.row-1] += e.value;
}

对于大矩阵,您可以将for循环拆分为多个较小的范围,并在结尾处添加结果。

如果您只需要每行的总和(而不是columwise),CSR也是直接的(甚至更有效):

std::vector<int> row_idx = { 0, 3, 5, 8, 11, 13 };
std::vector<int> value = { 1, -1, -3, -2, 5, 4, 6, 4, -4, 2, 7, 8, -5 };

std::vector<int> sum(5);

for(size_t i = 0; i < row_idx.size()-1; ++i) {
    sum[i] = std::accumulate(value.begin() + row_idx[i], value.begin() + row_idx[i + 1], 0);
}

同样,对于并​​行性,您可以简单地拆分循环。