MATLAB 矢量化:创建相邻索引数组的元胞数组

MATLAB vectorization: creating a cell array of neighbor index arrays

我有一个包含 n 点的逻辑矩阵 X,其中 X(i, j) == 1 如果点 ij 是邻居并且 0否则。

我想创建一个元胞数组 Y,每个条目 Y{i}i1n)包含一个数组点 i 的邻居的索引。

换句话说,我想对以下内容进行矢量化:

n = 10;
X = (rand(n, n) < 0.5);

Y = cell(1, 10);
for i = 1:10
    [Y{i}] = find(X(i, :));
end

作为一种方法,您可以使用 accumarray -

[R,C] = find(X.') %//'
Y = accumarray(C(:),R(:),[],@(x) {x})

如果你需要每个单元格都是一个行向量,你需要用x在那里添加一个转置,就像这样-

Y = accumarray(C(:),R(:),[],@(x) {x.'})

作为另一种方法,您也可以使用 arrayfun,但我认为这不是 向量化 解决方案 -

Y  = arrayfun(@(n) R(C==n),1:max(C),'Uni',0)

如果你不关心每个单元格中元素的顺序,你可以避免转置 X 得到 RC 像这样 -

[R,C] = find(X)

然后,将 RC 的位置与前面列出的基于 accumarrayarrayfun 的方法交换。

这里还有一些巫术:

Y = mat2cell(nonzeros(bsxfun(@times, X, 1:size(X,1)).').', 1, sum(X,2));

这里最重要的函数是bsxfun。要查看代码的工作原理,我建议您从最里面向外观察部分结果:首先是bsxfun(@times, X, 1:size(X,1)).',然后是nonzeros(...),等等