【问题标题】:MATLAB vectorization: creating a cell array of neighbor index arraysMATLAB 向量化:创建相邻索引数组的元胞数组
【发布时间】:2015-06-22 00:19:21
【问题描述】:

我有一个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

【问题讨论】:

    标签: performance matlab for-loop vectorization cell-array


    【解决方案1】:

    这里还有一些巫术:

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

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

    【讨论】:

      【解决方案2】:

      作为一种方法,您可以使用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 的方法互换。

      【讨论】:

      • 谢谢@Divakar,这就行了。但对我来说它看起来像巫毒! :-) 您能否解释一下您是如何使用accumarray 的?我特别不明白@x {x} 部分。
      • @MGA 据我所知,{x} 部分根据 C 中的下标累积来自 R 的数据,并将每个下标的单元格数组的单元格存储为单元格。因此,基本上这些花括号表示将输出存储为单元格。
      猜你喜欢
      • 1970-01-01
      • 2015-05-29
      • 2011-07-17
      • 1970-01-01
      • 2014-11-17
      • 1970-01-01
      • 2017-04-14
      • 2019-09-09
      • 1970-01-01
      相关资源
      最近更新 更多