Writing a script for multiple arrays with a set criteria for each array and identifying certain value locations

1 view (last 30 days)
I am working with arrays of data, where each value is a latitude and longitude grid point - columns are longitude and rows are latitude.
There are three arrays of equal size, representing the same latitude-longitude grid points over the Earth. Each array however contains a different type of data: the first, temperature; the second, wind; the third, height of the atmosphere.
I want to develop a script which identifies certain grid points according to some criteria: The process:
  1. scanning the first array for if certain values are 20 units less than the surrounding grid points
  2. For these locations of where minimum values are, scanning the second array to check whether the value two places above it is negative.
  3. For these locations where the both the minimum values are (for the first array) and two places above is negative (for the second array), scanning the third array for where the value to the right of the location must be greater.
I presume this will require if statements and for loops.
For Example:
1st array
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
2nd array
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
3rd array
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
The script would scan array 1, find the values, scan array 2 at those values lcoations, if it matches critera, it scans array 3 at these lcoations, if it matches the criteria, creates a lsit of the row and column where the lcoations match all 3 criteria. for the above example it would be row and column ([r c]):
4 4
5 2
because in row 5, column 2:
1)10 is less than surrounding eight grid points, 2) the -5 two above it is negative and 3) the 200 is greater than 100.
Thanks for any help
  1 Comment
Oliver
Oliver on 31 Oct 2014
Edited: Oliver on 31 Oct 2014
Thank you for your answers, all methods work fine :)
One extra thing
For multiple time steps, how do I create a table which calculates the occurrences
e.g.
for n = 1:10
endii = imerode(A(:,:,1),[1 1 1;1 0 1;1 1 1]) > A(:,:,1) &...
imerode(A(:,:,2),[1;0;1;0;0]) < 0 &...
imdilate(A(:,:,3),[1,1,0]) > A(:,:,3);
[r,c] = find(ii);
end
Instead of it just displaying a the r and c value for every n value in the command window, could another matrix be created which fills in r and n values as it goes along e.g.
1 4 34
2 3 90
2 7 75
3 14 89
Where in the above the first column is n, the second r and the third c.

Sign in to comment.

Accepted Answer

Star Strider
Star Strider on 29 Oct 2014
Edited: Star Strider on 29 Oct 2014
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.
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.
  4 Comments
Oliver
Oliver on 3 Nov 2014
I am having a problem with the script, am running it over a large for loop to repeat the process for different datasets
In some of these, there are no differences and it displays
Undefined function or variable 'A2rc'.
Is there an if statement that can be used that if nothing is found, it just moves onto the the next dataset. Thanks :)
Star Strider
Star Strider on 3 Nov 2014
Probably the easiest way to do this is to insert a test for ‘A2rc’ being empty just before the reshape call:
if ~isempty(A2rc)
A2rc = reshape(A2rc(A2rc>0),[],2); % Remove Zero Elements
else
continue
end
That will cause it to stop executing further statements in the loop and continue to the next iteration.
This is obviously untested, so if it causes further problems, let me know.

Sign in to comment.

More Answers (1)

Andrei Bobrov
Andrei Bobrov on 30 Oct 2014
Edited: Andrei Bobrov on 30 Oct 2014
A = cat(3,[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],...
[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],...
[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]);
With Image Processing Toolbox
ii = imerode(A(:,:,1),[1 1 1;1 0 1;1 1 1]) > A(:,:,1) &...
imerode(A(:,:,2),[1;0;1;0;0]) < 0 &...
imdilate(A(:,:,3),[1,1,0]) > A(:,:,3);
[r,c] = find(ii);
Without Image Processing Toolbox
n = size(A);
f1 = false(1,n(2));
f2 = false(n(1),1);
l1 = [f1;diff(A(:,:,1))<0] & [flipud(diff(A(end:-1:1,:,1)))<0;f1] &...
[f2,diff(A(:,:,1),1,2)<0] & [fliplr(diff(A(:,end:-1:1,1),1,2))<0,f2];
l2 = sign(A(rem(n(1)-k +(0:n(1)-1),n(1))+1,:,2)) == -1;
l3 = [diff(A(:,:,3),1,2) > 0, f2];
[r,c] = find(l1 & l2 & l3);
  2 Comments
Oliver
Oliver on 30 Oct 2014
Edited: Oliver on 30 Oct 2014
for the first step
imerode(A(:,:,1),[1 1 1;1 0 1;1 1 1]) > A(:,:,1) &...
Is this 20 less or just less than?
Also I presume using separate array names such as A1, A2 and A3 in place of A(:,:,1), A(:,:,2) and A(:,:,3) works equally well?
Oliver
Oliver on 31 Oct 2014
Thank you for your answer, I have posted an additional bit to the question above, do you mind having a look at it for me, thanks :)

Sign in to comment.

Categories

Find more on 3-D Scene Control 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!