假设我有一个可以是任意大小的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 posts this关于获取所有可能的差异,但其中大多数是针对向量中的项目(并忽略维度问题)。有谁知道快速修复?
答案 0 :(得分:1)
具体维度案例
如果您不关心一般解决方案,对于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
如此概括,呵呵!