离散卷积定理
首先, 定义两种向量之间的运算: 乘积 \(f \circ g\) 和卷积 \(f*g\):
向量 \(f,g\) 之间的乘积计算 \(f \circ g: \mathbb{R}^n \times \mathbb{R}^n \mapsto \mathbb{R}^n\) 定义为 \[ (f \circ g)_k \triangleq f_k g_k, \quad k = 0,1,\ldots,n-1 \] 向量 \(f,g\) 之间的卷积计算 \(f*g: \mathbb{R}^n \times \mathbb{R}^n \mapsto \mathbb{R}^n\) 定义为 \[ (f*g)_k \triangleq \sum_{i=0}^{n-1} f_i g_{k-i}, \quad k = 0,1,\ldots,n-1 \] 我在这篇文章中希望说明的是, 向量的 乘积/卷积 运算, 总是可以通过 卷积/乘积 运算得到同样的结果. 将这两种运算联系到一起的就是离散卷积定理.
接下来我们将举一个数例, 说明卷积的计算过程
如果直接按照定义去计算卷积, 那么需要 (\(n\) 个分量 \(\times\) 每个分量需要 \(n\) 次乘法 \(=\) \(n^2\)) 计算量, 接下来我们将给出离散形式的卷积定理, 使用该方法, 并搭配上快速 Fourier 变换, 可以实现更高效率地计算卷积.
在证明该定理之前, 我们首先通过一个算例验证一下该定理:
使用离散卷积定理计算卷积的计算量为
- 物理空间到相空间的变换, \(2n^2\)
- 乘积 \(c \circ d\), \(n\)
- 相空间到物理空间的变换, \(n^2\)
总共需要 \(3n^2 + n\) 次乘法! 这比直接用定义计算还要多上 \(3\) 倍! 那么为什么说使用卷积定理计算速度更快呢? 这是因为在第 1 和第 3 步的矩阵乘法运算可以通过快速 Fourier 变换 (Fast Fourier Transformation, FFT) 替代, 这只需要 \(\mathcal{O}(n \log n)\) 次计算量.
接下来, 我们将用矩阵方法证明卷积定理. 首先将左侧的 \(f\) 向量拉成一个 \(n \times n\) 的矩阵, 矩阵的每一行对应上一行向右移动一个元素的位置, 右侧溢出的元素补缺到每一行的最左侧: \[ C_f \triangleq \begin{pmatrix} f_0 & f_{n-1} & \cdot & \cdot & f_{1} \\ f_{1} & f_{0} & f_{n-1} & \cdot & f_{2} \\ \cdot & f_{1} & f_{0} & \cdot & \cdot \\ \cdot & \cdot & \cdot & \cdot & f_{n-1} \\ f_{n-1} & f_{n-2} & \cdot & f_{1} & f_{0} \end{pmatrix} \] 可以看到, 卷积 \(f*g\) 结果就等于矩阵乘法 \(C_f g\) 得到的向量. 接下来我们考察矩阵 \(C_f\) 的特征值和特征向量. 立刻可以看到的是, 向量 \((1,1,\ldots,1)^T\) 是矩阵的一个特征向量, 并且对应的特征值为 \(\lambda_0 = \sum_{k=0}^{n-1} f_k\). 向量 \((1,w,\ldots,w^{n-1})^T\) 同样也是矩阵 \(C_f\) 的一个特征向量, 对应特征值为 \[ \lambda_1 = \sum_{k=0}^{n-1} f_{k} w^{n-k} = \sum_{k=0}^{n-1} f_{k} w^{-k} \] 我们可以验证第 \(j\) 行的计算结果, 左侧矩阵乘法得到的第 \(j\) 个分量为 \[ LHS = f_j \times 1 + f_{j-1} \times w + \cdots + f_0 w^j + f_{n-1} w^{j+1} + \ldots + f_{j+1} w^{n-1} \] 提取因子 \(w^j\) 得到 \[ LHS = w^j \left( \underbrace{f_j \times w^{-j} + f_{j-1} \times w^{-(j-1)} + \cdots + f_1 w^{-1} + f_0 w^0}_{\clubsuit} + \underbrace{f_{n-1} w^{1} + \ldots + f_{j+1} w^{n-j-1}}_{\spadesuit} \right) \] 对于式中 \(\spadesuit\) 部分, 我们可以除因子 \(w^n\) (并且不改变这一部分的大小, 因为 \(w^n=1\)) 得到 \[ f_{n-1} w^{1} + \ldots + f_{j+1} w^{n-j-1} = f_{n-1} w^{-(n-1)} + \ldots + f_{j+1} w^{-(j+1)} \] 重新排列就可以得到右端项向量第 \(j\) 行分量: \[ LHS = w^j \lambda_1 = RHS \] 一般的, 我们可以得到矩阵 \(C_f\) 的特征向量为 Fourier 变换矩阵 \(F\) 的列向量, 特征值为 \(f\) 的 Fourier 变换系数 \(c[f]\) 再乘 \(n\). 写成矩阵的形式为 \[ C_f F = F \Lambda_f,\quad \Lambda_f = n ~\mathrm{diag}~ (c[f]) \] 而这样的矩阵分解, 恰好对应于离散卷积定理. 我们现在用矩阵乘法将卷积 \(f*g\) 表示为周期矩阵 \(C_f\) 与向量 \(g\) 的矩阵乘积, \(C_f\) 可以分解为三个特殊的矩阵之间的乘积 \(F \Lambda_f (F)^{-1}\), 因此, 卷积计算过程也可以分解为对应地 “三步走”:
- 对向量 \(g\) 作变换 \((F)^{-1}g\), 得到关于 \(g\) 的 Fourier 变换系数 \(d\)
- \(\Lambda d\) 得到向量 \(n(c \circ d)\), 也就是 \(n\) 倍的 \(c\), \(d\) 乘积
- 对乘积 \(n(c \circ d)\) 作变换 \(F\), 得到卷积 \(f*g\)
由此得到如下离散卷积定理的表达式: \[ (F)^{-1}(f*g) = (F)^{-1} F \Lambda_f (F)^{-1} g = n \left[ (F)^{-1}f \right] \circ \left[ (F)^{-1}g \right] \tag{2} \] 我们可以立刻看到, 式 (2) 与前文得到的式 (1) 其实说明的是一回事.
按照上面的矩阵证明方法, 同样也可以说明反方向用乘积计算卷积也是可行的. 如果我们将变换后的向量 \(c\) \(d\) 之间卷积写成矩阵乘积的形式, 就得到 \[ c*d = C_c d \] 矩阵 \(C_c\) 的特征向量为变换矩阵 \(\overline F\) 的列向量, 特征值为 \(f[c]\), 写成矩阵的形式就得到 \[ C_c \overline F = \overline F \Lambda_c,\quad \Lambda_c = \mathrm{diag}~ (f[c]) \] 所以 \[ c*d = \overline F \Lambda_c (\overline F)^{-1} d = \frac{1}{n} \overline F \Lambda_c g = F^{-1}(f \circ g) \] 综合上述讨论, 我们可以将离散卷积定理总结为如下对称且优美的形式: \[ \begin{aligned} (F)^{-1}(f*g) &= n \left[ (F)^{-1}f \right] \circ \left[ (F)^{-1}g \right] \\ F^{-1}(f \circ g) &= \left[ (F)^{-1}f \right]*\left[ (F)^{-1}f \right] \end{aligned} \]