Determine if there are 3 consecutive rows and columns in a list of subscripts

조회 수: 9(최근 30일)
I have a 28x2 matrix (see printout below) of subscript values (row, col) and I want to determine if there are 3 consecutive rows and then 3 connective columns coming stemming from a single reference point in the list of subscripts. From the example list below, the answer to this questions would be 'yes'. This is because the 3 consecutive rows are (44,13), (45,13), (46,13), and the 3 consecutive columns are (44,13), (44,14), (44,15). How would I execute this in matlab? I was thinking of using diff(A) to determine changes in subscript values but I am unsure exactly how. Sorry if this is confusing at all, wasn't sure how to explain my problem.
A =
43 15
44 13
44 14
44 15
44 16
45 12
45 13
45 14
45 15
45 16
46 12
46 13
46 14
46 15
46 16
47 12
47 13
47 14
48 11
48 12
48 13
49 11
49 12
49 13
50 11
50 12
50 13

채택된 답변

Matt J
Matt J 2018년 9월 17일
편집: Matt J 2018년 9월 17일
map=conv2( accumarray(A,1), ones(3),'same');
any3x3 = any(map(:))>=9
  댓글 수: 7
Guillaume
Guillaume 2018년 9월 17일
Hum, the convolution looks for the pattern
[1 1 1
1 1 1
1 1 1]
which as far as I understood is not what was asked for and is a lot more restrictive. E.g, the code fails with:
A = [1 1; 1 2; 1 3; 2 1; 3 1]
And I'm not sure my answer matches what was asked for either. I understood that the 3 consecutive columns and 3 consecutive rows could be completely independent. Rereading the question, I think that the 3 consecutive rows and columns must intersect.

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

추가 답변(1개)

Guillaume
Guillaume 2018년 9월 17일
One option:
hasconseccols = any(accummarray(A(:, 1), A(:, 2), [], @(v) ~isempty(strfind(sort(diff(v))', [ 1 1]))))
hasconsecrows = any(accummarray(A(:, 2), A(:, 1), [], @(v) ~isempty(strfind(sort(diff(v))', [ 1 1]))))
which basically, regroup together in a vector all the indices corresponding to a row/column respectively, sort that vector, take its diff and search for [1 1] which indicates at least 3 consecutive indices. If the search is not empty you have at least one row/column with 3 consecutive points.
Another option:
B = zeros(max(A));
B(sub2ind(max(A), A(:, 1), A(:, 2))) = 1;
hasconseccols = any(any(conv2(B, [1, 1, 1]) == 3))
hasconsecrows = any(any(conv2(B, [1; 1; 1]) == 3))
which basically fills a matrix with 1 at your given indices, then convolves it with a column or row of three 1. If that result in a 3, you know you have 3 consecutive indices.
  댓글 수: 5
Guillaume
Guillaume 2018년 9월 17일
I think I misunderstood a bit what was asked and that the consecutive rows and column must intersect. If that is the case, then the accumarray option would not work.
You can build on my conv2 solution to get the correct result:
B = accumarray(A, 1); %simpler than my initial 2 lines. From matt's answer
[row, centrecol] = find(conv2(B, [1, 1, 1], 'same') == 3); %consecutive columns in a row
[centrerow, col] = find(conv2(B, [1; 1; 1], 'same') == 3); %consecutive rows in a column
colexpanded = (centrecol + [-1, 0, 1])';
rowexpanded = (centrerow + [-1, 0, 1])';
ptsconsecrow = [repelem(row, 3, 1), colexpanded(:)];
ptsconseccol = [rowexpanded(:), repelem(col, 3, 1)];
intersections = intersect(ptsconsecrow, ptsconseccol, 'rows')

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

범주

Find more on Loops and Conditional Statements in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by