How to match points in two unequal list?
5 views (last 30 days)
Show older comments
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
Adam Danz
on 15 Aug 2019
I didn't understand this part "Finally I need the omitted elements in the list. " but my answer addresses the rest.
Accepted Answer
Adam Danz
on 15 Aug 2019
Edited: Adam Danz
on 15 Aug 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 Comments
Bruno Luong
on 19 Aug 2019
Edited: Bruno Luong
on 19 Aug 2019
Sorry, but you stuck with a flawed algorithm.
I show one more time that my code below actually works.
Adam Danz
on 19 Aug 2019
Edited: Adam Danz
on 19 Aug 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.
More Answers (0)
See Also
Categories
Find more on Creating and Concatenating Matrices in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!