# Simple way to create a block-diagonal matrix from a single vector.

3 views (last 30 days)
Jon B. on 28 Nov 2021
Commented: Star Strider on 28 Nov 2021
I am working with a vector of the following form
and I would like to transform this vector into a block-diagonal matrix
without resorting to any sort of looping.
If I call the above vector x the following does, in principle, work
Z = reshape(x',3,4)';
[eye(2),zeros(2),zeros(2,4);zeros(2,4),zeros(2),eye(2)]*blkdiag(Z,Z)
It's just that my actual vector is fairly high dimensional and I feel that there must be a more organic way to obtain the same result, i.e., a way that does not rely on the manual construction of a selection matrix and that does not require typing
blkdiag(Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,..)
everytime the dimensionality changes. So essentialy, I would like to take a vector populate the first n coordinates of the first row of a matrix with the first n coodinates of this vector, fill in the rest of this row with zeros, move to the second row, populate the first first n coordinates with the second (!) n coordinates coordinates of my vector and continue until I reached the -st coordinate of my vectore, then I start populating the first n cooridnates of the -st row of my matrix with zeros and the second n cooridnates with the next elements of my vector, and so on...
I'd very much appreciate any pointers.
Thanks!

Star Strider on 28 Nov 2021
I don’t understand exactly what ‘z’ is or what the desired result is.
One possibility is to replicate the original matrix using repmat, then create it as a cell array using mat2cell, and then providing that result as the argument to blkdiag.
If I understand the problem correctly, this approach appears to provide the automation desired —
d = 3; % Matrix Dimension (For This Simulation)
n = 5; % Desired Number Of Repititions
z = randi([10 99],d) % Matrix To Be Replicated
z = 3×3
28 52 96 17 59 94 57 97 85
zm = repmat(z,1,n)
zm = 3×15
28 52 96 28 52 96 28 52 96 28 52 96 28 52 96 17 59 94 17 59 94 17 59 94 17 59 94 17 59 94 57 97 85 57 97 85 57 97 85 57 97 85 57 97 85
zmc = mat2cell(repmat(z,1,n), d, ones(1,n)*d)
zmc = 1×5 cell array
{3×3 double} {3×3 double} {3×3 double} {3×3 double} {3×3 double}
zmc{1} % Demonstrate That The Result Is As Desired
ans = 3×3
28 52 96 17 59 94 57 97 85
zmc{end} % Demonstrate That The Result Is As Desired
ans = 3×3
28 52 96 17 59 94 57 97 85
BD = blkdiag(zmc{:}) % Show Final Result
BD = 15×15
28 52 96 0 0 0 0 0 0 0 0 0 0 0 0 17 59 94 0 0 0 0 0 0 0 0 0 0 0 0 57 97 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 28 52 96 0 0 0 0 0 0 0 0 0 0 0 0 17 59 94 0 0 0 0 0 0 0 0 0 0 0 0 57 97 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 28 52 96 0 0 0 0 0 0 0 0 0 0 0 0 17 59 94 0 0 0 0 0 0 0 0 0 0 0 0 57 97 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 28 52 96 0 0 0
This replicates the original matrix, segments the replicated matrix into a cell array (a comma-separated list, exactly what blkdiag wants for an argument), then creates the bolck diagonal matrix.
.
##### 2 CommentsShowHide 1 older comment
Star Strider on 28 Nov 2021
As always, my pleasure!
This was an interesting (and challenging) problem!
.

R2021a

### Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!