Как повторить вектор по диагонали в Matlab
я хотел бы повторить вектора A
длиной n
по диагонали m
раз, чтобы получить (n+m-1) x m
матрица B
. В качестве примера скажем A = [a;b;c;d]
, m = 4
. Это должно привести к
B =
[a 0 0 0;
b a 0 0;
c b a 0;
d c b a;
0 d c b;
0 0 d c;
0 0 0 d]
любые предложения по быстрому способу достижения этого? blkdiag(repmat(A,1,m))
не помогает мне в этом деле, так как создает (n*m) x m
матрица.
в конце концов, я на самом деле просто интересуюсь матричным продуктом D
третьей матрицы C
С B
:
D=C*B
если вы видите другой вариант получить D
для определения B
, Я был бы признателен. Но решение проблемы выше сделало бы меня очень счастливым, а также! n
и m
будет довольно большой, кстати.
спасибо!
3 ответов
неуклюжий, но общий однострочный
n = 3; %number of elements in A;
m = 5; %repetitions
A = (1:n);
B = full( spdiags( repmat(A(:),1,m)' , 1-(1:n) , n+m-1, m) )
возвращает:
B =
1 0 0 0 0
2 1 0 0 0
3 2 1 0 0
0 3 2 1 0
0 0 3 2 1
0 0 0 3 2
0 0 0 0 3
альтернативно улучшенная, общая версия решение rubenvb
B = toeplitz( [A(:);zeros(m-1,1)] , zeros(1,m) )
в обоих случаях A
может быть либо строка или вектор-столбец.
более быстрое решение (фактор 2x) является первым с spdiags
!
Edit: еще более неуклюжий, но до 10x быстрее (это зависит от n, m), чем toeplitz
подход:
B = reshape( [repmat([A(:);zeros(m,1)],m-1,1) ; A3(:)] ,[],m )
потому что @mathematician1975 слишком ленив, чтобы написать правильный ответ.
Matlab имеет функцию для этого, называемую toeplitz
вы бы назвали это так:
c=[1;2;3;4;0;0;0];
r=[0, 0, 0, 0];
toeplitz(c,r)
ans =
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
Вы можете играть с нуля, чтобы сформировать матрицу так, как вы хотите.
полное решение, без матрицы B
, это сделать свертку каждой строки C
С A
. вы можете сделать это с помощью цикла for:
for k=1:size(C,1)
D(k,:)=conv(C(k,:),A');
end
D=D(:,length(A)-1:end-length(A)+1); % elliminate the convolution edges
Я думаю, что это можно сделать и без цикла, путем arrayfun
:
k=1:size(C,1);
D=arrayfun(@(x) conv(C(x,:),A'), k);
D=D(:,length(A)-1:end-length(A)+1); % elliminate the convolution edges