scipy.linalg.

卷积矩阵#

scipy.linalg.convolution_matrix(a, n, mode='full')[源代码]#

构造一个卷积矩阵。

构造表示一维卷积的 Toeplitz 矩阵 [1]。详情请参阅下方的注释。

参数:
a(…, m) array_like

要进行卷积的一维数组。N维数组被视为批次处理:沿着最后一个轴的每个切片都是一个要进行卷积的一维数组。

nint

结果矩阵中的列数。它表示与 a 进行卷积的输入长度。这类似于 numpy.convolve(a, v)v 的长度。

modestr

这类似于 numpy.convolve(v, a, mode) 中的 mode 参数。它必须是 ('full', 'valid', 'same') 中的一个。有关 mode 如何确定结果形状的详情,请参见下方。

返回:
A(…, k, n) ndarray

卷积矩阵,其行数 k 取决于 mode 参数

=======  =========================
 mode    k
=======  =========================
'full'   m + n -1
'same'   max(m, n)
'valid'  max(m, n) - min(m, n) + 1
=======  =========================

对于批次输入,输出的最后两个维度上形状为 (k, n) 的每个切片都与输入的最后一个维度上形状为 (m,) 的切片相对应。

另请参见

toeplitz

Toeplitz 矩阵

注释

以下代码

A = convolution_matrix(a, n, mode)

创建了一个 Toeplitz 矩阵 A,使得 A @ v 等同于使用 convolve(a, v, mode)。返回的数组始终具有 n 列。行数取决于指定的 mode 参数,如上所述。

在默认的 'full' 模式下,A 的条目由以下方式给出:

A[i, j] == (a[i-j] if (0 <= (i-j) < m) else 0)

其中 m = len(a)。例如,假设输入数组是 [x, y, z]。卷积矩阵的形式为

[x, 0, 0, ..., 0, 0]
[y, x, 0, ..., 0, 0]
[z, y, x, ..., 0, 0]
...
[0, 0, 0, ..., x, 0]
[0, 0, 0, ..., y, x]
[0, 0, 0, ..., z, y]
[0, 0, 0, ..., 0, z]

在 'valid' 模式下,A 的条目由以下方式给出:

A[i, j] == (a[i-j+m-1] if (0 <= (i-j+m-1) < m) else 0)

这对应于一个矩阵,其行是 'full' 模式下行的子集,其中 a 中的所有系数都包含在该行中。对于输入 [x, y, z],该数组看起来像

[z, y, x, 0, 0, ..., 0, 0, 0]
[0, z, y, x, 0, ..., 0, 0, 0]
[0, 0, z, y, x, ..., 0, 0, 0]
...
[0, 0, 0, 0, 0, ..., x, 0, 0]
[0, 0, 0, 0, 0, ..., y, x, 0]
[0, 0, 0, 0, 0, ..., z, y, x]

在 'same' 模式下,A 的条目由以下方式给出:

d = (m - 1) // 2
A[i, j] == (a[i-j+d] if (0 <= (i-j+d) < m) else 0)

'same' 模式的典型应用是当有一个长度为 n 的信号(其中 n 大于 len(a)),并且期望的输出是仍然长度为 n 的滤波信号。

对于输入 [x, y, z],该数组看起来像

[y, x, 0, 0, ..., 0, 0, 0]
[z, y, x, 0, ..., 0, 0, 0]
[0, z, y, x, ..., 0, 0, 0]
[0, 0, z, y, ..., 0, 0, 0]
...
[0, 0, 0, 0, ..., y, x, 0]
[0, 0, 0, 0, ..., z, y, x]
[0, 0, 0, 0, ..., 0, z, y]

在 1.5.0 版本中添加。

参考文献

示例

>>> import numpy as np
>>> from scipy.linalg import convolution_matrix
>>> A = convolution_matrix([-1, 4, -2], 5, mode='same')
>>> A
array([[ 4, -1,  0,  0,  0],
       [-2,  4, -1,  0,  0],
       [ 0, -2,  4, -1,  0],
       [ 0,  0, -2,  4, -1],
       [ 0,  0,  0, -2,  4]])

将通过 A 的乘法与使用 numpy.convolve 进行比较。

>>> x = np.array([1, 2, 0, -3, 0.5])
>>> A @ x
array([  2. ,   6. ,  -1. , -12.5,   8. ])

验证 A @ x 产生的结果与应用卷积函数的结果相同。

>>> np.convolve([-1, 4, -2], x, mode='same')
array([  2. ,   6. ,  -1. , -12.5,   8. ])

为了与上面显示的 mode='same' 情况进行比较,这里是相同系数和大小下,mode='full'mode='valid' 产生的矩阵。

>>> convolution_matrix([-1, 4, -2], 5, mode='full')
array([[-1,  0,  0,  0,  0],
       [ 4, -1,  0,  0,  0],
       [-2,  4, -1,  0,  0],
       [ 0, -2,  4, -1,  0],
       [ 0,  0, -2,  4, -1],
       [ 0,  0,  0, -2,  4],
       [ 0,  0,  0,  0, -2]])
>>> convolution_matrix([-1, 4, -2], 5, mode='valid')
array([[-2,  4, -1,  0,  0],
       [ 0, -2,  4, -1,  0],
       [ 0,  0, -2,  4, -1]])