【问题标题】:Submatrix Indexing and Operations Without Loops没有循环的子矩阵索引和操作
【发布时间】:2014-10-22 00:50:10
【问题描述】:

我遇到以下问题:我有一个矩阵 20 x 1000,我想将它分成四个大小为 20 x 250 的子矩阵。

之后,我想对每个子矩阵进行操作,假设我有一个长度等于子矩阵数量 4 的向量 P

P= [ 3 4 5 6] 

我对每个子矩阵(A)的目标如下:

对于第一个子矩阵:A(:,1:P(1))=1

还有第二个子矩阵:A(:,1:P(2))=1等等。

没有循环我怎么能做到这一点?

【问题讨论】:

  • 关于此处介绍的唯一解决方案中提到的方法的任何 cmet?

标签: matlab matrix vectorization submatrix


【解决方案1】:

一种矢量化方法可以结合使用cumsumbsxfun,尽管这可能会占用一些内存 -

blocksize = 250;
valid_idx = bsxfun(@le,[1:max(P)],P');
idx_mat = bsxfun(@plus,cumsum(valid_idx,2),[0:numel(P)-1]'*blocksize);
A(:,idx_mat(valid_idx)) = 1; %// You can replace this with "A(:,unique(idx_mat))=1;"

另一种略有不同的方法 -

blocksize = 250;
maxP = max(P);
valid_idx = bsxfun(@le,[1:maxP],P');
idx_mat = bsxfun(@plus,[0:numel(P)-1]'*blocksize,1:maxP);
A(:,idx_mat(valid_idx))=1;

请注意,要真正看到矢量化解决方案的好处,您需要在原始循环代码进行大量迭代时使用它。否则,与设置矢量化方法的准备工作相关的开销将是一种浪费。因此,我假设您的实际案例不仅仅涉及 4 个子矩阵。


另一种基于cumsum 的方法,尝试这种方法一定很有趣,甚至可能被证明是最好的-

blocksize = 250;

%//Get monotonically increasing labels within each group, defined by limits from idx
array1 = zeros(1,sum(P));
grp_starts = cumsum(P(1:end-1))+1;
array1(grp_starts) = P(1:end-1);
grp_labels = [1:numel(array1)] - cumsum(array1);

%// Get offsetted indices
array2 = zeros(1,sum(P));
array2(grp_starts) = blocksize;
offsetted_grp_labels = grp_labels + cumsum(array2);

A(:,offsetted_grp_labels)=1; %// perform the operation(s)

【讨论】:

  • 感谢 Divakar 的帮助...我会尝试你的建议并告诉你
猜你喜欢
  • 2013-02-16
  • 1970-01-01
  • 2013-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多