卷积矩阵#
- 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]])