How do I create a simulator to scan a matrix and switch some of the elements in it?
2 views (last 30 days)
I want to create a simulator with for loops to simulate this scenario.
For example, I have a 20x20 matrix with 1s or 0s, and I want to find how many 1s are there around every 1 and 0. If there is 2 or 3 1s around 1, then this '1' will be kept, otherwise, it will be turned into a 0 in the next step. As for 0s, if there is exact three 1s around it, it will be turned to a 1, otherwise it will still be 0.
I tried to use a filter to make this happen, but failed.
Athul Prakash on 18 Mar 2021
Using a filter along with conv2 should work, for example..
% It may be easier to store a logical array
inp = (rand(20,20) < 0.80); % creates an input matrix of 1's and 0's (mostly 1's)
k = [0 1 0;
1 0 1;
0 1 0 ]; % filter to look for 1's in adjacent positions (excluding diagonally adjacent)
% This convolution counts the required number of adjacent 1's
num_ones = conv2(inp, k, 'same');
% 'same' makes sure that 'num_ones' and 'inp' have the same size.
% find the indices of 1's in the output.
valid_ones_idx = (inp & (num_ones==2 | num_ones==3)); % for input 1's, if no. of adj ones is 2 or 3.
valid_zeros_idx = ( ~inp & (num_ones==3) ); % for input 0's, if no. of adj ones is 3.
% 'inp' and 'num_ones==1' are both logical arrays, and hence we can simply
% ... use '&' and '|' operators over them.
% output is the array with 1's coming from either of the above conditions,
% and 0 everywhere else. This is simply an OR operation.
out = valid_ones_idx | valid_zeros_idx;
1) If you need to convert any of these logical arrays to MATLAB's default double type, use arr = double(arr);
For the reverse, use arr = logical(arr);
2) I wasn't sure what you meant by adjacent, I've used one exampe of a kernel to show that the idea works. You may try other kernels if your definition of adjacent is different.
Hope it helps!