MATLAB 矢量化:创建相邻索引数组的元胞数组
MATLAB vectorization: creating a cell array of neighbor index arrays
我有一个包含 n
点的逻辑矩阵 X
,其中 X(i, j) == 1
如果点 i
和 j
是邻居并且 0
否则。
我想创建一个元胞数组 Y
,每个条目 Y{i}
(i
从 1
到 n
)包含一个数组点 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
得到 R
和 C
像这样 -
[R,C] = find(X)
然后,将 R
和 C
的位置与前面列出的基于 accumarray
和 arrayfun
的方法交换。
这里还有一些巫术:
Y = mat2cell(nonzeros(bsxfun(@times, X, 1:size(X,1)).').', 1, sum(X,2));
这里最重要的函数是bsxfun
。要查看代码的工作原理,我建议您从最里面向外观察部分结果:首先是bsxfun(@times, X, 1:size(X,1)).'
,然后是nonzeros(...)
,等等
我有一个包含 n
点的逻辑矩阵 X
,其中 X(i, j) == 1
如果点 i
和 j
是邻居并且 0
否则。
我想创建一个元胞数组 Y
,每个条目 Y{i}
(i
从 1
到 n
)包含一个数组点 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
得到 R
和 C
像这样 -
[R,C] = find(X)
然后,将 R
和 C
的位置与前面列出的基于 accumarray
和 arrayfun
的方法交换。
这里还有一些巫术:
Y = mat2cell(nonzeros(bsxfun(@times, X, 1:size(X,1)).').', 1, sum(X,2));
这里最重要的函数是bsxfun
。要查看代码的工作原理,我建议您从最里面向外观察部分结果:首先是bsxfun(@times, X, 1:size(X,1)).'
,然后是nonzeros(...)
,等等