N 维中的 MATLAB 成对差异

MATLAB pairwise differences in Nth dimension

假设我有一个 N 维矩阵 A,它可以是任意大小。例如:

A = rand([2,5,3]);

我想沿着给定维度计算矩阵元素之间所有可能的成对差异。例如,如果我想计算维度 3 的差异,一个快捷方式是创建一个矩阵,如下所示:

B = cat(3, A(:,:,2) - A(:,:,1), A(:,:,3) - A(:,:,1), A(:,:,3) - A(:,:,2));

但是,我希望它能够沿着任何维度、任何大小的矩阵运行。因此,理想情况下,我想创建一个接受矩阵 A 并计算沿维度 DIM 的所有成对差异的函数,或者找到一个执行相同操作的内置 MATLAB 函数。

diff函数看起来很有用,但它只计算相邻元素之间的差异,而不是所有可能的差异。

在研究这个问题时,我发现了一个 couple of posts 关于获取所有可能差异的方法,但其中大部分是针对向量中的项目(忽略维数问题)。有人知道快速修复吗?

具体维度案例

如果您不关心通用解决方案,对于 dim=3 案例,它会像几行代码一样简单 -

dim = 3
idx = fliplr(nchoosek(1:size(A,dim),2))
B = A(:,:,idx(:,1)) - A(:,:,idx(:,2))

如果您碰巧事先知道维度,则可以将这些 idx(..) 移动到特定的维度位置。所以,假设 dim = 4,然后只做 -

B = A(:,:,:,idx(:,1)) - A(:,:,:,idx(:,2))

或者假设 dim = 3,但是 A 是一个 4D 数组,然后执行 -

B = A(:,:,idx(:,1),:) - A(:,:,idx(:,2),:)

一般案例

对于 Nth dim 个案例,您似乎需要欢迎 reshapespermutes -

的聚会
function out = pairwise_diff(A,dim)

%// New permuting dimensions
new_permute = [dim setdiff(1:ndims(A),dim)];

%// Permuted A and its 2D reshaped version
A_perm = permute(A,new_permute);
A_perm_2d = reshape(A_perm,size(A,dim),[]);

%// Get pairiwse indices for that dimension
N = size(A,dim);
[Y,X] = find(bsxfun(@gt,[1:N]',[1:N])); %//' OR fliplr(nchoosek(1:size(A,dim),2))

%// Get size of new permuted array that would have the length of 
%// first dimension equal to number of such pairwise combinations 
sz_A_perm = size(A_perm);
sz_A_perm(1) = numel(Y);

%// Get the paiwise differences; reshape to a multidimensiona array of same
%// number of dimensions as the input array
diff_mat = reshape(A_perm_2d(Y,:) - A_perm_2d(X,:),sz_A_perm);

%// Permute back to original dimension sequence as the final output
[~,return_permute] = sort(new_permute);
out = permute(diff_mat,return_permute);

return

概括到此为止,呵呵!