通过将一个 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
给定的a
和index
是:
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
实际上,a
和index
是n*3
矩阵,其中n
非常大。
a
是节点坐标,index
是节点的三角面索引。
表面太大,所以我真的需要加快这个循环。
我认为矢量化可以使代码更快。但我无法获得理想的输出结果,即使使用一些矩阵 "resize" 或矩阵旋转函数,如 resize
或 reshape
。
对于这个例子(我认为是一般情况),您可以使用 reshape
和 permute
的组合。
请注意,我使用了几个转置 (.'
) 操作来使 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
在下面的示例中,我通过使用变量 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
给定的a
和index
是:
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
实际上,a
和index
是n*3
矩阵,其中n
非常大。
a
是节点坐标,index
是节点的三角面索引。
表面太大,所以我真的需要加快这个循环。
我认为矢量化可以使代码更快。但我无法获得理想的输出结果,即使使用一些矩阵 "resize" 或矩阵旋转函数,如 resize
或 reshape
。
对于这个例子(我认为是一般情况),您可以使用 reshape
和 permute
的组合。
请注意,我使用了几个转置 (.'
) 操作来使 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