Info

This question is closed. Reopen it to edit or answer.

How to find multliple values in larger arrays where the value two above it is a negative

1 view (last 30 days)
I work with larger arrays (100x100) and am trying to develop a script which finds values where the value 2 above it is negative. For example, in the following array:
10 10 10 10 10 10
10 10 -3 10 10 10
10 10 10 10 10 -6
10 10 20 10 10 10
10 10 10 10 10 25
The values I would like to find would be the '20' and '25'.
Thing I am trying to achieve from the script:
  • something which identifies these values in the array (value 2 above it is negative)
  • a script which displays the location of where these minima are in the command window
I suppose it could be done by using if statements, but I'm not sure.
Thanks for any help :)

Answers (3)

Guillaume
Guillaume on 23 Oct 2014
Edited: Guillaume on 23 Oct 2014
You basically want to find the location of negative values in your array:
[row, col] = find(a < 0);
You can then offset the row by 2 to get the numbers you want. But first make sure, it's not the last two rows:
isvalidrow = row < size(a, 1) - 2;
col = col(isvalidrow);
row = row(isvalidrow) + 2; %drop down two rows
To get the numbers, you convert the row and col into linear indices:
numbers = a(sub2ind(size(a), row, col));
As an aside, 100x100 is not a large array, it is actually rather small.

Star Strider
Star Strider on 23 Oct 2014
I don’t entirely understand what you want your script to do, but this will get you started:
M = [10 10 10 10 10 10
10 10 -3 10 10 10
10 10 10 10 10 -6
10 10 20 10 10 10
10 10 10 10 10 25];
[Mr,Mc] = find(M<0); % Row, Col Indices Of Negatives
for k1 = 1:length(Mc)
R(k1) = M(Mr(k1)+2,Mc(k1)); % Values At Row+2
end
  4 Comments
Star Strider
Star Strider on 29 Oct 2014
Edited: Star Strider on 29 Oct 2014
To an extent, yes. This doesn’t search diagonally — that requires 2D filtering or convolution that could take some time to implement, and given the constraints may not be possible to do with the requisite accuracy — but it does search adjacent rows and columns. (NOTE: With the EDIT following my original Comment, it now considers diagonal elements as well.)
A1 = [30 30 30 30 30 30 30 30
30 30 30 30 30 10 30 30
30 20 30 30 30 30 30 30
30 30 30 10 30 30 30 30
30 10 30 30 30 30 30 30
30 30 30 30 30 30 30 30];
A2 = [22 22 22 22 22 22 22 22
22 22 22 -5 22 22 22 22
22 -5 22 22 22 22 22 22
22 22 22 22 22 22 22 22
22 22 22 22 22 22 22 22
22 22 22 22 22 22 22 22];
A3 = [100 100 100 100 100 100 100 100
100 100 100 100 100 100 100 100
100 100 100 100 100 100 100 100
100 100 100 100 200 100 100 100
100 100 200 100 100 100 100 100
100 100 100 100 100 100 100 100];
drA1 = diff([A1(:,1) A1],1,2);
dcA1 = diff([A1(1,:); A1],1,1);
[A1r,A1c] = find((drA1 == -20) & (dcA1 == -20)); % Step #1
for k1 = 1:length(A1r) % Step #2
A2q = circshift(A2, [3-A1r(k1) 0]);
A2rc(k1,:) = (A2q(1,A1c(k1))<0)*[A1r(k1) A1c(k1)];
end
A2rc = reshape(A2rc(A2rc>0),[],2); % Remove Zero Elements
for k1 = 1:size(A2rc,1) % Step #3
A3q = circshift(A3, [0 1-A2rc(k1,2)])
A3rc(k1,:) = (A3q(A2rc(k1,1),2) > A3q(A2rc(k1,1),1))*A2rc(k1,:);
end
The ‘A3rc’ array contains the rows and columns that meet the criteria (except for the diagonal search in ‘A1’).
EDIT The 2D filter can replace these lines:
drA1 = diff([A1(:,1) A1],1,2);
dcA1 = diff([A1(1,:); A1],1,1);
[A1r,A1c] = find((drA1 == -20) & (dcA1 == -20)); % Step #1
with these lines, now searching the diagonals as well:
h =- [-1 -1 -1; -1 20 -1; -1 -1 -1];
Y = filter2(h, A1);
[A1r,A1c] = find(Y > 0); % Step #1
This can be done with core MATLAB functions, not requiring the Image Processing Toolbox.

Matt J
Matt J on 28 Oct 2014
Edited: Matt J on 28 Oct 2014
map=circshift(yourMatrix<0,[2,0]);
map(1:2,:)=0;
[row,col]=find(map)
values=yourMatrix(map)

Community Treasure Hunt

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

Start Hunting!