在Matlab中高效操作大型非稀疏矩阵

4
我需要在Matlab中操作大型三维非稀疏矩阵。使用纯向量化会导致计算时间很长。因此,我尝试将操作分成10个块,然后解析结果。当我看到以下图表时,我感到惊讶,发现纯向量化与数据大小不太相关。
我提供了两种方法的示例。
% Parameters:
M = 1e6;  N = 50;  L = 4;  K = 10;

% Method 1: Pure vectorization
mat1 = randi(L,[M,N,L]);
mat2 = repmat(permute(1:L,[3 1 2]),M,N);
result1 = nnz(mat1>mat2)./(M+N+L);

% Method 2: Split computations
result2 = 0;
for ii=1:K
    mat1 = randi(L,[M/K,N,L]);
    mat2 = repmat(permute(1:L,[3 1 2]),M/K,N);
    result2 = result2 + nnz(mat1>mat2);
end
result2 = result2/(M+N+L);

因此,我想知道是否还有其他方法可以使Matlab中的大矩阵操作更有效率。我知道这是一个非常广泛的问题,但我愿意冒险去问 :)

编辑:

使用@Shai的实现

% Method 3
mat3 = randi(L,[M,N,L]);
result3 = nnz(bsxfun( @gt, mat3, permute( 1:L, [3 1 2] ) ))./(M+N+L);

时间是:

enter image description here

1个回答

3

为什么使用repmat而不是bsxfun

result = nnz(bsxfun( @gt, mat1, permute( 1:L, [3 1 2] ) ))./(M+N+L);

看起来你正在使用大量的RAM,操作系统开始为非常大的矩阵分配交换空间。内存交换始终是一个非常耗时的操作,随着所需内存的增加,情况会变得更糟。
我相信你正在目睹抖动


谢谢。这正是我寻找的处理大矩阵的方法。 - tashuhka
1
bsxfun的文档中,我发现了单例扩展的解释:“每当A或B的一个维度是单例(等于一)时,bsxfun会在该维度上虚拟复制数组以匹配另一个数组”。我实际上不知道这个有用的功能。 - tashuhka
1
@tashuhka bsxfun非常有用。请查看其标签wiki以获取更多信息。 - Shai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接