【问题标题】:Loopless submatrix assignment in MatlabMatlab中的无环子矩阵赋值
【发布时间】:2015-10-24 21:21:02
【问题描述】:

我有一个大小为D-by-N 的矩阵F 和一个长度为N 的向量N,由[1,a] 范围内的随机整数组成。我想创建一个大小为D * a 的矩阵M,使得每个列M(:,i) 具有从索引(A(i)-1)*D+1(A(i)-1)*D+D 的向量F(:,i)

例子:

F = [1 2 3 10
     4 5 6 22]

A = [3 2 1 2]

a = 4

M = [0 0 3 0
     0 0 6 0
     0 2 0 10
     0 5 0 22
     1 0 0 0
     4 0 0 0
     0 0 0 0
     0 0 0 0]

我可以用一个简单的循环来做到这一点

        for i = 1 : N
            M((A(i)-1)*D+1:(A(i)-1)*D+D,i) = F(:,i);
        end

但对于大型N,这可能需要一段时间。我正在寻找一种没有循环的方法。

【问题讨论】:

  • 我认为这是相当快的。您是否甚至为a / N 的大值计时以检查您的陈述是否正确?
  • 嗯,它并不是很慢,但如果可能的话,我想要更快的东西,因为我的这部分代码在我的主算法的每次迭代中运行。在我的电脑上,a = 3D = 6N = 1e6 时需要 3s
  • 如果A = [3 2 1 2]a 怎么可能是4A 包含从 13 的元素。
  • @Divakar 有些值可能会丢失,因为它们是随机抽样的。在这种情况下(缺少 4)矩阵的底部将为 0(在示例中为最后两行)。
  • 我猜是有道理的。

标签: matlab matrix vectorization matrix-indexing submatrix


【解决方案1】:

您可以将bsxfun 用于基于linear-indexing 的方法-

[D,N] = size(F);    %// Get size of F

start_idx = (A-1)*D+1 + [0:N-1]*D*a;          %// column start linear indices
all_idx = bsxfun(@plus,start_idx,[0:D-1]');   %//'# all linear indices

out = zeros(D*a,N); %// Initialize output array with zeros
out(all_idx) = F;   %// Insert values from F into output array

示例运行 -

F =
     1     2     3    10
     4     5     6    22
A =
     3     2     1     2
a =
     4
out =
     0     0     3     0
     0     0     6     0
     0     2     0    10
     0     5     0    22
     1     0     0     0
     4     0     0     0
     0     0     0     0
     0     0     0     0

【讨论】:

  • 谢谢,您的代码非常快(比我的循环快 10 倍)。但是,如果 A 的所有元素都是 1,则它会给出不正确的结果。我正在使用D = 2; N = 1e2; a = 4; F = rand(D,N); A = ones(1,N); 进行测试
  • @Simon 哦,我以为A 会是1:N,我的错!您能否在问题中添加一个不像[1,2,3] 这样简单的示例作为示例?
  • 你是对的,问题中的例子太琐碎了,并没有说明A包含[1,a]范围内的随机整数。我编辑了我的问题。
  • @Simon 相应地编辑了我的解决方案。
  • 谢谢! N 越大,与我的循环相比,您的代码就越快。对于N = 1e6,它快了 10 倍!
猜你喜欢
  • 1970-01-01
  • 2012-10-19
  • 2018-07-06
  • 2018-07-16
  • 1970-01-01
  • 2023-04-10
  • 2014-05-12
  • 2017-10-25
  • 1970-01-01
相关资源
最近更新 更多