MATLAB - 稀疏到密集矩阵

时间:2017-01-08 05:27:36

标签: matlab sparse-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

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

  

经过的时间是0.599023秒。

     

经过的时间是0.001978秒。

     

经过的时间是0.000406秒。

     

经过的时间是275.462138秒。

matlab中有没有快速的方法呢?

这是我到目前为止所尝试的内容:

parfor - 这给了我

  

有效指数在parfor循环中受到限制

我厌倦了重新设置for循环,如下所示:

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

我收到错误

  

订阅的分配维度不匹配。

1 个答案:

答案 0 :(得分:1)

您最后一次尝试不起作用的原因是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,一种简单的方法是使用函数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不是一个快速的函数(但它会比你的循环快得多),所以如果你有很多数据,你可能想要自己计算线性索引:< / p>

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;