我在 MATLAB 中编写以下代码时遇到了很大困难:假设您有以下向量:
a
b
c
d
e
f
g
h
...
指定(偶数)窗口大小,L
按n
列创建以下维度矩阵(例如,L = 4
):
a c e ...
b d f ...
c e g ...
d f h ...
更困难的是采用任意长度的向量,指定窗口的数量,并优化(最大化)窗口大小,以便在向量末尾转储更少的值。
我在 MATLAB 中编写以下代码时遇到了很大困难:假设您有以下向量:
a
b
c
d
e
f
g
h
...
指定(偶数)窗口大小,L
按n
列创建以下维度矩阵(例如,L = 4
):
a c e ...
b d f ...
c e g ...
d f h ...
更困难的是采用任意长度的向量,指定窗口的数量,并优化(最大化)窗口大小,以便在向量末尾转储更少的值。
bsxfun
在这种情况下是你的朋友。下面的单线(假设你知道L
并且v
是你的向量)做你想要的
v(bsxfun(@plus, [0:L-1]', 1:L/2:numel(v)-L))
为了尝试并理解它,让我们进一步看看。这个想法是首先创建一个向量来确定窗口在v
向量中的起始位置。Windows 启动每个L/2
条目(L
是偶数,所以我们可以划分)。但是有多少个窗户适合?我们可以依靠 MATLAB 来解决这个问题:
start_offset = 1:L/2:numel(v)-L;
这里我们只需要指定
L/2
条目现在,示例的其余部分:
v = 'a':'z';
L = 4;
% indices in every output matrix column are contiguous
% and the difference between first and last is `L-1`
id1 = [0:L-1]';
% start_offset determines where in the input vector v every window starts.
% windows start every L/2 entries. The last entry that fits will start
% at some index, from which we can still use L subsequent indices to access v
start_offset = 1:L/2:numel(v)-L;
% calculate how many entries were dropped from v
% from number of elements in v subtract the largest index value used
dropped = numel(v) - (start_offset+L-1);
% window indices are created using bsxfun and singleton expansion.
% Every window's indices are given by [0:L-1] + window start index
idx = bsxfun(@plus, id1, start_offset);
v(x)
ans =
acegikmoqsu
bdfhjlnprtv
cegikmoqsuw
dfhjlnprtvx
在向量中创建索引矩阵。对于 L=4(我假设您与 L/2 重叠),索引为 [1,2,3,4;3,4,5,6;5,6,7,8] 等。令 x = 1 :L, y = L/2, 索引向量为 x+0y,x+1y,x+2y,以此类推。
% let your initial data be in vector "data"
L = 4
N = floor(length(data)/(L/2))-1 % number of windows, or you specify this
mi = repmat(1:L,[N,1]) + repmat((L/2) * (0:(N-1))',[1,L]) % x + y * 0,1,2...
out = data(mi) % out is N-by-L, transpose to L-by-N if you like
这是做你想做的事情的一般方法:
1)计算适当的窗口宽度(和相应的移位)
2)通过从 1 迭代您希望每列移动窗口的量直到最终值来确定每列的起始索引。将其设为行向量。
3) 用于bsxfun
将其扩展为索引矩阵。
4) 使用索引从原始向量中获取值。
vec = 1:17; #% original data vector
num_windows = 3; #% specified number of windows
possible_window_length = 1:length(vec);
window_length = possible_window_length(find(possible_window_length +...
(num_windows-1) * possible_window_length/2 < length(vec),1,'last'));
window_shift = floor(window_length)/2;
window_length = window_shift * 2; #% calculated window length
max_final_start_index = (length(vec)-window_length+1);
start_indices = 1:window_shift:max_final_start_index;
inds = bsxfun(@plus,start_indices,(0:window_length-1)');
soln = vec(inds); #% get the solution
num_excluded_vals = max_final_start_index - start_indices(end)
disp(soln);
num_excluded_vals = 1
disp(soln);
1 5 9
2 6 10
3 7 11
4 8 12
5 9 13
6 10 14
7 11 15
8 12 16
在 MATLAB 中有很多方法可以通过操作索引、过程方法、矢量化解决方案等来做到这一点。然而,我不禁想到,如果 MATLAB 对函数式编程。本着这种精神,我提出以下解决方案。确保在定义时这些变量中没有任何值。
take=@(mat,n)mat(1:n)
partition=@(mat,L)cell2mat(arrayfun(@(x)take(circshift(mat(:),-x*L/2),L),...
0:fix((length(mat)-L)/2+1)-1,'UniformOutput',0))
现在用一个测试向量试试:
partition(1:10,4)
%ans =
% 1 3 5 7
% 2 4 6 8
% 3 5 7 9
% 4 6 8 10
上述解决方案丢弃了向量末尾不适合L
分区后长度的最终值。您现在可以在此基础上处理其他安排,并找出最佳窗口长度以最大限度地减少最终浪费等。