Find the max/min values within determined segments of a matrix

5 views (last 30 days)
For two matrices A and B:
A = [1 2 3; 4 5 6; 7 8 9; 10 11 12];
B = [3 5 8; 3 1 2; 1 5 2; 5 8 0];
For certain segments in A, I want to get the highest values related values in B. For this example, dividing the matrix into segments every 2 values of A, the output should be:
A = [1 2 3; 4 5 6; 7 8 9; 10 11 12];
Bmax = [5 5 8; 8 2 2; 5 5 5; 5 8 8];
Bmin = [3 3 3; 3 1 1; 1 1 2; 2 0 0];
To clarify the example, for values of A between 5 and 6, the maximum values of A where 2, while the minimum where 1.
Look into the comments below to get more information on the reasons for asking this question.
Thanks!
  5 Comments
Hamoon
Hamoon on 14 Sep 2015
Well, I hoped you'd say something about your data, and the reasons you are doing this. Actually it's not about Matlab, it's about what you want to do and how you want to do it, and the programming part of that is not an issue here. It's not hard to calculate maximum and minimum of B in that ranges, when you found that ranges you can white this into your loop:
IndexB = B<=val1 & B>=val0;
B_max_current = max(B(IndexB));
B_min_current = min(B(IndexB));
But I don't think that's your problem. It would be better if you talked about your database and the reason you're doing this. Then it's possible someone brings up with some ideas and algorithms to help you on this.
Victor Francisco Pajuelo Madrigal
Edited: Victor Francisco Pajuelo Madrigal on 14 Sep 2015
Thanks again Hamoon, sorry to do not give more information on my dataset, I just thought that MATLAB Answers was rather directed to the programming side of the issue instead of the individual problems with data. But is actually better for me to share my problem as it is, instead of creating examples.
I am trying to compute "Soil Moisture Index" ( SMI) with Landsat 8 images, precisely bands 4 (red), 5 (near infrared), 10 and 11 (thermal). SMI is computed by relating "Normalized Difference Vegetation Index" ( NDVI) to the Temperature. Computing NDVI is easy:
NDVI = ((nir-red)./(nir+red));
But SMI is rather more complex:
SMI = ((Tsmax - Ts)./(Tsmax - Tsmin));
Where Tsmax and Tsmin are the maximum and minimum temperatures for a given NDVI value, and Ts is the temperature at a certain pixel for a given NDVI. The problem here lies in getting both Tsmax and Tsmin, since they are calculated as follows:
Tsmax = (a_max*NDVI) + b_max
Tsmin = (a_min*NDVI) + b_min
Where a_max and a_min are the slopes for the linear fitted lines at the highest values of Temperature for NDVI, and b_max and b_min are the intercepts for those lines. The problem that I am encountering is that I am unable to get a line fitted to only the highest and lowest values of the plot shown below. When selecting min and max temperatures for NDVI values, this also includes the Temperature values at the center of the plot, since those are the maximums and minimums for some of the given NDVI. The fitting lines for max and min are then very similar and close to a normal regression between NDVI and Temperature, which is not what I am looking for here.
Therefore, my approach was to calculate the max/min temperature by segments of NDVI, getting the highest and the lowest absolute values for the segments. From there, I will fit the line to those highest and lowest values, getting the slope and intercepts that I need. For an example of this fitting being performed look at page 15 of this presentation: http://www2.le.ac.uk/departments/physics/research/eos/format-eo/final-group-presentations/group-4-soil-moisture-mapping
Thanks!

Sign in to comment.

Accepted Answer

Hamoon
Hamoon on 14 Sep 2015
Actually you were right, MATLAB answers is directed to the programming side of the issue, I just wanted to know what you exactly want, because your example was not clear enough. So you have two matrices (A and B) with same size and different values, and you want to find minimum and maximum values of those elements in the "B" which their values lies in a specific range according to "A". So you won't have a Bmin and Bmax as it is in your example. Bmin and Bmax would be two vectors with "n" elements, where "n" is the number of ranges you chose. I changed your code a little bit. you just compare this code with your own code and tell me is that what you want? because its output is not like what you said in your example:
A = [1 2 3; 4 5 6; 7 8 9; 10 11 12];
B = [3 5 8; 3 1 2; 1 5 2; 5 8 0];
n = 6; % number of ranges
Amin=min(A(:));
Amax=max(A(:));
% initialize Bmax and Bmin
Bmax = zeros(1,n);
Bmin = zeros(1,n);
ranges = linspace(Amin,Amax+1,n+1); % split values into "n" ranges with equal size
% you may do something else to find your
% desire ranges
for i = 1 : n
indices = ( A<ranges(i+1) & A>=ranges(i) );
Bmax(i) = max(B(indices));
Bmin(i) = min(B(indices));
end
the answer is like this:
Bmax =
5 8 2 5 5 8
Bmin =
3 3 1 1 2 0
  2 Comments
Victor Francisco Pajuelo Madrigal
Edited: Victor Francisco Pajuelo Madrigal on 14 Sep 2015
Thank you very much for this Hamoon. I am just a beginner in Matlab (started using it one week ago) so the comments on your code helped me adapting it to mine, so I could find new functions and ways to initialize new matrices. I hope that this thread will help other users of MATLAB and Landsat images, since I could not find anything related to the process that I am computing in any forum or user community.
Here are the results with my previous code (for my dataset), and the code:
%%Trial Regression Min
%Getting the min of NDVI
NDVImin=min(ndvi(:));
NDVImax=max(ndvi(:));
%Entering segmentation number desired
it_num=0.05;
%Generating a vector of segments
it=NDVImin:it_num:NDVImax;
counter=1:numel(it);
itvector(counter)=it;
%Establishing indices to refer to vector values
max_it=numel(itvector);
for val_it=2:1:max_it; %Iterate over vector locations
val_it_low=val_it-1; %Set lower part of range
val0=itvector(val_it_low) %Get value of lower part of range
val1=itvector(val_it) %Get value of higher part of range
IndexNDVI=(ndvi>val0 & ndvi<=val1) %Look for values that are in the range
ndvi(IndexNDVI)=1; %Set to 1 those values that are in range
b11(IndexNDVI)=min(b11(ndvi==1)) %Find the min values for the values at range
ndvi=((nir-red)./(nir+red)); %Reset dependent values
end
Since I could not create an adequate vector of segments, the Bmin takes values for all the NDVI in range.
And here are the results with your inputs on the code:
%%Trial with Hamoon tweak
%Getting the min and max of A
NDVImin=min(ndvi(:));
NDVImax=max(ndvi(:));
%Entering segmentation number desired
it_num=0.05;
%Generating a vector of segments
it=NDVImin:it_num:NDVImax;
counter=1:numel(it);
itvector(counter)=it;
%Establishing indices to refer to vector values
max_it=numel(itvector);
% initialize Bmax and Bmin
Bmax = zeros(1,max_it);
Bmin = zeros(1,max_it);
Ndvi = zeros(1,max_it);
for val_it=2:1:max_it; %Iterate over vector locations
val_it_low=val_it-1; %Set lower part of range
val0=itvector(val_it_low) %Get value of lower part of range
val1=itvector(val_it) %Get value of higher part of range
IndexNDVI=(ndvi>val0 & ndvi<=val1) %Look for values that are in the range
ndvi(IndexNDVI)=1; %Set to 1 those values that are in range
Bmax(IndexNDVI)=max(b11(ndvi==1)); %Find the min values for the values at range
Bmin(IndexNDVI)=min(b11(ndvi==1));
Ndvi(IndexNDVI)=((val1+val0)./2); %Setting the values at the center of the range
ndvi=((nir-red)./(nir+red)); %Reset dependent values
end
Obviously, with your inputs the code is both more efficient and less resource intensive. And the results of the line fitting are way better.
Thanks Hamoon!
Hamoon
Hamoon on 14 Sep 2015
My pleasure.
Actually you still can modify your code and optimize it. But there is another issue. Instead of using maximum/minimum value for each range, you can use for example "m" smallest/largest values and compute mean value or mode value for that "m" smallest/largest values (or perform any other statistical methods on them) and consider this value as smallest/largest value, this can reduce the effect of outliers.

Sign in to comment.

More Answers (0)

Products

Community Treasure Hunt

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

Start Hunting!