复制矢量并将每个副本向下移1行而不进行for循环

时间:2015-03-23 11:42:22

标签: matlab matrix vectorization

我想复制一个向量N次以创建一个矩阵,每个副本向下移动1行。见图像(第一列是向量1到5)。如果可以在不使用for循环的情况下实现这一点,那就太棒了。

enter image description here

到目前为止,能够执行此操作repmat(my_vector, 1, 5)来创建N x 5矩阵。

2 个答案:

答案 0 :(得分:6)

您可以使用toeplitztril;

执行此操作
a = [1 2 3 4 5]
out = tril( toeplitz(a) )

out = toeplitz(a, a*0)
%// out = toeplitz(a, zeros(size(a)) )  %// for large arrays

或者如果你不介意一些快乐的翻转:

out = flipud( hankel( flipud(a(:)) ) )

答案 1 :(得分:3)

解决方案代码

这似乎是一种基于repmatbsxfun的快速方法,因为下一节中列出的基准可能会让我们信服 -

%// Concatenate one zero at the end of a column vector version of the input vector.
%// Then, replicate the whole vector along columns to have a 2D matrix. 
%// Then "progressively" set elements from each column as zeros corresponding 
%// to the starting zeros of the desired output.
val = repmat([A(:);0],1,N).*bsxfun(@le,[1:N+1]',N:-1:1);  %//'

%// Chop-off at N x N length and reshape to have the final output
out = reshape(val(1:N*N),N,N);

基准

在本节中,我们将介绍针对所述问题在本页列出的各种方法的运行时基准测试。

基准代码 -

%datasizes = [10 20 50 70 100 200 500 700 1000]; %// Set -1
datasizes = [1000 2000 5000 7000 10000];         %// Set -2
fcns = {'repvecshiftdown_flipud_hankel','repvecshiftdown_toeplitz',...
'repvecshiftdown_repmat_bsxfun','repvecshiftdown_tril_toeplitz'};%//approaches
tsec = zeros(numel(fcns),numel(datasizes));

for k1 = 1:numel(datasizes),
    A = randi(9,1,datasizes(k1)); %// Creare random input vector
    for k2 = 1:numel(fcns), %// Time approaches  
        tsec(k2,k1) = timeit(@() feval(fcns{k2}, A), 1);
        fprintf('\tFunction: %s (%3.2f sec)\n',fcns{k2},tsec(k2,k1));
    end
end

figure;  %% Plot Runtimes
plot(datasizes,tsec(1,:),'-rx'), hold on
plot(datasizes,tsec(2,:),'-bo')
plot(datasizes,tsec(3,:),'-k+')
plot(datasizes,tsec(4,:),'-g.')
set(gca,'xgrid','on'),set(gca,'ygrid','on'),
xlabel('Datasize (# elements)'), ylabel('Runtime (s)')
legend(upper(strrep(fcns,'_',' '))),title('Runtime')

相关功能代码(所有方法) -

function out = repvecshiftdown_repmat_bsxfun(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);
return;

function out = repvecshiftdown_tril_toeplitz(A)
out = tril( toeplitz(A) );
return;

function out = repvecshiftdown_toeplitz(A)
out = toeplitz(A, zeros(size(A)));
return;

function out = repvecshiftdown_flipud_hankel(A)
out = flipud( hankel( flipud(A(:)) ) );
return;

运行时图 -

设置#1 [从10到1000数据]:

enter image description here

设置#2 [从1000到10000数据]:

enter image description here