Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace each element in a matrix with a diagonal matrix

Say I have a matrix A of dimension NxV. I want to create a larger matrix of size NTxVT, i.e. I want to replace each element e of the matrix A(e) with diag(T)*A(e)., while keeping the general orientation of the matrix (for instance, A(e) is to the left of A(e-1), so diag(T)*A(e) is to the left of diag(T)*A(e-1).

Is there a trick to accomplish this in matlab? (making each diagonal matrix and concatenating them will take forever).

Many thanks ^^

like image 633
Draper Avatar asked Mar 20 '15 22:03

Draper


2 Answers

A = magic(3);
T = diag([-1 1]);
kron(A,T)

gives

-8     0    -1     0    -6     0
 0     8     0     1     0     6
-3     0    -5     0    -7     0
 0     3     0     5     0     7
-4     0    -9     0    -2     0
 0     4     0     9     0     2

ps. I copied the idea from this example

like image 140
Nasser Avatar answered Sep 22 '22 02:09

Nasser


Here is a solution using bsxfun

A = magic(3);
T = [-1 1]
T = diag(T);
M=bsxfun(@times,permute(A,[3,1,4,2]),permute(T,[1,3,2,4]));
M=reshape(M,size(T).*size(A));

It creates a 4D-Matrix where the individual blocks are M(:,i,:,j), then this is reshaped to a 2D-Matrix.

The image processing toolbox provides another solution which is very short but slow:

A = magic(3);
T = [-1 1]
T = diag(T);
M=blockproc(A,[1 1],@(x) x.data.*T);

And finally a implementation which generates a sparse matrix, which might be helpful for large T as your matrix will contain many zeros:

T=[-1 1];
A=magic(3);
%p and q hold the positions where the first element element is stored. Check sparse(p(:),q(:),A(:)) to understand this intermediate step
[p,q]=ndgrid(1:numel(T):numel(T)*size(A,1),1:numel(T):numel(T)*size(A,2));
%now p and q are extended to hold the indices for all elements
tP=bsxfun(@plus,p(:),0:numel(T)-1);
tQ=bsxfun(@plus,q(:),0:numel(T)-1);
%
tA=bsxfun(@times,A(:),T);
M=sparse(tP,tQ,tA);

When T is of size nx1 the sparse solution cuts your memory usage by a factor of roughly n/1.55.

like image 33
Daniel Avatar answered Sep 23 '22 02:09

Daniel