Суммирование строк, но с разными терминами в каждой строке удалено
Извиняюсь, если это относительно простой вопрос - я все еще немного новичок в программировании, и особенно в Matlab. По сути, я хочу создать вектор столбца 4940x1, где каждый член равен сумме соответствующей строки квадратной матрицы 4940x4940. Пока все достаточно просто.
Тем не менее, я бы хотел, чтобы в каждой строке был удален ряд терминов из суммы, в частности первые 26 членов строки для первых 26 строк, 2-е 26 членов (т.е. термины 27-52) для 2-й строки и т. Д. И т. Д. пока вы не получите 190-й набор из 26 терминов (т.е. 4940,4915:4940) для последних 26 строк. Я не уверен, хорошо ли я объясняю это, поэтому, возможно, лучше всего это проиллюстрировать с помощью волшебной матрицы 4:
A =
16 3 2 13;
5 10 11 8;
9 6 7 12;
4 15 14 1
В дополнение к вычислению суммы каждой строки, я хотел бы вычесть 1,1:2 (т.е. 34-16-3) из строки 1, 2,1:2 из строки 2 (т.е. 34-5-10), 3,3:4 из ряда 3 (т.е. 34-7-12) и 4,3:4 из ряда 4 (34-14-1).
Благодарен за любую помощь здесь!
3 ответа
Умножьте матрицу поэлементно на следующую матрицу:
M = 1-kron(eye(4940/26),ones(26));
Таким образом, вы умножаете элементы, которые вы не хотите считать, на 0, а остальные на 1.
Теперь вы можете просто суммировать результат, как вы делали это раньше: sum(.,2)
,
За волшебный пример вы получаете M =
0 0 1 1
0 0 1 1
1 1 0 0
1 1 0 0
а также A .* M =
0 0 2 13
0 0 11 8
9 6 0 0
4 15 0 0
а также sum(A.*M, 2) =
15
19
15
19
Я обновил ответ, принимая во внимание первый комментарий Дивакара. Что касается скорости, см. Дополнительные комментарии ниже.
Для суммы, удалив некоторые элементы, вы можете легко создать маску (с blkdiag
) чтобы указать, какие элементы обнуляются:
%// Total sum:
s1 = sum(A, 2);
%// Sum removing elements:
m = size(A, 1);
n = 26;
c = repmat({true(26)}, m/n, 1);
s2 = sum(A.* ~blkdiag(c{:}), 2)
bsxfun
основанный подход суммирования и изменения формы -
sublen = 26; %// subset length
nrows = size(A,1); %// number of rows in input matrix
nsubs = nrows/sublen; %// number of subsets
idx1 = bsxfun(@plus,[1:sublen]',[0:sublen-1]*nrows);%//'# starting block indices
idx2 = bsxfun(@plus,idx1(:),[0:nsubs-1]*(nrows*sublen+sublen));%// all block indices
exclude_sum = sum(A(reshape(idx2,sublen,sublen,[])),2); %// block elements summed
%// (these would be subtracted from the wholesome sum)
out = sum(A,2) - exclude_sum(:); %// desired output
Этот подход, кажется, 6-7x
быстрее, чем улучшенная версия другого kron
основанный подход.
Вот время выполнения - https://ideone.com/vZRRfe