Sum each nth line in Matlab

Is there an easy way to summarize every nth line in Matlab? Let's say I have:

A =

 1     2     3
 4     5     6
 7     8     9
10    11    12
13    14    15
16    17    18

I want to add every 2 lines, for example: row1+row3+row5and then row2+row4+row6, therefore my output:

B =

21    24    27
30    33    36

I know that this can be done with help sum(A(1:2:end,:)), but it is not useful if you have a large matrix and a lot of nth row, and a loop foris another option, but so far I have not been able to get it to work. Do you have any suggestions / solutions, how can this be solved with a loop, foror perhaps there is a built-in function?

+4
source share
6 answers

How about this?

B = cell2mat(arrayfun(@(x) sum(A(x:n:end,:)),1:n,'uni',0)')

accumarray, . , .

:

[a,b] = size(A);
idx = bsxfun(@plus, 1:b,repmat([0:b:b*n-1]',a/n,1)) 
B = reshape(accumarray(idx(:),A(:)),b,[]).'
+6

arrayfun n, . -

[M,N] = size(A); %// Get the size of A for later usage
rowd = reshape(1:M,n,M/n)'; %// Get new row indices based on every nth selection
A1 = A(rowd(:),:); %// Reshaped A that has all the nth rows packed up consecutively for easing summing up
A2 = reshape(A1,M/n,[]); %// Reshape into a matrix with the number of rows equal to number of rows in each nth grouping
out = reshape(sum(A2),[],N); %// Get the final output by summing across columns and reshaping into the N-column format as with A
+4

( Amro Benchmark-)

function [t,v] = nthSum()
    n = 3; 
    A = randi(100,10000*n,3);

    % functions to compare
    fcns = {
        @() sum1(A,n);
        @() sum2(A,n);
        @() sum3(A,n);
        @() sum4(A,n);
        @() sum5(A,n);
        @() sum6(A,n);
    };

    % timeit
    t = zeros(6,1);
    for ii = 1:100;
        t = t + cellfun(@timeit, fcns);
    end

    % check results
    v = cellfun(@feval, fcns, 'UniformOutput',false);
    assert(isequal(v{:}));
end

function B = sum1(A,n)   %thewaywewalk#1
    [a,b] = size(A);
    idx = bsxfun(@plus, 1:b,repmat([0:b:b*n-1]',a/n,1)); 
    B = reshape(accumarray(idx(:),A(:)),b,[]).';
end

function B = sum2(A,n)  %thewaywewalk#2
    B = cell2mat(arrayfun(@(x) sum(A(x:n:end,:)),1:n,'uni',0)');
end

function B = sum3(A,n) %Dennis Jaheruddin
    B=zeros(n,size(A,2));

    for k=1:n
        B(k,:)=sum(A(k:n:end,:),1);
    end
end

function B = sum4(A,n) %Luis Mendo
    B = squeeze(sum(reshape(permute(A, [1 3 2]), n,[] ,size(A,2)), 2));
end

function B = sum5(A,n) % Bentoy13
    [k,l] = size(A);
    B = sum(reshape([A',zeros(l,mod(-k,n))],l,n,ceil(k/n)),3)';
end

function B = sum6(A,n) % Divakar
    [M,N] = size(A); 
    rowd = reshape(1:M,n,M/n)'; 
    A1 = A(rowd(:),:);
    A2 = reshape(A1,M/n,[]); 
    B = reshape(sum(A2),[],N);
end

100 30000x3 A

0.1616s   %// thewaywewalk#1
0.0667s   %// thewaywewalk#2
0.0499s   %// Dennis Jaheruddin
0.0211s   %// Luis Mendo
0.0791s   %// Bentoy13
0.0784s   %// Divakar   

, . ( ), , - ;)

,

100 3000x1000 A

6.5646s   %// thewaywewalk#1
2.6314s   %// thewaywewalk#2
2.5939s   %// Dennis Jaheruddin
0.6412s   %// Luis Mendo
4.1996s   %// Bentoy13
1.9975s   %// Divakar

, 1000 , 10 * 25 1e6 * 25 .

enter image description here

:

N               10          20          50          100         200         500         1e+03       2e+03       5e+03       1e+04       2e+04       5e+04   1e+05   2e+05   5e+05   1e+06
thewaywewalk #1     0.000282    0.000401    0.000399    0.000341    0.000276    0.000306    0.000358    0.000538    0.00109     0.0015      0.00283     0.0111  0.021   0.0427  0.112   0.224
thewaywewalk #2     7.15e-05    0.000106    0.000129    0.000137    0.000149    0.000262    0.000433    0.000929    0.00313     0.00581     0.0122      0.0289  0.0567  0.121   0.327   0.635
Divakar             3.21e-05    4.36e-05    4.65e-05    4.63e-05    4.52e-05    6.86e-05    0.000116    0.00024     0.000668    0.00179     0.00378     0.00962 0.0193  0.0442  0.116   0.245
Bentoy13            4.58e-05    6.48e-05    7.43e-05    7.31e-05    7.16e-05    0.000103    0.000192    0.000387    0.00115     0.0028      0.00585     0.015   0.0303  0.0623  0.158   0.298
Dennis Jaheruddin   3.76e-05    5.54e-05    6.07e-05    6.25e-05    6.47e-05    0.000114    0.000183    0.000376    0.000999    0.00165     0.00345     0.0162  0.0318  0.0657  0.163   0.326
Luis Mendo          7.44e-05    0.000108    0.00011     9.45e-05    7.83e-05    8.56e-05    0.000102    0.000154    0.000323    0.000452    0.000892    0.00203 0.00374 0.00741 0.0186  0.0368

( 1000 ) Divakar ; , , .

+4

, -.

, 3D-, . , A n.

:

[k,l] = size(A);

, k=n*x (x integer). , A 0. k=n*x+y, y k n, ny 0 A ( 0 y == 0). Matlab mod, :

A1 = [A;zeros(mod(-k,n),l)];

, mod(-k,n) .

, : 3D- , . :

A2 = reshape(A1',l,n,ceil(k/n));

3- , :

B = sum(A2,3)';

, ( k l , ... ok, ):

[k,l] = size(A);
B = sum(reshape([A',zeros(l,mod(-k,n))],l,n,ceil(k/n)),3)';
+3

Permissive dimensions and shape changes:

B = squeeze(sum(reshape(permute(A, [1 3 2]), n,[],size(A,2)), 2));
+3
source

I still think the loop forwill be simple here and probably quite efficient if you have long matrices:

A = [ 1     2     3
 4     5     6
 7     8     9
10    11    12
13    14    15
16    17    18];

n=2;
result=zeros(n,size(A,2));

for k=1:n
   result(k,:)=sum(A(k:n:end,:),1);
end
+1
source

Source: https://habr.com/ru/post/1541381/


All Articles