matlab - Summing rows by index using accumarray -


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 convert l indices used first input accumarray. 1 more step.
  • accumarray can sum numbers, not row vectors (its second input can column vector, not matrix). you'd need call accumarray once per column of m.