Reputation: 599
I'm trying to extract from a 2-D matrix with id values the neighboring ids of each element on the board.
I have a list of of IDs and their coordinates (of n elements), and I'm creating the following: (Example for left neighbor only).
%Left:
leftIndex = (currentLocationIndex - bSize);
hasLeft = leftIndex >= 1; %If element on first col, value will be 0 or negative
hasLeft = hasLeft(:) & board(leftIndex)==0;
I get: Subscript indices must either be real positive integers or logicals.
I want to use the pricipal of && operand or some other logic. the leftIndex contains all the indices left to a current index in the table. Some are legal some arn't. If hasLeft vector is true then the leftIndex vector value is legal in the 'board'.
How can I check for a neighbor in a certain value of the vector only if the hasLeft is true?
Thanks!
Upvotes: 0
Views: 1229
Reputation: 11
my approach for solving this issue was using the “try” statement to determent if an index is legal and then assign it, if it is.
this is the closest thing I found to a straightforward check index legality command.
here is a code to illustrate
initialization
M=4; N=5;
Mat=rand(M,N);
m=2; n=1;
the code: try to access this element... assign the element as a legal Neighbor only if Succeeded
near= [m,n-1;m,n+1;m+1,n;m-1,n];
Neibs=[];
for i =1:4
try
Mat(near(i,1),near(i,2));
Neibs=[Neibs;[near(i,1),near(i,2)]];
catch
end
end
results presentation
BW=zeros(M,N);
if ~isempty(Neibs)
for i =1:length(Neibs(:,1))
BW(Neibs(i,1),Neibs(i,2))=true;
end
end
of course once the point is made, changing the size, dimensions, or neighborhood metrica is not a problem
Upvotes: 1
Reputation: 46405
Reading your question more carefully, and answering only what you asked for (which became clearer after I had read some of your other recent questions...):
The first problem you run into is the fact that your array leftIndex
may contain values < 1, and therefore cannot legally be used in the expression hasLeft = hasLeft(:) & board(leftIndex)==0;
To get around this, you neeed to index board
with only "valid" indices, which you can get by changing the previous line to
hasLeft = find(leftIndex >= 1);
Note that your original, hasLeft = leftIndex >= 0;
generates a logical array of "true" and "false" values of the same size as leftIndex
. By contrast, the find
command returns only the indices of the elements that meet the criteria. Now we need to do two more things: 1) find the elements in board
with a valid index and a value >=0; and 2) map these back to the index of the "whole thing" (not the index in the subarray). Here is how you do it:
interestingSquare = (board(hasLeft)==0);
hasLeft = hasLeft(interestingSquare);
This last line takes you back from "position of an interesting square in the sub-array 'hasLeft'" to "position relative to the original leftIndex
array.
I do wonder whether you really meant to test for board == 0
but I'm sure that if that was a typo, you would figure it out...
Upvotes: 1
Reputation: 46405
I would do two things:
First, find "all the neighbors" including the "illegal" ones. For example, if the indices are n, m
then all "potential neighbors" are [pn pm]= meshgrid(n+(-1:1), m+(-1:1));
. Note this also includes the point itself.
Second, mask out only "legal" neighbors by testing their value against the limits of the array. If you have a 2D array with size N by M, you could use
legal = find(pn>0 && pn <= N && pm > 0 && pm <= M && ~(pn==n && pm==m));
That should give you (up to 8) all legal neighbors. Obviously if you don't want the "kitty corner" neighbors you change the statement that created pn
and pm
. I hope you get the idea.
Upvotes: 2