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.
source to share
Method 1:
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:
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.
source to share
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
source to share