I want to create a 16*16 square matrix from 4*4 square matric based on a condition that 4*4 (i.e. 256) elements add together to form a new element for smaller matrix. Example is shown below.

댓글 수: 2

Torsten
Torsten 2023년 10월 4일
If this is an IQ test, I didn't pass it...
All the 16 elements in the blue boxes were added to get a number 72. And all the 16 elements in yellow boxes were added to get a number 92. Likewise, I want to add all 4*4 (16 elements) to form a new smaller 4*4 matrix in matlab. It is about contracting the dimensions of a matrix.

댓글을 달려면 로그인하십시오.

 채택된 답변

Voss
Voss 2023년 10월 4일
M = randi(10,16,16); % 16-by-16 matrix of integers between 1 and 10
disp(M);
7 4 5 5 2 3 4 10 10 5 1 8 8 4 1 4 3 5 6 7 10 6 6 8 7 5 3 2 10 5 6 4 7 4 9 6 1 9 8 7 2 8 3 8 2 7 4 5 3 10 6 7 9 7 6 1 9 3 7 5 3 2 7 5 8 8 7 7 2 7 4 10 4 3 5 5 6 8 1 5 4 9 2 4 9 3 9 10 10 7 6 3 7 8 3 10 9 7 1 2 10 5 4 6 5 6 9 2 9 10 4 10 10 3 7 2 6 4 10 3 5 6 2 6 2 5 5 1 7 6 7 8 7 8 2 2 5 8 7 2 5 4 10 2 10 9 10 9 6 5 10 9 5 2 8 6 3 8 8 1 10 7 8 2 6 9 9 3 5 2 10 3 4 8 1 4 1 10 2 8 8 8 8 2 4 2 7 5 9 10 10 2 1 9 1 3 3 7 3 1 8 5 4 3 4 1 1 6 7 10 3 6 2 5 3 8 3 1 1 4 1 1 1 7 3 4 3 2 9 2 8 9 4 2 10 8 6 8 8 1 5 6 7 4 3 1 4 8 3 6 10 3 6 5 6 10
siz = [4 4]; % size of smaller matrices to divide M into
args = arrayfun(@(n,s)n*ones(1,s/n),siz,size(M),'UniformOutput',false);
m = cellfun(@(b)sum(b,'all'),mat2cell(M,args{:}))
m = 4×4
94 97 86 77 90 102 84 94 114 102 81 89 74 76 75 72
% check
m(1,1) == sum(M(1:4,1:4),'all')
ans = logical
1
m(2,1) == sum(M(5:8,1:4),'all')
ans = logical
1
m(3,4) == sum(M(9:12,13:16),'all')
ans = logical
1

댓글 수: 1

Or using some loops:
M = randi(10,16,16); % 16-by-16 matrix of integers between 1 and 10
disp(M)
9 2 2 5 4 1 5 9 5 5 1 10 3 3 3 3 1 7 6 10 4 2 4 3 7 3 1 3 6 3 7 9 10 2 9 8 8 8 1 8 1 7 2 7 3 6 3 1 3 8 6 2 4 8 1 10 5 10 7 4 8 7 5 10 8 9 5 4 10 10 8 2 7 3 6 9 2 2 4 8 3 2 9 3 7 10 7 4 3 6 8 8 2 4 2 7 8 10 4 5 9 8 5 4 2 5 1 4 5 4 9 3 9 10 3 7 1 5 4 5 1 1 7 1 9 5 7 7 9 1 10 8 3 7 6 6 8 1 9 1 9 1 8 5 4 5 3 6 6 9 4 8 1 10 2 9 7 10 7 8 7 2 9 9 5 1 10 1 7 3 9 2 4 1 4 2 10 5 6 9 5 7 3 8 3 9 8 8 3 8 7 3 5 4 9 2 4 5 6 1 7 1 9 1 3 5 8 9 7 8 8 4 4 5 4 4 8 3 7 7 5 4 10 10 5 7 5 4 1 7 7 10 7 9 10 4 10 9 8 6 3 6 7 4 8 5 1 2 6 8 6 2 1 5 7 3
siz = [4 4]; % size of smaller matrices to divide M into
n = size(M)./siz;
m = zeros(n);
for ii = 1:n(1)
for jj = 1:n(2)
m(ii,jj) = sum(M((ii-1)*siz(1)+(1:siz(1)),(jj-1)*siz(2)+(1:siz(2))),'all');
end
end
disp(m)
90 80 78 80 99 99 72 80 103 89 90 87 88 74 95 103
% check
m(1,1) == sum(M(1:4,1:4),'all')
ans = logical
1
m(2,1) == sum(M(5:8,1:4),'all')
ans = logical
1
m(3,4) == sum(M(9:12,13:16),'all')
ans = logical
1

댓글을 달려면 로그인하십시오.

추가 답변 (2개)

Torsten
Torsten 2023년 10월 4일
편집: Torsten 2023년 10월 4일
You mean
rng("default")
A = rand(16);
for i = 1:4
for j = 1:4
B = A((i-1)*4+1:i*4,(j-1)*4+1:j*4);
A_compressed(i,j) = sum(B(:));
end
end
A_compressed
A_compressed = 4×4
9.5135 8.3613 7.5381 7.0071 7.4615 8.0673 5.5216 8.6224 10.1127 6.9479 8.0587 7.2866 7.9292 8.0528 7.6726 7.9785
?

댓글 수: 2

Thank You Torsten. There seems to be numbers with decimal points for the answer, which shall not be expected. Voss has explained with the example.
Torsten
Torsten 2023년 10월 4일
편집: Torsten 2023년 10월 4일
Well, you didn't mention the condition that the matrix elements should be integers - so I generated doubles for the 16x16 matrix. But no problem ...

댓글을 달려면 로그인하십시오.

Adam Danz
Adam Danz 2023년 10월 4일
편집: Adam Danz 2023년 10월 4일
Here are two more options. Neither are very readable but I knew there was a grouping solution and a vectorized solution and I was in the mood for a challenge.
Grouping solution
The variable group is a matrix the same size as A that groups the values of A into 4x4 sub-matrixes.
rng("default")
A = randi(10,16);
group = repelem(reshape(1:16,4,4)',4,4);
sumVec = groupsummary(A(:),group(:),'sum'); % alternative: =splitapply(@sum,A(:),group(:));
m = reshape(sumVec,4,4)'
m = 4×4
104 92 85 80 82 88 62 94 107 78 87 83 87 87 86 89
Vectorized solution
This reshapes matrix A into a 4-dimensional array and then permutes the array so that sum can be applied acros the first two dimensions. Then the results are reshaped back into a matrix.
m = reshape(sum(permute(reshape(A',4,4,4,4),[1 3 2 4]),[1,2]),4,4)'
m = 4×4
104 92 85 80 82 88 62 94 107 78 87 83 87 87 86 89

카테고리

도움말 센터File Exchange에서 Resizing and Reshaping Matrices에 대해 자세히 알아보기

질문:

2023년 10월 4일

편집:

2023년 10월 4일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by