通过将一个 2D 矩阵与另一个进行索引来矢量化创建 3D 矩阵

Vectorized creation of a 3D matrix by indexing one 2D matrix with another

在下面的示例中,我通过使用变量 index 索引 a 的行来创建 result。我可以用一个循环来完成这个工作:

a=repmat(1:6,3,1)';
index=[1:3;2:4];

result=zeros(3,3,size(index,1));
for i=1:size(index,1)
    result(:,:,i)=a(index(i,:),:)
end

给定的aindex是:

a =
     1     1     1
     2     2     2
     3     3     3
     4     4     4
     5     5     5
     6     6     6

index =
     1     2     3
     2     3     4

输出应该是:

result(:,:,1) =
     1     1     1
     2     2     2
     3     3     3

result(:,:,2) =
     2     2     2
     3     3     3
     4     4     4

实际上,aindexn*3矩阵,其中n非常大。

a是节点坐标,index是节点的三角面索引。

表面太大,所以我真的需要加快这个循环

我认为矢量化可以使代码更快。但我无法获得理想的输出结果,即使使用一些矩阵 "resize" 或矩阵旋转函数,如 resizereshape

对于这个例子(我认为是一般情况),您可以使用 reshapepermute 的组合。

请注意,我使用了几个转置 (.') 操作来使 reshape 工作,您可能可以简化它,但它不应该很慢:

result = permute( reshape( a(index.',:).', size(a,2), size(index,2), [] ), [2 1 3] );

如果总是知道 size(a,2) = size(index,2) = 3,正如您的问题所暗示的那样,那么您当然可以缩短它(但不太笼统):

result = permute( reshape( a(index.',:).', 3, 3, [] ), [2 1 3] );

分解这个,

a(index.',:).'          % Gives the 2D results
reshape( ..., size(a,2), size(index,2), [] ) % Convert 2D to 3D, with row and column
                                             % sizes defined by 'a' and 'index'
permute( ..., [2 1 3] ) % We need another "transpose", but that isn't defined in the
                        % 3D case. Use 'permute' to swap the 1st and 2nd dimensions