2017-01-08 143 views
1

我在由代码产生的数据文件的稀疏矩阵(其不是MATLAB)。数据文件由四列组成。前两列是矩阵项的实部和虚部,第三列和第四列分别是对应的行和列索引。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循环的罪魁祸首)。

经过时间0.599023秒。

已用时间为0.001978秒。

经过时间0.000406秒。

经过时间275.462138秒。

matlab有没有快速的方式做到这一点?

这里是我试过到目前为止:

parfor - 这让我

有效的索引,在PARFOR限制循环

我累了重铸for环路类似这样的:

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

,并且出现错误

下标的分配维度不匹配。

回答

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是没有这样的快速功能(但它会比你的循环更快),所以如果你有大量的数据,你可能想通过自己做线性指数的计算:

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)); 

PS:

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

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

quicker比:

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

能否请你解释一下'IND =(可乐-1)*尺寸(A,1) + rowA;'是吗?我无法理解这一点。 – Rhinocerotidae

+0

我明白了。 https://in.mathworks.com/help/matlab/math/matrix-indexing.html?refresh=true#f1-85511。非常感谢 。你为我节省了很多时间! – Rhinocerotidae