can sum rows or columns on several indices without using loop?
i have n n matrix, m
, represents co-occurrence of vocabulary terms n length of vocabulary.
i have n n logical mask, l
, represents pairs of vocabulary pair has form (singular, plural). example, in pseudo-code, l('octopus', 'octopuses') = true
i want add entries in m
pair contains plural entry pair contains corresponding singular. example, in pseudo-code, m_sum('octopus', 'swim') = m('octopus', 'swim') + m('octopuses', 'swim')
;
to illustrate i've tried far, let's use following toy data.
vocabulary = {'octopus', 'octopuses', 'swim'}; % co-occurrence matrix symmetric m = [0, 9, 3; 9, 0, 1; 3, 1, 0;]; % example has 1 plural singular pair l = [0, 1, 0; 0, 0, 0; 0, 0, 0;];
to find singular plural correspondence, can use find
[singular, plural] = find(l == 1);
if there 1 plural each singular, summing rows or columns simple
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;
however, if there several plurals correspond 1 singular, approach cannot used.
for example,
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;];
the correct answer should be
m_sum = [0, 16, 12, 15; 16, 0, 7, 1; 12, 7, 0, 11; 15, 1, 11, 0;];
but using above method returns
m_sum = [0, 16, 5, 14; 16, 0, 7, 1; 5, 7, 0, 11; 14, 1, 11, 0;];
basically, m_sum(singular, :) = m_sum(singular, :) + m(plural, :);
uses last plural
index.
i think need use accumarray
here, i'm having trouble formulating correct statement because have 2 indices, plural
, singular
. if accumarray
not correct approach, other solutions welcome.
try this:
m_sum = (l + eye(size(l,1)))*m; m_sum = triu(m_sum, 1); m_sum = m_sum + m_sum.';
this works because have matrix l
, matrix multiplication can used select , sum rows of m
.
using accumarray
here have 2 drawbacks:
- you'd need apply
find
convertl
indices used first inputaccumarray
. 1 more step. accumarray
can sum numbers, not row vectors (its second input can column vector, not matrix). you'd need callaccumarray
once per column ofm
.