在多维矩阵

时间:2015-11-06 10:08:34

标签: matlab matrix multidimensional-array indexing equality

我正在生成一个有两行的三维矩阵(例如一个2x1000x10矩阵)。这些包含点运动路径的x和y坐标,其中第一行包含x坐标,第二行包含y坐标。列数(此处:1000)取决于运动路径的长度。第三维中的级别数取决于点数(此处:10)。

我想知道一些点是否会重叠,即如果在同一时间点t的第三维上的任何x和y坐标,即(:, t, :)的任何组合是相同的。所以比较将在矩阵内。

i = [1:size(matrix, 3)];
j = [1:size(matrix, 3)];
t = [1:size(matrix, 2)];

crash = any(coordinates(:, t, i)==coordinates(:, t, j))

是微不足道的,因为ij可以是相同的,因此说该点等于它自己。

您知道我如何在矩阵维度上检测到等值组合吗?如果它们存在,我该如何编制索引?

2 个答案:

答案 0 :(得分:1)

我认为这可以满足您的需求。要查明是否发生了崩溃

t = bsxfun(@eq, coordinates, permute(coordinates, [1 2 4 3]));
crash = any(sum(any(all(t,1),2),4)>1,3);

我们首先使用bsxfun来计算一个4D数组(t),它测试相同坐标(第一个昏暗)和路径上相同位置(第二个暗淡)的相等性,其中第3个和第四个dims在所有点对上运行。如果两个坐标(all(,...,1))对于任何“参考”点({{1}的多个“其他”点(any(...,2))中的任何列(sum(...,4)>1)相等,则会发生崩溃}})。我们需要指定“多个”,因为任何点至少等于它自己(对于给定的位置和坐标)。

示例:

any(...,3)

找到崩溃的坐标

>> coordinates = randi(9,2,5,4)
coordinates(:,:,1) =
     7     4     3     3     8
     7     1     4     2     4
coordinates(:,:,2) =
     8     7     8     4     8
     4     4     7     2     9
coordinates(:,:,3) =
     3     4     7     8     5
     7     8     2     9     8
coordinates(:,:,4) =
     6     2     7     8     5
     2     4     8     3     1

>> t = bsxfun(@eq, coordinates, permute(coordinates, [1 2 4 3]));
>> crash = any(sum(any(all(t,1),2),4)>1,3)
crash =
     0

>> coordinates(:,2,4) = coordinates(:,2,1) %// 4th dot equal to 1st dot in column 2
coordinates(:,:,1) =
     7     4     3     3     8
     7     1     4     2     4
coordinates(:,:,2) =
     8     7     8     4     8
     4     4     7     2     9
coordinates(:,:,3) =
     3     4     7     8     5
     7     8     2     9     8
coordinates(:,:,4) =
     6     4     7     8     5
     2     1     8     3     1

>> t = bsxfun(@eq, coordinates, permute(coordinates, [1 2 4 3]));
>> crash = any(sum(any(all(t,1),2),4)>1,3)
crash =
     1

在后一个例子中,这给出了

t = bsxfun(@eq, coordinates, permute(coordinates, [1 2 4 3]));
[m,n,p] = size(coordinates);
ii = find(squeeze(all(bsxfun(@times, t, ...
    bsxfun(@ne, reshape(1:p, 1,1,[]), reshape(1:p, 1,1,1,[]) )),1)));
[col, dot_ref, dot_oth] = ind2sub([n p p], ii);

告诉你点4等于第2列中的点1;然后当然点1等于第2列中的第4点。

这计算与上面相同的col = 2 2 dot_ref = 4 1 dot_oth = 1 4 。然后沿第三维和第四维(t)乘以逻辑掩码,以避免检测到每个点与其自身相似。最后,它要求所有坐标(bsxfun(@ne, reshape(1:p, 1,1,[]), reshape(1:p, 1,1,1,[]) ))都相同,以便将两个点声明为崩溃,并应用find来定位这些点。结果(all(...,1))是维度路径长度×点数×点数的3D数组的线性索引,其由ind2sub沿路径和崩溃点的身份转换为位置。 / p>

答案 1 :(得分:0)

A=[1 2 ;3 4];B=[5 6;3 9];
A==B
ans =
     0     0
     1     0

这适用于2D,但也适用于3D。您可以使用find

找到相同数字的位置
C=permute(A,[3 2 1]);
D=permute(B,[3 2 1]);
find(C==D)
ans =
     3

其中3是相等数字位置的线性索引。

for ii = 1:size(A,3)-1
    for jj = ii+1:size(A,3)
        [r{ii,jj},c{ii,jj},v{ii,jj}] = find(squeeze(A(:,:,ii))==squeeze(A(:,:,jj)));
    end
end

这将在第三维中循环遍历矩阵,即物理点。它将挤出每个点的2D矩阵并检查每个其他点的2D矩阵。如果找到任何内容,它会将行,列和值存储在单元格rcv的交集处,其中索引对应于点数,即{{ 1}}将给出第2点和第4点之间交叉点的行号。