MATLAB Answers

0

How to match points in two unequal list?

Asked by Rishi Kiran Shankar on 15 Aug 2019
Latest activity Edited by Adam Danz
on 19 Aug 2019
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 Comments

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

Sign in to comment.

1 Answer

Answer by Adam Danz
on 15 Aug 2019
Edited by Adam Danz
on 15 Aug 2019
 Accepted Answer

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 Comments

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?
Sorry, but you stuck with a flawed algorithm.
I show one more time that my code below actually works.
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.

Sign in to comment.