1
votes

I have two arrays A and B and I would like to find the values in the first column in A that are closest to the values in the first column in B and sort them by difference/closeness.

Example: A is 29x2 and B is 14x2

A=[0, 2;
408, 642;
492, 66;
1527, 108;
1560, 16;
1755, 182;
1809, 10;
2133, 42;
2235, 444;
2289, 4191;
2334, 86;
2661, 22;
2709, 2;
2787, 2652;
3072, 200;
3081, 110;
3147, 638;
3963, 10;
4080, 2;
4332, 1674;
4462, 14;
5148, 1042;
5649, 8;
5895, 44;
6078, 284;
6315, 2;
6989, 4;
7485, 46;
7623, 3458;
];


B= [0, 2;
165, 2114;
572, 122;
576, 5416;
581, 176;
583, 278;
653, 28;
655, 4;
656, 154;
657, 16;
658, 4188;
665, 3475;
903, 20;
1145, 8;
]

The final arrays needs to be sorted by the closest/nearest x values (1st column) in it. so when the C array is generated it would have [0,0;492,572] etc...

I included two plots to give a graphic example. The first plot shows all the data points of A and B represented as stars and circles and the second plot is zoomed in to show the nearest points between the arrays the final array would have the items that are circled in orange. (Please ignore the y axis in the plot I'm just interested in how close the values are on the x axis)

How can I create the C array using matlab/octave?

Figure 1 full plot

Figure 2 zoomed in plot

2

2 Answers

2
votes

bsxfun approach -

%// Find the minimum absolute diferences and corresponding indices for each
%// element in the first column of B against all other elements in the 
%// first column of A.
[min_val,min_ind] = min(abs(bsxfun(@minus,A(:,1),B(:,1)'))) %//'

%// Find the sorted indices for the minimum absolute diferences
[~,sorted_ind] = sort(min_val)

%// Index into A using min_ind to assciate each element in the first
%// column of B against the corresponding closest element in the first
%// column of A.
C = [A(min_ind,1) B(:,1)]

%// Sort rows of C acoording to sorted_indices to have the desired output
C = C(sorted_ind,:)

Alternative approach using pdist2 [Pairwise distance between two sets of observations], would require just one change in the above code -

[min_val,min_ind] = min(pdist2(A(:,1),B(:,1)))
1
votes

To find the nearest point in A corresponding to each value in B, use interp1 with the nearest mode.

AnearB = interp1(A(:,1), A(:,1), B(:,1), 'nearest');
C = [AnearB B(:,1)];

Then sort the results by closeness.

dist = abs(diff(C'));
[~, order] = sort(dist);
C = C(order,:);

Results for your sample data

C =

           0           0
         492         572
         492         576
         492         581
         492         583
         492         653
         492         655
         492         656
           0         165
         492         657
         492         658
         492         665
        1527        1145
         492         903