网址:https://ww2.mathworks.cn/help/signal/ug/linear-and-circular-convolution.html
描述:本案例由1个示例构成
-
针对以上案例,采用Python语言实现。
-
线性卷积和循环卷积是本质不同的运算。然而,在某些条件下,线性卷积和循环卷积是等效的。建立这种等效关系具有重要意义。对于两个向量x和y,循环卷积等于二者的离散傅里叶变换(DFT)之积的逆DFT变换。了解线性卷积和循环卷积等效的条件,可让您使用DFT来高效地计算线性卷积。
包含N个点的向量x和包含L个点的向量y的线性卷积长度为N+L-1。
为了使x和y的循环卷积与之等效,在进行DFT之前,必须用零填充向量,使长度至少为N+L-1。对DFT的积求逆后,只保留前N+L-1个元素。
创建两个向量x和y,并计算两个向量的线性卷积。
python
import numpy as np
# from numpy.fft import fft, ifft
from scipy.fft import fft, ifft
from matplotlib import pyplot as plt
python
x = np.array([2, 1, 2, 1])
y = np.array([1, 2, 3])
输出长度为 4+3-1。用 0 填充两个向量,使长度为 4+3-1。求出两个向量的 DFT,将其相乘,并求乘积的逆 DFT。
python
clin = np.convolve(x,y)
N = len(x) + len(y) -1
num = np.arange(1, N+1, 1)
print(num)
print(clin)
[1 2 3 4 5 6]
[ 2 5 10 8 8 3]
python
xzeropad = np.zeros(N - len(x))
yzeropad = np.zeros(N - len(y))
xpad = np.concatenate([x, xzeropad])
ypad = np.concatenate([y, yzeropad])
print(xpad)
print(ypad)
[2. 1. 2. 1. 0. 0.]
[1. 2. 3. 0. 0. 0.]
python
ccirc = ifft(fft(xpad)*fft(ypad))
print(ccirc)
[ 2.+0.j 5.+0.j 10.+0.j 8.+0.j 8.-0.j 3.+0.j]
将向量填充到长度为12,并使用DFT之积的逆DFT求得循环卷积。仅保留前4+3-1个元素,以产生与线性卷积等效的结果。
python
xzeropads = np.zeros(12 - len(x))
yzeropads = np.zeros(12 - len(y))
xpads = np.concatenate([x, xzeropad])
ypads = np.concatenate([y, yzeropad])
ccircs = ifft(fft(xpad)*fft(ypad))
ccircs = ccircs[0:N]
python
plt.subplot(311)
plt.stem(num, clin)
plt.title('Linear Convolution of x and y')
plt.subplot(312)
plt.stem(num, ccirc)
plt.title('Circular Convolution of x and y')
plt.subplot(313)
plt.stem(num, ccircs)
plt.title('Circular Convolution of x and y')
plt.show()
填零后的向量xpad和ypad的循环卷积等效于x和y的线性卷积。保留ccirc的所有元素,因为输出长度为4+3-1。绘制线性卷积的输出和DFT之积的逆,以显示二者等效。
python