【问题标题】:How do I multiply two sparse matrices in C?如何在 C 中将两个稀疏矩阵相乘?
【发布时间】:2013-09-05 13:18:03
【问题描述】:

我有一个稀疏矩阵 D,我想将 D_transpose 和 D 相乘得到 L,如下所示:

L = D'*D;

我正在使用 sparseBLAS 处理稀疏矩阵,但 documentation 表示没有什么可以将两个稀疏矩阵相乘。

我完全陷入困境,不知道如何继续。

D 的尺寸通常约为 500,000 x 250,000。我根本无法分配那么多内存,所以只能使用稀疏矩阵来完成。

我使用 MATLAB 进行了此操作,但如果 MATLAB 在接口下方也使用 sparseBLAS,我不明白它是如何做到的 - 或者是吗?如果不是,它有什么用?我也可以用。

感谢您的阅读!

编辑:已解决。我需要 L 矩阵与向量相乘。因此,我没有首先计算 L,而是简单地做了 D'*(D*x),从而避免了两个稀疏矩阵相乘的需要。我现在只做稀疏矩阵和密集向量乘法,sparseBLAS 支持。

【问题讨论】:

  • 您也可以从您的 C 应用程序中调用 Matlab 函数。搜索“Matlab 编译器运行时”。

标签: c blas sparse-matrix


【解决方案1】:

它实际上是在发布的文档中说明的。

第 11 页

5.2 使用稀疏 BLAS 矩阵

一旦一个稀疏 BLAS 矩阵句柄被完全构造(某 可以通过检查属性 blas_valid_handle 进行测试),可以 使用矩阵句柄执行操作。 此时显示的四个操作 支持表 3.2 和 3.3 中的内容。 除了使用稀疏 BLAS 矩阵执行操作之外,还可以 通过其句柄查询其属性。表 5.5 列出了可用的属性 通过调用 get properties 例程获得。

表 3.3 第 4 页

USMM 稀疏矩阵-矩阵乘法

所以支持似乎在那里。我只是找不到BLAS_usmm 函数的签名。也许你可以检查一下标题。

编辑:如果您从 NIST 获得 sparseBLas,您可以检查 blas_sparse_proto.h 文件中的 BLAS_*usmm 函数的签名和参数。

 /* Level 3 Computational Routines */

int BLAS_susmm( enum blas_order_type order, enum blas_trans_type transa,
    int nrhs, float alpha, blas_sparse_matrix A, const float *b, int ldb,
        float *c, int ldc );
int BLAS_dusmm( enum blas_order_type order, enum blas_trans_type transa,
        int nrhs, double alpha, blas_sparse_matrix A, const double *b,
        int ldb, double *c, int ldc );
int BLAS_cusmm( enum blas_order_type order, enum blas_trans_type transa,
         int nrhs, const void *alpha, blas_sparse_matrix A, const void *b, 
     int ldb, void *c, int ldc );
int BLAS_zusmm( enum blas_order_type order, enum blas_trans_type transa,
         int nrhs, const void *alpha, blas_sparse_matrix A, const void *b, 
     int ldb, void *c, int ldc );

【讨论】:

  • 谢谢。实际上,我希望将两个稀疏矩阵相乘,而不是一个稀疏矩阵与一个密集矩阵相乘。您描述的功能适用于后一种情况。不过,我找到了一种规避这个问题的方法。感谢您的意见!
【解决方案2】:

据我了解,您的问题主要是在内存中存储了巨大的矩阵。您可以将值存储在(行,列)对中。例如,

1 0 0
0 0 2
0 4 0

这个矩阵可以存储在std::map<pair<int, int>, int>中:

map[make_pair(1, 1)] = 1
map[make_pair(2, 3)] = 2
map[make_pair(3, 2)] = 4

现在是计算部分。假设第一个矩阵存储在map1,第二个矩阵存储在map2,答案存储在mapAns

for each element x in map1:
    for each element y in map2:
        if x.column == y.row:
            mapAns[x.row, y.column] += x.value * y.value

如果你想在 C 中做同样的事情,你需要使用类似于自定义数据结构的映射。

【讨论】:

  • 他没有询问如何实现稀疏矩阵,因为他已经在使用支持该功能的库。
  • COO 格式对于大矩阵通常效率不高。 (取决于非零值的数量)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多