MATLAB循环优化

Eug*_*nio 1 performance matlab loops vectorization

我有一个矩阵,matrix_logical(50000,100000),这是一个稀疏的逻辑矩阵(很多谬误,有些是真的).我必须生成一个矩阵,相交(50000,50000),对于每对,i,j,matrix_logical(50000,100000)的行,存储行ij都具有"true"的列数作为价值.

这是我写的代码:

% store in advance the nonzeros cols
for i=1:50000
    nonzeros{i} = num2cell(find(matrix_logical(i,:)));
end

intersect = zeros(50000,50000);

for i=1:49999
    a = cell2mat(nonzeros{i});
    for j=(i+1):50000
        b = cell2mat(nonzeros{j});
        intersect(i,j) = numel(intersect(a,b));
    end
end
Run Code Online (Sandbox Code Playgroud)

是否有可能进一步提高性能?计算矩阵需要很长时间.我想避免代码的第二部分中的双循环.

matrix_logical是稀疏的,但在MATLAB中它没有保存为稀疏,因为否则性能变得最差.

Ita*_*atz 5

由于[i,j]条目计算行i和j的逐元素乘法中非零元素的数量,因此可以通过乘以matrix_logical其转置来实现(您应该首先转换为数字数据类型,例如matrix_logical = single(matrix_logical)):

inter = matrix_logical * matrix_logical';
Run Code Online (Sandbox Code Playgroud)

它适用于稀疏或完整表示.

编辑

为了计算numel(intersect(a,b))/numel(union(a,b));(如要求在您的评论),您可以使用两套事实ab,你有

length(union(a,b)) = length(a) + length(b) - length(intersect(a,b))
Run Code Online (Sandbox Code Playgroud)

所以,你可以做到以下几点:

unLen = sum(matrix_logical,2);
tmp = repmat(unLen, 1, length(unLen)) + repmat(unLen', length(unLen), 1);
inter = matrix_logical * matrix_logical';
inter = inter ./ (tmp-inter);
Run Code Online (Sandbox Code Playgroud)