如何在Matlab中使用信号样本的移位版本创建矩阵?

时间:2019-04-24 22:03:08

标签: matlab

我有一个大小为25001x1的矢量,它代表我的一个信号样本,并且我想创建一个矩阵,使得矩阵的第一列是我的矢量或信号,其余各列是原始信号的移位版本或向量。我可以通过以下方式(将10x1的向量用于理解目的)通过加零来完成。

 y=[1 2 3 4 5 6 7 8  9 10 ]';

 A=zeros(10,10);

 for i=1:length(y)
 A(:,i)=y;
 y=[1 2 3 4 5 6 7 8  9 10 ]';
 y=[zeros(1,(i))';y(1:end-(i))];

 end  

导致关注

>> A

 A =

 1     0     0     0     0     0     0     0     0     0
 2     1     0     0     0     0     0     0     0     0
 3     2     1     0     0     0     0     0     0     0
 4     3     2     1     0     0     0     0     0     0
 5     4     3     2     1     0     0     0     0     0
 6     5     4     3     2     1     0     0     0     0
 7     6     5     4     3     2     1     0     0     0
 8     7     6     5     4     3     2     1     0     0
 9     8     7     6     5     4     3     2     1     0
10     9     8     7     6     5     4     3     2     1

现在,当我想要移动多个元素或想要添加多个零时,我做了以下

y=[1 2 3 4 5 6 7 8  9 10 11 ]';

A=zeros(11,11);

for i=1:length(y)
A(:,i)=y;
y=[1 2 3 4 5 6 7 8  9 10 11  ]';
y=[zeros(1,(i*2))';y(1:end-(i*2))];
if (i>=(length(y)/2))
    break;
end 


end 

这将导致以下

>> A

A =

 1     0     0     0     0     0     0     0     0     0     0
 2     0     0     0     0     0     0     0     0     0     0
 3     1     0     0     0     0     0     0     0     0     0
 4     2     0     0     0     0     0     0     0     0     0
 5     3     1     0     0     0     0     0     0     0     0
 6     4     2     0     0     0     0     0     0     0     0
 7     5     3     1     0     0     0     0     0     0     0
 8     6     4     2     0     0     0     0     0     0     0
 9     7     5     3     1     0     0     0     0     0     0
10     8     6     4     2     0     0     0     0     0     0
11     9     7     5     3     1     0     0     0     0     0

是否有任何泛化方法可以做同样的事情而无需使用for循环?

1 个答案:

答案 0 :(得分:1)

问题的第一部分得到了in this other Q&A的回答。最快的方法(不是可接受的答案)如下:

N = numel(A);
val = repmat([A(:);0],1,N).*bsxfun(@le,[1:N+1]',[N:-1:1]);
out = reshape(val(1:N*N),N,N);

对于MATLAB R2016b及更高版本,我们可以对其进行现代化:

N = numel(A);
val = repmat([A(:);0],1,N) .* ((1:N+1).' <= (N:-1:1));
out = reshape(val(1:N*N),N,N);

(我只是将bsxfun(@le,x,y)替换为x<=y,因为几年前在这些情况下不再需要使用bsxfun。我还删除了多余的串联运算符{{1 }},并用[]替换了',这种用法更正确。)

对于您问题的第二部分,我们需要以不平凡的方式来概括以上代码。以下代码是其结果:

.'

我已将N = numel(A); step = 2; % Set this to however many zeros you want to add each column indx = N:-step:1; M = numel(indx); val = (1:N+step).' <= indx; % use bsxfun(@le, (1:N+step).',indx) instead for older MATLAB val = repmat([A(:);zeros(step,1)],1,M).* val; out = reshape(val(1:N*M),N,[]); 替换为N:-1:1,这是主要更改。我还需要将N:-step:1的零添加到step,而不是仅添加一个(这是A,之前是[A(:);zeros(step,1)])。而且我调整了各处的大小,以解决较小的输出数组。

请注意,这不会产生任何空(全零)列。要添加这些内容,最简单的方法是:

[A(:);0]