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

1 次查看(过去 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')

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Logical 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by