How to match points in two unequal list?

Hi I have two lists. For example, A(1.1 2.2 3.1515 4.92121 1.1) and B = (1.25 6.754 2.332 3.15454 5.01214 1.25).
In above you can see that A has 5 elements and B has 6 elements and I have to match an element from both the list which are of closest value.
I have to match each elements from both the list from starting but B(2) is a new unrelated value and must be omitted and the matching should continue with next elements.
A(1) = B(1), A(2) = B(3), A(3) = B(4), A(4) = B(5), A(5) = B(6)
Each elements should be matched with only one elemnents of other list.
Finally I need the elements which didn't match with any other element.
Can anyone help me please?
I am a beginner and finding it difficult to find a logic.
Thanks in advance

2 comentarios

Adam Danz
Adam Danz el 15 de Ag. de 2019
I didn't understand this part "Finally I need the omitted elements in the list. " but my answer addresses the rest.
Rishi Kiran Shankar
Rishi Kiran Shankar el 15 de Ag. de 2019
Hi,
I want the element which is not matched with any other element.
For above example the answer should be B(2) = 6.754.

Iniciar sesión para comentar.

 Respuesta aceptada

Adam Danz
Adam Danz el 15 de Ag. de 2019
Editada: Adam Danz el 15 de Ag. de 2019
Here's how to find the closest value in B for each value in A.
A = [1.1 2.2 3.1515 4.92121 1.1]; % Row vector!
B = [1.25 6.754 2.332 3.15454 5.01214 1.25]; % Row vector!
[~, minIdx] = min(abs(A - B'),[],1);
% Summary Table
T = table(A', B(minIdx)', (1:numel(A))', minIdx', 'VariableNames', {'A', 'B_pair', 'A_index','B_index'});
Result
T =
5×4 table
A B_pair A_index B_index
______ ______ _______ _______
1.1 1.25 1 1
2.2 2.332 2 3
3.1515 3.1545 3 4
4.9212 5.0121 4 5
1.1 1.25 5 1
[addendum]
For each value of A, here's how to find the closest value in B that hasn't already been chosen.
A = [1.1 2.2 3.1515 4.92121 1.1]; % Row vector!
B = [1.25 6.754 2.332 3.15454 5.01214 1.25]; % Row vector!
B2 = B;
minIdx = zeros(size(A));
for i = 1:numel(A)
[~, minIdx(i)] = min(abs(A(i)-B2));
B2(minIdx(i)) = NaN;
end
% Summary Table
T = table(A', B(minIdx)', (1:numel(A))', minIdx', 'VariableNames', {'A', 'B_pair', 'A_index','B_index'});
Result
T =
5×4 table
A B_pair A_index B_index
______ ______ _______ _______
1.1 1.25 1 1
2.2 2.332 2 3
3.1515 3.1545 3 4
4.9212 5.0121 4 5
1.1 1.25 5 6
And here's how to find which indices of B have not been selected.
Bidx_notChosen = find(~isnan(B2)); %omit find() for logical index (more optimal)

13 comentarios

Rishi Kiran Shankar
Rishi Kiran Shankar el 15 de Ag. de 2019
Hi,
Thanks for your quick response. But the 5th element of list A should match with 6th element of list B.
Thanks.
Adam Danz
Adam Danz el 15 de Ag. de 2019
Editada: Adam Danz el 15 de Ag. de 2019
Why? The 6th and 1st elements of B are identical!
What rule are you following, specifically? I can imagine several rules that would force the choice of index-6 rather than index-1 so please explain the rule as specifically as possible.
Rishi Kiran Shankar
Rishi Kiran Shankar el 15 de Ag. de 2019
Because I have to find the unmatched elements in the list. My lists are of order 1x55 and 1x66, so 11 elements are different and unmatched. I want all those unmatched elements for further analysing my images. Thanks.
Adam Danz
Adam Danz el 15 de Ag. de 2019
Editada: Adam Danz el 15 de Ag. de 2019
Now I'm confused. Your original question was asking how to match A to B knowing that there will be leftover values in B. Now it seems that you're trying to do that matching and then find which elements of B have not been matched. If that's correct, I still need to know the rule you'll use to match A to B.
For example, is this the rule?
Match A to B such that the matched indices of B are monotonically increasing. For example, once B(5) is matched, only consider B(6:end).
Or is this the rule?
Match A to B but once a value in B is already matched, don't use that index again in a future match.
Or is it a different rule?
The problem has to be well defined before a solution is conceived.
Rishi Kiran Shankar
Rishi Kiran Shankar el 15 de Ag. de 2019
The rule is,
Match A to B but once a value in B is already matched, don't use it again in a future match.
I am more concerned about the unmatched elements in list B.
Adam Danz
Adam Danz el 15 de Ag. de 2019
Editada: Adam Danz el 15 de Ag. de 2019
In order to determine what is unmatched, we first have to determine what is matched. I'll update my answer in few minutes.
See updated answer.
Rishi Kiran Shankar
Rishi Kiran Shankar el 15 de Ag. de 2019
Hi Adam Danz,
Thanks for the code and I have used it for analysing objects(which are genes) in my .tiff 3D image.
But I have encountered another problem.
For example say,
A =
1.6800 2.2000 3.1515 4.9212 1.2500
B =
1.2500 6.7540 2.3320 3.1545 5.0121 1.6800
A_index B_index
_______ _______
1 6
2 3
3 4
4 5
5 1
How can I add tolerance of say 5% and match the elements in order?
If you want to ask this question seperately, I can do that?
Thanks for your help so much. So far its very helpful for a beginner like me.
Adam Danz
Adam Danz el 16 de Ag. de 2019
Glad I can help!
I don't mind continuing the conversation here. Could you give an example of what you mean by "add tolerance of 5% and match the elements in order".
  1. 5% of what?
  2. What do you mean "in order"?
  3. How would your example above change under the new tolerance rule?
Rishi Kiran Shankar
Rishi Kiran Shankar el 19 de Ag. de 2019
Hi,
A = [1.6800 2.2000 3.1515 4.9212 1.5960]
B = [1.5960 6.7540 2.3320 3.1545 5.0121 1.6800]
Say that this is my A and B matrix and when try matching the elements,
A_index B_index
_____ _____
1 6
2 3
3 4
4 5
5 1
  1. Each element can have an error of + or - 5% of value. For instance A(1) is 1.68 and if B(1) is between A(1) - 5%(A(1)) to A(1) + 5%(A(1)) then it should be a match. This is what I mean by tolerance error.
  2. The order is same as above in the coding you have given. A list elements should match with elements in B in an order.
A(1) = B(1), A(2) = B(3), A(3) = B(4), A(4) = B(5), A(5) = B(6)
3. The numbers from two list doesn't have to be close or exactly
same when matching, it can also have some percentage of error.
Thanks in advance.
This is how you could add that tolerance requirement.
But there's a warning: with this method, if there are no values within tolerance, the code will break. If you define what shoud occur in that case, I can recommend a solution.
tol = 0.05; % ADD TOLERANCE
minIdx = zeros(size(A));
for i = 1:numel(A)
[~, minIdx(i)] = find(abs(A(i)-B2) < A(i)*2*tol,1,'first'); % REQUIRE MATCH TO BE WITHIN +/-TOL
B2(minIdx(i)) = NaN;
end
Rishi Kiran Shankar
Rishi Kiran Shankar el 19 de Ag. de 2019
Hi,
Yep as you said it's throwing tolerance error.
I have included A and B list(That I am working on) within this text.
In list B, B(5) is 338.3443 which doesn't match with 5th element in A. B(15) doesn't match with corresponding elements in A and so on. I want the unmatched B elements alone. A size is (1*55) and B's is (1*66), so there should be 11 unmatched elements in the B list. Can you help me out please?
Bruno Luong
Bruno Luong el 19 de Ag. de 2019
Editada: Bruno Luong el 19 de Ag. de 2019
Sorry, but you stuck with a flawed algorithm.
I show one more time that my code below actually works.
Adam Danz
Adam Danz el 19 de Ag. de 2019
Editada: Adam Danz el 19 de Ag. de 2019
Please let me know if this goal description is corrected:
For each 'A(i)', match the nearest value in 'B' that is at least within +/-5% of A(i).Each B can only be matched once. Then return any B that is unmatched.
If that's the case, here's an updated version
tol = 0.05; %tolerance (+/- 5% of A)
B2 = B;
minIdx = zeros(size(A));
for i = 1:numel(A)
ABdiff = abs(A(i)-B2);
[~, minIdx(i)] = min(ABdiff);
% If the closest match is within tolerance, eliminate the B value
% from being selected again.
if ABdiff(minIdx(i)) < A(i)*tol*2
B2(minIdx(i)) = NaN;
end
end
% Summary Table
T = table(A', B(minIdx)', (1:numel(A))', minIdx', 'VariableNames', {'A', 'B_pair', 'A_index','B_index'});
To find the indices of B that have not been matched,
Bidx_notMatched = ~ismember(1:numel(B),T.B_index);
B(Bidx_notMatched) %B values that are not matched
sum(Bidx_notMatched) % total amount of unmatched in B (=11)
BTW, one reason there is so much back-and-forth on this is because the goal is not clearly defined. I know it's hard sometimes to communicate the goal but that's the bottleneck here. The good news is that I think we're close and the solution should just involve a few lines of code.

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Operators and Elementary Operations en Centro de ayuda y File Exchange.

Preguntada:

el 15 de Ag. de 2019

Editada:

el 19 de Ag. de 2019

Community Treasure Hunt

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

Start Hunting!

Translated by