Find elements from A in B and get the index of found element in B

Hi
I have two arrays, A and B, A has 12,000 elements and B has 260,000 elements.
I need to find every instance when an element in A equals B and get the index of B when this occurs.
So for example at A(5) I need to search all elements of B for the value in A(5) and return the index location of B where it is found.
var_found = []
for i : length(A)
B( find(A(i)) ) = var_found(i);
end
Please can someone advise

 채택된 답변

Jos (10584)
Jos (10584) 2017년 12월 19일
편집: Jos (10584) 2017년 12월 19일
You want to find all the indices of all elements of A in B? So, some elements of A might occur once, other multiple times, and some not at all. Therefore you need to resort to cell arrays. With arrayfun you can loop over all elements of A:
A = [1 2 3 4]
B = [2 2 1 4 2 1]
C = arrayfun(@(x) find(B==x), A, 'un', 0)
% C{k} now holds the indices into B, where B equals A(k)

댓글 수: 6

Hi, Thanks for the reply.
I don't think this is what I looking for. This gives me sizes like [1x2 double] and I am unsure what I should do with that.
All my values in B are unique. So when A(i) is found in B that's the value, there are no other occurrences of this element in B. I need the index of this found location in B.
This cannot be true. If all values in B are unique, the size of C{k} should be 1-by-1, for all k.
Your original question stated: " I need to find every instance when an element in A equals B and get the index of B when this occurs.".
So, be more precise. What doe you mean by "every instance", and "get the index of B"?
Nathan Kennedy
Nathan Kennedy 2017년 12월 19일
편집: Nathan Kennedy 2017년 12월 19일
Array B goes from 0 to approximately 2 in increments of 0.0001.
Array A is a sin wave with values between 0 and 2 with values at 4 decimal places.
For every value contained in array A, find the equivalent value in array B but also get the index position of that value in B.
So for example if A(5) is -1.2044 then find that value in B and also say what position it is in B, like its in B(25300)
@Nathan: Oh, it would have been better to explain these important details in the question already. Remember that Matlab works with the type double as default and "0 to approximately 2 in increments of 0.0001" might differ from what you expect. See the standard example:
any((0:0.1:1) - 0.3)
The answer is false, because 0.1+0.1+0.1 does not equal 0.3 . See https://www.mathworks.com/matlabcentral/answers/57444-faq-why-is-0-3-0-2-0-1-not-equal-to-zero.
You write: For every value contained in array A, find the equivalent value in array B but also get the index position of that value in B.
  • The equivalent value in B will be the same value of A, by definition.
  • The index in B will be the second (or third) output of intersect.
btw, did you take floating point problems into account? Two floating points may look the same but may in fact differ minutely, so they are treated as not being equal:
a = 0.3 % looks like 0.3000
b = 0.1 + 0.2 % looks like 0.3000
a==b % false ...
fprintf('%.20f\n',[a b]) % ... as they do differ!
I do begin to suspect your problems are arising from this ...

댓글을 달려면 로그인하십시오.

추가 답변 (4개)

You can use the 'intersect' command in order to extract the common values along with the indices from base arrays A and B.
[output_array,index_a,index_b] = intersect(A,B,'stable');

댓글 수: 2

Hi, Thanks for the reply.
So I have implemented this and it only returns one set of values, the output is
output array = 0
index_a = 1
index_b = 200001
Which is right, A(1) had its first occurrence at B(200001). But it doesn't find them all... i.e. A(2), A(3)... A(length(A))
Can intersect be looped? It does not show that on the link you gave
Intersect returns all data elements common to A and B. There is no need to loop. If output_array has only one element, it implies that only one common element exists between A and B. However, this method neglects indices in data containing repetitive elements and is suitable for a unique set.
>> A = [ 1.01 2.02 3.03 4.04 5.05 6.06];
>> B = [ 1 2 3.03 4 5.05 6 ];
>> [output_array,index_a,index_b] = intersect(A,B,'stable');
>> output_array
output_array =
3.0300 5.0500
>> index_a
index_a =
3
5
>> index_b
index_b =
3
5

댓글을 달려면 로그인하십시오.

Jan
Jan 2017년 12월 19일
편집: Jan 2017년 12월 19일
[iA, locB] = ismembertol(A, B, 1e-6);
Or maybe
[iB, locA] = ismembertol(B, A, 1e-6);
If this can be "looped" depends on what "looped" means.
Nathan Kennedy
Nathan Kennedy 2017년 12월 19일
편집: Nathan Kennedy 2017년 12월 19일
I am interested in what Jo says, but I don't think that's the issue? I have tried what others have written above and it does not seem to be quite working.
So I have placed a section of code below to show its not working.
%Setup Sampling of waveform
f = (20.2 : 0.01 : 21.2)*10^9;
Fs = 3*max(f); %over 2 sampling frequency to prevent nyquist
Ts = 1/Fs;
end_t = 0.2*10^(-6);
number_samples = end_t /Ts;
dt = 0 : Ts : end_t-Ts;
%Generate a lot of sinusoids that will be added to form waveform
for a = 1:length(f)-1
y(a,:) = 0.1 * sin(2*pi .* f(a) .* dt) ;
end
waveform = sum(y); % What we all called Array A
%In Decibels
power_in = [-20 : 1 : 6]';
power_in = [-20 : 0.0001 : 6]'; %interpolated
%In Volts
power_in = 10.^((power_in/20)); %What we all called Array B
%Code advised
[output_array, index_a,index_b] = intersect(abs(waveform),power_in);

댓글 수: 2

I'm 99.99999999...% sure that floating points is one of the issues here when using intersect.
Also did you plot waveform en power_in. waveform contains negative values, whereas power_in does not!
"I am interested in what Jo says, but I don't think that's the issue?"
Actually the floating point error is the exact cause of what you are experiencing. Why do you think it isn't?

댓글을 달려면 로그인하십시오.

Jos (10584)
Jos (10584) 2017년 12월 19일
I think you'll find my function NEARESTPOINT pretty helpful in this respect. You can download it from the File Exchange:
Based on your code above:
IDX = nearestpoint(waveform, power_in)
will return an index into B for each value of A, so that the difference between A(k) and B(IDX(k)) is minimal. Nearestpoint is quite fast :)

댓글 수: 3

This work thanks, just before I accept as answer. Is there another way around this without using nearest point? Thanks
"Is there another way around this without using nearest point?"
Of course! Did you read Jan Simon's answer? You could also use bsxfun and abs, then compare against a tolerance. You are not limited using nearestpoint, although it does provide a very simple calling syntax.
Indeed, of course you can! There are many ways to Rome ...
However, nearestpoint is quite optimised in both speed and memory efficiency. Note that bsxfun creates an intermediate matrix of M-by-N for two vectors with M and N elements.

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Matrix Indexing에 대해 자세히 알아보기

질문:

2017년 12월 19일

댓글:

2017년 12월 20일

Community Treasure Hunt

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

Start Hunting!

Translated by