The most efficient pairwise distance computation

バージョン 1.2.1 (4.67 KB) 作成者: wfH
Enhannced `pdist2`! Vectorized code that achieve 10x~100x efficienficy for nD-array (i.g., i-by-j-by-k). Support many distance metrics.
ダウンロード: 40
更新 2022/12/14

ライセンスの表示

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!

引用

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. 取得済み .

MATLAB リリースの互換性
作成: R2022b
すべてのリリースと互換性あり
プラットフォームの互換性
Windows macOS Linux

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!
バージョン 公開済み リリース ノート
1.2.1

feat(measure): support Mahalanobis distance, Chi-squared distance, and Earth Mover's distance.
doc(help): typo & table of measures.

1.0.1

fix `ndnorm`

1.0.0