通过重复重叠矢量来创建矩阵

时间:2012-10-19 02:24:58

标签: matlab vector matrix vectorization

我在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 ...

更难的是采用任意长度的向量,指定窗口数量,并优化(最大化)窗口大小,以便转储向量末尾的较少值。

4 个答案:

答案 0 :(得分:4)

在矢量中创建索引矩阵。对于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 :(得分:4)

简短回答

在这种情况下,

bsxfun是你的朋友。以下单行(假设您知道Lv是您的向量)做你想要的

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;

这里我们只需要指定

  • 第一个窗口位于索引1
  • windows启动每个L/2条目
  • 最后一个窗口应该在v vector 结束之前至少L个条目。所以最后一个窗口拳头在那里。

现在,示例的其余部分:

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

答案 2 :(得分:2)

这是一种做你想做的事情的一般方法:

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

答案 3 :(得分:1)

通过操作索引,程序方法,矢量化解决方案等,在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。您现在可以在此基础上进行处理,以便处理其他布置,并找出最佳窗口长度以减少最终浪费等。