将成员延伸到细胞

时间:2016-10-26 22:45:36

标签: matlab vectorization cells

我搜索了论坛,但没有找到足够的信息来帮助我解决这个问题。

考虑集合(向量的单元格)

A = {[1],[1 2],[2],[1 2 3],[1 2 3 4],[1 3]}

我想构建一个看起来像

的矩阵B.
B = [1 1 0 1 1 1
     0 1 0 1 1 0
     0 1 1 1 1 0
     0 0 0 1 1 0
     0 0 0 0 1 0
     0 0 0 1 1 1]

矩阵B指定向量相对于彼此的成员资格。也就是说,第一行查看A中的第一个元素[1],并检查它是否是其他向量的成员,如果它是成员则放置1,否则放置0。

我可以使用两个for循环执行此操作:一个在A的元素上,另一个嵌套在A的每个元素上,用于检查A的每个其他成员的成员资格。

我想避免使用for循环。是否存在从A?

获得B的向量化解决方案

2 个答案:

答案 0 :(得分:2)

使用单元格数组很难避免循环或其表兄cellfun。我就是这样做的:

[ii, jj] = ndgrid(1:numel(A)); % indices of all possible pairs
result = cellfun(@(x,y) all(ismember(x,y)), A(ii), A(jj)); % see if all elements in the 
    % first are present in the second

答案 1 :(得分:2)

你问过它,所以这是一个使用bsxfunpermute的几乎*矢量化解决方案 -

lens = cellfun('length',A) 
vals = [A{:}]

mask = bsxfun(@ge,lens,[1:max(vals)]')
a = nan(size(mask))
a(mask) = vals
matches =  bsxfun(@eq,a,permute(a,[3,4,1,2]));
out = bsxfun(@eq,squeeze(sum(any(matches,3),1)),lens(:))

*:几乎是因为在cellfun开头使用了cellfun('length',A),但由于它只是在那里得到了单元格的长度,所以在计算上可以忽略不计。

另外,请注意这种方法会占用大量内存资源,因此可能没有用处,只是尽可能地尊重矢量化解决方案的要求!