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

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 :)

1 comentario

Please don't overload the tags with near duplicate and irrelevant tags

Respuestas (3)

Guillaume
Guillaume el 23 de Oct. de 2014
Editada: Guillaume el 23 de Oct. de 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.
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 comentarios

That's great :) is there a way of identifying the row and column of the 20 and 25 in the command window, not the actual values. Thanks :)
My pleasure!
Probably the most visually convenient way to display the row and column index vectors in the command window would be to create a separate matrix with the row and column indices in each row of the display matrix:
RowCol = [Mr Mc]
producing:
RowCol =
2 3
3 6
so the first one is at (2,3) and the second at (3,6).
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 el 28 de Oct. de 2014
Editada: Matt J el 28 de Oct. de 2014
map=circshift(yourMatrix<0,[2,0]);
map(1:2,:)=0;
[row,col]=find(map)
values=yourMatrix(map)

La pregunta está cerrada.

Preguntada:

el 23 de Oct. de 2014

Cerrada:

el 20 de Ag. de 2021

Community Treasure Hunt

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

Start Hunting!

Translated by