Ответ на первую часть вашего вопроса в этом другом вопросе . Самый быстрый способ там (не принятый ответ) заключается в следующем:
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
в этих случаях. Я также удалил избыточные операторы конкатенации []
и заменил '
с .'
, что более правильно для этого использования.)
По второй части вашего вопроса нам нужно обобщить приведенный выше код нетривиальным образом. Следующий код является результатом этого:
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]
). И я везде изменил размеры, чтобы учесть меньший выходной массив.
Обратите внимание, что это не приводит к появлению пустых (полностью нулевых) столбцов. Чтобы добавить их, проще всего сделать:
out2 = zeros(N,N);
out2(:,1:size(out,2)) = out;