Суммирование строк по индексу с использованием accumarray

Можно ли суммировать строки или столбцы по нескольким индексам без использования цикла for?

У меня есть матрица n на n, M, что представляет собой одновременное вхождение словарных терминов, где n - длина словарного запаса.

У меня также есть логическая маска, L, который представляет пары словарного запаса, где пара имеет форму (единственное, множественное число). Например, в псевдокоде L('octopus', 'octopuses') = True

Я хочу добавить записи в M для любой пары, которая содержит множественное число для записи для пары, которая содержит соответствующее единственное число. Например, в псевдокоде M_sum('octopus', 'swim') = M('octopus', 'swim') + M('octopuses', 'swim');

Чтобы проиллюстрировать то, что я пробовал до сих пор, давайте использовать следующие игрушечные данные.

vocabulary = {'octopus', 'octopuses', 'swim'};
% The co-occurrence matrix is symmetric
M = [0, 9, 3; 
     9, 0, 1;  
     3, 1, 0;];
% This example has only one plural singular pair
L = [0, 1, 0; 
     0, 0, 0; 
     0, 0, 0;];  

Чтобы найти единственное и множественное число соответствий, я могу использовать поиск

[singular, plural] = find(L == 1);

Если существует только одно множественное число для каждого единственного числа, суммирование строк или столбцов является простым

M_sum = M;
M_sum(singular, :) = M_sum(singular, :) + M(plural, :);
M_sum(:, singular) = M_sum(:, singular) + M(:, plural);
% Remove diagonal entries
M_sum(eye(size(M))==1) = 0; 

Однако, если есть несколько множественных чисел, которые соответствуют одному единственному, этот подход не может быть использован.

Например,

vocabulary = {'octopus', 'octopuses', 'octopi', 'swim'};
M = [0, 9, 5, 3; 
     9, 0, 7, 1; 
     5, 7, 0, 11; 
     3, 1, 11, 0;];
L = [0, 1, 1, 0; 
     0, 0, 0, 0; 
     0, 0, 0, 0; 
     0, 0, 0, 0;];  

Правильный ответ должен быть

M_sum = [0, 16, 12, 15;
         16, 0, 7, 1;
         12, 7, 0, 11;
         15, 1, 11, 0;];

Но использование вышеупомянутого метода возвращает

M_sum = [0, 16, 5, 14;
         16, 0, 7, 1;
         5, 7, 0, 11;
         14, 1, 11, 0;];

В принципе, M_sum(singular, :) = M_sum(singular, :) + M(plural, :); использует только последний plural индекс.

Я думаю, что мне нужно использовать accumarray здесь, но у меня есть некоторые проблемы с формулировкой правильного утверждения, потому что у меня есть два индекса, plural а также singular, Если accumarray это не правильный подход, другие решения также приветствуются.

1 ответ

Решение

Попробуй это:

M_sum = (L + eye(size(L,1)))*M;
M_sum = triu(M_sum, 1);
M_sum = M_sum + M_sum.';

Это работает, потому что у вас уже есть матрица L, так что матричное умножение может быть использовано для выбора и суммирования строк M,


С помощью accumarray здесь было бы два недостатка:

  • Вам нужно подать заявку find преобразовать L в индексы, которые будут использоваться в качестве первого входа в accumarray, Итак, еще один шаг.
  • accumarray может только суммировать числа, а не векторы строк (вторым входом может быть только вектор столбца, а не матрица). Так что вам нужно позвонить accumarray один раз в столбце M,
Другие вопросы по тегам