Toeplitz matrix of toeplitz matrix

这一生的挚爱 提交于 2019-12-18 06:56:31

问题


I want to create a toeplitz matrix of toeplitz matrix. H1, H2 and H3 are toeplitz matrices already. My result should look like that: H1 0 0 H2 H1 0 H3 H2 H1 0 H3 H2 0 0 H3

The existing toeplitz-function only accepts vector, so I can't use it for matrix. Currently I'm using vstack to create the first column, then second column etc. and then I use hstackto merge all columns. This takes a lot of effort, since I have to specifically add np.zeros matrices at certain places. I can't think of a better way to concatenate numpy arrays, since there are only a few functions for that and none of them really fits my problem.


回答1:


Instead of nested calls to vstack and hstack, it will be more efficient to preallocate the final array, and then use a nested loop to fill in the array. You can initially use a higher dimensional array to keep the code clean.

For example, this script

import numpy as np

H1 = np.array([[11, 11], [11, 11]])
H2 = np.array([[22, 22], [22, 22]])
H3 = np.array([[33, 33], [33, 33]])

inputs = (H1, H2, H3)

# This assumes all the arrays in `inputs` have the same shape,
# and that the data type of all the arrays is the same as H1.dtype.
nh = len(inputs)
nrows = 2*nh - 1
m, n = H1.shape
# T is a 4D array.  For a given i and j, T[i, :, j, :] is a 2D array
# with shape (m, n).  T can be intepreted as a 2D array of 2D arrays. 
T = np.zeros((nrows, m, nh, n), dtype=H1.dtype)
for i, H in enumerate(inputs):
    for j in range(nh):
        T[i + j, :, j, :] = H

# Partially flatten the 4D array to a 2D array that has the desired
# block structure.
T.shape = (nrows*m, nh*n)

print(T)

prints

[[11 11  0  0  0  0]
 [11 11  0  0  0  0]
 [22 22 11 11  0  0]
 [22 22 11 11  0  0]
 [33 33 22 22 11 11]
 [33 33 22 22 11 11]
 [ 0  0 33 33 22 22]
 [ 0  0 33 33 22 22]
 [ 0  0  0  0 33 33]
 [ 0  0  0  0 33 33]]

(Note that the result is not a Toeplitz matrix; it is a block Toeplitz matrix.)




回答2:


Here's an alternative approach, for anyone interested in this problem

from pylab import *
import scipy.linalg

H1 = array([[11, 11], [11, 11]])
H2 = array([[22, 22], [22, 22]])
H3 = array([[33, 33], [33, 33]])

# Setup blocks 
t = array([zeros_like(H1), H1, H2, H3])
# Create index to each block, using toeplitz
idx = scipy.linalg.toeplitz(r_[1, 2, 3, zeros(2)], r_[1, zeros(2)]).astype(int)
# Index into blocks, transpose and reshape to get re-ordered array
#  copy is used to ensure memory is nicely ordered
T = t[idx].transpose(0, 2, 1, 3).reshape(10, 6).copy()

Most of the time is spent in scipy.linalg.toeplitz, making it slower than filling in memory in an array for the small matrices used here, so I'd recommend profiling before using this approach.



来源:https://stackoverflow.com/questions/36464191/toeplitz-matrix-of-toeplitz-matrix

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!