假设我在matlab中有一个长度为v
的向量m
。我想从中提取一些切片,将它们放入一个新的矩阵中。我会有一个hopsize 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
代码应该与算法的这个变体一起使用,其中我对切片和hopsizes的所有组合都有一个双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
答案 0 :(得分:1)
对于您的第一种情况,您可以使用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{:});
您可以在h_size
中定义hrange
值的范围,在win_len
中定义wrange
值。
<强> EDIT2 强>
如果您尝试在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