pythonnumpylinear-programming

Numpy Matrix tiling and multiplication combination


I'm looking for a function capable of taking a m x n array, which repeats each row n times over a identity-like grid of m size.

For demo:

input = [[a1, b1, c1],
         [a2, b2, c2]]

output = [[a1, b1, c1,  0,  0,  0],
          [a1, b1, c1,  0,  0,  0],
          [a1, b1, c1,  0,  0,  0],
          [ 0,  0,  0, a2, b2, c2],
          [ 0,  0,  0, a2, b2, c2],
          [ 0,  0,  0, a2, b2, c2]]

Last time I asked something similar I was told of the Kronecker product, is there some similar function?


Solution

  • While looking similar, it appears to me that the given problem cannot be solved using a Kronecker product: with the latter, you could only manage to get repetitions of your complete input matrix as blocks of the result matrix.

    I stand corrected: For a solution that employs the Kronecker product, see @ThomasIsCoding's answer.

    In any case, what you need is the individual rows, repeated, as blocks of the result matrix. So that is what the code below does: it constructs a block matrix from the rows, using scipy.linalg.block_diag(), then repeats them as required, using numpy.repeat(). Note that block_diag() expects individual blocks as individual arguments, which is why a is unpacked with the * prefix.

    import numpy as np
    import scipy
    
    a = np.asarray([[11, 21, 31], [21, 22, 32], [31, 32, 33]])
    print(a)
    # [[11 21 31]
    #  [21 22 32]
    #  [31 32 33]]
    
    blocked = scipy.linalg.block_diag(*a)
    print(blocked)
    # [[11 21 31  0  0  0  0  0  0]
    #  [ 0  0  0 21 22 32  0  0  0]
    #  [ 0  0  0  0  0  0 31 32 33]]
    
    result = np.repeat(blocked, a.shape[1], axis=0)
    print(result)
    # [[11 21 31  0  0  0  0  0  0]
    #  [11 21 31  0  0  0  0  0  0]
    #  [11 21 31  0  0  0  0  0  0]
    #  [ 0  0  0 21 22 32  0  0  0]
    #  [ 0  0  0 21 22 32  0  0  0]
    #  [ 0  0  0 21 22 32  0  0  0]
    #  [ 0  0  0  0  0  0 31 32 33]
    #  [ 0  0  0  0  0  0 31 32 33]
    #  [ 0  0  0  0  0  0 31 32 33]]