# How to insert a Matrix into a larger matrix

I have a 4x4 matrix

      v1 v2 v3 v4

myM={{a1,a2,c1,c2},    v1
{a2,a3,c2,c3},    v2
{c1,c2,d1,d2},    v3
{c2,c3,d2,d3}}    v4


And I want to insert this matrix into a 8x8 matrix as follows:

       u1  u2  v1  v2  u3  u4  v3  v4

myLM={{ 0,  0,  0,  0,  0,  0,  0,  0},    u1
{ 0,  0,  0,  0,  0,  0,  0,  0},    u2
{ 0,  0, a1, a2,  0,  0, c1, c2},    v1
{ 0,  0, a2, a3,  0,  0, c2, c3},    v2
{ 0,  0,  0,  0,  0,  0,  0,  0},    u3
{ 0,  0,  0,  0,  0,  0,  0,  0},    u4
{ 0,  0, c1, c2,  0,  0, d1, d2},    v3
{ 0,  0, c2, c3,  0,  0, d2, d3}}    v4


Is there a way to do this without index-nightmares?

It would also be great if the answer was general enough, in a sense that it works for 2x2 or also 8x8 matrices that I want to include into a larger matrix.

Both the smaller and the larger matrix have always an even number of columns/rows. And I divide the small and large matrices in 4 blocks and place each sub-block of the small matrix into the corresponding one of the large matrix. So in the given example the index 3 would be given and then it is clear how to insert the matrix (a1-> (3,3) and the rest follows).

So the general idea is I guess, that one has a matrix in some basis representation and wants to have this matrix now in a larger vector space adding the appropriate zeros and matrix elements etc.)

Initial basis:

{v1,v2,...,v1',v2'...}


New Basis (inserting at position n):

{u1,u2,...,un-1,v1,v2,...,un,....,u1',u2',...,un-1',v1',v2',...,un',...}

• where did the b's come from? b1,b2,....? did you mean d1,d2,....? Commented Apr 1, 2015 at 14:32
– NOhs
Commented Apr 1, 2015 at 14:33
• Your myM has many repeated identical elements. Is that always the case, or are they supposed to be all different? I mean, is there a pattern we can assume for the repetitions? Also, do you only need zeros in the large matrix to start with? This would affect the degree to which one could simplify things.
– Jens
Commented Apr 1, 2015 at 16:23

I propose:

quarter = Partition[#, Dimensions[#]/2] &;

matrixInsert[small_, large_] :=
ArrayFlatten[ pad @@ quarter /@ {small, large} ]


Test:

myM = {{a1, a2, c1, c2}, {a2, a3, c2, c3}, {c1, c2, d1, d2}, {c2, c3, d2, d3}};

myLM = Array[Plus, {8, 8}, {0, 1}];

matrixInsert[myM, myLM] // MatrixForm


$\left( \begin{array}{cccccccc} 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \\ 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 \\ 3 & 4 & \text{a1} & \text{a2} & 7 & 8 & \text{c1} & \text{c2} \\ 4 & 5 & \text{a2} & \text{a3} & 8 & 9 & \text{c2} & \text{c3} \\ 5 & 6 & 7 & 8 & 9 & 10 & 11 & 12 \\ 6 & 7 & 8 & 9 & 10 & 11 & 12 & 13 \\ 7 & 8 & \text{c1} & \text{c2} & 11 & 12 & \text{d1} & \text{d2} \\ 8 & 9 & \text{c2} & \text{c3} & 12 & 13 & \text{d2} & \text{d3} \\ \end{array} \right)$

Here is an extension to control placement of the smaller blocks within the larger blocks.

ClearAll[quarter, pad, matrixInsert]

quarter = Partition[#, Dimensions[#]/2] &;

matrixInsert[small_, large_, r_: 0, c_: 0] :=
pad[{0, 0, r, c}] @@ quarter /@ {small, large} // ArrayFlatten


Test:

matrixInsert[myM, myLM] // MatrixForm   (* default *)


$\left( \begin{array}{cccccccc} \text{a1} & \text{a2} & 3 & 4 & \text{c1} & \text{c2} & 7 & 8 \\ \text{a2} & \text{a3} & 6 & 7 & \text{c2} & \text{c3} & 10 & 11 \\ 7 & 8 & 9 & 10 & 11 & 12 & 13 & 14 \\ 10 & 11 & 12 & 13 & 14 & 15 & 16 & 17 \\ \text{c1} & \text{c2} & 15 & 16 & \text{d1} & \text{d2} & 19 & 20 \\ \text{c2} & \text{c3} & 18 & 19 & \text{d2} & \text{d3} & 22 & 23 \\ 19 & 20 & 21 & 22 & 23 & 24 & 25 & 26 \\ 22 & 23 & 24 & 25 & 26 & 27 & 28 & 29 \\ \end{array} \right)$

matrixInsert[myM, myLM, 1] // MatrixForm  (* one row down *)


$\left( \begin{array}{cccccccc} 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \\ \text{a1} & \text{a2} & 6 & 7 & \text{c1} & \text{c2} & 10 & 11 \\ \text{a2} & \text{a3} & 9 & 10 & \text{c2} & \text{c3} & 13 & 14 \\ 10 & 11 & 12 & 13 & 14 & 15 & 16 & 17 \\ 13 & 14 & 15 & 16 & 17 & 18 & 19 & 20 \\ \text{c1} & \text{c2} & 18 & 19 & \text{d1} & \text{d2} & 22 & 23 \\ \text{c2} & \text{c3} & 21 & 22 & \text{d2} & \text{d3} & 25 & 26 \\ 22 & 23 & 24 & 25 & 26 & 27 & 28 & 29 \\ \end{array} \right)$

matrixInsert[myM, myLM, 1, 2] // MatrixForm  (* one row down, two columns in *)


$\left( \begin{array}{cccccccc} 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \\ 4 & 5 & \text{a1} & \text{a2} & 8 & 9 & \text{c1} & \text{c2} \\ 7 & 8 & \text{a2} & \text{a3} & 11 & 12 & \text{c2} & \text{c3} \\ 10 & 11 & 12 & 13 & 14 & 15 & 16 & 17 \\ 13 & 14 & 15 & 16 & 17 & 18 & 19 & 20 \\ 16 & 17 & \text{c1} & \text{c2} & 20 & 21 & \text{d1} & \text{d2} \\ 19 & 20 & \text{c2} & \text{c3} & 23 & 24 & \text{d2} & \text{d3} \\ 22 & 23 & 24 & 25 & 26 & 27 & 28 & 29 \\ \end{array} \right)$

• That looks neat. What is the , 2 for in matrixInsert ? I just removed it and got the same result (Mathematica 10) And is there any way I can control the position of the small matrix within the quarter part of the large one?
– NOhs
Commented Apr 1, 2015 at 16:04
• @MrZ If you want to have a more general approach, then you may want to look at @kguler's answer here. But then your question should have made it clearer that you want a more general outcome.
– Jens
Commented Apr 1, 2015 at 16:14
• @Jens I thought that Mr.Wizard's code is already able to do what I asked for and that I was just unable to see how to change it accordingly. I do not understand why his code places the smaller matrix in the lower right corner.
– NOhs
Commented Apr 1, 2015 at 16:18
• @MrZ The positioning is in the PadLeft command. You could use ArrayPad there, too. That would allow arbitrary positioning.
– Jens
Commented Apr 1, 2015 at 16:21
• @MrZ (1) I hadn't thought about it but yes I guess in this case the result is the same even without the level parameter of MapThread. In fact MapThread can be eliminated. You can control placement by using the forth parameter of PadLeft, e.g. PadLeft[#, Dimensions@#2, #2, 1], or by using PadRight instead. ArrayPad could also be used but its padding specification is additive rather than absolute. Commented Apr 1, 2015 at 16:51

If the larger matrix consists of zeros (or other equal elements), one can use SparseArray function:

myM = {{a1, a2, c1, c2}, {a2, a3, c2, c3}, {c1, c2, d1, d2}, {c2, c3,
d2, d3}};
newM = SparseArray[{Band[{3, 3}] -> myM[[1 ;; 2, 1 ;; 2]],
Band[{3, 7}] -> myM[[1 ;; 2, 3 ;; 4]],
Band[{7, 3}] -> myM[[3 ;; 4, 1 ;; 2]],
Band[{7, 7}] -> myM[[3 ;; 4, 3 ;; 4]]}, {8, 8}]


Here Band[{3, 3}]->A says that starting from position {3,3} matrix A should be inserted. And myM[[i ;; j, k ;; m]] is just a submatrix of your small matrix. More information on Band can be found in documentation.

To get sparse matrix in normal form type:

newM // Normal

myM2 = Nest[Insert[#, 0, {{1}, {1}, {3}, {3}}] & /@ Transpose[#] &,  myM, 2];
myM2 // MatrixForm // TeXForm


$\left( \begin{array}{cccccccc} 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & \text{a1} & \text{a2} & 0 & 0 & \text{c1} & \text{c2} \\ 0 & 0 & \text{a2} & \text{a3} & 0 & 0 & \text{c2} & \text{c3} \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & \text{c1} & \text{c2} & 0 & 0 & \text{d1} & \text{d2} \\ 0 & 0 & \text{c2} & \text{c3} & 0 & 0 & \text{d2} & \text{d3} \\ \end{array} \right)$