从 Matlab 中没有循环的向量重叠的多个选择



>假设我在 matlab 中有一个长度为 m 的向量v。我想从中提取一些切片,将它们放入新的矩阵中。我将有一个跳跃大小h_size,一个窗口长度win_len和一些跳跃num_j。如何在不使用循环的情况下完成此操作?循环版本将是:

for i = 1:num_j
   slice(i,:) = v(1+(i-1)*h_size : win_len+(i-1)*h_size);
end

代码应该使用这种算法变体,其中我有一个双精度 for 循环,用于切片和跃点大小的所有组合。在这种情况下,我有不同长度的切片,所以我将使用单元格数组:

sliceInd = 0;
for i = 1:num_j
   for j = i:num_j
      sliceInd = sliceInd + 1;
      slice{sliceInd} = v(1+(i-1)*h_size : win_len+(j-1)*h_size);
   end
end

对于第一种情况,您可以使用bsxfun为您创建索引。

slice = v(bsxfun(@plus, 1:h_size:h_size*num_j, (0:win_len-1).').');

解释

这本质上的作用是识别您的所有起始位置:

starts = 1:h_size:(h_size * num_j);

然后从这些位置中的每一个开始,我们要对win_len点进行采样。要为给定的起始位置执行此操作,我们可以使用此公式。

inds = starts(k) + 0:(win_len - 1);

然后,我们可以使用 bsxfun 对所有开始位置执行此操作。

bsxfun(@plus, 1:h_size:h_size*num_j, (0:win_len-1).').';

然后,我们将其用作v的索引,以获得最终结果。

这假设您已正确选择变量,因此您不会尝试索引超过v末尾(即当(h_size * num_j) + win_len - 1 > numel(v) .

编辑

如果你真的需要循环遍历各种h_sizewin_len值的选项,你可以使用嵌套的arrayfun调用来获取结果而不循环,但老实说这有点混乱。

R = arrayfun(@(h,w)arrayfun(@(x)v(x+(0:w-1)), 1:h:h*num_j, 'uni', 0), hrange, wrange, 'uni', 0);
slice = cat(2, R{:});

您将在 hrange 中定义h_size值的范围,在 wrange 中定义win_len值的范围。

编辑2

如果您尝试一次对多行v执行此操作,以进行h_sizew_len的许多排列。我可能会以这种方式循环它。

% Anonymous function to get the indices
getinds = @(h,w)bsxfun(@plus, 1:h:h*num_j, (0:w-1).').';
% All permutations of h_size and w_len
[hh, ww] = meshgrid(hrange, wrange);
alldata = cell(size(hh));
for k = 1:numel(hh)
    inds = getinds(hh(k), ww(k));
    V = reshape(v(:, inds), [size(v, 1), size(inds)]);
    % V is a 3D array where the info for each window is along the third dim
    % i.e. Hop #1 for the first for of v is V(1,1,:)
    % Do whatever you want here
    % ... or store data in cell array for processing later
    alldata{k} = V;
end

最新更新