how to find distance between consecutive points - matlab

I have a matrix
A=[51.7365160000000 10.7978860000000;
51.7366230000000 10.8319610000000;
51.7389880000000 10.7849260000000;
51.7424430000000 10.9195510000000;
51.7443820000000 10.9157750000000;
51.7448080000000 10.9160750000000;
51.7523270000000 10.8756060000000;
51.7525920000000 10.8758210000000;
51.7526190000000 10.8738470000000;
51.7526460000000 10.8763360000000;
51.7528580000000 10.8477970000000;
51.7530180000000 10.8776230000000];
The first column of A indicates latitude, the second column indicates longitude, with each row being a different point. I want to find the distance between consecutive points. I have used the function pdist in this way
a = pdist(A,'euclidean')';
but it gives the distance between all points and not only between consecutive points.
Can you help me to solve the problem?
Thanks

As pointed out in the help of pdist you can use squareform to organize the data.
b = squareform(a);
The distances between neighbouring points are then the subdiagonals of this matrix.
dist = diag(b,1)
You can also easily calculate the distances manually
dist = sqrt(diff(A(:,1)).^2+diff(A(:,2)).^2)

Related

MATLAB: pdist, finding pixel locations of minimum pairwise distance in binary image

I have a binary image and have found the minimum distance connecting two nearby regions of interest/connected components using
min(min(pdist2(CCstats(1).PixelList,CCstats(2).PixelList)))
I also need to get the coordinates of these ends of this distance/the most adjacent pixels between these 2 regions of interest
I plan on drawing a line along this distance. I was going to use something like:
x=linspace(coord1(1), coord2(1),1000);
y=linspace(coord1(2), coord2(2),1000);
index=sub2ind(size(image),round(y),round(x));
image(index)=1;
Any suggestions for how to find these coordinates?
You will want the second output of min (combined with ind2sub) to determine the row/column of the pdist2 matrix that corresponds to the minimum distance.
distances = pdist2(CCstats(1).PixelList, CCstats(2).PixelList);
[mindist, minind] = min(distances(:));
%// Now convert this linear index into index1/index2 into your pixel lists
[index1, index2] = ind2sub(size(distances), minind);
%// Now grab the coordinates using these index values
coord1 = CCstats(1).PixelList(index1,:);
coord2 = CCstats(2).PixelList(index2,:);

Matlab calculating nearest neighbour distance for all (u, v) vectors in an array

I am trying to calculate the distance between nearest neighbours within a nx2 matrix like the one shown below
point_coordinates =
11.4179 103.1400
16.7710 10.6691
16.6068 119.7024
25.1379 74.3382
30.3651 23.2635
31.7231 105.9109
31.8653 36.9388
%for loop going from the top of the vector column to the bottom
for counter = 1:size(point_coordinates,1)
%current point defined selected
current_point = point_coordinates(counter,:);
%math to calculate distance between the current point and all the points
distance_search= point_coordinates-repmat(current_point,[size(point_coordinates,1) 1]);
dist_from_current_point = sqrt(distance_search(:,1).^2+distance_search(:,2).^2);
%line to omit self subtraction that gives zero
dist_from_current_point (dist_from_current_point <= 0)=[];
%gives the shortest distance calculated for a certain vector and current_point
nearest_dist=min(dist_from_current_point);
end
%final line to plot the u,v vectors and the corresponding nearest neighbour
%distances
matnndist = [point_coordinates nearest_dist]
I am not sure how to structure the 'for' loop/nearest_neighbour line to be able to get the nearest neighbour distance for each u,v vector.
I would like to have, for example ;
for the first vector you could have the coordinates and the corresponding shortest distance, for the second vector another its shortest distance, and this goes on till n
Hope someone can help.
Thanks
I understand you want to obtain the minimum distance between different points.
You can compute the distance for each pair of points with bsxfun; remove self-distances; minimize. It's more computationally efficient to work with squared distances, and take the square root only at the end.
n = size(point_coordinates,1);
dist = bsxfun(#minus, point_coordinates(:,1), point_coordinates(:,1).').^2 + ...
bsxfun(#minus, point_coordinates(:,2), point_coordinates(:,2).').^2;
dist(1:n+1:end) = inf; %// remove self-distances
min_dist = sqrt(min(dist(:)));
Alternatively, you could use pdist. This avoids computing each distance twice, and also avoids self-distances:
dist = pdist(point_coordinates);
min_dist = min(dist(:));
If I can suggest a built-in function, use knnsearch from the statistics toolbox. What you are essentially doing is a K-Nearest Neighbour (KNN) algorithm, but you are ignoring self-distances. The way you would call knnsearch is in the following way:
[idx,d] = knnsearch(X, Y, 'k', k);
In simple terms, the KNN algorithm returns the k closest points to your data set given a query point. Usually, the Euclidean distance is the distance metric that is used. For MATLAB's knnsearch, X is a 2D array that consists of your dataset where each row is an observation and each column is a variable. Y would be the query points. Y is also a 2D array where each row is a query point and you need to have the same number of columns as X. We would also specify the flag 'k' to denote how many closest points you want returned. By default, k = 1.
As such, idx would be a N x K matrix, where N is the total number of query points (number of rows of Y) and K would be those k closest points to the dataset for each query point we have. idx indicates the particular points in your dataset that were closest to each query. d is also a N x K matrix that returns the smallest distances for these corresponding closest points.
As such, what you want to do is find the closest point for your dataset to each of the other points, ignoring self-distances. Therefore, you would set both X and Y to be the same, and set k = 2, discarding the first column of both outputs to get the result you're looking for.
Therefore:
[idx,d] = knnsearch(point_coordinates, point_coordinates, 'k', 2)
idx = idx(:,2);
d = d(:,2);
We thus get for idx and d:
>> idx
idx =
3
5
1
1
7
3
5
>> d
d =
17.3562
18.5316
17.3562
31.9027
13.7573
20.4624
13.7573
As such, this tells us that for the first point in your data set, it matched with point #3 the best. This matched with the closest distance of 17.3562. For the second point in your data set, it matched with point #5 the best with the closest distance being 18.5316. You can continue on with the rest of the results in a similar pattern.
If you don't have access to the statistics toolbox, consider reading my StackOverflow post on how I compute KNN from first principles.
Finding K-nearest neighbors and its implementation
In fact, it is very similar to Luis Mendo's post to you earlier.
Good luck!

Finding the diameter of a graph

In MATLAB I'm dropping points into the square [0,1]X[0,1] uniformly at random. I'm then placing an edge between two points if the distance between the two points is less than 0.25. The code to do this (and plot the resulting graph is below).
num_Rx = 50
Rx_positions = rand(num_Rx,2);
%Generate edges between pairs of within norm of 0.25.
adj_matrix = zeros(num_Rx, num_Rx);
for i=1:num_Rx
for j=i+1:num_Rx
dist = norm(Rx_positions(i,:) - Rx_positions(j,:));
if dist < 0.25;
adj_matrix(i,j) = 1;
end
end
end
figure
gplot(adj_matrix, Rx_positions)
i.e. this is an undirected graph, with all edge weights equal to 1.
To find the diameter I want to call graphallshortestpaths() (http://www.mathworks.co.uk/help/bioinfo/ref/graphallshortestpaths.html), and take the maximum value returned (the diameter is the longest shortest path).
However, I'm having difficulty calling this function - I can't figure out how to make a call like the examples, from my adjacency matrix and/or my list of node positions. Specifically I don't understand any of the examples, how the matlab code given corresponds to the data presented.
How would I go about doing this.
It appears that all you're missing is converting your adjacency matrix to a sparse matrix. This should give you what you're looking for:
adj_sparse = sparse(adj_matrix);
distances = graphallshortestpaths(adj_sparse);
% if you don't care which nodes produce the
% longest shortest path, omit long_ind & long_sub
[diameter, long_ind] = max(distances(:));
long_sub = ind2sub(size(distances), long_ind);

mean squared displacement from multiple trajectories

I have a matrix of multiple particle trajectories that I would like to analyze separately The trajectory number is one of the columns of the matrix, so I am trying to sort based on that number. I am using some of the code from this answer: MSD with matlab (which was very helpful, thank you!) to calculate MSD, but I am having difficulty parsing out the individual trajectories. To explain in more detail what I am trying to do: I have trajectory outputs that are in matrix format, with one column for trajectory number, one column for x-position, one column for y-position, etc. I want to be able to take this information and calculate the mean-squared displacement for each trajectory. In order to do this, I have to create a way to distinguish data points based on trajectory number (which is listed in row 7 of mymatrix). This seems to be where I am having trouble. The important columns in this matrix are 1: x-position, 2: y-position and 7: trajectory number. So far I have
total_rows=size(mymatrix,1);
max_trajectory_number=mymatrix(total_rows,7);
nData=0;
msd=zeros(total_rows, 4)
for i=0:max_trajectory_number
trajectornumber= mymatrix(i,7);
if trajectorynumber.equals(i)
nData=nData+1; %counts the number of instances of this trajectory number, which is the number of data points in the trajectory
for dt = 1:nData
deltaCoords = mymatrix(1+dt:end,1:2) - traj0mat(1:end-dt,1:2); %calculates time-averaged MSD based on y and y positions in colums 1 and 2 respectively
squaredDisplacement = sum(deltaCoords.^2,2); %# dx^2+dy^2+dz^2
msd(dt,1) = trajectorynumber; %trajectory number
msd(dt,2) = mean(squaredDisplacement); %# average
msd(dt,3) = std(squaredDisplacement); %# std
msd(dt,4) = length(squaredDisplacement); %# n
end
end
Unfortunately when I run this on mymatrix, the resulting msd matrix remains all zeros. I think this is likely due to an error in sorting based on the trajectory number. I do not get an error just not the results I was looking for
If anyone has any suggestions on how to fix this, it would be greatly appreciated.
It looks like you want to bundle all rows identified by the same trajectory number. I assume that they show up in chronological order as you continue down a column. Then try something like
tnumbs = unique(mymatrix(:,7)); % identify unique trajectory numbers
for i=1:length(tnumbs) % loop through trajectories
icurr = find(mymatrix(:,7)==tnumbs(i)); % find indices to entries for current trajectory
% perform your averaging
deltaCoords = mymatrix(icurr(1+dt:end),1:2) - traj0mat(icurr(1:end-dt),1:2); %calculates time-averaged MSD based on y and y positions in colums 1 and 2 respectively
squaredDisplacement = sum(deltaCoords.^2,2); %# dx^2+dy^2+dz^2
msd(i,1) = tnumbs(i); %trajectory number
msd(i,2) = mean(squaredDisplacement); %# average
msd(i,3) = std(squaredDisplacement); %# std
msd(i,4) = length(squaredDisplacement); %# n
end

Calculating distance of all the points in a region with each other

I have a region with about 144 points. What i want to achieve is to measure the distance of a point with all others and store it in an array. I want to do this for all the points. If possible i would like to store this data in such a manner that there in no repetition. And i should be able to make queries like- All the distances between all the points without repetition, sum of all the distances for point no56 etc.
I have a 3*144 array with two columns storing the coordinates of the points.
A possible solution (I am not really clear with what you mean by no repetition, though):
X are your points with coordinates x = X(:,1), y = X(:,2)
dist = sqrt(bsxfun(#minus,X(:,1),X(:,1)').^2 + bsxfun(#minus,X(:,2),X(:,2)').^2)
so
dist(i,j) is the euclidean distance between i and j
of course the matrix is symmetric. You can easily reduce the complexity involved.
Let's say your array is A, where each column stores the coordinates of a single point. To obtain the combinations of all point pairs (without repetitions), use nchoosek:
pairs = nchoosek(1:size(A, 2), 2)
Then calculate the Euclidean distance like so:
dist = sqrt(sum((A(:, pairs(:, 1)) - A(:, pairs(:, 2))) .^ 2, 1))
If you have the Statistics Toolbox installed, you can use pdist(A) instead for the same effect.
If you have the statistics toolbox, and if you have all your data in the array X, then
D = pdist(X)
gives all the pairwise distances between all points in X.