我在代码生成的数据文件中有一个稀疏矩阵(不是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));
我收到错误
订阅的分配维度不匹配。
答案 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;