【问题标题】:Vectorizing access to a slice of a three-dimensional matrix in MATLAB在 MATLAB 中向量化访问一个三维矩阵的切片
【发布时间】:2016-07-06 19:35:11
【问题描述】:

我有一个这些大小的三维矩阵,大约

A = rand(20, 1000, 20);

第一个维度和第三个维度的长度始终相同。我想将主对角线切片中的元素归零。这就是我的意思

for ii = 1:size(A, 1)
    A(ii, :, ii) = 0;
end

是否有矢量化或其他更快的方法来执行此操作?这段代码运行了大约 100,000 次,使用这些近似大小,但每次的大小不完全相同。

【问题讨论】:

  • 对于相同的矩阵尺寸,它会运行 10 万次吗?
  • 不完全是。它在每个矩阵上运行约 100 次,并且有约 1000 个大小略有不同的此类矩阵。如果它们的大小始终相同,我会使用单个逻辑索引矩阵。

标签: arrays matlab multidimensional-array vectorization slice


【解决方案1】:

您可以对多个拖尾维度使用逻辑索引,同时对所有先前维度单独使用下标索引。这样您就可以轻松地对 1000 20 20 矩阵进行操作。要将其应用于您的矩阵,需要置换,这可能会很慢:

n=size(A,3)
A=permute(A,[2,1,3]);
A(:,diag(true(n,1)))=0;
A=permute(A,[2,1,3]);

如果可以在代码中永久交换 A 的维度并避免置换,这将导致最快的解决方案。

或者,您可以使用 repmat 将索引扩展到 A 的维度

ix=repmat(reshape(diag(true(n,1)),n,1,n),[1,size(A,2),1])
A(ix)=0

对于相同大小的矩阵,您可以保留 ix。目前无法访问 MATLAB,我不知道哪种解决方案更快。

【讨论】:

  • 我现在测试了这些方法。它们慢得多。我想这是矢量化并不优越的地方之一。
【解决方案2】:

您可以使用bsxfun 构建要归零的元素的线性索引:

ind = bsxfun(@plus, (0:size(A,2)-1).'*size(A,1), 1:size(A,1)*size(A,2)+1:numel(A) );
A(ind) = 0;

【讨论】:

  • 这比 Daniel 的建议提供了更好的时间,但仍然比 for 循环方法慢了 >2 倍。有趣的是,即使所有A 矩阵的大小是恒定的,并且bsxfun 只被调用一次,情况仍然如此。执行 A(ind) = 0; 100,000 次仍然比执行 for-loop 100,000 次要慢。我猜这是因为与使用A(ind) 访问“随机”索引相比,使用A(ii, :, ii) 访问内存更快。如果这是真的,这是反对矢量化此代码的情况。
  • 但由于我确实要求矢量化解决方案,我将接受这个答案作为最佳矢量化解决方案。
猜你喜欢
  • 2014-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-26
  • 2016-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多