pythonnumpylinear-algebraconvolutiontoeplitz

How can I generate a Toeplitz matrix in the correct form for performing discrete convolution?


Discrete convolution can be performed via the Toeplitz matrix, as shown below (Wiki article):

enter image description here

Note that this is not the exact same form as as the general Toeplitz matrix, but it has experienced various shifts and zero-paddings.

Is there a way to achieve this in numpy purely based on roll, hstack etc., i.e. without using any for loops? I have tried all sorts of shifts but I can't really get it in to the form shown above.


Solution

  • Yes, you can use scipy.linalg.toeplitz:

    import numpy as np
    from scipy import linalg
    
    h = np.arange(1, 6)
    
    padding = np.zeros(h.shape[0] - 1, h.dtype)
    first_col = np.r_[h, padding]
    first_row = np.r_[h[0], padding]
    
    H = linalg.toeplitz(first_col, first_row)
    
    print(repr(H))
    # array([[1, 0, 0, 0, 0],
    #        [2, 1, 0, 0, 0],
    #        [3, 2, 1, 0, 0],
    #        [4, 3, 2, 1, 0],
    #        [5, 4, 3, 2, 1],
    #        [0, 5, 4, 3, 2],
    #        [0, 0, 5, 4, 3],
    #        [0, 0, 0, 5, 4],
    #        [0, 0, 0, 0, 5]])