通过向每个列向下滑动给定向量一步来创建矩阵

时间:2015-02-24 15:12:04

标签: matlab matrix vectorization

鉴于此载体

a = [1 2 3 4]

我想创建一个像这样的矩阵

b = [1 0 0 0;
     2 1 0 0;
     3 2 1 0;
     4 3 2 1;
     0 4 3 2;
     0 0 4 3;
     0 0 0 4]

以矢量化的方式不使用循环。

4 个答案:

答案 0 :(得分:7)

提示:使用conv2(悬停鼠标查看代码):

  

a = [1 2 3 4];
b = conv2(a(:), eye(numel(a)));

或者,在类似的情绪中,您可以使用convmtx(来自信号处理工具箱):

  

a = [1 2 3 4];
b = convmtx(a(:), numel(a));

答案 1 :(得分:5)

一种方法:

a = [1 2 3 4]
n = numel(a);

%// create circulant matrix from input vector
b = gallery('circul',[a zeros(1,n-1)]).' %'

%// crop the result
c = b(:,1:n)

另一种方式:

b = union( tril(toeplitz(a)), triu(toeplitz(fliplr(a))),'rows','stable')

或略有变化

b = union( toeplitz(a,a.*0),toeplitz(fliplr(a),a.*0).','rows','stable')

甚至可能更快:

b = [ toeplitz(a,a.*0) ; toeplitz(fliplr(a),a.*0).' ]
b(numel(a),:) = []

答案 2 :(得分:2)

使用bsxfun -

na = numel(a)
b = zeros(2*na-1,na)
b(bsxfun(@plus,[1:na]',[0:na-1]*2*na)) = repmat(a(:),1,na)

如果您正在寻找faster pre-allocation,可以这样做 -

b(2*na-1,na) = 0;

答案 3 :(得分:2)

另一个bsxfun -

a=[1 2 3 4];
m=numel(a);
b=[a,zeros(1,m-1)].';

Q=bsxfun(@circshift, b, [0:m-1])