Reputation: 63
I would like to repeat a vector A
of length n
on a diagonal m
times to obtain a (n+m-1) x m
matrix B
. As an example let's say A = [a;b;c;d]
, m = 4
. This should result in
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]
Any suggestions for a fast way to achieve this? blkdiag(repmat(A,1,m))
does not help me in this case as it creates a (n*m) x m
matrix.
In the end I am actually just interested in the matrix product D
of a third matrix C
with B
:
D=C*B
If you see another option to obtain D
without having to generate B
, I would appreciate it. But a solution for the problem above would make me very happy as well! n
and m
will be quite big by the way.
Thanks!
Upvotes: 6
Views: 1779
Reputation: 3071
Total solution, without matrix B
, is to do convolution of each row of C
with A
. you can do it by for loop:
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
I think it can be done also without the loop, by 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
Upvotes: 2
Reputation: 25242
A clumsy, but generic one-liner
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) )
returns:
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
Alternatively an improved, generic version of rubenvb's solution
B = toeplitz( [A(:);zeros(m-1,1)] , zeros(1,m) )
in both cases A
can be either a row or column vector.
The faster solution (factor 2x) is the first one with spdiags
!
Edit: even clumsier, but up to 10x faster (it depends on n,m) than the toeplitz
-approach:
B = reshape( [repmat([A(:);zeros(m,1)],m-1,1) ; A3(:)] ,[],m )
Upvotes: 5
Reputation: 76795
Because @mathematician1975 is too lazy to write a proper answer.
Matlab has a function for this, called toeplitz
You would call it like this:
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
You can play with the zeroes to shape the matrix the way you want it.
Upvotes: 7