我有一个大小为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循环?
答案 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]