使用线性索引提取3D矩阵切片的相同部分

时间:2015-08-04 03:54:12

标签: matlab matrix indexing

的确,我的问题是我之前问题的继承问题:

1) Extract submatrices, 2) vectorize and then 3) put back

感谢Dan和他的想法完美地达到了目的。

我的新问题是:

如果我有一个3D矩阵,8乘8乘以12,例如A = randn(8,8,12)

让我们看一下第一片的线性索引:

enter image description here

根据Dan的解决方案,我了解A[4:6, 4:6, :]可以提取所有切片的相应部分。

然而,回到我的实际情况,通过实际计算行和列来提取部件似乎不适合我的目的,因为我的矩阵大小很大,我确实有许多子矩阵要提取。

所以,我更喜欢研究线性索引,并想询问是否有任何方法可以解决这种可能性。

这是我的试用版:

通过定义sub_group = [28 29 30 36 37 38 44 45 46]A(sub_group)可以从3D矩阵的第一个切片A中提取子矩阵。

我了解A(sub_group + 8*8*(n-1))可以从nth切片中提取子矩阵。

我的目标是只使用我的sub_group,然后提取每个切片的相同部分。

最重要的是,我必须在更新其值后放回子矩阵。

那么,matlab是否有任何快速语法可以用于我的目的?

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

方法#1

对于需要计算线性指数的情况,您可以使用此处所示的bsxfun -

%// Store number of rows in A as a variable
M = size(A,1)

%// Get start and offset linear indices for the first slice and thus sub_group
start_idx = (colstart-1)*M + rowstart
offset_idx = bsxfun(@plus,[0:rowstop - rowstart]', [0:colstop-colstart]*M) %//'
sub_group = reshape(start_idx + offset_idx,1,[])

%// Calculate sub_groups for all 3D slices
all_sub_groups = bsxfun(@plus,sub_group',[0:size(A,3)-1]*numel(A(:,:,1)))

示例运行 -

A(:,:,1) =
     0.096594      0.52368      0.76285      0.83984      0.27019
      0.84588      0.65035      0.57569      0.42683       0.4008
       0.9094      0.38515      0.63192      0.63162      0.55425
     0.011341       0.6493       0.2782      0.83347      0.44387
A(:,:,2) =
     0.090384     0.037262      0.38325      0.89456      0.89451
      0.74438       0.9758      0.88445      0.39852      0.21417
     0.032615      0.52234      0.25502      0.62502    0.0038592
      0.42974      0.90963      0.90905       0.5676      0.88058
rowstart =
     2
rowstop =
     4
colstart =
     3
colstop =
     5
sub_group =
    10    11    12    14    15    16    18    19    20
all_sub_groups =
    10    30
    11    31
    12    32
    14    34
    15    35
    16    36
    18    38
    19    39
    20    40

方法#2

对于基于快速语法的解决方案,可以在此处建议sub2ind。实现看起来像这样 -

[X,Y] = ndgrid(rowstart:rowstop,colstart:colstop);
sub_group = sub2ind(size(A(:,:,1)),X,Y);

[X,Y,Z] = ndgrid(rowstart:rowstop,colstart:colstop,1:size(A,3));
all_sub_groups = sub2ind(size(A),X,Y,Z);