The most efficient pairwise distance computation
Version 1.2.1 (4,67 ko) par
wfH
Enhannced `pdist2`! Vectorized code that achieve 10x~100x efficienficy for nD-array (i.g., i-by-j-by-k). Support many distance metrics.
In human motion analysis, a commond need is the computation of the distance between defferent point sets.
The builtin function `pdist2` could be helpful, but it is inefficient for multiple timeframes data.
Currently avaliable codes in FEX are also insufficient as they can only compute (squared) Euclidean distance and they still cannot handle nD-array.
Therefore, I created this handy function `markerdistance` to enhance `pdist2`.
My code is vectorized to achieve 10x~100x efficienficy for nD-array (i.g., i-by-j-by-k).
Additionally, `markerdistance` supports many different distance metrics, including 'euclidean', 'cityblock', 'chebychev', 'minkowski', 'cosine', 'correlation', 'mahalanobis', 'chisquare', and 'Earth's mover' distance.
Note1.
This function heavly depends on the calculation of vector-wise norm.
If you don't have the builtin `vecnorm` that was introduced in R2017b, use local subfunction `ndnorm` as an alternative (all you need to do is simply replace `vecnorm` with `ndnorm`).
Note2.
Computation of Mahalanobis distance requires `pagetranspose`, `pagemtimes`, and 'pageinv'.
Note3.
I don't really know much about the measurements above as I am not working at these research fields.
All I did is vectorize the codes for nD-array. Don't blame on me if the results are not what you expected.
The following code is for demo.
metric = 'euclidean'; % euclidean, cityblock, chebychev, cosine, correlation, mahalanobis
Xn = randi([1, 10], 1);
Yn = randi([1, 10], 1);
d = 3;
slice = 123456;
X = rand(Xn, d, slice);
Y = rand(Yn, d, slice);
tic;
D1 = markerdistance(X, Y, metric);
t1 = toc
tic;
D2 = zeros(Xn, Yn, slice);
for pp2 = 1:slice
D2(:, :, pp2) = pdist2(X(:, :, pp2), Y(:, :, pp2), metric);
end
t2 = toc
efficiency = t2/t1
reserr = max(abs(D1(:)-D2(:)), [], 1)
if strncmpi(metric, 'e', 1)
% `sqdist` could be found in FEX
tic;
D3 = zeros(Xn, Yn, slice);
for pp3 = 1:slice
D3(:, :, pp3) = sqdist(X(:, :, pp3).', Y(:, :, pp3).');
end
D3 = sqrt(D3);
t3 = toc
efficiency2 = t3/t1
reserr2 = max(abs(D1(:)-D3(:)), [], 1)
% Note. For large-scale data (e.g., Xn or Yn is large), `sqdist` might be better.
end
No more for-loop!
Enjoy!
Citation pour cette source
wfH (2024). The most efficient pairwise distance computation (https://www.mathworks.com/matlabcentral/fileexchange/121962-the-most-efficient-pairwise-distance-computation), MATLAB Central File Exchange. Récupéré le .
Compatibilité avec les versions de MATLAB
Créé avec
R2022b
Compatible avec toutes les versions
Plateformes compatibles
Windows macOS LinuxTags
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Découvrir Live Editor
Créez des scripts avec du code, des résultats et du texte formaté dans un même document exécutable.
Version | Publié le | Notes de version | |
---|---|---|---|
1.2.1 | feat(measure): support Mahalanobis distance, Chi-squared distance, and Earth Mover's distance.
|
||
1.0.1 | fix `ndnorm` |
||
1.0.0 |