measure_theory
measure_theory

Reputation: 874

Numpy: function that creates block matrices

Say I have a dimension k. What I'm looking for is a function that takes k as an input and returns the following block matrix.

Let I be a k-dimensional identity matrix and 0 be k-dimensional square matrix of zeros

That is:

def function(k):
...
return matrix 

function(2) -> np.array([I, 0])

function(3) -> np.array([[I,0,0]
                         [0,I,0]])

function(4) -> np.array([[I,0,0,0]
                         [0,I,0,0],
                         [0,0,I,0]])

function(5) -> np.array([[I,0,0,0,0]
                         [0,I,0,0,0],
                         [0,0,I,0,0],
                         [0,0,0,I,0]])

That is, the output is a (k-1,k) matrix where identity matrices are on the diagonal elements and zero matrices elsewhere.

What I've tried:

I know how to create any individual row, I just can't think of a way to put it into a function so that it takes a dimension, k, and spits out the matrix I need.

e.g.

np.block([[np.eye(3),np.zeros((3, 3)),np.zeros((3, 3))],
          [np.zeros((3, 3)),np.eye(3),np.zeros((3, 3))]])

Would be the desired output for k=3

scipy.linalg.block_diag seems like it might be on the right track...

Upvotes: 3

Views: 1611

Answers (4)

SpghttCd
SpghttCd

Reputation: 10880

IMO, np.eye already has everything you need, as you can define number of rows and columns separately.
So your function should simply look like

def fct(k):
    return np.eye(k**2-k, k**2)

Upvotes: 3

Tai
Tai

Reputation: 7994

IIUC, you can also try np.fill_diagonal such that you create the right shape of matrices and then fill in the diagonal parts.

def make_block(k):
    arr = np.zeros(((k-1)*k, k*k))
    np.fill_diagonal(arr, 1)
    return arr

Upvotes: 0

BenBoulderite
BenBoulderite

Reputation: 336

If I understand you correctly, this should work:

a = np.concatenate((np.eye((k-1)*k),np.zeros([(k-1)*k,k])), axis=1)

(at least, when I set k=3 and compare with the np.block(...) expression you gave, both results are identical)

Upvotes: 1

cmitch
cmitch

Reputation: 273

There are two interpretations to your question. One is where you are basically creating a matrix of the form [[1, 0, 0], [0, 1, 0]], which can be mathematically represented as [I 0], and another where each element contains its own numpy array entirely (which does reduce computational ability but might be what you want).

The former: np.append(np.eye(k-1), np,zeros((k-1, 1)), axis=1)

The latter (a bit more complicated):

I = np.eye(m) #Whatever dimensions you want, although probably m==n
Z = np.eye(n) 
arr = np.zeros((k-1, k)
for i in range(k-1):
    for j in range(k):
        if i == j:
            arr[i,j] = np.array(I)
        else:
            arr[i,j] = np.array(Z)

I really have no idea how the second one would be useful, so I think you might be a bit confused on the fundamental structure of a block matrix if that's what you think you want. Generally [A b], for example, with A being a matrix and b being a vector, is generally thought of as now representing a single matrix, with block notation just existing for simplicity's sake. Hope this helps!

Upvotes: -1

Related Questions