2016-10-26 3 views
2

Я искал форум и не нашел достаточно информации, чтобы помочь мне решить эту проблему.Расширение ismember для ячеек

Рассмотрим множество (ячейка векторов)

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 в противном случае.

я могу сделать это, используя два для петель: одна по элементам А, а другой вложен, для каждого элемента, который проверяет членство в отношении любого другого члена А.

Я хочу, чтобы избежать используя для петель. Существует ли векторизованное решение для получения B из A?

ответ

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 
+0

Хорошее решение. Вы упомянули, что cellfun - двоюродный брат цикла - он в основном просто перебирает все элементы клетки? – jonem

+0

@jonem Да, он берет каждую ячейку от ввода/с и применяет указанную функцию к ней/им. По производительности это похоже на цикл. Векторизация обычно не возможна для клеток :-( –

2

Ну вы просили об этом, так вот почти * Векторизованных решение с использованием bsxfun и permute -

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), но так как он просто получает длину ячеек, так что вычислительно будет пренебрежимо мало.

Также обратите внимание, что этот подход будет использовать много ресурсов памяти, поэтому может быть не полезно, а просто как можно больше соблюдайте требования векторизованного решения!

Смежные вопросы