>假设我在 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_size
和win_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_size
和w_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