Find the minimum difference between any pair of elements between two vectors - matlab

Which of the following statements will find the minimum difference between any pair of elements (a,b) where a is from the vector A and b is from the vector B.
A. [X,Y] = meshgrid(A,B);
min(abs(X-Y))
B. [X,Y] = meshgrid(A,B);
min(abs(min(Y-X)))
C. min(abs(A-B))
D. [X,Y] = meshgrid(A,B);
min(min(abs(X-Y)))
Can someone please explain to me?

By saying "minimum difference between any pair of elements(a,b)", I presume you mean that you are treating A and B as sets and you intend to find the absolute difference in any possible pair of elements from these two sets. So in this case you should use your option D
[X,Y] = meshgrid(A,B);
min(min(abs(X-Y)))
Explanation: Meshgrid turns a pair of 1-D vectors into 2-D grids. This link can explain what I mean to say:
http://www.mathworks.com/help/matlab/ref/meshgrid.html?s_tid=gn_loc_drop
Hence (X-Y) will give the difference in all possible pairs (a,b) such that a belongs to A and b belongs to B. Note that this will be a 2-D matrix.
abs(X-Y) would return the absolute values of all elements in this matrix (the absolute difference in each pair).
To find the smallest element in this matrix you will have to use min(min(abs(X-Y))). This is because if Z is a matrix, min(Z) treats the columns of Z as vectors, returning a row vector containing the minimum element from each column. So a single min command will give a row vector with each element being the min of the elements of that column. Using min for a second time returns the min of this row vector. This would be the smallest element in the entire matrix.
This can help:
http://www.mathworks.com/help/matlab/ref/min.html?searchHighlight=min
Options C is correct if you treat A and B as vectors and not sets. In this case you won't be considering all possible pairs. You'll end up finding the minimum of (a-b) where a,b are both in the same position in their corresponding vectors (pair-wise difference).

D. [X,Y] = meshgrid(A,B);
min(min(abs(X-Y)))
meshgrid will generate two grids - X and Y - from the vectors, which are arranged so that X-Y will generate all combinations of ax-bx where ax is in a and bx is in b.
The rest of the expression just gets the minimum absolute value from the array resulting from the subtraction, which is the value you want.

CORRECT ANSWER IS D
Let m = size(A) and n = size(B)
You want to subtract each pair of (a,b) such that a is from vector A and b is from vector B.
meshgrid(A,B) creates two matrices X Y both of size nxm where X have rows sames have vector A while Yhas columns same as vector B .
Hence , Z = X-Y will give you a matrix with n*m values corresponding to the difference between each pair of values taken from A and B . Now all you have to do is to find the absolute minimum among all values of Z.
You can do that by
req_min = min(min(abs(z)))
The whole code is
[X Y ] = meshgrid(A,B);
Z= X-Y;
Z = abs(Z);
req_min = min(min(Z));

You could also use bsxfun instead of meshgrid:
min(min(abs(bsxfun(#minus, A(:), B(:).'))))
Or use pdist2:
min(min(pdist2(A(:),B(:))))

Related

Calculate distance matrix for 3D points

I have the lists xA, yA, zA and the lists xB, yB, zB in Matlab. The contain the the x,y and z coordinates of points of type A and type B. There may be different numbers of type A and type B points.
I would like to calculate a matrix containing the Euclidean distances between points of type A and type B. Of course, I only need to calculate one half of the matrix, since the other half contains duplicate data.
What is the most efficient way to do that?
When I'm done with that, I want to find the points of type B that are closest to one point of type A. How do I then find the coordinates the closest, second closest, third closest and so on points of type B?
Given a matrix A of size [N,3] and a matrix B of size [M,3], you can use the pdist2 function to get a matrix of size [M,N] containing all the pairwise distances.
If you want to order the points from B by their distance to the rth point in A then you can sort the rth row of the pairwise distance matrix.
% generate some example data
N = 4
M = 7
A = randn(N,3)
B = randn(M,3)
% compute N x M matrix containing pairwise distances
D = pdist2(A, B, 'euclidean')
% sort points in B by their distance to the rth point in A
r = 3
[~, b_idx] = sort(D(r,:))
Then b_idx will contain the indices of the points in B sorted by their distance to the rth point in A. So the actual points in B ordered by b_idx can be obtained with B(b_idx,:), which has the same size as B.
If you want to do this for all r you could use
[~, B_idx] = sort(D, 1)
to sort all the rows of D at the same time. Then the rth row of B_idx will contain b_idx.
If your only objective is to find the closest k points in B for each point in A (for some positive integer k which is less than M), then we would not generally want to compute all the pairwise distances. This is because space-partitioning data structures like K-D-trees can be used to improve the efficiency of searching without explicitly computing all the pairwise distances.
Matlab provides a knnsearch function that uses K-D-trees for this exact purpose. For example, if we do
k = 2
B_kidx = knnsearch(B, A, 'K', k)
then B_kidx will be the first two columns of B_idx, i.e. for each point in A the indices of the nearest two points in B. Also, note that this is only going to be more efficient than the pdist2 method when k is relatively small. If k is too large then knnsearch will automatically use the explicit method from before instead of the K-D-tree approach.

matlab - ith element of vector is the sum of the first i elements of a different vector

I'm trying to compute a vector A for which the ith element is the sum of the first i elements of a different vector B (this vector is given).
I couldn't work out how to do this and the internet wasn't much help either.
I am very new to matlab so an easy solution would be preferred :)
Use MATLAB's cumsum function.
code example:
%generates random vector b
b = rand(5,1);
%calculates accomulative sum
a = cumsum(b);
Result:
b = [0.4319 0.9616 0.5671 0.8731 0.5730]
a = [0.4319 1.3935 1.9606 2.8338 3.4068]

How can I generalize this function to `n` terms?

I'd like to create a function that adds several gaussian terms of various width over some specified region:
G(a,b,x) = a_1 exp(- b_1 x^2) + a_2 exp(- b_2 x^2) + ... a_N exp(-b_N x^2)
I'd like this function to output an array of length x, summing over the terms of parameters a,b provided, something like:
x = linspace(-2,2,1000);
N_gauss = #(a,b) a(:).*exp(-b(:)*x.^2);
This example actually works if a,b have only a single value, but when they become vectors it no longer works (I suppose Matlab doesn't know what should be added, multiplied or remain a vector). Is this even possible?
You can do this purely by matrix multiplication. Let's tackle the problem slowly and work our way up. You first need to form products of the elements of the vector b and scalar values stored in x. First create a 2D matrix of values where each row corresponds to the product-wise values between an element in b and an element in x. The element (i,j) in this matrix corresponds to the product of the ith element in x with the jth element in b.
You can achieve this by using the outer product. Make x a column vector and b a row vector, then perform the multiplication. Also, make sure you square each of the x terms as seen in your equation.
term1 = (x(:).^2)*b(:).';
Now you can apply the exponential operator and ensure you place a negative in the exponent so you can build the right side of each term (i.e. exp(- b_i x^2)):
term2 = exp(-term1);
The last thing you need to do is multiply each of the values in the 2D matrix with the right coefficient from the a vector. You can do this by enforcing that a be a column vector and performing matrix-vector multiplication.
out = term2*a(:);
Matrix-vector multiplication is the dot product between the column vector a with each row in the 2D matrix we created before. This exactly corresponds to the summation of your equation for each value in x. As such, this achieves the Gaussian summation for each value in x and places this into a n x 1 vector where n is the total number of elements in x. Putting this all together gives us:
out = exp(-(x(:).^2)*b(:).')*a(:);
To finally abstract this into an anonymous function, do:
N_gauss = #(a,b,x) exp(-(x(:).^2)*b(:).')*a(:);
This function takes in the vectors a, b and x as per your problem.

Euclidean distance between two columns of two vector Matlab

I have two vectors A & B of size 250x4. The first column in each vector has the X values and the second column has the Y values. I want to calculate the euclidean distance between each the X & Y of each row in the two vectors and save the result in a new vector C of size 250x1 which holds the result of the euclidean distance. For example, if the first row in A is A1x, A1y, A1n, A1m and the first row in B is B1x, B1y, B1n, B1m so I want to get the eucledian distance which will be [(A1x-B1x)^2 + (A1y-B1y)^2]^0.5 and the result will be saved in C1 and same will be done for the rest of the 250 rows. So if anyone could please advise how to do this in Matlab.
Like this:
%// First extract on x-y data from A and B
Axy = A(:,1:2);
Bxy = B(:,1:2);
%// Find all euclidean distances (row-wise)
C1 = sqrt(sum((Axy-Bxy).^2,2));
plus it handles higher dimension too
use pdist2:
C1=diag(pdist2(A(:,1:2),B(:,1:2)));
Actually, pdist2 will give you a 250x250 matrix, because it calculate all the distances. You need only the main diagonal, so calling diag on the result (as in the code above) will produce the wanted result.

Distance matrix calculation

I hope you will have the right answer to this question, which is rather challanging.
I have two uni-dimensional vectors Y and Z, which hold the coordinates of N grid points located on a square grid. So
Ny points along Y
Nz points along Z
N = Ny*Nz
Y = Y[N]; (Y holds N entries)
Z = Z[N]; (Z holds N entries)
Now, the goal would be generating the distance matrix D, which holds N*N entries: so each row of matrix D is defined as the distance between the i-th point on the grid and the remnant (N - i) points.
Generally, to compute the whole matrix I would call
D = squareform(pdist([Y Z]));
or,equivalently,
D = pdist2([Y Z],[Y Z]).
But, since D is a symmetric matrix, I'd like to generate only the N(N + 1)/2 independent entries and store them into a row-ordered vector Dd.
So the question is: how to generate a row-ordered array Dd whose entries are defined by the lower triangular terms of matrix D? I'd, furthermore, like storing the entries in a column-major order.
I hope the explanation is clear enough.
As woodchips commented, it is simpler and faster to compute the whole matrix and extract the elements you care about. Here's a way to do it:
ndx = find(tril(true(size(D))));
Dd = D(ndx);
If you absolutely must compute elements of Dd without computing matrix D first, you probably need a double for loop.