MATLAB - 稀疏到密集矩阵

MATLAB - sparse to dense matrix

我在代码生成的数据文件中有一个稀疏矩阵(不是 MATLAB)。数据文件由四列组成。前两列是矩阵项的实部和虚部,第三列和第四列分别是对应的行和列索引。

我使用以下脚本将其转换为 Matlab 中的密集矩阵。

tic
dataA = load('sparse_LHS.dat');
toc
% Initialise matrix
tic
Nr = 15; Nz = 15; Neq = 5;
A (Nr*Nz*Neq,Nr*Nz*Neq) = 0;
toc

tic
lA = length(dataA)
rowA = dataA(:,3); colA = dataA(:,4);
toc

tic
for i = 1:lA
    A(rowA(i), colA(i)) = complex(dataA(i,1), dataA(i,2));
end
toc

然而,这个脚本非常慢(for 循环是罪魁祸首)。

Elapsed time is 0.599023 seconds.

Elapsed time is 0.001978 seconds.

Elapsed time is 0.000406 seconds.

Elapsed time is 275.462138 seconds.

matlab有什么快速的方法吗?

这是我到目前为止尝试过的方法:

parfor - 这给了我

valid indices are restricted in parfor loops

我厌倦了将 for 循环改写成这样:

A(rowA(:),colA(:)) = complex(dataA(:,1), dataA(:,2));

然后出现错误

Subscripted assignment dimension mismatch.

您最后一次尝试失败的原因是 Matlab 无法获取列和行的下标列表,并匹配它们以按顺序分配元素。相反,它从列表中生成所有行和列的组合 - 这就是它的样子:

dataA = magic(4)
dataA =
    16     2     3    13
     5    11    10     8
     9     7     6    12
     4    14    15     1

dataA([1,2],[1,4]) =

    16    13
     5     8

所以我们得到了 4 个元素([1,1][1,4][2,1][2,4])而不是 2 个([1,1][2,4] ).

为了在列表中使用下标,您需要将它们转换为 linear indexing, and one simple way to do this is using the function sub2ind

使用此功能,您可以编写以下代码一次完成所有操作:

% Initialise matrix
Nr = 15; Nz = 15; Neq = 5;
A(Nr*Nz*Neq,Nr*Nz*Neq) = 0;
% Place all complex values from dataA(:,1:2) in to A by the subscripts in dataA(:,3:4):
A(sub2ind(size(A),dataA(:,3),dataA(:,4))) = complex(dataA(:,1), dataA(:,2));

sub2ind 不是一个快速的函数(但它会比你的循环快得多),所以如果你有很多数据,你可能想自己计算线性索引:

rowA = dataA(:,3);
colA = dataA(:,4);
% compute the linear index:
ind = (colA-1)*size(A,1)+rowA;
 % Place all complex values from dataA(:,1:2) in to A by the the index 'ind':
A(ind) = complex(dataA(:,1), dataA(:,2));

P.S.:

如果您使用的是 Matlab R2015b 或更高版本:

A = zeros(Nr*Nz*Neq,Nr*Nz*Neq);

quicker
A(Nr*Nz*Neq,Nr*Nz*Neq) = 0;