repmat que matrices index hace for array matlab matrix vectorization

matlab - que - Replicar vector y desplazar cada copia en 1 fila hacia abajo sin for-loop



reshape matlab que hace (2)

Me gustaría replicar un vector N veces para crear una matriz con cada copia desplazada 1 fila hacia abajo. Ver imagen (la primera columna es el vector 1 a 5). Sería genial si esto se puede lograr sin usar for loop.

Hasta ahora pude hacer este repmat(my_vector, 1, 5) para crear una matriz N x 5.


Código de solución

Este parece ser un enfoque rápido basado en repmat y bsxfun ya que los puntos de referencia enumerados en la siguiente sección podrían convencernos:

%// 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);

Benchmarking

En esta sección, cubriremos la evaluación comparativa del tiempo de ejecución para los diversos enfoques enumerados en esta página para el problema establecido.

Código de Benchmarking -

%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'')

Códigos de función asociados (todos los enfoques) -

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;

Parcelas en tiempo de ejecución -

Set # 1 [De 10 a 1000 datatases]:

Set # 2 [De 1000 a 10000 datatases]:


Puedes hacerlo con toeplitz y tril ;

a = [1 2 3 4 5] out = tril( toeplitz(a) )

o

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

o si no te importa un poco feliz de voltear:

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