【问题标题】:matlab: sum values of different sized subarrays without loopmatlab:没有循环的不同大小子数组的总和值
【发布时间】:2014-08-12 11:54:16
【问题描述】:

我想知道是否可以获得不同大小子数组的最小/最大值 在 matlab 中不使用循环。

% create a 1D vector with arbitory floating point values
A = rand(100,1,'double');

% get start indexes of sections of A (eg. A>0.9)
pos01 = A>0.9;
posIdx= [1;find(pos01);size(A,1)];

% if 1 or size(A,1) where not required, remove them
posIdx = unique(posIdx); 

% min/max all sections:
for ix=1:size(posIdx,1)-1
    Amin(ix) = min(A(posIdx(ix):posIdx(ix+1)));
    Amax(ix) = max(A(posIdx(ix):posIdx(ix+1)));
end

如果您有一个非常大的向量 A 和很多部分,那么最后一行可能会非常慢。 我想知道如何在 matlab 中对这个循环进行矢量化。

我尝试使用 arrayfun、remap、bsxfun 等提出解决方案。 但是我能想到的所有解决方案都要求这些部分具有相同的大小 - 情况并非如此:(

有什么想法吗?

最好, 延斯·亨利克

【问题讨论】:

  • 你真的需要在 last/fist 元素中重叠部分吗?
  • 我可以避免重叠。 accumarray 正在完成这项工作。太好了。

标签: matlab max vectorization min arrays


【解决方案1】:

使用cumsumaccumarray

A = rand(100,1,'double');
pos01 = A > 0.9;
subs = ( pos01(1) == 0 ) + cumsum( pos01(:) ); % convert posIdx to subs. note the special treatment of the first entry. 
Amin = accumarray( subs, A, [], @min );
Amax = accumarray( subs, A, [], @max );

【讨论】:

  • +1 用 accumarray 很好地完成了,可能比 bsxfun 实现快得多..
  • 您是否注意到 OP 将部分重叠了一个元素?除此之外,你的方法将是要走的路(当我说你的时候,我正在写一个答案)
  • @LuisMendo 有趣的点。我没有注意到这个细节。它确实让事情变得更复杂了......我会看看我能不能解决。
  • 我认为Amax = max(Amax, A([find(pos01); end])); 会起作用。 +1
  • accumarray() 只是我正在寻找的命令 - 太棒了。谢谢 Shai,谢谢 Luis - 你的 cmets 真的很有帮助!我会测试一下,如果这能通过简单的 for 循环实现预期的加速。
【解决方案2】:

bsxfun 替换你的 for 循环部分的方法 -

t1 = bsxfun(@le,1:size(A,1),posIdx(2:end)) & bsxfun(@ge,1:size(A,1),posIdx(1:end-1));
t1 = t1';
t2 = A(:,ones(1,size(t1,2))).*t1;
t2(~t1)=nan;
Amin = nanmin(t2);
Amax = nanmax(t2);

【讨论】:

  • bsxfun 很有趣,但恐怕不是用它的正确地方:(a) 生成的代码很难理解。 (b) 它使用了太多的内存 o(n^2)。
  • @Shai 感谢您的反馈。同意你的观点,这个问题看起来确实比较慢。但是,bsxfun 将始终使用o(n^2),如果提供足够的计算资源和内存带宽,它可能会很有用。此o(n^2) 内存要求适用于所有使用bsxfun 的解决方案。在解释部分,有时我会让提问者主动询问代码的特定部分,如果有任何疑问。
  • 确实 bsxfun 将始终使用 o(n^2) 但在许多情况下这是合理的:恐怕这里不是这种情况。我觉得对于这个特定任务bsxfun 不是正确的工具,对于许多其他任务bsxfun 非常有用,我认为每个Matlab 程序员都应该让自己熟悉。跨度>
  • +1 用于正确处理 OP 似乎想要的单元素重叠
  • @LuisMendo 实际上我根本没有处理这个问题,这段代码只替换了 for 循环部分。欣赏+1! :) 仍然想知道是否有一个矢量化解决方案可以击败 for 循环部分。
猜你喜欢
  • 2023-01-03
  • 2015-02-22
  • 1970-01-01
  • 1970-01-01
  • 2014-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-27
相关资源
最近更新 更多