Reputation: 111
I have two arrays of different size A and B. I am comparing A to B and want to find for each element in A the first element in B that is smaller/larger.
I would like to use something like ismember(A,B), except that I am not looking for identical elements. The problem is that 'find' will not work because A and B are not the same size.
I now used a loop but am looking for a more elegant way to program this. Here is the loop:
for zz=1:length(A)
tmpmax(zz) = find(B>=A(zz),1);
tmpmin(zz) = find(B<=A(zz),1,'last');
end
Thanks for your suggestions!
Immo
Upvotes: 0
Views: 2041
Reputation:
It depends on how often you will do this, and how large your vectors are. But I would suggest preprocessing the array B
. For example, consider the test case:
B = rand(1,10)
B =
0.82346 0.69483 0.3171 0.95022 0.034446 0.43874 0.38156 0.76552 0.7952 0.18687
We will need to build a cumulative min and max vector. If B
is fairly long, there are several ways this might be done.
Bmin = B;
N = inf;
while numel(Bmin) < N
N = numel(Bmin);
k = find(diff(Bmin) >= 0);
Bmin(k+1) = [];
end
Bmax = B;
N = inf;
while numel(Bmax) < N
N = numel(Bmax);
k = find(diff(Bmax) <= 0);
Bmax(k+1) = [];
end
then
Bmin
Bmin =
0.82346 0.69483 0.3171 0.034446
Bmax
Bmax =
0.82346 0.95022
(I could have built Bmin
and Bmax
using a simple for loop too, and it would probably have been faster, but the while loop was more fun to write.)
Now it is simple. In order to find the first element of B
that is larger than any given value, use histc
on Bmax
. And since histc
is vectorized, the operation is fast. To do it, look at the second return argument of histc
. Or, you could write a vectorized binary search scheme. histc
will also solve the minimum element problem, by flipping the order of the elements in Bmin
.
If your goal is to find the INDEX of the element, this too is simple enough, by retaining that information when you build Bmin
and Bmax
.
Upvotes: 1
Reputation: 11168
You can get rid of the loop with:
tmpmin = arrayfun(@(x) find(B>=x,1), A);
tmpmax = arrayfun(@(x) find(B<=x,1,'last'), A );
Upvotes: 1