2013-06-13 1 views
5

Есть ли эквивалент bsxfun для нечисловых данных?Использование `bsxfun` для нечисловых данных

Например, я хочу, чтобы сравнить все пары строк, хранящиеся в двух клеточных массивах:

>> a = {'aa', 'bb', 'cc'}; 
>> b = {'dd', 'aa'}; 
>> bsxfun(@strcmp, a, b'); % not working for cells :-(
+3

Я всегда заканчиваю цикл ... Вы можете попробовать отправить этот запрос на повышение в TMW. – Oleg

ответ

3

Боюсь, что нет такого эквивалента для сотовых массивов :-(

Что касается как я могу видеть, вы можете:

  1. предложение и использование Последуйте Олега петли
  2. используйте существующие реализации, такие как mAryCellFcn или csxfun с Обмен файлами.
  3. Сверните свою собственную функцию. Например, вот вариант идеи Роберта, которая работает для входов любых размеров (в соответствии с ограничениями bsxfun, конечно) и произвольная бинарная функция func:

    function C = mybsxfun(func, A, B) 
        idx_A = reshape(1:numel(A), size(A)); 
        idx_B = reshape(1:numel(B), size(B)); 
        C = bsxfun(@(ii, jj)func(A(ii), B(jj)), idx_A, idx_B); 
    

    Если ваша функция может работать на всех Массивах ячеек элемента -wise, вы могли бы выполнить одноплодное расширение ваших клеток массивов, а затем кормить их непосредственно к функции func:

    mask = bsxfun(@or, true(size(A)), true(size(B))); 
    idx_A = bsxfun(@times, mask, reshape(1:numel(A), size(A))); 
    idx_B = bsxfun(@times, mask, reshape(1:numel(B), size(B))); 
    C = func(A(idx_A), B(idx_B)); 
    

    последний метод может быть быстрее, если func оптимизирован для векторизованных операций на клеточных массивах.

+2

'csxfun' не годится; это просто «cellfun» и ничего больше. 'mAryCellFcn' выглядит неплохо, хотя ... –

+0

@RodyOldenhuis Спасибо, что заметили это! –

+1

@EitanT, +1, хороший! –

2

Как насчет

[str,ia,ib] = intersect(a,b) 

?

+1

(но опять же, я думаю, что Шай ищет общий подход, который может заменить 'bsxfun' больше, чем просто сравнение этих строк) –

+0

@RobertP. - Ты прав. В качестве примера я использовал 'strcmp'. – Shai

4

Мне нравится Rody's solution, но вы могли также сделать обходной путь, как это:

ia=(1:length(a)).'; ib=1:length(b); 
a=a(:); 
bsxfun(@(ii,jj) strcmp( a(ii),b(jj)) ,ia, ib); 
+0

+1. Это не даст правильных размеров для 2D/3D-массивов. Тем не менее, я адаптировал ваш вопрос к работам на массивах ячеек, как и исходный 'bsxfun' (надеюсь, вы не против). –

+0

@EitanT, конечно нет! –

2

Как сказано в сообщении об ошибке, только вещание работает для числовых типов. Вот и другие возможные альтернативы:

a = {'aa', 'bb', 'cc'}; 
b = {'dd'; 'aa'}; 

%# obviously doesnt work 
%#bsxfun(@strcmp, a, b) 

%# do the singleton expansion ourselves 
strcmp(repmat(a,size(b)), repmat(b,size(a))) 

%# if you dislike REPMAT, we can use Tony's trick 
strcmp(a(ones(size(b)),:), b(:,ones(size(a)))) 

%# we could also use CELLFUN 
cell2mat(cellfun(@(s)strcmp(a,s), b, 'UniformOutput',false)) 

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

  • Нет связанных вопросов^_^