user247534
user247534

Reputation: 123

Stacking matrices to make a matrix with sites of parent matrices map as block diagonals

How stack matrices as follows in python such that elements of parent matrices make a block diagonal at the same block diagonal site of the daughter matrix. example: I have four matrices AA,AB,BA, BB

I want to make the matrix out as shown in attached image.Making out from AA,AB,BA,BB

Upvotes: 1

Views: 149

Answers (1)

hpaulj
hpaulj

Reputation: 231475

In [35]: arr = np.arange(1,17).reshape(4,4)
In [36]: arr2 = arr.reshape(2,2,2,2)
In [37]: arr2
Out[37]: 
array([[[[ 1,  2],
         [ 3,  4]],

        [[ 5,  6],
         [ 7,  8]]],


       [[[ 9, 10],
         [11, 12]],

        [[13, 14],
         [15, 16]]]])

I did some trial and errors with transpose idea but didn't get any where.

But lets step back an try sliced insertion:

In [42]: out = np.zeros_like(arr)
In [43]: out[::2,::2]=arr2[0,0]
In [44]: out[::2,1::2]=arr2[0,1]
In [45]: out
Out[45]: 
array([[1, 5, 2, 6],
       [0, 0, 0, 0],
       [3, 7, 4, 8],
       [0, 0, 0, 0]])

This seems to be a workable solution. That could be put into a loop (or 2).

In [50]: out = np.zeros_like(arr)
In [51]: for i,j in np.ndindex(2,2):
    ...:     out[i::2,j::2] = arr2[i,j]
    ...:     
In [52]: out
Out[52]: 
array([[ 1,  5,  2,  6],
       [ 9, 13, 10, 14],
       [ 3,  7,  4,  8],
       [11, 15, 12, 16]])

Splitting out into the 4d array may help us visualize a transformation from Out[37]:

In [57]: out.reshape(2,2,2,2)
Out[57]: 
array([[[[ 1,  5],
         [ 2,  6]],

        [[ 9, 13],
         [10, 14]]],


       [[[ 3,  7],
         [ 4,  8]],

        [[11, 15],
         [12, 16]]]])

But maybe the more obvious iterative solution is fast enough.

This, for example, creates the correct 2x2 blocks:

In [59]: arr2.transpose(0,2,3,1)
Out[59]: 
array([[[[ 1,  5],
         [ 2,  6]],

        [[ 3,  7],
         [ 4,  8]]],


       [[[ 9, 13],
         [10, 14]],

        [[11, 15],
         [12, 16]]]])

and one more swap:

In [62]: arr2.transpose(2,0,3,1).reshape(4,4)
Out[62]: 
array([[ 1,  5,  2,  6],
       [ 9, 13, 10, 14],
       [ 3,  7,  4,  8],
       [11, 15, 12, 16]])

Upvotes: 1

Related Questions