Суммирование строк по индексу с использованием 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
,