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
个案例,您似乎需要欢迎 reshapes
和 permutes
-
的聚会
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
概括到此为止,呵呵!
假设我有一个 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
个案例,您似乎需要欢迎 reshapes
和 permutes
-
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
概括到此为止,呵呵!