Decrease the matrix by adding all n

Not sure how to explain this, so in this example:

A=[1 0 0 1 4 4 4 4
   0 0 0 0 2 3 2 2
   0 0 0 0 0 0 0 1
   2 3 4 5 2 3 4 1 ]

      

result:

b=[ 1 1 13 12
    5 9 5  6];

      

Each of the elements is computed by adding an N-sized submatrix inside the original, in this case N=2

.

therefore b(1,1)

- A(1,1)+A(1,2)+A(2,1)+A(2,2)

, and b(1,4)

- A(1,7)+A(2,7)+A(1,8)+A(2,8)

.

Visually and clearer:

A=[|1 0| 0 1| 4 4| 4 4|
   |0 0| 0 0| 2 3| 2 2|
   ____________________
   |0 0| 0 0| 0 0| 0 1|
   |2 3| 4 5| 2 3| 4 1| ]

      

b

is the sum of the elements on these squares in this example of size 2.

I can imagine how to do this with loops, but its just feels to be vectorized. Any ideas on how this can be done?

Suppose matrix A has dimensions that are factors of N.

+3


source to share


3 answers


If you have an Imaging Tool , this could be an option as well: blockproc



B = blockproc(A,[2 2],@(x) sum(x.data(:)))

      

+4


source


Method 1:

Using mat2cell

andcellfun

n = 2;
AC = mat2cell(A,repmat(n,size(A,1)/n,1),repmat(n,size(A,2)/n,1));
out = cellfun(@(x) sum(x(:)), AC)

      

Method 2:



Using permute

andreshape

n = 2;
[rows,cols] = size(A);
out = reshape(sum(sum(permute(reshape(A,n,rows/n,n,[]),[1 3 2 4]))),rows/n,[]);

      

PS: Here's a rough question related to this that you might find helpful. The question is to find the average while it should find the sum.

+4


source


Here are two alternative methods:

Method # 1 - im2col

Another technique using the image manipulation toolbar is to use im2col

with a flag distinct

and sum over all the resulting columns. Then you will need to resize the matrix to your desired size:

n = 2;
B = im2col(A, [n n], 'distinct');
C = reshape(sum(B, 1), size(A,1)/n, size(A,2)/n);

      

We get for C

:

>> C

C =

     1     1    13    12
     5     9     5     6

      


Method number 2 - accumarray

andkron

We can generate an index matrix c kron

, which we can use as cells in accumarray

and call sum

as a custom function. Again, we would have to resize the matrix to the correct size:

n = 2;
M = reshape(1:prod([size(A,1)/n, size(A,2)/n]), size(A,1)/n, size(A,2)/n);
ind = kron(M, ones(n));
C = reshape(accumarray(ind(:), A(:), [], @sum), size(A,1)/n, size(A,2)/n);

      

Again we get C

:

C =

     1     1    13    12
     5     9     5     6

      

+4


source







All Articles