Find upper bound index in sorted vector - matlab

I have a vector like the following in Matlab.
Columns 1 through 4
0.160000000000000 0.208000000000000 0.244000000000000 0.268000000000000
Column 5
0.280000000000000
And I want to find the upper bound index of the following value:
0.16230400000000
I know this value is between the 1° and 2° indices, but I want to find the upper bound which in this case is index 2, even when the closest value is at index 1. How do I get that in Matlab without a loop?
I found the following method to find the closest value but I need always the upper bound.
[c ind] = min(abs(probCum-codComp));

You can get the index of the upper bound by counting how many entries are smaller than the value of interest increased by one:
id = sum(value < data)+1;
Note that, if all elements are smaller than the value of interest, data(id) will return an error because id is larger than the size of data.

If your array is sorted in an ascending fashion, the find command is especially powerful:
find (a>0.162,1)

You can subtract the value you search for from the vector and observe the sign
V = [0.1600 0.2080 0.2440 0.2680 0.2800];
v = 0.162304;
V-v
ans =
-0.0023 0.0457 0.0817 0.1057 0.1177
Now you can find the first non-negative entry in this vector - this is your upper bound
find(V-v>=0, 1, 'first')
ans =
2
You can also change the inequality in the expression above to suite your needs.

You can use the second output from min to get the indices to the "proper" index:
[~,index] = min(abs(data-value));
then check if the lower or upper was taken, and adjust index accordingly:
if value > data(index)
index = min(length(data), index+1); end

Related

MATLAB: find whether the specific index in the correspondinig column

The problem is as follow:
I have a k-nearest index matrix. The column of the matrix denotes the number of an image (1:n). The row of index matrix denotes the index of k-nearest pixels correspoinding to the query pixel.
So I am using for-loops to find out whether a-th index is in column b: for example, 3 is in the first column (1-th pixel), then find out whether 1 is in 3-th column, if no, assign value, if yes, assign another value.
The code is here:
for pix = 1:row*col
for i = 1:k
position = find(Index(:, Index(i,pix)) == pix);
if isempty(position) difference = - weight(k, Index(i,pix)) ;
else difference = weight(i,pix) - weight(position, Index(i,pix)) ; end
end
end
Since row*col is very large. I hope to reduce the code into one for-loop. Is there any other method to speed up? Thanks in advance!

Matlab find function throws size difference error when there is no apparent one

My matlab code is attempting to find the indices in a 601 by 1 matrix that correspond to a given value but says the left and right sides have a different number of elements
pH_fine = pH(1):0.01:pH(end);
pH_labvals = [7.72,9.87,7.4,7.63,7.06,6.85,8.29,9.37,11.1];
index_labvals = [];
a = find(pH_fine == 8); %This works perfectly
for i = 1:length(pH_labvals)
index_labvals(i) = find(pH_fine == pH_labvals(i)); %This throws an error
end
Your problem is that the find(pH_fine == pH_labvals(i)) on the right side sometimes doesn't find any match, and returns an empty result for an index, specifically a 1-by-0 row vector. This doesn't match the size of the left side, which is indexing a 1-by-1 element from your vector index_labvals.
You need to check first if the result of find is empty, and decide what you will put in the index vector in that case, like a 0 or NaN. You will also need to deal with find giving you a vector of indices if pH_labvals has the same value repeated. If you simply want to remove repeated values, you could use unique like so:
pH_labvals = unique(pH_labvals, 'stable');
If you're wondering why you're getting an empty result from find, you should read through this post about the perils of floating-point comparison. One possible solution, assuming pH_labvals contains non-repeated values with 2 decimal places of precision, is to first round your pH_fine vector to 2 decimal places:
pH_fine = round(pH(1):0.01:pH(end), 2);
This should allow you to avoid the errors from floating-point comparison.
An alternative approach is to use interp1 for table lookup:
pH = [1,14]; % Not sure what values you use here, it doesn't matter for the example.
pH_fine = pH(1):0.01:pH(end);
pH_labvals = [7.72,9.87,7.4,7.63,7.06,6.85,8.29,9.37,11.1];
index_labvals = interp1(pH_fine,1:numel(pH_fine),pH_labvals,'nearest')
Here, we're finding the nearest index within pH_fine that matches each of the values in pH_labvals. 1:numel(pH_fine) are the indices into pH_fine.
Note that there's no need for a loop, as interp1 will lookup all pH_labvals at once.

using Matlab, how to find the maximum value over a certain range?

i want to know the coding to find the maximum value, over a certain range.
i already coded like below.
f=f'
ac_yyyy_f=ac_yyyy_f'
[row,col] = ind2sub(size(ac_yyyy_f),find(ac_yyyy_f==max(ac_yyyy_f)))
but the problem is, sometimes the maximum value of Y axis choosen by my code is not what i want.
the X axis has the range of 0 to 100000 and i want the maximum between 20000 to 100000. the problem is sometimes the max value show up at the range of 0 to 20000.
How can i figure this out?
Use the max() function:
%let R be your range of values
R = [2 1 7 4];
[value, index] = max(R);
In the above example, value will be 7 and index will be 3
For more info: http://fr.mathworks.com/help/matlab/ref/max.html
I'm using a vector of random integers to stand in for your function output.
a = floor(rand(1,100000)*100);
[val, idx] = max(a(20000:100000));
You want to use the max function here to find the maximum value rather than find.
Now, the other part of the task is getting the max value from a certain part of your matrix. You can pass just a subset of a vector or matrix to a function by indexing it with a range of values. Note that idx gives you the position of val within a(20000:100000). If you need the position within a, you need to use idx+19999.
Also, you should take a look at the matrix indexing reference—there are many different and fun ways to index a matrix—because indexing is one of the most important features of matlab.
Here's the reference for the max function:
http://www.mathworks.com/help/matlab/ref/max.html
And the reference for indexing:
http://www.mathworks.com/help/matlab/math/matrix-indexing.html
You can use the max function with a subset of your array. It will return the maximum value, as well as the index where it is located. Be sure to correct the index it returns you based on your desired range. Like this:
%//create an array of 100,000 values to play with.
f=floor(rand(100000,1).*100);
%//find the max between f(20000) and f(100000)
[myMax, I] = max( f(20000:100000) );
%//correct the index based on where we started looking
%//for the max. Subtract 1 because it's MATLAB!
myIndex = I+20000-1;
This results in:
>> myMax
myMax =
99
>> myIndex
myIndex =
20045
>> f(myIndex)
ans =
99

Using find on non-integer MATLAB array values

I've got a huge array of values, all or which are much smaller than 1, so using a round up/down function is useless. Is there anyway I can use/make the 'find' function on these non-integer values?
e.g.
ind=find(x,9.5201e-007)
FWIW all the values are in acceding sequential order in the array.
Much appreciated!
The syntax you're using isn't correct.
find(X,k)
returns k non-zero values, which is why k must be an integer. You want
find(x==9.5021e-007);
%# ______________<-- logical index: ones where condition is true, else zeros
%# the single-argument of find returns all non-zero elements, which happens
%# at the locations of your value of interest.
Note that this needs to be an exact representation of the floating point number, otherwise it will fail. If you need tolerance, try the following example:
tol = 1e-9; %# or some other value
val = 9.5021e-007;
find(abs(x-val)<tol);
When I want to find real numbers in some range of tolerance, I usually round them all to that level of toleranace and then do my finding, sorting, whatever.
If x is my real numbers, I do something like
xr = 0.01 * round(x/0.01);
then xr are all multiples of .01, i.e., rounded to the nearest .01. I can then do
t = find(xr=9.22)
and then x(t) will be every value of x between 9.2144444444449 and 9.225.
It sounds from your comments what you want is
`[b,m,n] = unique(x,'first');
then b will be a sorted version of the elements in x with no repeats, and
x = b(n);
So if there are 4 '1's in n, it means the value b(1) shows up in x 4 times, and its locations in x are at find(n==1).

Find highest/lowest value in matrix

very basic question: How can I find the highest or lowest value in a random matrix.
I know there is a possibility to say:
a = find(A>0.5)
but what I'm looking for would be more like this:
A = rand(5,5)
A =
0.9388 0.9498 0.6059 0.7447 0.2835
0.6338 0.0104 0.5179 0.8738 0.0586
0.9297 0.1678 0.9429 0.9641 0.8210
0.0629 0.7553 0.7412 0.9819 0.1795
0.3069 0.8338 0.7011 0.9186 0.0349
% find highest (or lowest) value
ans = A(19)%for the highest or A(7) %for the lowest value in this case
Have a look at the min() and max() functions. They can return both the highest/lowest value, and its index:
[B,I]=min(A(:)); %# note I fixed a bug on this line!
returns I=7 and B=A(7)=A(2,2). The expression A(:) tells MATLAB to treat A as a 1D array for now, so even though A is 5x5, it returns the linear index 7.
If you need the 2D coordinates, i.e. the "2,2" in B=A(7)=A(2,2), you can use [I,J] = ind2sub(size(A),I) which returns I=2,J=2, see here.
Update
If you need all the entries' indices which reach the minimum value, you can use find:
I = find(A==min(A(:));
I is now a vector of all of them.
For matrices you need to run the MIN and MAX functions twice since they operate column-wise, i.e. max(A) returns a vector with each element being the maximum element in the corresponding column of A.
>> A = rand(4)
A =
0.421761282626275 0.655740699156587 0.678735154857773 0.655477890177557
0.915735525189067 0.0357116785741896 0.757740130578333 0.171186687811562
0.792207329559554 0.849129305868777 0.743132468124916 0.706046088019609
0.959492426392903 0.933993247757551 0.392227019534168 0.0318328463774207
>> max(max(A))
ans =
0.959492426392903
>> min(min(A))
ans =
0.0318328463774207
Note that this only works for matrices. Higher dimensional arrays would require running MIN and MAX as many times as there are dimensions which you can get using NDIMS.
Try this out
A=magic(5)
[x,y]=find(A==max(max(A))) %index maximum of the matrix A
A_max=A(x,y)
[x1,y1]=find(A==min(max(A))) %index minimum of the matrix A
A_min=A(x1,y1)