Toeplitz矩阵的Toeplitz矩阵

时间:2016-04-06 23:39:31

标签: python numpy matrix concatenation

我想创建一个toeplitz矩阵的toeplitz矩阵。 H1,H2和H3已经是toeplitz矩阵。我的结果应该是这样的: H1 0 0 H2 H1 0 H3 H2 H1 0 H3 H2 0 0 H3

现有的toeplitz函数只接受向量,所以我不能将它用于矩阵。目前我正在使用vstack创建第一列,然后是第二列等,然后我使用hstack来合并所有列。这需要付出很多努力,因为我必须在某些地方专门添加np.zeros矩阵。我想不出更好的方法来连接numpy数组,因为只有少数几个函数,它们都不适合我的问题。

2 个答案:

答案 0 :(得分:3)

不是嵌套调用vstackhstack,而是预先分配最终数组,然后使用嵌套循环来填充数组。您最初可以使用更高维度的数组来保持代码清洁。

例如,这个脚本

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)

打印

[[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]]

(注意结果不是Toeplitz矩阵;它是block Toeplitz matrix。)

答案 1 :(得分:0)

对于对此问题感兴趣的人,这是另一种方法

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()

大多数时间都花在scipy.linalg.toeplitz中,这比在此处使用的小型矩阵的数组中填充内存要慢,因此我建议在使用此方法之前进行性能分析。