【问题标题】:Algorithm for multiplying two sparse matrices两个稀疏矩阵相乘的算法
【发布时间】:2026-01-12 11:00:01
【问题描述】:

我在 Matlab 中工作,我将稀疏矩阵存储为具有字段的结构数组:行、列和数据。因此,对于两个矩阵,我将有一个数组集合,为每个非零条目提供(行、列、数据)。

我正在尝试编写一个高效的程序来以这种形式将两个稀疏矩阵相乘,但遇到了一些困难。

然而,这有一个问题是数组中有重复的条目,而我真的想添加它们。

非常感谢任何帮助。

【问题讨论】:

  • 你这样做是为了锻炼,对吧?你知道Matlab有built-in functionality for sparse matrices吗?
  • 是的,我这样做是为了尝试理解这些功能!谢谢
  • 我已经想到了一种方法,只要有列和行匹配,我们就会执行另一个 for 循环,循环遍历所有先前的匹配,这将有助于,但是放置另一个循环那里似乎有点矫枉过正?
  • 我不确定这是否有助于您理解。用于矩阵相乘的函数不是用 matlab 编写的,而是用 C 编写的。因此,在 matlab 中执行此操作的最有效方法在 C 中可能不是最有效的。
  • @Wooster:您选择的用于存储稀疏矩阵的数据结构效率不高:en.wikipedia.org/wiki/Sparse_matrix#Storing_a_sparse_matrix

标签: arrays matlab matrix sparse-matrix matrix-multiplication


【解决方案1】:

首先,您可以通过使用ismember 来取消forloops,如下所示:

[lia,locb] = ismember([a.column],[b.row]);
loca = find(lia);

这将为您提供localocb,它们分别是答案矩阵的行和列索引。您可以按如下方式确定最终数组中的目标条目:

[dest,~,i] = unique([loca',locb'],'rows');
dest_row = num2cell(dest(:,1));
dest_col = num2cell(dest(:,2));

这里我们使用基于行的唯一排序来确保我们不会在最终矩阵中重复条目。 i 索引数组是从初始数据(可能有重复)到最终数据(无重复)的映射。然后,您可以使用accumarray 根据这些索引对数据求和:

dest_data = num2cell(accumarray(i,[a(loca).data].*[b(locb).data]));

我们将它们中的每一个都转换为元胞数组,以便更轻松地形成最终矩阵,您很快就会看到。假设您还没有,您应该预先分配最终矩阵:

len = size(dest,1); % number of unique entries in the final matrix
c = repmat(struct('row',[],'column',[],'data',[]),len,1);

我们现在可以设置最终矩阵中的值:

[c.row] = dest_row{:};
[c.column] = dest_col{:};
[c.data] = dest_data{:};

【讨论】: