Reputation: 31
How can I take the following square array (or any other square array ebtered by the user) and take the center NxN square? For example:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
is entered along with specifications for the middle 2x2, so it becomes
6 7
10 11
Here is my code thus far:
function [FinalMatrix] = arraycenter(x, m)
% arraycenter takes a large square NxN matrix and trims away everything
% other than the center 'm'x'm' submatrix.
% x must be a square 2 dimension matrix that is at least 3x3
% m must be an integer less than or equal to N, and if N is even, m
% must be even, and vice versa
% Find dimensions of x and check to make sure it is a square, 2D matrix
columndim = size(x, 1);
rowdim = size(x, 2);
pagedim = size(x, 3);
if columndim < 2 || rowdim < 2 || pagedim ~= 1
error('Your first matrix entered was not two dimensional. Try again.')
end
if columndim ~= rowdim
error('Your first matrix was not a square. Try again.')
end
% Make sure m is the correct size
if m >= columndim || m >= rowdim
error('m is too large. Try again.')
end
% Make sure N and m match (N is odd, m is odd; N is even, m is even)
if rem(rowdim, 2) == 0 && rem(m, 2) == 1
error('N is even and m is odd. Try again.')
end
if rem(rowdim, 2) == 1 && rem(m, 2) == 0
error('N is odd and m is even. Try again.')
end
% Perform the operation to find the center matrix
end
As you can see, I have done all the data validation. I am stuck on the actual performance of the task. Thank you in advance!
Upvotes: 2
Views: 118
Reputation: 6015
The following function crops out a square matrix from center of another. It does not control the even/odd criteria implemented in your code. If equal margins cannot be created according to the dimensions of x
and the value of m
, the top and left margins will be smaller than the right and bottom margins by one element.
function [y, sI, eI] = arraycenter(x, m)
% returns an m by m matrix from center of square matrix x
% startIndex and endIndex are index of first and last
% column (or row) if x that will be copied to y,
% so that y = x(sI:eI, sI:eI)
% check if x is a square 2d matrix
sz = size(x);
if ~ismatrix(x) || sz(1)~=sz(2)
error('x must be a square 2D matrix');
end
% check id m is equal or less than d
d = sz(1);
if m>d
error('m must be equal or less than size(x, 1).');
end
sI = floor((d-m)/2)+1;
eI = sI+m-1;
y = x(sI:eI, sI:eI);
end
But if you insist to inform caller that all margins will not be equal, you can add the following control as well:
if mod((d-m), 2)
warning('y can not be exactly at the center of x.');
end
Use it like:
n = 5;
M = magic(n)
for i=1:n
fprintf('%dx%d:\n', i, i);
disp(arraycenter(M, i));
end
M =
17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9
1x1:
13
2x2:
5 7 6 13
3x3:
5 7 14 6 13 20 12 19 21
4x4:
17 24 1 8 23 5 7 14 4 6 13 20 10 12 19 21
5x5:
17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9
Upvotes: 1