【问题标题】:Vectorized creation of a 3D matrix by indexing one 2D matrix with another通过将一个 2D 矩阵与另一个 2D 矩阵索引来矢量化创建 3D 矩阵
【发布时间】:2020-01-06 04:25:57
【问题描述】:

在下面的示例中,我通过使用变量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是节点的三角面索引。

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

我有一个想法,矢量化可以使代码更快。但我无法获得理想的输出结果,即使有一些矩阵“调整大小”或矩阵旋转功能,如resizereshape

【问题讨论】:

    标签: matlab matrix optimization indexing vectorization


    【解决方案1】:

    对于这个例子(我认为是一般情况),您可以使用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
    

    【讨论】:

    • 我只是把速度对比记录在这里给别人。我的'a'矩阵是188802*3,'index'是377644*3。前一个循环的时间约为 0.9 s;使用这个答案的时间是 0.08s。矢量化方法显然要快得多。
    • @ZhangWei 很高兴我能帮上忙,它加快了你的代码速度!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-11
    • 1970-01-01
    • 2015-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多