Eug*_*nio 1 performance matlab loops vectorization
我有一个矩阵,matrix_logical(50000,100000),这是一个稀疏的逻辑矩阵(很多谬误,有些是真的).我必须生成一个矩阵,相交(50000,50000),对于每对,i,j,matrix_logical(50000,100000)的行,存储行i和j都具有"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中它没有保存为稀疏,因为否则性能变得最差.
由于[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));(如要求在您的评论),您可以使用两套事实a和b,你有
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)