在 MATLAB 循环期间加速巨大稀疏矩阵中的索引
Accelerating the index in huge sparse matrix during loop in MATLAB
我需要在迭代中构造一个巨大的稀疏矩阵。代码如下:
function Huge_Matrix = Create_Huge_Matrix(len, Weight, Index)
k = size(Weight,1);
Huge_Matrix = spalloc(len, len,floor(len*k));
parfor i = 1:len
temp = sparse(1,len);
ind = Index(:,i);
temp(ind) = Weight(:,i);
Huge_Matrix(i,:) = temp;
end
Huge_Matrix = Huge_Matrix + spdiags(-k*ones(len,1),0,len,len);
end
如图所示,len
是输入图片的高*重量的大小,对于200*200的图片,len
是40000!我根据 Index
中存储的位置将 Weight
分配到这个巨大的矩阵中。即使我用parfor
加速循环,速度也很慢
我一开始也尝试创建全矩阵,看起来代码可以变得更快,但内存有限。还有其他方法可以加快代码速度吗?提前致谢!
正如 在评论中所说,可能有比创建 40kx40k 矩阵更好的方法来完成您想要做的事情,但是如果您 有 要创建一个大的稀疏矩阵,最好让 MATLAB 帮你做。
sparse 函数有一个签名,它采用矩阵的非零元素的行、列和对应值的列表:
S = sparse(i,j,v)
generates a sparse matrix S
from the triplets i
, j
, and v
such that S(i(k),j(k)) = v(k)
. The max(i)-by-max(j)
output matrix has space allotted for length(v)
nonzero elements. sparse
adds together elements in v
that have duplicate subscripts in i
and j
.
If the inputs i
, j
, and v
are vectors or matrices, they must have the same number of elements. Alternatively, the argument v
and/or one of the arguments i
or j
can be scalars.
所以,我们可以简单地传递 Index
作为行索引和 Weight
作为值,所以我们只需要一个与 Index
大小相同的列索引数组:
col_idx = repmat(1:len, k, 1);
Huge_Matrix = sparse(Index, col_idx, Weight, len, len);
(最后两个参数指定稀疏矩阵的大小。)
下一步是创建另一个大的稀疏矩阵并将其添加到第一个矩阵中。这似乎有点浪费,那么为什么不在创建矩阵之前将这些条目添加到现有数组中呢?
这是最终函数:
function Huge_Matrix = Create_Huge_Matrix(len, Weight, Index)
k = size(Weight,1);
% add diagonal indices/weights to arrays
% this avoids creating second huge sparse array
Index(end+1, :) = [1:len];
Weight(end+1, :) = -k*ones(1,len);
% create array of column numbers corresponding to each Index
% make k+1 rows because we've added the diagonal
col_idx = repmat(1:len, k+1, 1);
% let sparse do the work
Huge_Matrix = sparse(Index, col_idx, Weight, len, len);
end
我需要在迭代中构造一个巨大的稀疏矩阵。代码如下:
function Huge_Matrix = Create_Huge_Matrix(len, Weight, Index)
k = size(Weight,1);
Huge_Matrix = spalloc(len, len,floor(len*k));
parfor i = 1:len
temp = sparse(1,len);
ind = Index(:,i);
temp(ind) = Weight(:,i);
Huge_Matrix(i,:) = temp;
end
Huge_Matrix = Huge_Matrix + spdiags(-k*ones(len,1),0,len,len);
end
如图所示,len
是输入图片的高*重量的大小,对于200*200的图片,len
是40000!我根据 Index
中存储的位置将 Weight
分配到这个巨大的矩阵中。即使我用parfor
加速循环,速度也很慢
我一开始也尝试创建全矩阵,看起来代码可以变得更快,但内存有限。还有其他方法可以加快代码速度吗?提前致谢!
正如
sparse 函数有一个签名,它采用矩阵的非零元素的行、列和对应值的列表:
S = sparse(i,j,v)
generates a sparse matrixS
from the tripletsi
,j
, andv
such thatS(i(k),j(k)) = v(k)
. Themax(i)-by-max(j)
output matrix has space allotted forlength(v)
nonzero elements.sparse
adds together elements inv
that have duplicate subscripts ini
andj
.If the inputs
i
,j
, andv
are vectors or matrices, they must have the same number of elements. Alternatively, the argumentv
and/or one of the argumentsi
orj
can be scalars.
所以,我们可以简单地传递 Index
作为行索引和 Weight
作为值,所以我们只需要一个与 Index
大小相同的列索引数组:
col_idx = repmat(1:len, k, 1);
Huge_Matrix = sparse(Index, col_idx, Weight, len, len);
(最后两个参数指定稀疏矩阵的大小。)
下一步是创建另一个大的稀疏矩阵并将其添加到第一个矩阵中。这似乎有点浪费,那么为什么不在创建矩阵之前将这些条目添加到现有数组中呢?
这是最终函数:
function Huge_Matrix = Create_Huge_Matrix(len, Weight, Index)
k = size(Weight,1);
% add diagonal indices/weights to arrays
% this avoids creating second huge sparse array
Index(end+1, :) = [1:len];
Weight(end+1, :) = -k*ones(1,len);
% create array of column numbers corresponding to each Index
% make k+1 rows because we've added the diagonal
col_idx = repmat(1:len, k+1, 1);
% let sparse do the work
Huge_Matrix = sparse(Index, col_idx, Weight, len, len);
end