Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I transform blocks into a blockdiagonal matrix (NumPy)

Tags:

python

numpy

I have three same-size square matrices in NumPy. I would like to combine these to a block-diagonal matrix.

Example:

a1 = np.array([[1,1,1],[1,1,1],[1,1,1]])
a2 = np.array([[2,2,2],[2,2,2],[2,2,2]])
a3 = np.array([[3,3,3],[3,3,3],[3,3,3]])

r = np.array([[1,1,1,0,0,0,0,0,0],[1,1,1,0,0,0,0,0,0],[1,1,1,0,0,0,0,0,0],[0,0,0,2,2,2,0,0,0],[0,0,0,2,2,2,0,0,0],[0,0,0,2,2,2,0,0,0],[0,0,0,0,0,0,3,3,3],[0,0,0,0,0,0,3,3,3],[0,0,0,0,0,0,3,3,3]])

What is the best way to do this?

like image 807
Peter Smit Avatar asked Nov 11 '10 12:11

Peter Smit


People also ask

How do you create a NumPy block matrix?

To build a block of matrix, use the numpy. block() method in Python Numpy. Blocks in the innermost lists are concatenated along the last dimension (-1), then these are concatenated along the secondlast dimension (-2), and so on until the outermost list is reached.

How do I create an identity matrix in NumPy?

Step 1: Import numpy. Step 2: Take dimensions as input from the user. Step 3: Print the identity matrix using numpy. identity() function.


2 Answers

scipy.linalg has a block_diag function to do this automatically

>>> a1 = np.array([[1,1,1],[1,1,1],[1,1,1]])
>>> a2 = np.array([[2,2,2],[2,2,2],[2,2,2]])
>>> a3 = np.array([[3,3,3],[3,3,3],[3,3,3]])
>>> import scipy.linalg
>>> scipy.linalg.block_diag(a1, a2, a3)
array([[1, 1, 1, 0, 0, 0, 0, 0, 0],
       [1, 1, 1, 0, 0, 0, 0, 0, 0],
       [1, 1, 1, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 2, 2, 2, 0, 0, 0],
       [0, 0, 0, 2, 2, 2, 0, 0, 0],
       [0, 0, 0, 2, 2, 2, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 3, 3, 3],
       [0, 0, 0, 0, 0, 0, 3, 3, 3],
       [0, 0, 0, 0, 0, 0, 3, 3, 3]])
>>> r = np.array([[1,1,1,0,0,0,0,0,0],[1,1,1,0,0,0,0,0,0],[1,1,1,0,0,0,0,0,0], [0,0,0,2,2,2,0,0,0],[0,0,0,2,2,2,0,0,0],[0,0,0,2,2,2,0,0,0],[0,0,0,0,0,0,3,3,3],[0,0,0,0,0,0,3,3,3],[0,0,0,0,0,0,3,3,3]])
>>> (scipy.linalg.block_diag(a1, a2, a3)  == r).all()
True
like image 103
Josef Avatar answered Sep 18 '22 13:09

Josef


Since these answers, numpy has added a block function

In [695]: A=np.arange(1,10).reshape(3,3)
In [696]: B=np.arange(10,14).reshape(2,2)
In [698]: C = np.zeros((3,2),int)

In [699]: np.block([[A,C],[C.T,B]])
Out[699]: 
array([[ 1,  2,  3,  0,  0],
       [ 4,  5,  6,  0,  0],
       [ 7,  8,  9,  0,  0],
       [ 0,  0,  0, 10, 11],
       [ 0,  0,  0, 12, 13]])
like image 38
hpaulj Avatar answered Sep 18 '22 13:09

hpaulj